Module: Solace::Utils::PDA
- Included in:
- PublicKey
- Defined in:
- lib/solace/utils/pda.rb
Overview
Raised when Program Derived Address (PDA) generation fails.
This error is raised when attempting to derive a PDA that is invalid, typically because the seeds and program ID combination results in a point that lies on the Ed25519 curve (PDAs must be off-curve). This is a rare occurrence but can happen with certain seed combinations.
Defined Under Namespace
Classes: InvalidPDAError
Constant Summary collapse
- PDA_MARKER =
!@attribute PDA_MARKER PDA_MARKER is the marker used in PDA calculations
'ProgramDerivedAddress'- MAX_BUMP_SEED =
!@attribute MAX_BUMP_SEED The maximum seed value for PDA calculations
255
Class Method Summary collapse
-
.create_program_address(seeds, program_id) ⇒ String
Creates a program address from seeds and program ID.
-
.find_program_address(seeds, program_id) ⇒ Array
Finds a valid program address by trying different seeds.
-
.looks_like_base58_address?(string) ⇒ Boolean
Checks if a string looks like a base58 address.
-
.seed_to_bytes(seed) ⇒ Array
Prepares a list of seeds for creating a program address.
Class Method Details
.create_program_address(seeds, program_id) ⇒ String
Creates a program address from seeds and program ID
65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/solace/utils/pda.rb', line 65 def self.create_program_address(seeds, program_id) seed_bytes = seeds.map { |seed| seed_to_bytes(seed) }.flatten program_id_bytes = Solace::Utils::Codecs.base58_to_bytes(program_id) combined = seed_bytes + program_id_bytes + PDA_MARKER.bytes hash_bin = Digest::SHA256.digest(combined.pack('C*')) raise InvalidPDAError if Solace::Utils::Curve25519Dalek.on_curve?(hash_bin) Solace::Utils::Codecs.bytes_to_base58(hash_bin.bytes) end |
.find_program_address(seeds, program_id) ⇒ Array
Finds a valid program address by trying different seeds
48 49 50 51 52 53 54 55 56 57 |
# File 'lib/solace/utils/pda.rb', line 48 def self.find_program_address(seeds, program_id) MAX_BUMP_SEED.downto(0) do |bump| address = create_program_address(seeds + [bump], program_id) return [address, bump] rescue InvalidPDAError next end raise 'Unable to find a valid program address' end |
.looks_like_base58_address?(string) ⇒ Boolean
Checks if a string looks like a base58 address
100 101 102 103 |
# File 'lib/solace/utils/pda.rb', line 100 def self.looks_like_base58_address?(string) string.length.between?(32, 44) && Solace::Utils::Codecs.valid_base58?(string) end |
.seed_to_bytes(seed) ⇒ Array
Prepares a list of seeds for creating a program address
83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/solace/utils/pda.rb', line 83 def self.seed_to_bytes(seed) case seed when String looks_like_base58_address?(seed) ? Solace::Utils::Codecs.base58_to_bytes(seed) : seed.bytes when Integer seed.between?(0, 255) ? [seed] : seed.digits(256) when Array seed else seed.to_s.bytes end end |