Class: Solace::Utils::AccountContext
- Inherits:
-
Object
- Object
- Solace::Utils::AccountContext
- Defined in:
- lib/solace/utils/account_context.rb
Overview
Utility for managing account context for composers
This utility is used to manage the accounts in a transaction composer and instructions composer. It provides methods for managing the accounts and their permissions, as well as compiling the accounts into the final format required by the instruction builders. Concerns like deduplication and ordering are handled by this utility.
Constant Summary collapse
- DEFAULT_ACCOUNT =
Returns The default account data with lowest level of permissions.
{ signer: false, writable: false, fee_payer: false }.freeze
Instance Attribute Summary collapse
-
#accounts ⇒ Object
The accounts in the transaction.
-
#DEFAULT_ACCOUNT ⇒ Object
The default account data.
-
#header ⇒ Object
The header for the transaction.
-
#pubkey_account_map ⇒ Object
The map of accounts.
Instance Method Summary collapse
-
#add_readonly_nonsigner(pubkey) ⇒ Object
Add a readonly account.
-
#add_readonly_signer(pubkey) ⇒ Object
Add a readonly signer account.
-
#add_writable_nonsigner(pubkey) ⇒ Object
Add a writable account.
-
#add_writable_signer(pubkey) ⇒ Object
Add a signer account.
-
#compile(loaded_accounts: []) ⇒ AccountContext
Compile accounts into final format.
-
#fee_payer?(pubkey) ⇒ Boolean
Predicate to check if an account is a fee payer.
-
#index_of(pubkey_str) ⇒ Integer
Index of a pubkey in the combined account space.
-
#indices ⇒ Hash{String => Integer}
Map of pubkey => index across the combined space (static keys followed by any loaded accounts), so instruction indices resolve the same way the runtime does once lookup tables are expanded.
-
#initialize ⇒ AccountContext
constructor
Initialize the account context.
-
#merge_from(other_context) ⇒ Object
Merge all accounts from another AccountContext into this one.
-
#readonly_nonsigner?(pubkey) ⇒ Boolean
Predicate to check if an account is readonly and not a signer.
-
#readonly_signer?(pubkey) ⇒ Boolean
Predicate to check if an account is a readonly signer.
-
#set_fee_payer(pubkey) ⇒ Object
Set the fee payer account.
-
#signer?(pubkey) ⇒ Boolean
Predicate to check if an account is a signer.
-
#writable?(pubkey) ⇒ Boolean
Predicate to check if an account is writable.
-
#writable_nonsigner?(pubkey) ⇒ Boolean
Predicate to check if an account is writable and not a signer.
-
#writable_signer?(pubkey) ⇒ Boolean
Predicate to check if an account is a writable signer.
Constructor Details
#initialize ⇒ AccountContext
Initialize the account context
62 63 64 65 66 67 |
# File 'lib/solace/utils/account_context.rb', line 62 def initialize @header = [] @accounts = [] @loaded_accounts = [] @pubkey_account_map = {} end |
Instance Attribute Details
#accounts ⇒ Object
The accounts in the transaction
53 54 55 |
# File 'lib/solace/utils/account_context.rb', line 53 def accounts @accounts end |
#DEFAULT_ACCOUNT ⇒ Object
The default account data
37 38 39 40 41 |
# File 'lib/solace/utils/account_context.rb', line 37 DEFAULT_ACCOUNT = { signer: false, writable: false, fee_payer: false }.freeze |
#header ⇒ Object
The header for the transaction
47 48 49 |
# File 'lib/solace/utils/account_context.rb', line 47 def header @header end |
#pubkey_account_map ⇒ Object
The map of accounts
59 60 61 |
# File 'lib/solace/utils/account_context.rb', line 59 def pubkey_account_map @pubkey_account_map end |
Instance Method Details
#add_readonly_nonsigner(pubkey) ⇒ Object
Add a readonly account
100 101 102 |
# File 'lib/solace/utils/account_context.rb', line 100 def add_readonly_nonsigner(pubkey) merge_account(pubkey, signer: false, writable: false) end |
#add_readonly_signer(pubkey) ⇒ Object
Add a readonly signer account
93 94 95 |
# File 'lib/solace/utils/account_context.rb', line 93 def add_readonly_signer(pubkey) merge_account(pubkey, signer: true, writable: false) end |
#add_writable_nonsigner(pubkey) ⇒ Object
Add a writable account
86 87 88 |
# File 'lib/solace/utils/account_context.rb', line 86 def add_writable_nonsigner(pubkey) merge_account(pubkey, signer: false, writable: true) end |
#add_writable_signer(pubkey) ⇒ Object
Add a signer account
79 80 81 |
# File 'lib/solace/utils/account_context.rb', line 79 def add_writable_signer(pubkey) merge_account(pubkey, signer: true, writable: true) end |
#compile(loaded_accounts: []) ⇒ AccountContext
Compile accounts into final format
Gets unique accounts and sorts them in the following order:
- Signers first (Solana requirement)
- Then writable accounts
- Then readonly accounts
For a v0 (versioned) transaction, accounts resolved through lookup tables leave the static account list entirely: the message carries only the static keys, and the runtime rebuilds the combined space [static..., loaded...] at execution time. Passing them keeps #index_of resolving against that combined space (so instructions index correctly) while dropping them from the static accounts and the header. They must be ordered writable-first to match the runtime's combined space. With no loaded accounts (the default) this is the legacy compilation, unchanged.
188 189 190 191 192 193 194 |
# File 'lib/solace/utils/account_context.rb', line 188 def compile(loaded_accounts: []) @loaded_accounts = loaded_accounts self.header = calculate_header(loaded_accounts) self.accounts = order_accounts(loaded_accounts) self end |
#fee_payer?(pubkey) ⇒ Boolean
Predicate to check if an account is a fee payer
108 109 110 |
# File 'lib/solace/utils/account_context.rb', line 108 def fee_payer?(pubkey) @pubkey_account_map.dig(pubkey, :fee_payer) end |
#index_of(pubkey_str) ⇒ Integer
Index of a pubkey in the combined account space
200 201 202 |
# File 'lib/solace/utils/account_context.rb', line 200 def index_of(pubkey_str) indices[pubkey_str] || -1 end |
#indices ⇒ Hash{String => Integer}
Map of pubkey => index across the combined space (static keys followed by any loaded accounts), so instruction indices resolve the same way the runtime does once lookup tables are expanded.
209 210 211 |
# File 'lib/solace/utils/account_context.rb', line 209 def indices (accounts + @loaded_accounts).each_with_index.to_h end |
#merge_from(other_context) ⇒ Object
Merge all accounts from another AccountContext into this one
163 164 165 166 167 168 |
# File 'lib/solace/utils/account_context.rb', line 163 def merge_from(other_context) other_context.pubkey_account_map.each do |pubkey, data| signer, writable, fee_payer = data.values_at(:signer, :writable, :fee_payer) merge_account(pubkey, signer: signer, writable: writable, fee_payer: fee_payer) end end |
#readonly_nonsigner?(pubkey) ⇒ Boolean
Predicate to check if an account is readonly and not a signer
156 157 158 |
# File 'lib/solace/utils/account_context.rb', line 156 def readonly_nonsigner?(pubkey) (acc = @pubkey_account_map[pubkey]) && !acc[:signer] && !acc[:writable] end |
#readonly_signer?(pubkey) ⇒ Boolean
Predicate to check if an account is a readonly signer
148 149 150 |
# File 'lib/solace/utils/account_context.rb', line 148 def readonly_signer?(pubkey) (acc = @pubkey_account_map[pubkey]) && acc[:signer] && !acc[:writable] end |
#set_fee_payer(pubkey) ⇒ Object
Set the fee payer account
72 73 74 |
# File 'lib/solace/utils/account_context.rb', line 72 def set_fee_payer(pubkey) merge_account(pubkey, signer: true, writable: true, fee_payer: true) end |
#signer?(pubkey) ⇒ Boolean
Predicate to check if an account is a signer
116 117 118 |
# File 'lib/solace/utils/account_context.rb', line 116 def signer?(pubkey) @pubkey_account_map.dig(pubkey, :signer) end |
#writable?(pubkey) ⇒ Boolean
Predicate to check if an account is writable
124 125 126 |
# File 'lib/solace/utils/account_context.rb', line 124 def writable?(pubkey) @pubkey_account_map.dig(pubkey, :writable) end |
#writable_nonsigner?(pubkey) ⇒ Boolean
Predicate to check if an account is writable and not a signer
140 141 142 |
# File 'lib/solace/utils/account_context.rb', line 140 def writable_nonsigner?(pubkey) (acc = @pubkey_account_map[pubkey]) && !acc[:signer] && acc[:writable] end |
#writable_signer?(pubkey) ⇒ Boolean
Predicate to check if an account is a writable signer
132 133 134 |
# File 'lib/solace/utils/account_context.rb', line 132 def writable_signer?(pubkey) (acc = @pubkey_account_map[pubkey]) && acc[:signer] && acc[:writable] end |