Module: Solana::Ruby::Kit::TransactionConfirmation

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

Class Method Summary collapse

Class Method Details

.wait_for_blockheight_lifetime(rpc, signature, last_valid_block_height:, commitment: :confirmed, poll_interval: 0.5) ⇒ Object



76
77
78
79
80
81
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
# File 'lib/solana/ruby/kit/transaction_confirmation.rb', line 76

def wait_for_blockheight_lifetime(
  rpc,
  signature,
  last_valid_block_height:,
  commitment:    :confirmed,
  poll_interval: 0.5
)
  sig_str = signature.respond_to?(:value) ? T.cast(signature, Keys::Signature).value : signature.to_s
  commitment_order = i[processed confirmed finalized]
  min_order        = commitment_order.index(commitment) || 1

  Kernel.loop do
    # Check if blockheight has been exceeded
    current_height = rpc.get_block_height
    Kernel.raise Timeout::Error, 'Transaction lifetime expired (blockheight)' if current_height > last_valid_block_height

    res    = rpc.get_signature_statuses([sig_str], search_transaction_history: false)
    status = res.value.first
    next Kernel.sleep(poll_interval) if status.nil?

    err = status.respond_to?(:err) ? status.err : status[:err]
    Kernel.raise SolanaError.new(SolanaError::TRANSACTIONS__FAILED_TRANSACTION_PLAN, err: err.inspect) if err

    current_commitment = status.respond_to?(:confirmation_status) ? status.confirmation_status : status[:confirmation_status]
    current_order      = commitment_order.index(current_commitment) || 0

    return status if current_order >= min_order

    Kernel.sleep(poll_interval)
  end
end

.wait_for_confirmation(rpc, signature, commitment: :confirmed, timeout_secs: 30, poll_interval: 0.5) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/solana/ruby/kit/transaction_confirmation.rb', line 35

def wait_for_confirmation(
  rpc,
  signature,
  commitment:    :confirmed,
  timeout_secs:  30,
  poll_interval: 0.5
)
  sig_str    = signature.respond_to?(:value) ? T.cast(signature, Keys::Signature).value : signature.to_s
  commitment_order = i[processed confirmed finalized]
  min_order  = commitment_order.index(commitment) || 1

  Timeout.timeout(timeout_secs) do
    Kernel.loop do
      res    = rpc.get_signature_statuses([sig_str], search_transaction_history: false)
      status = res.value.first
      next Kernel.sleep(poll_interval) if status.nil?

      err = status.respond_to?(:err) ? status.err : status[:err]
      Kernel.raise SolanaError.new(SolanaError::TRANSACTIONS__FAILED_TRANSACTION_PLAN, err: err.inspect) if err

      current_commitment = status.respond_to?(:confirmation_status) ? status.confirmation_status : status[:confirmation_status]
      current_order      = commitment_order.index(current_commitment) || 0

      return status if current_order >= min_order

      Kernel.sleep(poll_interval)
    end
  end
end

.wait_for_nonce_invalidation(rpc, signature, nonce_account:, nonce:, commitment: :confirmed, timeout_secs: 120, poll_interval: 1.0) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/solana/ruby/kit/transaction_confirmation.rb', line 122

def wait_for_nonce_invalidation(
  rpc,
  signature,
  nonce_account:,
  nonce:,
  commitment:    :confirmed,
  timeout_secs:  120,
  poll_interval: 1.0
)
  sig_str          = signature.respond_to?(:value) ? T.cast(signature, Keys::Signature).value : signature.to_s
  commitment_order = i[processed confirmed finalized]
  min_order        = commitment_order.index(commitment) || 1

  Timeout.timeout(timeout_secs) do
    Kernel.loop do
      # First check if transaction already confirmed
      res    = rpc.get_signature_statuses([sig_str], search_transaction_history: false)
      status = res.value.first
      unless status.nil?
        err = status.respond_to?(:err) ? status.err : status[:err]
        Kernel.raise SolanaError.new(SolanaError::TRANSACTIONS__FAILED_TRANSACTION_PLAN, err: err.inspect) if err

        current_commitment = status.respond_to?(:confirmation_status) ? status.confirmation_status : status[:confirmation_status]
        current_order      = commitment_order.index(current_commitment) || 0
        return status if current_order >= min_order
      end

      # Check if nonce has advanced (transaction expired without confirming)
      nonce_res = rpc.(, encoding: 'jsonParsed')
      current_nonce_hash = nonce_res.value&.respond_to?(:data) ? nonce_res.value.data&.dig('parsed', 'info', 'blockhash') : nil
      Kernel.raise Timeout::Error, 'Nonce advanced — transaction expired' if current_nonce_hash && current_nonce_hash != nonce

      Kernel.sleep(poll_interval)
    end
  end
end