К основному содержанию
скилл CX Codex

seeker-connect — скилл для Claude Code: кошелёк Seeker в dapp

Подключает веб-, React Native- и Kotlin-приложения к встроенному кошельку на телефоне Seeker: вход через Solana, подпись сообщений и транзакций.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add solana-mobile/solana-mobile-skills --skill seeker-connect -a claude-code
Открыть на GitHub

Что делает seeker-connect

Скилл объясняет агенту, как встроить Seeker Connect — прослойку над Mobile Wallet Adapter. Каждое обращение к кошельку открывает короткую сессию MWA, выполняет один запрос и закрывается, поэтому reconnect-циклы и keep-alive тут только мешают. Для приложения это обычный кошелёк Wallet Standard с именем «Seeker Connect».

Три пути на выбор: Expo/React Native, Kotlin и веб. В шаблонах expo-kit-minimal и kotlin-compose-minimal из npx solana-mobile@latest create оба мобильных пути уже собраны, реле настраивать не нужно, а фирменный интерфейс рисуется нативно. Для веба регистрация идёт через registerSeekerConnect до первого рендера — под SSR вызов придётся вынести в клиентский модуль или обернуть проверкой typeof window !== 'undefined'.

Соединение работает только на самом устройстве: на десктопе подключение падает с ошибкой association-failed. Сессия ходит через Nostr-реле, и SDK своего реле не даёт — Solana Mobile предлагает relay.solanamobile.com, бесплатное и в продакшене, но с условием принять их условия. Берите версию 0.1.2 или новее: в более ранних релизах на MWA 2.x вызов кошелька мог зависнуть навсегда при обрыве сессии, а в 0.1.2 он отклоняется с session-closed.

Какие задачи решает

  • подключить кошелёк к Expo-приложению на телефоне Seeker
  • добавить вход через Solana в веб-dapp
  • подписать сообщение или транзакцию через встроенный кошелёк
  • зарегистрировать кошелёк Wallet Standard в приложении
  • разобраться, почему подключение падает с association-failed

Примеры запросов агенту

  • Добавь в мой Expo-проект подключение кошелька через Seeker Connect
  • Зарегистрируй кошелёк «Seeker Connect» и настрой relayDomain для веб-dapp
  • Почему у меня ошибка association-failed при подключении?

Как установить seeker-connect

1Через Skills CLI (Vercel)

npx skills add solana-mobile/solana-mobile-skills --skill seeker-connect -a claude-code

2Вручную: положить файлы

~/.claude/skills/seeker-connect/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/seeker-connect/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о seeker-connect

Как установить seeker-connect в Claude?

Выполните npx skills add solana-mobile/solana-mobile-skills --skill seeker-connect -a claude-code. Скилл окажется в ~/.claude/skills/seeker-connect/SKILL.md.

Что делает seeker-connect?

Описывает агенту подключение dapp к встроенному кошельку на телефоне Seeker: регистрацию кошелька Wallet Standard, настройку реле, вход через Solana и подпись сообщений с транзакциями.

Что нужно для работы Seeker Connect?

Реле relay.solanamobile.com и согласие с условиями Solana Mobile, а также версия 0.1.2 или новее. Подключение проходит только на самом устройстве — на десктопе оно падает с association-failed.

Исходный текст

SKILL.md · Apache-2.0
---
name: seeker-connect
description: Connect a web, React Native, or Kotlin dapp to the Seeker device's built-in wallet with Seeker Connect. Use when adding wallet connection, sign-in with Solana, message signing, or transaction signing to an Expo or React Native app on a Seeker phone, a Kotlin app on it, or a website that runs in its browser, registering the "Seeker Connect" Wallet Standard wallet, setting the Nostr relay for relayDomain, using the seeker-connect-button element or the SeekerConnectButton native view, installing @solana-mobile/seeker-connect-react-native or com.solanamobile:seeker-connect, or debugging SeekerConnectError codes like association-failed.
---

# Seeker Connect

Seeker Connect links a web page open in the browser **on the device** to a Solana Mobile
certified device's own wallet — Seeker is the first such device. It is a dapp-only SDK built
on top of the official Mobile Wallet Adapter libraries: a UX/DX layer, not a protocol
reimplementation. Where generic MWA centers on a "pick a wallet" chooser, Seeker Connect
launches the device wallet directly through the MWA spec's Endpoint-specific URI (Android
App Link) mechanism, carries the session over a Nostr relay, and ships Seeker-branded
progress and error UI — all exposed to the app as an ordinary Wallet Standard wallet named
**"Seeker Connect"**.

