> ## Documentation Index
> Fetch the complete documentation index at: https://solanalabs-beeman-seeker-connect-docs-location-1e9568.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Install Seeker Connect and add a branded wallet connect flow to your app.

export const FooterDisclaimer = () => {
  return <p className="not-prose mt-16 text-center text-xs text-gray-500 dark:text-gray-400">
      Code samples on this page are subject to the{" "}
      <a className="underline underline-offset-2" href="https://www.apache.org/licenses/LICENSE-2.0">
        Apache 2.0 license
      </a>
      .
    </p>;
};

export const RelayUrl = () => {
  const RELAY_URL = "relay.solanamobile.com";
  const [open, setOpen] = useState(false);
  const [agreed, setAgreed] = useState(false);
  const [accepted, setAccepted] = useState(false);
  const [error, setError] = useState(false);
  const [copied, setCopied] = useState(false);
  const [copyFailed, setCopyFailed] = useState(false);
  const accept = () => {
    if (!agreed) {
      setError(true);
      return;
    }
    setError(false);
    setAccepted(true);
  };
  const cancel = () => {
    setOpen(false);
    setError(false);
  };
  const copy = async () => {
    try {
      await navigator.clipboard.writeText(RELAY_URL);
      setCopyFailed(false);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch {
      setCopyFailed(true);
    }
  };
  const terms = ["You will use this resource solely for authorized testing or educational purposes.", "You will not use this resource to perform any illegal activities or to harm others.", "You will not share this URL with unauthorized individuals.", "You understand that your activities may be logged and monitored.", "You understand that misuse of this resource may result in termination of access and potential legal consequences."];
  return <div className="not-prose my-4 rounded-xl border border-gray-200 dark:border-white/10 bg-gray-50 dark:bg-white/5">
{accepted ? <div className="flex flex-wrap items-center justify-between gap-3 p-4">
<div className="flex flex-col gap-1">
<span className="text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
Relay URL
</span>
<code className="text-sm text-gray-900 dark:text-gray-100">
{RELAY_URL}
</code>
</div>
<button onClick={copy} className="flex items-center rounded-lg bg-primary-dark px-3 py-1.5 text-sm font-medium text-white dark:bg-white dark:text-gray-950 hover:opacity-90">
{copyFailed ? "Copy failed" : copied ? "Copied" : "Copy"}
</button>
</div> : open ? <div className="flex flex-col gap-4 p-5">
<h3 className="m-0 text-base font-semibold text-gray-900 dark:text-gray-100">
Terms & Conditions
</h3>
<p className="m-0 text-sm text-gray-600 dark:text-gray-300">
By accessing the relay URL, you agree to the following terms and
conditions:
</p>
<ol className="m-0 flex list-decimal flex-col gap-1.5 pl-5 text-sm text-gray-600 dark:text-gray-300">
{terms.map(term => <li key={term}>{term}</li>)}
</ol>
<p className="m-0 text-sm text-gray-500 dark:text-gray-400">
This resource is provided "as is" without warranty of any kind,
express or implied.
</p>
<label className="flex items-start gap-2 text-sm text-gray-700 dark:text-gray-200">
<input type="checkbox" checked={agreed} onChange={e => {
    setAgreed(e.target.checked);
    if (e.target.checked) setError(false);
  }} className="mt-0.5" />
<span>
I have read, understood, and agree to the terms and conditions.
</span>
</label>
{error && <p className="m-0 text-sm text-red-600 dark:text-red-400">
You must accept to view the URL.
</p>}
<div className="flex gap-2">
<button onClick={cancel} className="rounded-lg border border-gray-300 px-3 py-1.5 text-sm font-medium text-gray-700 dark:border-white/20 dark:text-gray-200 hover:opacity-90">
Cancel
</button>
<button onClick={accept} className="rounded-lg bg-primary-dark px-3 py-1.5 text-sm font-medium text-white dark:bg-white dark:text-gray-950 hover:opacity-90">
Accept
</button>
</div>
</div> : <button onClick={() => setOpen(true)} className="flex w-full items-center justify-between gap-2 p-4 text-left text-sm font-medium text-gray-900 dark:text-gray-100">
<span>View Solana Mobile Nostr relay URL</span>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d="m9 18 6-6-6-6" />
</svg>
</button>}
</div>;
};

Connect your app directly to a Solana Mobile certified device's own wallet. The web SDK is available today; React Native and Android are planned.

Most apps use the Wallet Standard entry point, which discovers and drives Seeker Connect like any other [Wallet Standard](https://github.com/wallet-standard/wallet-standard) wallet — no Seeker-specific code in your connect flow.

## Install

<CodeGroup>
  ```bash npm theme={null}
  npm install @solana-mobile/seeker-connect-wallet-standard @wallet-standard/app @wallet-standard/features
  ```

  ```bash pnpm theme={null}
  pnpm add @solana-mobile/seeker-connect-wallet-standard @wallet-standard/app @wallet-standard/features
  ```

  ```bash bun theme={null}
  bun add @solana-mobile/seeker-connect-wallet-standard @wallet-standard/app @wallet-standard/features
  ```
</CodeGroup>

The Wallet Standard package pulls in the rest of the SDK transitively. `@wallet-standard/app` and `@wallet-standard/features` are the registry helpers most Solana apps already have.

## Relay URL

Seeker Connect utilizes Mobile Wallet Adapter's extended remote communication protocol over a Nostr relay. Any Nostr relay that supports public access and ephemeral events can be used. Solana Mobile provides a Nostr relay that satisfies these requirements and is free to use. Use of the Solana Mobile Nostr relay requires agreement to our terms.

<RelayUrl />

## Quick start

<Steps>
  <Step title="Register Seeker Connect">
    Call `registerSeekerConnect` once, early in your app's lifecycle. It adds the wallet to the page's Wallet Standard registry.

    ```ts theme={null}
    import { registerSeekerConnect } from "@solana-mobile/seeker-connect-wallet-standard";

    registerSeekerConnect({
      identity: { name: "My App", uri: window.location.origin, icon: "/icon.png" },
      relayDomain: "<relay-domain>",
    });
    ```
  </Step>

  <Step title="Discover the wallet">
    Find Seeker Connect like any other Wallet Standard wallet.

    ```ts theme={null}
    import { getWallets } from "@wallet-standard/app";
    import { SeekerConnectWalletName } from "@solana-mobile/seeker-connect-wallet-standard";

    const wallet = getWallets()
      .get()
      .find((w) => w.name === SeekerConnectWalletName);
    ```
  </Step>

  <Step title="Connect">
    `connect()` launches the wallet for user consent on the first connection, then returns the authorized accounts.

    ```ts theme={null}
    import { StandardConnect } from "@wallet-standard/features";

    const { accounts } = await wallet.features[StandardConnect].connect();
    console.log("connected as", accounts[0]?.address);
    ```
  </Step>
</Steps>

"Connected" means your app holds a wallet-issued authorization token — there is no long-lived transport. Each interaction runs in its own short-lived session and silently reauthorizes with the cached token, so the user is not re-prompted for consent.

<FooterDisclaimer />
