End-to-end flows with @agonx402/sdk — register, fund, sign, settle, withdraw.
This page is the SDK-native version of Your First Payment. Everything is expressed in terms of @agonx402/sdk helpers. If you want the low-level protocol walkthrough, start there.
All examples target the live devnet deployment (program Ba2puU8D2CLD1dYfRQ4YBXxirdyz3zVLLChvMf9AqJ1Y, chain ID 1). Replace the programId and AGON_CHAIN_IDS.* value for other environments.
Channels are one-way and per-token. One channel per (payer, payee, token) tuple.
await client .createChannel({ owner: alice.publicKey, payeeOwner: bob.publicKey, tokenId, authorizedSigner: null, // or a delegated signer }) .signers([alice]) // bob also needs to sign if his inbound policy is ConsentRequired .rpc();const channelState = client.channelAddress( aliceInfo.participantId, bobInfo.participantId, tokenId,);
Hold on to Alice’s signed message. Bob doesn’t have to submit every one — he can keep stacking fresher messages and only submit the latest, since cumulative commitments supersede earlier ones.
The on-chain program walks each Ed25519 signature in order, finds the corresponding channel, and applies the new cumulative. The number passed as count must match the number of entries in the pre-instruction.
payeeRef is a 0-based index into the participant list in the order the round is signed. See Settlement → Clearing rounds for the full protocol behaviour.
If Alice wants a service key to sign commitments on her behalf (without giving it custody of funds), pass the delegate when creating the channel:
const signerKp = Keypair.generate();await client .createChannel({ owner: alice.publicKey, payeeOwner: bob.publicKey, tokenId, authorizedSigner: signerKp.publicKey, }) .signers([alice]) .rpc();// From now on, commitments are signed by signerKp, not alice:const ed25519Ix = createEd25519Instruction(signerKp, message);
See Authorized settler for the full trust model, including the difference between authorized_signer and authorized_settler (a per-message optional field emitted by createCommitmentMessage).