mcpField
S
seeker-connect

seeker-connect

github.com/solana-mobile开发87.9k 次安装1 周前更新
代码仓库

关于 seeker-connect

Seeker Connect 是面向 dapp 的 SDK,可将 Solana Mobile 认证设备上的浏览器页面连接到设备钱包。它通过 Wallet Standard 暴露钱包,并经由 Nostr 中继处理短时会话。

主要功能

  1. 01直接启动设备钱包
  2. 02注册 Wallet Standard 钱包
  3. 03连接、登录与签名流程
  4. 04通过 Nostr 中继传输加密载荷
  5. 05品牌化进度与错误界面

适用场景

  1. 01为 Web dapp 添加 Seeker 钱包访问
  2. 02支持钱包连接和消息签名
  3. 03从设备签名或提交 Solana 交易

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/solana-mobile/solana-mobile-skills --skill seeker-connect

安装后在 Claude Code 中输入/seeker-connect确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
imperative-api.md
kotlin.md
react-native.md
troubleshooting.md

详细介绍

Seeker Connect

Seeker Connect 可将设备上浏览器中打开的网页连接到 Solana Mobile 认证设备自带的钱包——Seeker 是首款此类设备。它是基于官方 Mobile Wallet Adapter 库构建的纯 dapp SDK:它提供 UX/DX 层,而非重新实现协议。通用 MWA 以“选择钱包”为中心,而 Seeker Connect 会通过 MWA 规范中的 Endpoint 专用 URI(Android App Link)机制直接启动设备钱包,通过 Nostr 中继传递会话,并提供 Seeker 品牌的进度和错误界面——应用看到的则是一个名为 “Seeker Connect” 的普通 Wallet Standard 钱包。

目标平台:Expo / React Native、Kotlin 和 Web 均已支持。 对于 Expo 或 React Native 应用,请先阅读下方的思路说明,然后参阅 references/react-native.md;对于 Kotlin 应用,请参阅 references/kotlin.md。运行 npx solana-mobile@latest create 时,expo-kit-minimal 和 kotlin-compose-minimal 模板已分别接入对应方案。两者都提供与 Web 相同的客户端 API,无需配置中继,品牌界面也由原生方式绘制。本文件其余部分介绍 Web 方案。在 React Native 中使用不带 Seeker Connect 的纯 Mobile Wallet Adapter 时,请使用 solana-mobile-wallet 技能。

思路说明——编写代码前请先阅读

  • 连接不会长期保持。 每次钱包交互(连接、签名消息、签名交易)都会开启一个独立的短时 MWA 会话,执行一次请求后便结束。每次交互都会启动钱包应用并显示品牌进度浮层——静默连接是唯一例外,它只读取缓存,不会开启会话。这是有意设计的,不要围绕它构建重连循环或保活逻辑。
  • “已连接”表示“持有已缓存的授权”。 首次调用 connect() 时,会保存钱包签发的 authToken 以及账户和功能信息(默认存储在 localStorage 中)。后续操作会静默重放该令牌,不会反复提示用户授权。
  • 断开连接只会在本地忘记令牌。 它特意不会调用钱包的 deauthorize,因为这样做会仅为断开连接而启动钱包应用。
  • 该功能只能在设备上完成。 在桌面设备上,连接会以 association-failed 失败——通常在几秒内发生,因为没有任何程序响应钱包启动;关联超时仅适用于钱包已启动但始终未连接的情况。请无条件注册该钱包;在其他设备上,它只会无法完成关联。
  • SDK 不提供默认中继。 请使用 Solana Mobile 的中继 relay.solanamobile.com;该服务免费,生产环境中也可使用。使用该服务需要同意 Solana Mobile 的条款,因此请告知开发者接受条款——步骤 2。

步骤 1:安装

新项目: Solana Mobile CLI 中的 react-kit-shadcn 模板已在 Solana Mobile 的中继上接入 Seeker Connect。接下来,create 命令输出的步骤会提示开发者在快速入门页面上接受中继条款:

npx solana-mobile@latest create my-app --template react-kit-shadcn

**现有应用:**安装 Wallet Standard 入口,以及下方代码片段导入的 Wallet Standard 辅助程序:

npm install @solana-mobile/seeker-connect-wallet-standard @solana/wallet-standard-features @wallet-standard/app @wallet-standard/features

请使用 0.1.2 或更高版本。早期版本基于 Mobile Wallet Adapter 2.x,当会话中断时,钱包调用可能会一直处于等待状态;0.1.2 则升级到 MWA 3.0,会以 session-closed 拒绝该调用。

