Class: Solace::Utils::AccountContext

Inherits:
Object
  • Object
show all
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.

Examples:

Usage

# Create a new account context
context = Solace::Utils::AccountContext.new

# Add accounts
context.add_writable_signer('pubkey1')
context.add_readonly_nonsigner('pubkey2')

# Merge accounts from another context
context = context.merge_from(other_context)

# Set fee payer
context.set_fee_payer('pubkey3')

# Compile the accounts
context.compile

See Also:

Since:

  • 0.0.3

Constant Summary collapse

DEFAULT_ACCOUNT =

Returns The default account data with lowest level of permissions.

Returns:

  • (Hash)

    The default account data with lowest level of permissions

Since:

  • 0.0.3

{
  signer:    false,
  writable:  false,
  fee_payer: false
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAccountContext

Initialize the account context

Since:

  • 0.0.3



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

#accountsObject

The accounts in the transaction



53
54
55
# File 'lib/solace/utils/account_context.rb', line 53

def accounts
  @accounts
end

#DEFAULT_ACCOUNTObject

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

#headerObject

The header for the transaction



47
48
49
# File 'lib/solace/utils/account_context.rb', line 47

def header
  @header
end

#pubkey_account_mapObject

The map of accounts



59
60
61
# File 'lib/solace/utils/account_context.rb', line 59

def 
  @pubkey_account_map
end

Instance Method Details

#add_readonly_nonsigner(pubkey) ⇒ Object

Add a readonly account

Parameters:

Since:

  • 0.0.3



100
101
102
# File 'lib/solace/utils/account_context.rb', line 100

def add_readonly_nonsigner(pubkey)
  (pubkey, signer: false, writable: false)
end

#add_readonly_signer(pubkey) ⇒ Object

Add a readonly signer account

Parameters:

Since:

  • 0.0.3



93
94
95
# File 'lib/solace/utils/account_context.rb', line 93

def add_readonly_signer(pubkey)
  (pubkey, signer: true, writable: false)
end

#add_writable_nonsigner(pubkey) ⇒ Object

Add a writable account

Parameters:

Since:

  • 0.0.3



86
87
88
# File 'lib/solace/utils/account_context.rb', line 86

def add_writable_nonsigner(pubkey)
  (pubkey, signer: false, writable: true)
end

#add_writable_signer(pubkey) ⇒ Object

Add a signer account

Parameters:

Since:

  • 0.0.3



79
80
81
# File 'lib/solace/utils/account_context.rb', line 79

def add_writable_signer(pubkey)
  (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.

Parameters:

  • loaded_accounts (Array<String>) (defaults to: [])

    Pubkeys resolved through lookup tables

Returns:

Since:

  • 0.0.3



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

Parameters:

  • pubkey (String)

    The pubkey of the account

Returns:

  • (Boolean)

    Whether the account is a fee payer

Since:

  • 0.0.3



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

Parameters:

  • pubkey_str (String)

    The public key of the account

Returns:

  • (Integer)

    The index in the combined space, or -1 if not found

Since:

  • 0.0.3



200
201
202
# File 'lib/solace/utils/account_context.rb', line 200

def index_of(pubkey_str)
  indices[pubkey_str] || -1
end

#indicesHash{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.

Returns:

  • (Hash{String => Integer})

    The indices of the pubkeys

Since:

  • 0.0.3



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

Parameters:

Since:

  • 0.0.3



163
164
165
166
167
168
# File 'lib/solace/utils/account_context.rb', line 163

def merge_from(other_context)
  other_context..each do |pubkey, data|
    signer, writable, fee_payer = data.values_at(:signer, :writable, :fee_payer)
    (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

Parameters:

  • pubkey (String)

    The pubkey of the account

Returns:

  • (Boolean)

    Whether the account is readonly and not a signer

Since:

  • 0.0.3



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

Parameters:

  • pubkey (String)

    The pubkey of the account

Returns:

  • (Boolean)

    Whether the account is a readonly signer

Since:

  • 0.0.3



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

Parameters:

Since:

  • 0.0.3



72
73
74
# File 'lib/solace/utils/account_context.rb', line 72

def set_fee_payer(pubkey)
  (pubkey, signer: true, writable: true, fee_payer: true)
end

#signer?(pubkey) ⇒ Boolean

Predicate to check if an account is a signer

Parameters:

  • pubkey (String)

    The pubkey of the account

Returns:

  • (Boolean)

    Whether the account is a signer

Since:

  • 0.0.3



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

Parameters:

  • pubkey (String)

    The pubkey of the account

Returns:

  • (Boolean)

    Whether the account is writable

Since:

  • 0.0.3



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

Parameters:

  • pubkey (String)

    The pubkey of the account

Returns:

  • (Boolean)

    Whether the account is writable and not a signer

Since:

  • 0.0.3



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

Parameters:

  • pubkey (String)

    The pubkey of the account

Returns:

  • (Boolean)

    Whether the account is a writable signer

Since:

  • 0.0.3



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