Module: Solana::Ruby::Kit::Transactions

Extended by:
T::Sig
Defined in:
lib/solana/ruby/kit/transactions/transaction.rb

Defined Under Namespace

Classes: FullySignedTransaction, Transaction

Constant Summary collapse

TransactionMessageBytes =

The wire-encoded bytes of a compiled transaction message. Mirrors TypeScript’s TransactionMessageBytes (branded Uint8Array).

T.type_alias { String }
SignaturesMap =

An ordered map of signer addresses to their Ed25519 signatures (or nil when the address has been reserved for signing but not yet signed). Mirrors TypeScript’s ‘SignaturesMap = OrderedMap<Address, SignatureBytes | null>`.

T.type_alias { T::Hash[String, T.nilable(String)] }

Class Method Summary collapse

Class Method Details

.assert_fully_signed_transaction!(transaction) ⇒ Object



60
61
62
63
64
65
66
67
68
# File 'lib/solana/ruby/kit/transactions/transaction.rb', line 60

def assert_fully_signed_transaction!(transaction)
  missing = transaction.signatures.filter_map { |addr, sig| addr if sig.nil? }
  return if missing.empty?

  Kernel.raise SolanaError.new(
    :SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,
    addresses: missing
  )
end

.fully_signed_transaction?(transaction) ⇒ Boolean

Returns:



53
54
55
# File 'lib/solana/ruby/kit/transactions/transaction.rb', line 53

def fully_signed_transaction?(transaction)
  transaction.signatures.values.all? { |sig| !sig.nil? }
end

.get_signature_from_transaction(transaction) ⇒ Object



43
44
45
46
47
48
# File 'lib/solana/ruby/kit/transactions/transaction.rb', line 43

def get_signature_from_transaction(transaction)
  sig_bytes = transaction.signatures.values.first
  Kernel.raise SolanaError.new(:SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING) unless sig_bytes

  Keys.encode_signature(Keys::SignatureBytes.new(sig_bytes))
end

.partially_sign_transaction(signing_keys, transaction) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/solana/ruby/kit/transactions/transaction.rb', line 82

def partially_sign_transaction(signing_keys, transaction)
  new_signatures  = transaction.signatures.dup
  unexpected      = T.let([], T::Array[String])

  signing_keys.each do |signing_key|
    verify_key = signing_key.verify_key
    addr_str   = Addresses.encode_address(verify_key.to_bytes)

    unless new_signatures.key?(addr_str)
      unexpected << addr_str
      next
    end

    sig_bytes = Keys.sign_bytes(signing_key, transaction.message_bytes)
    existing  = new_signatures[addr_str]

    next if existing && existing == sig_bytes.value

    new_signatures[addr_str] = sig_bytes.value
  end

  if unexpected.any?
    Kernel.raise SolanaError.new(
      :SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION,
      expected_addresses:    transaction.signatures.keys,
      unexpected_addresses:  unexpected
    )
  end

  Transaction.new(
    message_bytes: transaction.message_bytes,
    signatures:    new_signatures
  )
end

.sign_transaction(signing_keys, transaction) ⇒ Object



125
126
127
128
129
130
131
132
133
# File 'lib/solana/ruby/kit/transactions/transaction.rb', line 125

def sign_transaction(signing_keys, transaction)
  signed = partially_sign_transaction(signing_keys, transaction)
  assert_fully_signed_transaction!(signed)

  FullySignedTransaction.new(
    message_bytes: signed.message_bytes,
    signatures:    signed.signatures
  )
end