Solana program for HelmutPay. Handles the handle registry, spending policies, agent wallets, and USDC transfer routing. Built with Anchor 0.31 and the Token-2022 program.
Deployed on devnet at DairzHtZ9QXkcKviMjTzMy3ezosGyj3w4pAT9AnoZ6mz.
The program is split into four instruction groups:
Handle Registry — Users register a personal handle (e.g. alice) that resolves to their Solana address. From there they can register agent handles under their namespace (alice/research-agent) that resolve to a separate keypair. Handles are stored as PDAs and can be updated or deregistered at any time.
Spending Policies — A SpendingPolicy account defines the rules for a wallet: per-transaction limits, daily and monthly caps, velocity limits, allowed and blocked recipient lists, a co-sign threshold, and an optional expiry. Policies are created once and can be updated or closed when no wallets are bound to them.
Agent Wallets — An AgentWallet is provisioned and tied to a policy. The wallet PDA is set as the authority on the associated USDC token account, so the program can sign transfers on behalf of the agent once policy checks pass. Wallets can be paused, resumed, or closed.
Transfers — Two paths for sending USDC. execute_transfer runs policy validation and fires the token CPI in one instruction. For amounts at or above the policy's co-sign threshold, queue_co_sign_transfer creates a PendingTransfer account and locks the funds. The wallet owner then approves, rejects, or lets it expire.
- Rust (stable)
- Solana CLI 1.18+
- Anchor CLI 0.31
- Node.js 18+ and Yarn
Install TypeScript dependencies:
yarn installanchor buildAfter the first build, sync the program ID into both Anchor.toml and lib.rs:
anchor keys syncTests run against devnet by default. Make sure you have a funded wallet at ~/.config/solana/helmutpay-devnet.json before running.
anchor testThe test suite covers handle registration, policy creation and updates, wallet lifecycle (create, pause, resume, close), direct transfers, co-sign queuing and approval, co-sign rejection, and policy closure.
- Generate a new wallet if you do not have one:
solana-keygen new --outfile ~/.config/solana/helmutpay-devnet.json- Point the Solana CLI at devnet and set the keypair:
solana config set --url devnet
solana config set --keypair ~/.config/solana/helmutpay-devnet.json- Airdrop enough SOL to cover deployment (you will need around 2 to 3 SOL):
solana airdrop 2- Build and sync:
anchor build
anchor keys sync- Deploy:
anchor deploy --provider.cluster devnetprograms/helmut-pay/src/
lib.rs # Entry point, instruction dispatch
state.rs # Account structs and size constants
errors.rs # Custom error codes
instructions/
handles.rs # Handle registry
policies.rs # Spending policy management
wallets.rs # Agent wallet lifecycle
transfers.rs # Transfer execution and co-sign flow
The agent's USDC token account must be created with the wallet PDA as its authority before calling create_wallet. This is what allows the program to sign token transfers via PDA seeds without holding a private key. The client is responsible for setting this up when provisioning a new agent.
USDC on devnet uses the Token-2022 program. The devnet mint is 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU and is validated at instruction time rather than hardcoded in the program.