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

# How It Works

> Understand the Action Codes flow

Action Codes create a simple bridge between users and apps without requiring wallet connections in your app.

## The core idea

Instead of your app connecting to the user's wallet directly, the user generates a **short-lived code** in their wallet app. Your app uses this code to request actions, and the user approves them in their wallet.

```mermaid theme={null}
sequenceDiagram
    participant User as User Wallet
    participant App as Your App
    participant AC as actioncode.app

    User->>AC: Generate code
    AC-->>User: 8-digit code
    User->>App: Share code
    App->>App: Attach action to code
    User->>AC: See pending request
    User->>AC: Approve with wallet
    AC-->>App: Signed result
```

## The lifecycle

Every action code goes through these stages:

<Steps>
  <Step title="Generated">
    User visits [actioncode.app](https://actioncode.app) and generates a code tied to their wallet.

    **Code is:** 8 digits, valid for \~2 minutes, tied to one wallet
  </Step>

  <Step title="Shared">
    User copies the code and shares it with your app — via text input, chat message, or any other method.

    **Your app:** Receives the code and calls `client.resolve(code)` to verify it
  </Step>

  <Step title="Attached">
    Your app attaches an action (transaction or message) to the code.

    **Your app:** Calls `client.attachTransaction(code, tx)` or `client.attachMessage(code, msg)`

    **User sees:** The pending request appears in actioncode.app
  </Step>

  <Step title="Approved">
    User reviews the request in actioncode.app and approves it with their wallet.

    **User wallet:** Signs the transaction or message
  </Step>

  <Step title="Finalized">
    Your app receives the signed result.

    **Your app:** `observeStatus()` returns `finalizedSignature` or `signedMessage`
  </Step>
</Steps>

## Status flow

```mermaid theme={null}
stateDiagram-v2
    [*] --> pending: Code generated
    pending --> attached: Action attached
    attached --> finalized: User approves
    attached --> expired: Timeout (~2 min)
    pending --> expired: Timeout (~2 min)
    finalized --> [*]
    expired --> [*]
```

| Status      | Meaning                                    |
| ----------- | ------------------------------------------ |
| `pending`   | Code exists, nothing attached yet          |
| `attached`  | Action attached, waiting for user approval |
| `finalized` | User approved, signature available         |
| `expired`   | Code timed out (codes live \~2 minutes)    |

## Where users get codes

Users generate codes at **[actioncode.app](https://actioncode.app)**.

<Steps>
  <Step title="Open in wallet browser">
    User opens actioncode.app in their wallet's built-in browser (Phantom, Solflare, Backpack, etc.)
  </Step>

  <Step title="Connect wallet">
    User connects their wallet to actioncode.app
  </Step>

  <Step title="Get code">
    User taps "Get Code" and receives an 8-digit code
  </Step>

  <Step title="Share code">
    User copies the code and shares it with your app
  </Step>

  <Step title="Approve requests">
    When your app attaches an action, user sees it in actioncode.app and can approve
  </Step>
</Steps>

<Tip>
  Users should keep actioncode.app open while waiting for requests. When you attach an action, it appears there for them to review and approve.
</Tip>

## Why this design?

| Benefit                   | How                                                          |
| ------------------------- | ------------------------------------------------------------ |
| **No wallet in your app** | You never handle private keys or wallet connections          |
| **Works everywhere**      | Bots, CLIs, embedded apps — anywhere you can accept 8 digits |
| **User stays in control** | They approve each action explicitly in their wallet          |
| **Short-lived**           | Codes expire in \~2 minutes, limiting exposure               |
| **One-time use**          | Each code can only be used once                              |

## SDK methods by stage

| Stage  | SDK Method                           | What it does                            |
| ------ | ------------------------------------ | --------------------------------------- |
| Verify | `client.resolve(code)`               | Check code validity, get wallet address |
| Attach | `client.attachTransaction(code, tx)` | Attach a transaction for signing        |
| Attach | `client.attachMessage(code, msg)`    | Attach a message for signing            |
| Watch  | `client.observeStatus(code)`         | Stream status updates                   |
| Check  | `client.getStatus(code)`             | One-time status check                   |

## Example: Sign-in flow

Here's how you might use Action Codes for wallet-based authentication:

```typescript theme={null}
import { ActionCodesClient } from '@actioncodes/sdk'

const client = new ActionCodesClient({
  authToken: process.env.ACTION_CODES_TOKEN
})

async function signIn(code: string) {
  // 1. Verify the code and get the wallet address
  const actionCode = await client.resolve(code)
  const walletAddress = actionCode.pubkey

  // 2. Create a sign-in message with a nonce
  const nonce = crypto.randomUUID()
  const message = `Sign in to MyApp\nWallet: ${walletAddress}\nNonce: ${nonce}`

  // 3. Attach it to the code
  await client.attachMessage(code, message)

  // 4. Wait for user to sign
  for await (const status of client.observeStatus(code)) {
    if (status.signedMessage) {
      // 5. Verify the signature matches the wallet
      const isValid = verifySignature(status.signedMessage, message, walletAddress)

      if (isValid) {
        // Create session for this wallet
        return createSession(walletAddress)
      }
    }
  }

  throw new Error('Sign-in failed or timed out')
}
```

## Next steps

<CardGroup cols={2}>
  <Card title="Quick Start" href="/quickstart" icon="rocket">
    Get integrated in 5 minutes
  </Card>

  <Card title="SDK Methods" href="/sdk/methods" icon="code">
    Full API reference
  </Card>

  <Card title="Recipes" href="/recipes/sign-transaction" icon="book">
    Real-world examples
  </Card>

  <Card title="Advanced: Protocol" href="/protocol/overview" icon="flask">
    How the protocol works internally
  </Card>
</CardGroup>