Wallet Standard 软件包会将其他 Seeker Connect 软件包(core、ui、web)作为依赖项引入。不过,这些软件包不会重新导出,因此应用直接导入其中任何软件包时,也必须单独安装(例如,使用下方可选按钮时安装 @solana-mobile/seeker-connect-ui,使用参考资料中的命令式方式时安装 @solana-mobile/seeker-connect-web);pnpm 等严格的软件包管理器会拒绝导入未声明的传递依赖。

软件包用途
@solana-mobile/seeker-connect-core共享契约:配置、错误分类、SeekerLink 接口
@solana-mobile/seeker-connect-uiLit 元素:进度遮罩、错误对话框、品牌按钮
@solana-mobile/seeker-connect-wallet-standard入口——Wallet Standard 钱包
@solana-mobile/seeker-connect-web基于 Nostr 的 MWA 传输,以及命令式 SDK

步骤 2:设置中继

Seeker Connect 通过 Nostr 中继传输 MWA 的扩展远程通信协议,中继由 relayDomain 指定。dapp 与钱包之间的负载采用端到端加密;中继只传输密文。

请使用 relay.solanamobile.com。 Solana Mobile 为 Seeker Connect 运营该中继,可免费使用,包括在生产环境中使用。请传入不带协议的主机名;SDK 会自行添加 wss:// 协议。

请告知开发者接受中继条款。 使用 Solana Mobile 的中继需要同意 Solana Mobile 的条款。每次接入该中继时,都要说明这一点,并将开发者引导至接受条款的快速入门页面: https://docs.solanamobile.com/solana-mobile-stack/seeker-connect-quickstart

步骤 3:在启动时注册一次

在 UI 渲染前调用 registerSeekerConnect,以便钱包发现机制从首次渲染开始就能发现它。该调用必须在浏览器中运行——下方代码片段会读取 window,因此在 SSR 环境(Next.js 等)中,请将调用放在仅限客户端的模块中,或使用 typeof window !== 'undefined' 进行判断;在纯客户端渲染的应用中,可以在入口文件的模块作用域中调用:

import { registerSeekerConnect } from '@solana-mobile/seeker-connect-wallet-standard';

registerSeekerConnect({
  identity: {
    name: 'My Dapp',
    uri: window.location.origin,
    icon: '/icon.png', // resolved relative to uri; shown in the wallet's consent UI
  },
  relayDomain: 'relay.solanamobile.com', // requires accepting Solana Mobile's terms — Step 2
});

配置:

选项必填说明
associationTimeoutMs否启动等待多久后视为 association-failed。默认值为 30s
chain否授权时请求的链。默认值为 solana:mainnet
firstConnectWalletBaseUri否**除非 Solana Mobile 发布了可供填写的值,否则请保持未设置。**未设置时,首次连接会使用通用的 solana-wallet: 协议;设置后,页面会导航至该主机——请参阅 references/troubleshooting.md
identity是name、uri、可选的 icon。显示在钱包的授权界面中
relayDomain是承载会话流量的 Nostr 中继。请使用 relay.solanamobile.com——见步骤 2

registerSeekerConnect 还接受 seekerLink、authorizationCache 和 presenter 覆盖项——请参阅 references/imperative-api.md。

第 4 步:像使用其他钱包一样使用它

注册后,“Seeker Connect”会出现在 Wallet Standard 注册表中,因此 wallet-adapter、ConnectorKit、@solana/react-hooks 或原始的 @wallet-standard/app 列表都能自动发现它,无需进行其他配置。现有的连接按钮和签名代码会继续正常工作。

公开的功能:standard:connect、standard:disconnect、standard:events、solana:signMessage、solana:signIn,以及根据首次连接后钱包报告的功能,可能包含 solana:signTransaction 和/或 solana:signAndSendTransaction。

直接使用钱包:

import { SeekerConnectWalletName } from '@solana-mobile/seeker-connect-wallet-standard';
import { getWallets } from '@wallet-standard/app';
import { StandardConnect } from '@wallet-standard/features';

const seeker = getWallets()
  .get()
  .find((wallet) => wallet.name === SeekerConnectWalletName);
const { accounts } = await seeker.features[StandardConnect].connect();

在页面加载时恢复会话,使用静默连接——它会读取缓存,且不会启动钱包;如果没有缓存,则返回零个账户:

const { accounts } = await seeker.features[StandardConnect].connect({ silent: true });

检测签名路由是否可用。 首次连接前,默认认为两种交易功能都受支持;连接后,则会根据钱包的实际功能重新确定,并通过 standard:events 的 change 事件通知。调用前请先检查:

import { SolanaSignAndSendTransaction } from '@solana/wallet-standard-features';

const feature = seeker.features[SolanaSignAndSendTransaction];
if (feature) {
  const [{ signature }] = await feature.signAndSendTransaction({
    account,
    chain: seeker.chains[0],
    transaction,
  });
}

