Module: Solrengine::Programs::Pda

Defined in:
lib/solrengine/programs/pda.rb

Constant Summary collapse

ED25519_ORDER =

Ed25519 curve order

2**252 + 27742317777372353535851937790883648493
IDL_SEED_TYPES =

Map an IDL-declared argument type string to the symbol to_seed expects. Unknown or composite types fall back to :raw.

{
  "u8" => :u8,
  "u16" => :u16,
  "u32" => :u32,
  "u64" => :u64,
  "string" => :string,
  "pubkey" => :pubkey,
  "publicKey" => :pubkey,
  "bytes" => :raw
}.freeze

Class Method Summary collapse

Class Method Details

.create_program_address(seeds, program_id) ⇒ Object

Create a program address from seeds. Returns nil if the address is on the Ed25519 curve.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/solrengine/programs/pda.rb', line 22

def self.create_program_address(seeds, program_id)
  program_id_bytes = Base58.base58_to_binary(program_id, :bitcoin)

  hash_input = seeds.map { |s| seed_bytes(s) }.join
  hash_input += program_id_bytes
  hash_input += "ProgramDerivedAddress"

  hash = Digest::SHA256.digest(hash_input)

  # Reject if the hash is a valid Ed25519 point (on-curve)
  return nil if on_curve?(hash)

  Base58.binary_to_base58(hash, :bitcoin)
end

.find_program_address(seeds, program_id) ⇒ Object

Find a valid Program Derived Address by iterating bump seeds from 255 down to 0. Returns [address_base58, bump].

Raises:



12
13
14
15
16
17
18
19
# File 'lib/solrengine/programs/pda.rb', line 12

def self.find_program_address(seeds, program_id)
  255.downto(0) do |bump|
    address = create_program_address(seeds + [ bump.chr ], program_id)
    return [ address, bump ] if address
  end

  raise Error, "Could not find a valid PDA for the given seeds"
end

.seed_type_for_idl(idl_type) ⇒ Object



50
51
52
# File 'lib/solrengine/programs/pda.rb', line 50

def self.seed_type_for_idl(idl_type)
  IDL_SEED_TYPES[idl_type] || :raw
end

.to_seed(value, type = :raw) ⇒ Object

Convert a value to seed bytes based on type



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/solrengine/programs/pda.rb', line 55

def self.to_seed(value, type = :raw)
  case type
  when :string
    value.encode("UTF-8").b
  when :pubkey
    Base58.base58_to_binary(value, :bitcoin)
  when :u8
    [ value ].pack("C")
  when :u16
    [ value ].pack("v")
  when :u32
    [ value ].pack("V")
  when :u64
    [ value ].pack("Q<")
  when :raw
    value.is_a?(String) ? value.b : value
  else
    raise Error, "Unknown seed type: #{type}"
  end
end