Targets: **Expo / React Native, Kotlin, and web are all available.** For an Expo or React
Native app, read the mental model below, then follow
[references/react-native.md](references/react-native.md); for a Kotlin app,
[references/kotlin.md](references/kotlin.md). The `expo-kit-minimal` and
`kotlin-compose-minimal` templates of `npx solana-mobile@latest create` ship each path wired
up. Both expose the same client API as the web, with no relay to configure and the branded UI
drawn natively. The rest of this file walks the web
path. Plain Mobile Wallet Adapter in React Native, without Seeker Connect, is the
`solana-mobile-wallet` skill.

## The mental model — read this before writing code

- **There is no long-lived connection.** Every wallet interaction (connect, sign message,
  sign transaction) opens its own short-lived MWA session, runs one request, and tears down.
  Each interaction launches the wallet app and shows a branded progress overlay — the one
  exception is a silent connect, which only reads the cache and never opens a session. This
  is by design — do not build reconnect loops or keep-alive logic around it.
- **"Connected" means "holds a cached authorization."** The first `connect()` stores a
  wallet-issued `authToken` plus accounts and capabilities (localStorage by default). Later
  operations replay that token silently — no repeated consent prompt.
- **Disconnect only forgets the token locally.** It deliberately never calls the wallet's
  `deauthorize`, because that would launch the wallet app just to disconnect.
- **It only completes on the device.** On desktop, connect fails with `association-failed` —
  typically within seconds, when nothing answers the wallet launch; the association timeout
  only applies to a wallet that launches but never connects. Register the wallet
  unconditionally; it simply won't get past association elsewhere.
- **The SDK ships no default relay.** Use Solana Mobile's, `relay.solanamobile.com`: it is
  free, including in production. Using it requires agreeing to Solana Mobile's terms, so tell
  the developer to accept them — Step 2.

## Step 1: install

**New project:** the `react-kit-shadcn` template from the Solana Mobile CLI ships with
Seeker Connect already wired up on Solana Mobile's relay. The next steps `create` prints tell
the developer to accept the relay terms on the quickstart page:

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

**Existing app:** install the Wallet Standard entry point plus the Wallet Standard helpers
the snippets below import from:

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

Use `0.1.2` or later. Earlier releases sit on Mobile Wallet Adapter 2.x, which can leave a
wallet call pending forever when the session drops; `0.1.2` moves to MWA 3.0, which rejects
it with `session-closed` instead.

The Wallet Standard package pulls in the other Seeker Connect packages (`core`, `ui`, `web`)
as dependencies. They are not re-exported, though — so also install any of them the app
imports from directly (`@solana-mobile/seeker-connect-ui` for the optional button below,
`@solana-mobile/seeker-connect-web` for the imperative path in the references); strict
package managers like pnpm refuse imports of undeclared transitive dependencies.

| Package | Role |
| --- | --- |
| `@solana-mobile/seeker-connect-core` | Shared contracts: config, error taxonomy, `SeekerLink` port |
| `@solana-mobile/seeker-connect-ui` | Lit elements: progress overlay, error dialog, branded button |
| `@solana-mobile/seeker-connect-wallet-standard` | **The entry point** — the Wallet Standard wallet |
| `@solana-mobile/seeker-connect-web` | MWA-over-Nostr transport, plus an imperative SDK |

## Step 2: set the relay

Seeker Connect carries MWA's extended remote communication protocol over a Nostr relay,
named by `relayDomain`. Payloads are end-to-end encrypted between dapp and wallet; the relay
carries ciphertext only.

**Use `relay.solanamobile.com`.** Solana Mobile runs it for Seeker Connect, and it is free to
use, including in production. Pass the bare host; the SDK adds the `wss://` scheme itself.

**Tell the developer to accept the relay terms.** Using Solana Mobile's relay requires
agreeing to Solana Mobile's terms. Whenever you wire it in, say so, and point the developer at
the quickstart page where they accept them:
https://docs.solanamobile.com/solana-mobile-stack/seeker-connect-quickstart

## Step 3: register once at startup

Call `registerSeekerConnect` before the UI renders, so wallet discovery sees it from the
first render. It must run in the browser — the snippet below reads `window`, so under SSR
(Next.js and similar) put the call in a client-only module or guard it with
`typeof window !== 'undefined'`; in a plain client-rendered app, module scope of the entry
file is fine:

