Class: Solrengine::Programs::Account

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Model
Defined in:
lib/solrengine/programs/account.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}) ⇒ Account

Returns a new instance of Account.



144
145
146
147
148
# File 'lib/solrengine/programs/account.rb', line 144

def initialize(attributes = {})
  attributes.each do |key, value|
    send(:"#{key}=", value) if respond_to?(:"#{key}=")
  end
end

Instance Attribute Details

#lamportsObject (readonly)

Returns the value of attribute lamports.



8
9
10
# File 'lib/solrengine/programs/account.rb', line 8

def lamports
  @lamports
end

#pubkeyObject (readonly)

Returns the value of attribute pubkey.



8
9
10
# File 'lib/solrengine/programs/account.rb', line 8

def pubkey
  @pubkey
end

Class Method Details

.account_name(name = nil) ⇒ Object

Set the Anchor account name used for discriminator computation. If not set, defaults to the unqualified Ruby class name.



21
22
23
24
25
26
27
# File 'lib/solrengine/programs/account.rb', line 21

def (name = nil)
  if name
    @account_name = name
  else
    @account_name || self.name&.split("::")&.last
  end
end

.borsh_field(name, type, **options) ⇒ Object



29
30
31
32
33
34
# File 'lib/solrengine/programs/account.rb', line 29

def borsh_field(name, type, **options)
  borsh_fields << { name: name.to_sym, type: type, **options }

  # Define attribute accessor
  attr_accessor name
end

.borsh_fieldsObject



36
37
38
# File 'lib/solrengine/programs/account.rb', line 36

def borsh_fields
  @borsh_fields ||= []
end

.discriminatorObject



40
41
42
# File 'lib/solrengine/programs/account.rb', line 40

def discriminator
  BorshTypes::Discriminator.()
end

.from_account_data(pubkey, data_base64, lamports: 0) ⇒ Object

Decode a single account from base64 data



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/solrengine/programs/account.rb', line 84

def (pubkey, data_base64, lamports: 0)
  raw = Base64.decode64(data_base64)

  # Skip empty/closed accounts
  if raw.empty? || raw.bytesize < 8
    raise DeserializationError, "Account data too short (#{raw.bytesize} bytes)"
  end

  # Skip 8-byte discriminator
   = raw[8..]
  buffer = Borsh::Buffer.new()

  instance = new
  instance.instance_variable_set(:@pubkey, pubkey)
  instance.instance_variable_set(:@lamports, lamports)

  borsh_fields.each do |field|
    value = BorshTypes.read_field(buffer, field[:type])
    instance.send(:"#{field[:name]}=", value)
  end

  instance
end

.program_id(id = nil) ⇒ Object



11
12
13
14
15
16
17
# File 'lib/solrengine/programs/account.rb', line 11

def program_id(id = nil)
  if id
    @program_id = id
  else
    @program_id
  end
end

.query(filters: [], commitment: "confirmed") ⇒ Object

Query program accounts via RPC with memcmp filters. At least one user-provided filter is required to prevent unbounded queries.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/solrengine/programs/account.rb', line 46

def query(filters: [], commitment: "confirmed")
  if filters.empty?
    raise Error, "At least one memcmp filter is required to prevent unbounded getProgramAccounts queries"
  end

  # Build full filter list: dataSize + discriminator + user filters
  all_filters = build_filters(filters)

  result = Solrengine::Rpc.client.request("getProgramAccounts", [
    program_id,
    {
      "encoding" => "base64",
      "commitment" => commitment,
      "filters" => all_filters
    }
  ])

  accounts = result.dig("result") || []

  accounts.filter_map do ||
    pubkey = ["pubkey"]
    data_base64 = .dig("account", "data", 0)
    lamports = .dig("account", "lamports")

    next unless data_base64

    begin
      (pubkey, data_base64, lamports: lamports)
    rescue DeserializationError, ArgumentError, RangeError => e
      if defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger
        Rails.logger.warn("Skipping malformed account #{pubkey}: #{e.message}")
      end
      nil
    end
  end
end

Instance Method Details

#sol_balanceObject

SOL balance of this account



151
152
153
154
# File 'lib/solrengine/programs/account.rb', line 151

def sol_balance
  return 0 unless lamports
  lamports.to_f / 1_000_000_000
end