Skip to main content
This section is for advanced users. You do NOT need to read this to use Action Codes. The SDK handles all protocol details automatically.

When to read this

  • You’re building a custom relayer
  • You’re implementing a new chain adapter
  • You’re auditing the protocol security
  • You want to understand how codes are derived
If you’re just integrating Action Codes into your app, see the Quick Start instead.

Performance

The protocol is designed for speed:

Two Strategies

Action Codes supports two code generation strategies:

Wallet Strategy (Default)

Direct code generation from a user’s wallet. This is what most apps use. How it works:
  • User’s wallet signs a canonical message
  • Code is derived using HMAC-SHA256 with the signature as entropy
  • Codes are cryptographically bound to the wallet’s public key
  • Validation is immediate — no external dependencies
Use cases: Direct authentication, transaction signing, user interactions

Delegation Strategy (Advanced)

Pre-authorize a delegated keypair to generate codes on behalf of a wallet. Enables relayer services and automated workflows. How it works:
  1. User signs a delegation proof specifying: delegated keypair, chain, expiration
  2. Delegated keypair generates codes bound to the proof
  3. Relayers validate both the delegation proof AND the code signature
Security guarantees:
  • Stolen proofs cannot generate codes (require delegated private key)
  • Relayers cannot generate codes (only validate)
  • Cross-proof attacks are prevented through cryptographic binding
Use cases: Relayer services, automated trading bots, complex workflows

Core Concepts

Code derivation

Action Codes are deterministically derived:
  • signature — Wallet signature over canonical message (secret entropy)
  • pubkey — User’s wallet public key
  • timestamp — Current time, rounded to 2-minute windows
This makes codes:
  • Unpredictable — Cannot be guessed without the signature
  • Verifiable — Can be validated with the signature
  • Time-bound — Expire after ~2 minutes

Canonical messages

Every code generation involves signing a deterministic JSON message:
Deterministic serialization (sorted keys, no whitespace) prevents ambiguity.

Protocol Meta

Metadata attached to transactions: Maximum size: 512 bytes. When iss is present, both issuer and intent owner must sign.

Architecture

Components

The Relayer

The relayer is a trusted intermediary that:
  1. Validates codes — Verifies signature, timestamp, format
  2. Stores state — Encrypted transaction/message payloads
  3. Coordinates flow — Connects apps and wallets
  4. Enforces expiry — Rejects expired codes
The official relayer is free to use and maintained by Action Codes.

Security Model

Threat mitigations

For full security details, see Security & Determinism.

Using the Protocol Package

For low-level protocol access:
Most applications should use @actioncodes/sdk instead, which wraps the protocol with a simpler API and handles relayer communication.

Chain Adapters

Adapters provide chain-specific functionality:
Currently supported: Solana See Adapter Reference for implementation details.

Best Practices

  1. Set appropriate TTL — Balance security vs. user experience
  2. Validate server-side — Never trust client-only validation
  3. Use delegation carefully — Set short expiration windows
  4. Monitor relayer activity — Watch for unusual patterns
  5. Handle expiry gracefully — Prompt users to regenerate codes