Class: Solana::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/solana/client.rb

Defined Under Namespace

Classes: InsecureRpcUrlError, RpcError

Constant Summary collapse

MAX_RETRIES =
3
RETRY_DELAY =

seconds

1
DEFAULT_RPC_URL =
"https://api.devnet.solana.com"
HTTP_OK_HOSTS =

Hostnames where plain http:// is permitted (local testing only).

%w[localhost 127.0.0.1 ::1 0.0.0.0].freeze

Instance Method Summary collapse

Constructor Details

#initialize(rpc_url: nil) ⇒ Client

Returns a new instance of Client.



26
27
28
29
30
31
# File 'lib/solana/client.rb', line 26

def initialize(rpc_url: nil)
  @rpc_url = rpc_url || ENV.fetch("SOLANA_RPC_URL", DEFAULT_RPC_URL)
  @uri = URI.parse(@rpc_url)
  validate_rpc_scheme!
  @request_id = 0
end

Instance Method Details

#confirm_transaction(signature, commitment: "confirmed") ⇒ Object



73
74
75
# File 'lib/solana/client.rb', line 73

def confirm_transaction(signature, commitment: "confirmed")
  call("getSignatureStatuses", [[signature], { searchTransactionHistory: true }])
end

#get_account_info(pubkey, encoding: "base64", commitment: nil) ⇒ Object



33
34
35
36
37
# File 'lib/solana/client.rb', line 33

def (pubkey, encoding: "base64", commitment: nil)
  config = { encoding: encoding }
  config[:commitment] = commitment if commitment
  call("getAccountInfo", [pubkey, config])
end

#get_balance(pubkey) ⇒ Object



101
102
103
# File 'lib/solana/client.rb', line 101

def get_balance(pubkey)
  call("getBalance", [pubkey])
end

#get_latest_blockhash(commitment: "finalized") ⇒ Object



43
44
45
46
# File 'lib/solana/client.rb', line 43

def get_latest_blockhash(commitment: "finalized")
  result = call("getLatestBlockhash", [{ commitment: commitment }])
  result.dig("value", "blockhash")
end

#get_minimum_balance_for_rent_exemption(size) ⇒ Object



48
49
50
# File 'lib/solana/client.rb', line 48

def get_minimum_balance_for_rent_exemption(size)
  call("getMinimumBalanceForRentExemption", [size])
end

#get_token_account_balance(pubkey) ⇒ Object



39
40
41
# File 'lib/solana/client.rb', line 39

def (pubkey)
  call("getTokenAccountBalance", [pubkey])
end

#get_token_accounts_by_owner(owner_pubkey) ⇒ Object



109
110
111
112
113
114
115
# File 'lib/solana/client.rb', line 109

def get_token_accounts_by_owner(owner_pubkey)
  call("getTokenAccountsByOwner", [
    owner_pubkey,
    { programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" },
    { encoding: "jsonParsed" }
  ])
end

#get_transaction(signature, commitment: "confirmed") ⇒ Object



105
106
107
# File 'lib/solana/client.rb', line 105

def get_transaction(signature, commitment: "confirmed")
  call("getTransaction", [signature, { encoding: "json", commitment: commitment }])
end

#request_airdrop(pubkey, lamports) ⇒ Object



97
98
99
# File 'lib/solana/client.rb', line 97

def request_airdrop(pubkey, lamports)
  call("requestAirdrop", [pubkey, lamports])
end

#send_and_confirm(signed_tx_base64, timeout: 30, skip_preflight: false) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/solana/client.rb', line 77

def send_and_confirm(signed_tx_base64, timeout: 30, skip_preflight: false)
  signature = send_transaction(signed_tx_base64, skip_preflight: skip_preflight)

  deadline = Time.now + timeout
  loop do
    sleep 1
    result = confirm_transaction(signature)
    status = result.dig("value", 0)

    if status
      if status["err"]
        raise RpcError.new("Transaction failed: #{status['err']}")
      end
      return signature if status["confirmationStatus"] == "confirmed" || status["confirmationStatus"] == "finalized"
    end

    raise RpcError.new("Transaction confirmation timeout") if Time.now > deadline
  end
end

#send_transaction(signed_tx_base64, skip_preflight: false) ⇒ Object



52
53
54
55
# File 'lib/solana/client.rb', line 52

def send_transaction(signed_tx_base64, skip_preflight: false)
  opts = { encoding: "base64", skipPreflight: skip_preflight }
  call("sendTransaction", [signed_tx_base64, opts])
end

#simulate_transaction(signed_tx_base64, sig_verify: false, replace_recent_blockhash: false, commitment: "confirmed") ⇒ Object

Server-side pre-flight: run simulateTransaction against a base64 wire tx. sig_verify:false lets us simulate a tx without all signatures present (or without re-verifying ones that are). Returns the RPC ‘value` object ({ “err” =>, “logs” =>, “unitsConsumed” =>, … }); `value` is nil on success. Mirrors the client-side simulate the entry board used to run.



62
63
64
65
66
67
68
69
70
71
# File 'lib/solana/client.rb', line 62

def simulate_transaction(signed_tx_base64, sig_verify: false, replace_recent_blockhash: false, commitment: "confirmed")
  opts = {
    encoding: "base64",
    sigVerify: sig_verify,
    replaceRecentBlockhash: replace_recent_blockhash,
    commitment: commitment
  }
  result = call("simulateTransaction", [signed_tx_base64, opts])
  result&.dig("value")
end