```ts
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
});
```

Configuration:

| Option | Required | Notes |
| --- | --- | --- |
| `associationTimeoutMs` | no | How long a launch may take before `association-failed`. Default 30s |
| `chain` | no | Chain requested at authorization. Default `solana:mainnet` |
| `firstConnectWalletBaseUri` | no | **Leave unset** unless Solana Mobile publishes a value to paste. Unset, first connects use the generic `solana-wallet:` scheme; set, the page navigates to that host — see [references/troubleshooting.md](references/troubleshooting.md#first-connect-opens-a-generic-wallet-chooser) |
| `identity` | yes | `name`, `uri`, optional `icon`. Shown in the wallet's consent UI |
| `relayDomain` | yes | Nostr relay that carries the session traffic. Use `relay.solanamobile.com` — Step 2 |

`registerSeekerConnect` also accepts `seekerLink`, `authorizationCache`, and `presenter`
overrides — see [references/imperative-api.md](references/imperative-api.md).

## Step 4: use it like any other wallet

After registration, "Seeker Connect" appears in the Wallet Standard registry, so
wallet-adapter, ConnectorKit, `@solana/react-hooks`, or a raw `@wallet-standard/app` listing
all pick it up with no further wiring. Existing connect buttons and signing code keep
working.

Features exposed: `standard:connect`, `standard:disconnect`, `standard:events`,
`solana:signMessage`, `solana:signIn`, and — depending on the wallet's reported capabilities
after the first connect — `solana:signTransaction` and/or `solana:signAndSendTransaction`.

Working with the wallet directly:

```ts
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();
```

**Restore the session on page load** with a silent connect — it reads the cache and never
launches the wallet, resolving with zero accounts when there is nothing cached:

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

**Feature-detect the signing routes.** Until the first connect, both transaction features
are assumed; after it they are re-derived from the wallet's actual capabilities, announced
via a `standard:events` `change` event. Check before calling:

```ts
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` is part of the Wallet Standard input, but this wallet ignores it — the network is the
one passed to `registerSeekerConnect`, replayed from the cached authorization on every call.
Nothing cross-checks the two, so a per-call `solana:devnet` against a mainnet registration
submits on mainnet without complaint. Pass `seeker.chains[0]` so the two can never disagree,
and change networks at registration.

Transactions cross the feature boundary as raw serialized bytes (`Uint8Array`), legacy and
v0 both supported — serialize with whichever client library the app already uses. Sign-in
follows the SIWS spec via `solana:signIn`; `domain` defaults to `window.location.host`.

When sign-in authenticates a user, the server is the authority, not the client: issue a
single-use, short-lived nonce server-side, and verify the returned message and signature —
including the expected domain and validity window — on the server before creating a
session. The `seeker-genesis-token` skill walks through that server flow step by step.

## Handle errors by code

Wallet outcomes reject with a `SeekerConnectError` carrying a `code`:

| Code | Meaning |
| --- | --- |
| `association-failed` | No wallet completed the launch: timeout, relay unreachable or misconfigured, or not on a Seeker |
| `authorization-declined` | The user declined authorization. The cached token is wiped; the next connect prompts fresh consent |
| `cancelled` | The user dismissed the progress overlay. **A normal outcome — never surface it as an error** |
| `request-declined` | The wallet declined to sign or submit |
| `session-closed` | The session ended before the interaction completed. After `signAndSendTransaction` the transaction may still have landed, and the error carries no signature — never retry automatically — see [references/troubleshooting.md](references/troubleshooting.md#a-wallet-call-never-settles) |
| `wallet-error` | Any other wallet-reported error |

Three failures are plain `Error`s instead, and they are misuse rather than wallet outcomes:
`signAndSendTransaction` on a wallet that reported no support for it, any signing call before a
successful connect, and a sign-in the wallet answered without a result.

That distinction decides who shows the error. The branded dialog fires for `SeekerConnectError`
and nothing else — every code above except `cancelled`, which is a normal outcome and stays
silent. The three plain `Error`s never reach the presenter, so if the app shows nothing they
fail invisibly. Branch on the type first, then on `.code`:

```ts
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);
}
```

## Optional: the branded connect button

`@solana-mobile/seeker-connect-ui` ships a `<seeker-connect-button>` custom element in
Shadow DOM (no host CSS needed). The SDK defines its elements on first use; call
`defineSeekerConnectElements()` at startup to define them eagerly:

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

defineSeekerConnectElements();
```

```html
<seeker-connect-button theme="dark" variant="sign-in"></seeker-connect-button>
```

Attributes: `disabled`, `theme="light" | "dark"` (names the host page's theme), and
`variant="connect"` (default) or `variant="sign-in"` for the label. Wire `click` to the
connect or sign-in call yourself — the button is presentation only.

## Reference material

- [references/kotlin.md](references/kotlin.md) — the Kotlin SDK: Gradle setup, the
  `SeekerConnect` constructor, the client methods, the Compose button and dialogs, and
  `SeekerConnectException` codes
- [references/react-native.md](references/react-native.md) — the React Native package:
  install, `https` identity requirement, the client methods, and the native button
- [references/imperative-api.md](references/imperative-api.md) — the non-Wallet-Standard
  path via `createNostrSeekerLink().transact`, and the `seekerLink` /
  `authorizationCache` / `presenter` overrides
- [references/troubleshooting.md](references/troubleshooting.md) — association failures,
  desktop testing, capability-derived features, cache behavior

## Related skills

- `seeker-domains` — display `.skr` names instead of raw addresses
- `seeker-genesis-token` — verify Seeker device ownership after connecting
- `solana-mobile` — the CLI, templates, and toolchain behind `solana-mobile create`
- `solana-mobile-wallet` — wallet connection in React Native apps through Mobile Wallet
  Adapter directly, without Seeker Connect

## Links

- MWA web docs: https://docs.solanamobile.com/get-started/web/installation
- Seeker Connect docs: https://docs.solanamobile.com/solana-mobile-stack/seeker-connect
- Seeker Connect quickstart (relay terms live here): https://docs.solanamobile.com/solana-mobile-stack/seeker-connect-quickstart
- Seeker Connect repository: https://github.com/solana-mobile/seeker-connect

© solana-mobile · Apache-2.0 · solana-mobile/solana-mobile-skills

Похожие скиллы

Всё по теме «Мобильная разработка» →
appkit reown-com Скилл ведёт агента по интеграции Reown AppKit: модальное окно кошелька, смена сети, EVM, Solana и Bitcoin. Пригодится, когда в веб-приложение надо добавить подключение кошелька. CX Codex +1 1 100установок expo-module expo Справочник по разработке нативных модулей и view-компонентов на Swift, Kotlin и TypeScript для Expo приложений. Используй, когда пишешь новый модуль или добавляешь нативную функциональность — камеру, датчики, системные API. CX Codex +1 45 100установок expo-react-native-typescript Mindrally Скилл задаёт агенту правила разработки мобильных приложений на Expo, React Native и TypeScript: структура файлов, навигация, состояние, тесты. CX Codex +1 2 200установок onchainkit Mindrally Скилл для ИИ-агента, который помогает собирать onchain-приложения на OnchainKit SDK: компоненты, провайдеры, транзакции и обмен токенов. CX Codex +1 641установок design-mobile-apps designed-by-ai Генерирует экраны мобильных приложений через сервис Sleek и помогает перенести готовый макет в React Native или HTML. CX Codex +1 1 000 000установок vercel-react-native-skills vercel Набор правил по React Native и Expo для ИИ-агента: списки, анимации, навигация. Пригодится, когда агент правит мобильный код и надо, чтобы он делал это одинаково. CX Codex +1 255 200установок

Из того же набора6

integration-privy Скилл для подключения Privy-аутентификации к Solana Expo Android-приложению поверх Mobile Wallet Adapter через Sign-In-With-Solana. CX Codex +1 11 600установок seeker-domains Разбирает имена .skr в адреса кошельков и обратно, чтобы в профилях и списках друзей вместо обрезанных адресов стояли читаемые имена. CX Codex +1 11 600установок seeker-genesis-token Проверяет владение устройством Seeker через Sign-in-with-Solana и серверный поиск токена SGT. Помогает настроить закрытый доступ к наградам или защиту от мультиаккаунтов. CX Codex +1 11 600установок solana-mobile Скилл проводит через создание, настройку и отладку Solana Mobile приложений на Android: шаблоны Expo, проверка тулчейна, эмуляторы, локальный валидатор. CX Codex +1 11 700установок solana-mobile-publishing Помогает собрать, подписать и выпустить Android APK в Solana dApp Store через dapp-store CLI. Пригодится при первой публикации, выпуске обновлений и минте App NFT. CX Codex +1 6 700установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой