Module: Solana::SystemProgram
- Defined in:
- lib/solana/system_program.rb
Overview
System Program instruction encoders — the subset needed for DURABLE NONCE accounts (plus CreateAccount, which nonce creation needs). Mirrors the SplToken encoder pattern: each method returns a { program_id, accounts, data } hash for Transaction#add_instruction.
A durable nonce lets a transaction stay valid INDEFINITELY (until consumed) instead of expiring with a recent blockhash (~90s) — the canonical pattern for long / async / multi-party signing. A nonce-anchored tx sets recentBlockhash = the account’s stored nonce and MUST carry advance_nonce_account as its FIRST instruction, signed by the nonce authority.
Instruction data is ‘u32 LE index` + fields (the System Program’s bincode layout). Indices: CreateAccount 0, AdvanceNonceAccount 4, WithdrawNonceAccount 5, InitializeNonceAccount 6, AuthorizeNonceAccount 7. Each encoder is byte-match tested against a known-good @solana/web3.js reference before being trusted.
Constant Summary collapse
- PROGRAM_ID =
32 zero bytes
Transaction::SYSTEM_PROGRAM_ID
- RECENT_BLOCKHASHES_SYSVAR =
Keypair.decode_base58("SysvarRecentB1ockHashes11111111111111111111")
- RENT_SYSVAR =
Transaction::SYSVAR_RENT_PUBKEY
- NONCE_ACCOUNT_LENGTH =
80
Class Method Summary collapse
-
.advance_nonce_account(nonce:, authority:) ⇒ Object
AdvanceNonceAccount (ix 4): MUST be the first instruction of any tx anchored on this nonce.
-
.authorize_nonce_account(nonce:, authority:, new_authority:) ⇒ Object
AuthorizeNonceAccount (ix 7): rotate the nonce authority.
-
.create_account(from:, new_account:, lamports:, space:, owner:) ⇒ Object
CreateAccount (ix 0): fund + allocate ‘space` bytes owned by `owner`.
-
.initialize_nonce_account(nonce:, authority:) ⇒ Object
InitializeNonceAccount (ix 6): turn a freshly-created account into a nonce account owned by ‘authority`.
-
.normalize(value) ⇒ Object
base58 string / Keypair / 32-byte binary → 32-byte binary.
-
.u32(n) ⇒ Object
— helpers ————————————————————–.
- .u64(n) ⇒ Object
-
.withdraw_nonce_account(nonce:, to:, authority:, lamports:) ⇒ Object
WithdrawNonceAccount (ix 5): reclaim lamports from the nonce account.
Class Method Details
.advance_nonce_account(nonce:, authority:) ⇒ Object
AdvanceNonceAccount (ix 4): MUST be the first instruction of any tx anchored on this nonce. The ‘authority` signs it.
41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/solana/system_program.rb', line 41 def advance_nonce_account(nonce:, authority:) { program_id: PROGRAM_ID, accounts: [ { pubkey: normalize(nonce), is_signer: false, is_writable: true }, { pubkey: RECENT_BLOCKHASHES_SYSVAR, is_signer: false, is_writable: false }, { pubkey: normalize(), is_signer: true, is_writable: false } ], data: u32(4) } end |
.authorize_nonce_account(nonce:, authority:, new_authority:) ⇒ Object
AuthorizeNonceAccount (ix 7): rotate the nonce authority. Current authority signs.
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/solana/system_program.rb', line 83 def (nonce:, authority:, new_authority:) { program_id: PROGRAM_ID, accounts: [ { pubkey: normalize(nonce), is_signer: false, is_writable: true }, { pubkey: normalize(), is_signer: true, is_writable: false } ], data: u32(7) + normalize() } end |
.create_account(from:, new_account:, lamports:, space:, owner:) ⇒ Object
CreateAccount (ix 0): fund + allocate ‘space` bytes owned by `owner`. Both `from` (payer) and `new_account` must sign.
27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/solana/system_program.rb', line 27 def create_account(from:, new_account:, lamports:, space:, owner:) data = u32(0) + u64(lamports) + u64(space) + normalize(owner) { program_id: PROGRAM_ID, accounts: [ { pubkey: normalize(from), is_signer: true, is_writable: true }, { pubkey: normalize(new_account), is_signer: true, is_writable: true } ], data: data } end |
.initialize_nonce_account(nonce:, authority:) ⇒ Object
InitializeNonceAccount (ix 6): turn a freshly-created account into a nonce account owned by ‘authority`. Paired with create_account in one tx.
70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/solana/system_program.rb', line 70 def initialize_nonce_account(nonce:, authority:) { program_id: PROGRAM_ID, accounts: [ { pubkey: normalize(nonce), is_signer: false, is_writable: true }, { pubkey: RECENT_BLOCKHASHES_SYSVAR, is_signer: false, is_writable: false }, { pubkey: RENT_SYSVAR, is_signer: false, is_writable: false } ], data: u32(6) + normalize() } end |
.normalize(value) ⇒ Object
base58 string / Keypair / 32-byte binary → 32-byte binary.
100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/solana/system_program.rb', line 100 def normalize(value) if value.is_a?(Keypair) value.public_key_bytes elsif value.is_a?(String) && value.bytesize == 32 value.b elsif value.is_a?(String) Keypair.decode_base58(value) else value end end |
.u32(n) ⇒ Object
— helpers ————————————————————–
96 |
# File 'lib/solana/system_program.rb', line 96 def u32(n) = [n].pack("V") |
.u64(n) ⇒ Object
97 |
# File 'lib/solana/system_program.rb', line 97 def u64(n) = [n].pack("Q<") |
.withdraw_nonce_account(nonce:, to:, authority:, lamports:) ⇒ Object
WithdrawNonceAccount (ix 5): reclaim lamports from the nonce account.
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/solana/system_program.rb', line 54 def withdraw_nonce_account(nonce:, to:, authority:, lamports:) { program_id: PROGRAM_ID, accounts: [ { pubkey: normalize(nonce), is_signer: false, is_writable: true }, { pubkey: normalize(to), is_signer: false, is_writable: true }, { pubkey: RECENT_BLOCKHASHES_SYSVAR, is_signer: false, is_writable: false }, { pubkey: RENT_SYSVAR, is_signer: false, is_writable: false }, { pubkey: normalize(), is_signer: true, is_writable: false } ], data: u32(5) + u64(lamports) } end |