Skip to content

Use a Spending Limit

Transfers from a vault against an existing spending limit, signed by one of the limit's allowed signers — no proposal or threshold is involved. Works for SOL and for SPL Token / Token-2022 mints.

The amount draws down the limit's remaining allowance for the current period (SpendingLimitExceeded if it would overspend). For token limits, the destination's associated token account (ATA) must already exist.

Program method — use_spending_limit

Signs with payer + signer, then sends. For token limits, pass mint and token_program; the vault and destination ATAs are derived for you. Omit them for SOL.

ParameterTypeRequiredDefaultDescription
payerKeypairyesPays the fee; co-signs.
settings#to_syesThe settings account address.
signer#to_s · KeypairyesAn allowed signer of the limit; must sign.
spending_limit#to_syesThe SpendingLimit PDA to spend against.
smart_account#to_syesThe vault to transfer from.
destination#to_syesRecipient (receives SOL, or owns the destination ATA).
amountIntegeryesAmount to transfer, in the mint's base units.
decimalsIntegerno9Mint decimals (9 for SOL).
mint#to_snonilToken mint; omit for SOL.
token_program#to_snonilProgram owning the mint; required with mint.
memoStringnonilOptional indexing memo.

Plus the shared sign: / execute: controls and Solace::Transaction return — see Conventions.

ruby
# SOL spend
program.use_spending_limit(
  payer:          member,
  settings:       identity.settings_address,
  signer:         member,
  spending_limit: spending_limit,
  smart_account:  identity.smart_account_address,
  destination:    recipient.address,
  amount:         100_000_000 # 0.1 SOL
)

Composer — SquadsSmartAccountsUseSpendingLimitComposer

The composer does not derive ATAs — for token limits pass all four token accounts explicitly. For SOL, omit them.

ParameterTypeRequiredDefaultDescription
settings#to_syesThe settings account address.
signer#to_s · KeypairyesAn allowed signer; must sign.
spending_limit#to_syesThe SpendingLimit PDA.
smart_account#to_syesThe vault to transfer from.
destination#to_syesRecipient owner.
amountIntegeryesAmount (mint base units).
decimalsIntegerno9Mint decimals.
memoStringnonilIndexing memo.
mint#to_sno*nilToken mint (omit for SOL).
token_program#to_sno*nilProgram owning the mint.
smart_account_token_account#to_sno*nilThe vault's ATA for the mint.
destination_token_account#to_sno*nilThe destination owner's ATA (must exist).

* The four token fields are required together for token limits; all omitted for SOL.

ruby
composer = Solace::Composers::SquadsSmartAccountsUseSpendingLimitComposer.new(
  settings:       identity.settings_address,
  signer:         member.address,
  spending_limit: spending_limit,
  smart_account:  identity.smart_account_address,
  destination:    recipient.address,
  amount:         100_000_000
)

tx = Solace::TransactionComposer.new(connection:)
                                .add_instruction(composer)
                                .set_fee_payer(member)
                                .compose_transaction

tx.sign(member)
connection.send_transaction(tx.serialize)

Low-level instruction (advanced)

  • Discriminator: [41, 179, 70, 5, 194, 147, 239, 158]
  • Encodes (data): le_u64(amount) + decimals + option_string(memo)
ParameterTypeRequiredDefaultDescription
amountIntegeryesAmount to transfer.
decimalsIntegeryesMint decimals.
memoString, nilyesIndexing memo, or nil.
settings_indexIntegeryesIndex of the settings account.
signer_indexIntegeryesIndex of the allowed signer.
spending_limit_indexIntegeryesIndex of the SpendingLimit PDA.
smart_account_indexIntegeryesIndex of the vault.
destination_indexIntegeryesIndex of the destination.
system_program_indexIntegeryesIndex of the System program.
mint_indexIntegeryesIndex of the mint (program id when SOL).
smart_account_token_account_indexIntegeryesIndex of the vault ATA (program id when SOL).
destination_token_account_indexIntegeryesIndex of the destination ATA (program id when SOL).
token_program_indexIntegeryesIndex of the token program (program id when SOL).
program_indexIntegeryesIndex of the Squads program.

For SOL spends, the four token-account slots are filled with the Squads program id — Anchor's convention for an absent optional account.

Built on Solace