> ## Documentation Index
> Fetch the complete documentation index at: https://docs.walletsuite.io/llms.txt
> Use this file to discover all available pages before exploring further.

# End-to-End Walkthrough

> Run the full wallet journey in one sitting: create, list, check the balance, prepare, sign, broadcast, and track.

This page runs the whole journey in one sitting: create a wallet, see it in your wallet list, check its balance, prepare a transfer, sign it, then broadcast and track it. Everything up to the broadcast is safe with an unfunded wallet, so you can follow along before you move any real value.

The code mirrors the runnable samples that ship with the SDK, in the `examples/` directory of the SDK repository.

```bash theme={null}
export WALLETSUITE_API_KEY="your-api-key"
```

## Steps

<Steps>
  <Step title="Create a wallet">
    Create the wallet and derive an address. Save the wallet to durable storage you control, never a temp directory, and keep a secure backup. Your backup is your recovery.

    <CodeGroup>
      ```js journey.js theme={null}
      const { MpcClient } = require("@walletsuite/wallet");

      const client = new MpcClient("https://cosigner.walletsuite.io", process.env.WALLETSUITE_API_KEY);

      const wallet = await client.createWallet();
      await saveWallet(wallet); // your storage

      const address = client.deriveAddress(wallet, "base");
      console.log("fund me:", address);
      ```

      ```python journey.py theme={null}
      import os
      import walletsuite_wallet as ws

      client = ws.MpcClient("https://cosigner.walletsuite.io", api_key=os.environ["WALLETSUITE_API_KEY"])

      wallet = client.create_wallet()
      save_wallet(wallet)  # your storage

      address = client.derive_address(wallet, "base")
      print("fund me:", address)
      ```
    </CodeGroup>
  </Step>

  <Step title="See it in your wallet list">
    List your organization's wallets from `https://auth.walletsuite.io/v1/wallets` and find the new one by key id.

    <CodeGroup>
      ```js journey.js theme={null}
      const res = await fetch("https://auth.walletsuite.io/v1/wallets?limit=20", {
        headers: { "x-api-key": process.env.WALLETSUITE_API_KEY },
      });

      const { data } = await res.json();
      const keyId = client.walletKeyId(wallet);
      const mine = data.data.find((item) => item.keyId === keyId);
      ```

      ```python journey.py theme={null}
      import json
      import urllib.request

      req = urllib.request.Request(
          "https://auth.walletsuite.io/v1/wallets?limit=20",
          headers={"x-api-key": os.environ["WALLETSUITE_API_KEY"]},
      )
      with urllib.request.urlopen(req) as res:
          data = json.load(res)["data"]

      mine = next((item for item in data["data"] if item["keyId"] == client.wallet_key_id(wallet)), None)
      ```
    </CodeGroup>

    <Note>
      A new wallet appears in the list within a few seconds of creation. If it is not there on the first call, wait a moment and list again. The endpoint requires wallet access, returns newest first, and supports `limit` and `offset` query parameters.
    </Note>
  </Step>

  <Step title="Check the balance">
    Read the balance from the WalletSuite API. A fresh wallet reads zero, and that is fine. Signing needs no funds. Only the broadcast at the end needs a funded address.

    <CodeGroup>
      ```js journey.js theme={null}
      const balRes = await fetch(`https://api.walletsuite.io/api/balance/${address}?chain=base`, {
        headers: { "x-api-key": process.env.WALLETSUITE_API_KEY },
      });

      const bal = await balRes.json();
      console.log(bal.data.amount); // "0" on a fresh wallet
      ```

      ```python journey.py theme={null}
      req = urllib.request.Request(
          f"https://api.walletsuite.io/api/balance/{address}?chain=base",
          headers={"x-api-key": os.environ["WALLETSUITE_API_KEY"]},
      )
      with urllib.request.urlopen(req) as res:
          bal = json.load(res)

      print(bal["data"]["amount"])  # "0" on a fresh wallet
      ```
    </CodeGroup>

    <Note>
      The API host wraps results in an `{ ok, code, message, data }` envelope. The wallets endpoint uses `{ success, data }`. The status endpoint at the end of this page returns its fields bare. The snippets read each shape accordingly.
    </Note>
  </Step>

  <Step title="Prepare the transaction">
    Ask the API for the live nonce and gas parameters for a native transfer. Send to an address you control, and keep the amount small.

    <CodeGroup>
      ```js journey.js theme={null}
      const prepRes = await fetch("https://api.walletsuite.io/api/txs/prepare-sign", {
        method: "POST",
        headers: {
          "x-api-key": process.env.WALLETSUITE_API_KEY,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          chain: "base",
          txType: "TRANSFER_NATIVE",
          from: address,
          to: recipient, // an address you control
          amount: "0.00001",
        }),
      });

      const prepared = (await prepRes.json()).data;
      // { chain, chainId, from, to, valueWei, nonce,
      //   fee: { gasLimit, maxFeePerGas, maxPriorityFeePerGas, ... } }
      ```

      ```python journey.py theme={null}
      req = urllib.request.Request(
          "https://api.walletsuite.io/api/txs/prepare-sign",
          method="POST",
          headers={
              "x-api-key": os.environ["WALLETSUITE_API_KEY"],
              "Content-Type": "application/json",
          },
          data=json.dumps({
              "chain": "base",
              "txType": "TRANSFER_NATIVE",
              "from": address,
              "to": recipient,  # an address you control
              "amount": "0.00001",
          }).encode(),
      )
      with urllib.request.urlopen(req) as res:
          prepared = json.load(res)["data"]
      # { chain, chainId, from, to, valueWei, nonce,
      #   fee: { gasLimit, maxFeePerGas, maxPriorityFeePerGas, ... } }
      ```
    </CodeGroup>
  </Step>

  <Step title="Sign the transaction">
    Sign with `signEvm7702`, the EIP-7702 (type-4) smart-account signing path. Each signature is authorized automatically: the SDK mints a single-use, payload-bound signing intent for you, so you pass only the transfer. Give the gas limit extra headroom over the prepared estimate.

    <CodeGroup>
      ```js journey.js theme={null}
      const signed = await client.signEvm7702(
        wallet,
        8453,                                    // chain id (Base)
        Number(prepared.nonce),
        recipient,
        String(prepared.valueWei),               // wei, decimal string
        String(prepared.fee.maxPriorityFeePerGas),
        String(prepared.fee.maxFeePerGas),
        Number(prepared.fee.gasLimit) * 3,       // add headroom
        null, null, null, null                   // token, data, delegate, path
      );

      console.log(signed.raw);
      ```

      ```python journey.py theme={null}
      signed = client.sign_evm_7702(
          wallet,
          8453,                                      # chain id (Base)
          int(prepared["nonce"]),
          recipient,
          int(prepared["valueWei"]),                 # wei
          int(prepared["fee"]["maxPriorityFeePerGas"]),
          int(prepared["fee"]["maxFeePerGas"]),
          int(prepared["fee"]["gasLimit"]) * 3,      # add headroom
      )

      print(signed.raw)
      ```
    </CodeGroup>

    <Note>
      See [Signing intents](/mpc/signing-intents) for how each signature is authorized under the hood.
    </Note>
  </Step>

  <Step title="Broadcast and track">
    Send the signed transaction and poll its status by hash. This is the one step that needs a funded address.

    <CodeGroup>
      ```js journey.js theme={null}
      const sendRes = await fetch("https://api.walletsuite.io/api/txs/send", {
        method: "POST",
        headers: {
          "x-api-key": process.env.WALLETSUITE_API_KEY,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ chain: "base", signedTx: signed.raw }),
      });

      const hash = (await sendRes.json()).data.hash;

      const statusRes = await fetch(`https://api.walletsuite.io/api/txs/status/${hash}?chain=base`, {
        headers: { "x-api-key": process.env.WALLETSUITE_API_KEY },
      });

      const { status } = await statusRes.json(); // PENDING | SUCCEEDED | FAILED | UNKNOWN
      ```

      ```python journey.py theme={null}
      req = urllib.request.Request(
          "https://api.walletsuite.io/api/txs/send",
          method="POST",
          headers={
              "x-api-key": os.environ["WALLETSUITE_API_KEY"],
              "Content-Type": "application/json",
          },
          data=json.dumps({"chain": "base", "signedTx": signed.raw}).encode(),
      )
      with urllib.request.urlopen(req) as res:
          tx_hash = json.load(res)["data"]["hash"]

      req = urllib.request.Request(
          f"https://api.walletsuite.io/api/txs/status/{tx_hash}?chain=base",
          headers={"x-api-key": os.environ["WALLETSUITE_API_KEY"]},
      )
      with urllib.request.urlopen(req) as res:
          status = json.load(res)["status"]  # PENDING | SUCCEEDED | FAILED | UNKNOWN
      ```
    </CodeGroup>

    Poll every few seconds until you see `SUCCEEDED` or `FAILED`. `UNKNOWN` right after broadcast is normal. See [Broadcasting](/mpc/broadcasting) for the full state table.
  </Step>
</Steps>

## Next steps

<CardGroup cols={2}>
  <Card title="Signing intents" icon="ticket" href="/mpc/signing-intents">
    The authorization model behind every signature, handled for you by the SDK.
  </Card>

  <Card title="Signing" icon="signature" href="/mpc/signing">
    Every signing path across EVM, Tron, Bitcoin, and Solana.
  </Card>

  <Card title="Broadcasting" icon="paper-plane" href="/mpc/broadcasting">
    Broadcast paths and the transaction state table.
  </Card>

  <Card title="Shares & thresholds" icon="key" href="/mpc/key-shares">
    Where to keep the wallet you hold, and why it matters.
  </Card>
</CardGroup>
