Basic usage
Set up a programmatic signer, then sign and relay an action with the CLI or TypeScript.
CLI and clients are in progress
Follow the remaining work. If something is missing, confusing, or doesn't fit your workflow, open an issue.
The examples use the programs deployed on Devnet. Configure the Solana CLI to use Devnet:
Install
Build from source
The Rust crates on crates.io are placeholders and the npm package is not published yet. Use the source builds below.
You need Rust and the Solana CLI. The repository pins its toolchain.
Fund a fee payer
The fee payer signs and pays for every transaction you send, including the relay. It also funds the nonce account and the PDA below, so about 0.02 Devnet SOL is enough. Fund it from the Solana Faucet.
Create a relayer key and print its address for the faucet.
Derive the programmatic signer
The authority is an Ed25519 keypair. Its programmatic signer is a PDA derived from the authority's public key and has no private key of its own. Once the Ed25519 Signer program verifies the authority's signature, the PDA acts as a signer for the approved instructions.
Fund the PDA. The example action on this page transfers 0.001 SOL from it using Programmatic Signer.
Deriving the address gives the PDA no control over anything yet. For SOL, fund it. For tokens, stake, or a program, make the PDA the authority first. See migration.
Create a nonce account
Create the account and initialize it in the same transaction with the PDA as its authority. This account provides replay protection. Each authorization expects the account's current nonce value. Executor advances that value when the action runs, so the same authorization can never execute twice.
--cold-authority takes the public key of your offline Ed25519 signer. The CLI derives its programmatic signer PDA and stores that PDA as the nonce authority. --nonce-authority stores an address as given instead. The CLI generates a throwaway keypair for the new account unless you pass --nonce-keypair, fetches the rent minimum, sends CreateAccount and Initialize together, and reads the account back. The output includes the nonce account address and its first nonce value. Keep the address.
Read the nonce
Read the current value right before building an authorization. The signing machine is often air-gapped and cannot check it, so the value goes into the message on the online side.
The CLI checks that the account exists, belongs to the Nonce program, and is initialized. Then it prints the account details.
Build the execution message
The execution message is a legacy message with the instructions to run. This page builds a SOL transfer as an example, but yours can hold any instructions your application needs. It lists the PDA as a required signer and carries the current nonce in its blockhash field. In this example, the PDA is also the nonce authority. A different PDA can be the nonce authority if its own authority also signs the authorization.
The Solana CLI can compile a message without sending it. Pass the nonce value as the blockhash and the PDA as both the source and the fee payer.
The message field of the output is the base64 execution message. The --fee-payer flag only fills the message's first slot. The relayer pays the real fee. Do not use --nonce, which is for System durable nonces.
Simulate the action
transaction simulate will run the execution message through the executor program, so you can see what the action does before anyone signs.
Coming soon 🚧
Review and sign
The authorization message is what the authorities sign. It names the executor program that will run your execution message and the nonce account used for replay protection. Your signature covers all of it, including every byte of the execution message.
You can review and sign entirely offline.
transaction sign builds the authorization message from the execution message and signs it.
| Flag | Meaning |
|---|---|
--inner-message | The base64 execution message |
--nonce-account | The Nonce program account that protects the action |
--nonce-hash | The expected nonce value. Replaces the execution message's blockhash field |
--nonce-authority | The address stored in that nonce account, normally the PDA |
--authority | Repeat for every key whose PDA needs signer privilege |
--signer | Which key signs: a keypair file, usb://ledger, prompt://, or ASK. Repeat for several local keys. Each must appear in --authority |
For more than one authority, see collect signatures from several authorities.
What the review shows
Before signing, the CLI prints a review of what you are about to sign. Here it is for a sample 0.001 SOL transfer, trimmed to the key lines.
Review every line carefully before you press y, since your signature approves exactly what the review shows. The command then prints each address and signature, followed by the base64 authorization message. Nothing is submitted.
Pass this output to the relayer.
Relay
The relayer sends the authorization in a relay transaction. It puts the authorization message and signatures into a Submit instruction, adds a fresh blockhash, and signs as the fee payer. The authority does not sign the relay transaction, so it can stay offline.
Coming soon 🚧
Once the action executes, the nonce advances and the authorization can never run again.