-
Notifications
You must be signed in to change notification settings - Fork 0
Create an Associated Token Account
pzupan edited this page Jul 5, 2026
·
1 revision
A complete example showing how to create an SPL token account for a wallet. The ATA address is deterministic — derived from the wallet + mint — so no extra keypair is needed.
require 'base64'
require 'solana/ruby/kit'
Kit = Solana::Ruby::Kit
# ── 1. Signer and addresses ───────────────────────────────────────────────────
# Load your payer from 64 raw bytes (seed || public key).
# Replace File.binread with however you store your keypair.
payer = Kit::Signers.create_key_pair_signer_from_bytes(File.binread('wallet.bin'))
mint = Kit::Addresses.address('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v') # USDC
# ── 2. Build the instruction ──────────────────────────────────────────────────
# create_instruction derives the ATA address internally. Passing idempotent: true
# means the transaction succeeds even if the ATA already exists.
ix = Kit::Programs::AssociatedTokenAccount.create_instruction(
payer: payer.address,
wallet: payer.address,
mint: mint,
idempotent: true
)
# The derived ATA address is the second account in the instruction.
puts "ATA address : #{ix.accounts[1].address}"
# ── 3. Fetch a recent blockhash ───────────────────────────────────────────────
rpc = Kit::Rpc::Client.new(Kit::RpcTypes.mainnet)
bh = rpc.get_latest_blockhash
constraint = Kit::TransactionMessages::BlockhashLifetimeConstraint.new(
blockhash: bh.value.blockhash,
last_valid_block_height: bh.value.last_valid_block_height
)
# ── 4. Build the transaction message ─────────────────────────────────────────
message = Kit::Functional.pipe(
Kit::TransactionMessages.create_transaction_message(version: :legacy),
->(tx) { Kit::TransactionMessages.set_fee_payer(payer.address, tx) },
->(tx) { Kit::TransactionMessages.set_blockhash_lifetime(constraint, tx) },
->(tx) { Kit::TransactionMessages.append_instructions(tx, [ix]) }
)
# ── 5. Compile → sign → encode → send ────────────────────────────────────────
# compile_transaction_message serialises the message into Solana's on-wire
# format and reserves a nil signature slot for every required signer.
transaction = Kit::Transactions.compile_transaction_message(message)
# sign_transaction fills every slot and raises if any signer is missing.
signed = Kit::Transactions.sign_transaction(
[payer.key_pair.signing_key],
transaction
)
# wire_encode_transaction prepends the compact-u16 signature count + raw
# 64-byte signatures to the message bytes — the full payload for sendTransaction.
wire_base64 = Base64.strict_encode64(
Kit::Transactions.wire_encode_transaction(signed)
)
signature = rpc.send_transaction(wire_base64, skip_preflight: false)
puts "Transaction signature: #{signature}"