关于 seeker-connect
Seeker Connect 是面向 dapp 的 SDK,可将 Solana Mobile 认证设备上的浏览器页面连接到设备钱包。它通过 Wallet Standard 暴露钱包,并经由 Nostr 中继处理短时会话。
主要功能
- 01直接启动设备钱包
- 02注册 Wallet Standard 钱包
- 03连接、登录与签名流程
- 04通过 Nostr 中继传输加密载荷
- 05品牌化进度与错误界面
适用场景
- 01为 Web dapp 添加 Seeker 钱包访问
- 02支持钱包连接和消息签名
- 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.mdkotlin.mdreact-native.mdtroubleshooting.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-ui | Lit 元素:进度遮罩、错误对话框、品牌按钮 |
@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
链接
- MWA Web 文档:https://docs.solanamobile.com/get-started/web/installation
- Seeker Connect 文档:https://docs.solanamobile.com/solana-mobile-stack/seeker-connect
- Seeker Connect 快速入门(中继条款见此处):https://docs.solanamobile.com/solana-mobile-stack/seeker-connect-quickstart
- Seeker Connect 代码库:https://github.com/solana-mobile/seeker-connect