chain 是 Wallet Standard 输入的一部分,但此钱包会忽略它——网络由传递给 registerSeekerConnect 的值决定,并在每次调用时从缓存的授权中重放。系统不会交叉检查两者,因此,如果注册的是主网,却在某次调用中传入 solana:devnet,交易仍会在主网上提交,且不会报错。请传入 seeker.chains[0],以确保两者不会不一致;如需切换网络,请在注册时更改。

交易会以原始序列化字节(Uint8Array)跨越功能边界;legacy 和 v0 均受支持——使用应用已有的客户端库进行序列化即可。登录遵循 SIWS 规范,通过 solana:signIn 实现;domain 默认为 window.location.host。

登录用于验证用户身份时,权威方应是服务器,而非客户端:在服务器端签发一次性、短时有效的 nonce,并在创建会话前,于服务器端验证返回的消息和签名,包括预期的域名和有效期。seeker-genesis-token 技能会逐步讲解这套服务器端流程。

根据错误代码处理错误

钱包操作失败时,会以携带 code 的 SeekerConnectError 拒绝:

代码含义
association-failed没有钱包完成启动:超时、中继不可达或配置有误,或者设备不是 Seeker
authorization-declined用户拒绝了授权。缓存的令牌会被清除;下次连接时会重新请求授权
cancelled用户关闭了进度浮层。这是正常结果,不要将其显示为错误
request-declined钱包拒绝签名或提交
session-closed交互完成前会话已结束。在 signAndSendTransaction 之后,交易仍可能已经提交,且错误不包含签名——绝不要自动重试——请参阅 references/troubleshooting.md
wallet-error其他钱包报告的错误

另外三种失败会返回普通的 Error,它们属于误用,而非钱包操作结果:在钱包报告不支持 signAndSendTransaction 时调用它;在成功连接前调用任何签名方法;以及钱包响应登录请求时未返回结果。

这一区别决定了由谁显示错误。专用对话框只会在发生 SeekerConnectError 时触发,且不会因其他错误触发——上述代码中除 cancelled 外的所有代码都会触发;cancelled 是正常结果,应保持静默。三种普通的 Error 不会传递给展示组件,因此如果应用没有显示任何内容,它们就会被静默忽略。请先判断类型,再判断 .code:

import { SeekerConnectError, SeekerConnectErrorCode } from '@solana-mobile/seeker-connect-wallet-standard';

try {
  await seeker.features[StandardConnect].connect();
} catch (error) {
  if (error instanceof SeekerConnectError) {
    if (error.code === SeekerConnectErrorCode.cancelled) {
      return; // user closed the overlay; nothing to report
    }
    // The SDK has shown its dialog. Log, and leave the UI in the disconnected state.
    console.error(error);
    return;
  }
  // No dialog was shown for this one. Surface it yourself.
  showToast('Could not connect to the wallet.'); // your app's own error UI
  console.error(error);
}

可选:品牌化连接按钮

@solana-mobile/seeker-connect-ui 提供了一个使用 Shadow DOM 的 <seeker-connect-button> 自定义元素(无需宿主 CSS)。SDK 会在首次使用时定义其元素;要在启动时立即定义它们,请调用 defineSeekerConnectElements():

import { defineSeekerConnectElements } from '@solana-mobile/seeker-connect-ui';

defineSeekerConnectElements();
<seeker-connect-button theme="dark" variant="sign-in"></seeker-connect-button>

属性:disabled、theme="light" | "dark"(指定宿主页面的主题),以及 variant="connect"(默认值)或用于指定标签的 variant="sign-in"。请自行将 click 事件连接到连接或登录调用 — 此按钮仅负责呈现界面。

参考资料

  • references/kotlin.md — Kotlin SDK:Gradle 设置、SeekerConnect 构造函数、客户端方法、Compose 按钮和对话框,以及 SeekerConnectException 错误代码
  • references/react-native.md — React Native 包:安装、https 身份要求、客户端方法和原生按钮
  • references/imperative-api.md — 通过 createNostrSeekerLink().transact 使用非 Wallet-Standard 路径,以及 seekerLink / authorizationCache / presenter 覆盖项
  • references/troubleshooting.md — 关联失败、桌面测试、基于功能能力的特性、缓存行为

相关技能

  • seeker-domains — 显示 .skr 名称,而不是原始地址
  • seeker-genesis-token — 连接后验证 Seeker 设备所有权
  • solana-mobile — solana-mobile create 背后的 CLI、模板和工具链
  • solana-mobile-wallet — 在 React Native 应用中直接通过 Mobile Wallet Adapter 连接钱包,无需 Seeker Connect

链接

评论

支持 Markdown