Class: Coinbase::Transfer
- Inherits:
-
Object
- Object
- Coinbase::Transfer
- Defined in:
- lib/coinbase/transfer.rb
Overview
A representation of a Transfer, which moves an amount of an Asset from a user-controlled Wallet to another address. The fee is assumed to be paid in the native Asset of the Network. Currently only ETH transfers are supported. Transfers should be created through Wallet#transfer or Address#transfer.
Defined Under Namespace
Modules: Status
Instance Attribute Summary collapse
-
#amount ⇒ Object
readonly
Returns the value of attribute amount.
-
#asset_id ⇒ Object
readonly
Returns the value of attribute asset_id.
-
#from_address_id ⇒ Object
readonly
Returns the value of attribute from_address_id.
-
#network_id ⇒ Object
readonly
Returns the value of attribute network_id.
-
#to_address_id ⇒ Object
readonly
Returns the value of attribute to_address_id.
-
#wallet_id ⇒ Object
readonly
Returns the value of attribute wallet_id.
Instance Method Summary collapse
-
#initialize(network_id, wallet_id, from_address_id, amount, asset_id, to_address_id, client: Jimson::Client.new(ENV.fetch('BASE_SEPOLIA_RPC_URL', nil))) ⇒ Transfer
constructor
Returns a new Transfer object.
-
#status ⇒ Symbol
Returns the status of the Transfer.
-
#transaction ⇒ Eth::Tx::Eip1559
Returns the underlying Transfer transaction, creating it if it has not been yet.
-
#transaction_hash ⇒ String
Returns the transaction hash of the Transfer, or nil if not yet available.
-
#wait!(interval_seconds = 0.2, timeout_seconds = 10) ⇒ Transfer
Waits until the Transfer is completed or failed by polling the Network at the given interval.
Constructor Details
#initialize(network_id, wallet_id, from_address_id, amount, asset_id, to_address_id, client: Jimson::Client.new(ENV.fetch('BASE_SEPOLIA_RPC_URL', nil))) ⇒ Transfer
Returns a new Transfer object.
42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/coinbase/transfer.rb', line 42 def initialize(network_id, wallet_id, from_address_id, amount, asset_id, to_address_id, client: Jimson::Client.new(ENV.fetch('BASE_SEPOLIA_RPC_URL', nil))) raise ArgumentError, "Unsupported asset: #{asset_id}" if asset_id != :eth @network_id = network_id @wallet_id = wallet_id @from_address_id = from_address_id @amount = normalize_eth_amount(amount) @asset_id = asset_id @to_address_id = to_address_id @client = client end |
Instance Attribute Details
#amount ⇒ Object (readonly)
Returns the value of attribute amount.
13 14 15 |
# File 'lib/coinbase/transfer.rb', line 13 def amount @amount end |
#asset_id ⇒ Object (readonly)
Returns the value of attribute asset_id.
13 14 15 |
# File 'lib/coinbase/transfer.rb', line 13 def asset_id @asset_id end |
#from_address_id ⇒ Object (readonly)
Returns the value of attribute from_address_id.
13 14 15 |
# File 'lib/coinbase/transfer.rb', line 13 def from_address_id @from_address_id end |
#network_id ⇒ Object (readonly)
Returns the value of attribute network_id.
13 14 15 |
# File 'lib/coinbase/transfer.rb', line 13 def network_id @network_id end |
#to_address_id ⇒ Object (readonly)
Returns the value of attribute to_address_id.
13 14 15 |
# File 'lib/coinbase/transfer.rb', line 13 def to_address_id @to_address_id end |
#wallet_id ⇒ Object (readonly)
Returns the value of attribute wallet_id.
13 14 15 |
# File 'lib/coinbase/transfer.rb', line 13 def wallet_id @wallet_id end |
Instance Method Details
#status ⇒ Symbol
Returns the status of the Transfer.
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 107 108 |
# File 'lib/coinbase/transfer.rb', line 81 def status begin # Create the transaction, and attempt to get the hash to see if it has been signed. transaction.hash rescue Eth::Signature::SignatureError # If the transaction has not been signed, it is still pending. return Status::PENDING end onchain_transaction = @client.eth_getTransactionByHash(transaction_hash) if onchain_transaction.nil? # If the transaction has not been broadcast, it is still pending. Status::PENDING elsif onchain_transaction['blockHash'].nil? # If the transaction has been broadcast but hasn't been included in a block, it is # broadcast. Status::BROADCAST else transaction_receipt = @client.eth_getTransactionReceipt(transaction_hash) if transaction_receipt['status'].to_i(16) == 1 Status::COMPLETE else Status::FAILED end end end |
#transaction ⇒ Eth::Tx::Eip1559
Returns the underlying Transfer transaction, creating it if it has not been yet.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/coinbase/transfer.rb', line 58 def transaction return @transaction unless @transaction.nil? nonce = @client.eth_getTransactionCount(@from_address_id.to_s, 'latest').to_i(16) gas_price = @client.eth_gasPrice.to_i(16) params = { chain_id: BASE_SEPOLIA.chain_id, # TODO: Don't hardcode Base Sepolia. nonce: nonce, priority_fee: gas_price, # TODO: Optimize this. max_gas_fee: gas_price, gas_limit: 21_000, # TODO: Handle multiple currencies. from: Eth::Address.new(@from_address_id), to: Eth::Address.new(@to_address_id), value: (@amount * Coinbase::WEI_PER_ETHER).to_i } @transaction = Eth::Tx::Eip1559.new(Eth::Tx.validate_eip1559_params(params)) @transaction end |
#transaction_hash ⇒ String
Returns the transaction hash of the Transfer, or nil if not yet available.
131 132 133 134 135 |
# File 'lib/coinbase/transfer.rb', line 131 def transaction_hash "0x#{transaction.hash}" rescue Eth::Signature::SignatureError nil end |
#wait!(interval_seconds = 0.2, timeout_seconds = 10) ⇒ Transfer
Waits until the Transfer is completed or failed by polling the Network at the given interval. Raises a Timeout::Error if the Transfer takes longer than the given timeout.
115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/coinbase/transfer.rb', line 115 def wait!(interval_seconds = 0.2, timeout_seconds = 10) start_time = Time.now loop do return self if status == Status::COMPLETE || status == Status::FAILED raise Timeout::Error, 'Transfer timed out' if Time.now - start_time > timeout_seconds self.sleep interval_seconds end self end |