Note
This is the Anchor v2 copy of this example. Every anchor command on this page
needs the v2 CLI: cargo install anchor-cli --version 2.0.0-rc.1 --locked (avm has
no prebuilt binary for this pre-release). The Anchor v1 version of this example is in
../anchor-v1.
Authorize token transfers using an external secp256k1 delegate signature.
See the example overview for the signed-message format and nonce semantics shared with the Quasar variant, and the repository catalog.
UserAccountstate: the Solanaauthority, the delegate's 20-byteethereum_address, and anonceconsumed by each signature-authorized transfer.transfer_tokensrebuilds the authorized message onchain as keccak256(program id || user account || amount LE || recipient token account || nonce LE), recovers the signer with the secp256k1 syscall, compares the recovered Ethereum address to the stored one, and increments the nonce before the transfer CPI. Theauthoritymust also sign the transaction; the Ethereum signature supplements that check.authority_transfermoves tokens with only the Solana authority's signature.- Both transfer handlers use
transfer_checkedthroughanchor_spl::token_interface, so the program works against the Classic Token Program and the Token Extensions Program. - Tokens are held by a token account owned by a PDA derived from the user account's address; the program signs the CPI with that PDA.
From this directory (tokens/external-delegate-token-master/anchor/):
cargo build-sbfPrerequisites: Agave CLI (version in Anchor.toml [toolchain]) and Anchor.
Tests run in-process with LiteSVM. No local validator. Build first so target/deploy/external_delegate_token_master.so exists, then:
cargo testThe tests sign real transfer authorizations with a fixed secp256k1 key, send transactions, and assert token balances and nonce state, including the replay, wrong-amount, wrong-recipient, and wrong-authority failure paths.
Read the program source under programs/ and Anchor.toml for the program ID. For deployment, use anchor build && anchor deploy against your target cluster.