Class: Coinbase::Wallet

Inherits:
Object
  • Object
show all
Defined in:
lib/coinbase/wallet.rb

Overview

A representation of a Wallet. Wallets come with a single default Address, but can expand to have a set of Addresses, each of which can hold a balance of one or more Assets. Wallets can create new Addresses, list their addresses, list their balances, and transfer Assets to other Addresses. Wallets should be created through User#create_wallet or User#import_wallet.

Defined Under Namespace

Classes: Data

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, seed: nil, address_count: 0) ⇒ Wallet

Returns a new Wallet object. Do not use this method directly. Instead, use User#create_wallet or User#import_wallet.

Parameters:

  • model (Coinbase::Client::Wallet)

    The underlying Wallet object

  • seed (String) (defaults to: nil)

    (Optional) The seed to use for the Wallet. Expects a 32-byte hexadecimal with no 0x prefix. If not provided, a new seed will be generated.

  • address_count (Integer) (defaults to: 0)

    (Optional) The number of addresses already registered for the Wallet.

  • client (Jimson::Client)

    (Optional) The JSON RPC client to use for interacting with the Network

Raises:

  • (ArgumentError)


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/coinbase/wallet.rb', line 55

def initialize(model, seed: nil, address_count: 0)
  raise ArgumentError, 'Seed must be 32 bytes' if !seed.nil? && seed.length != 64

  @model = model

  @master = seed.nil? ? MoneyTree::Master.new : MoneyTree::Master.new(seed_hex: seed)

  # TODO: Make Network an argument to the constructor.
  @network_id = :base_sepolia
  @addresses = []

  # TODO: Adjust derivation path prefix based on network protocol.
  @address_path_prefix = "m/44'/60'/0'/0"
  @address_index = 0

  if address_count.positive?
    address_count.times { derive_address }
  else
    create_address
    # Update the model to reflect the new default address.
    update_model
  end
end

Instance Attribute Details

#addressesObject (readonly)

Returns the value of attribute addresses.



15
16
17
# File 'lib/coinbase/wallet.rb', line 15

def addresses
  @addresses
end

Class Method Details

.import(data) ⇒ Coinbase::Wallet

Imports a Wallet from previously exported wallet data.

Parameters:

Returns:

Raises:

  • (ArgumentError)


21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/coinbase/wallet.rb', line 21

def import(data)
  raise ArgumentError, 'data must be a Coinbase::Wallet::Data object' unless data.is_a?(Data)

  model = Coinbase.call_api do
    wallets_api.get_wallet(data.wallet_id)
  end

  # TODO: Pass these addresses in directly
  address_count = Coinbase.call_api do
    addresses_api.list_addresses(model.id).total_count
  end

  new(model, seed: data.seed, address_count: address_count)
end

Instance Method Details

#address(address_id) ⇒ Address

Returns the Address with the given ID.

Parameters:

  • address_id (String)

    The ID of the Address to retrieve

Returns:



120
121
122
# File 'lib/coinbase/wallet.rb', line 120

def address(address_id)
  @addresses.find { |address| address.id == address_id }
end

#balance(asset_id) ⇒ BigDecimal

Returns the balance of the provided Asset. Balances are aggregated across all Addresses in the Wallet.

Parameters:

  • asset_id (Symbol)

    The ID of the Asset to retrieve the balance for

Returns:

  • (BigDecimal)

    The balance of the Asset



137
138
139
140
141
142
143
144
145
# File 'lib/coinbase/wallet.rb', line 137

def balance(asset_id)
  response = Coinbase.call_api do
    wallets_api.get_wallet_balance(id, Coinbase::Asset.primary_denomination(asset_id).to_s)
  end

  return BigDecimal('0') if response.nil?

  Coinbase::Balance.from_model_and_asset_id(response, asset_id).amount
end

#balancesBalanceMap

Returns the list of balances of this Wallet. Balances are aggregated across all Addresses in the Wallet.

Returns:

  • (BalanceMap)

    The list of balances. The key is the Asset ID, and the value is the balance.



126
127
128
129
130
131
132
# File 'lib/coinbase/wallet.rb', line 126

def balances
  response = Coinbase.call_api do
    wallets_api.list_wallet_balances(id)
  end

  Coinbase::BalanceMap.from_balances(response.data)
end

#create_addressAddress

Creates a new Address in the Wallet.

Returns:



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/coinbase/wallet.rb', line 93

def create_address
  key = derive_key
  attestation = create_attestation(key)
  public_key = key.public_key.compressed.unpack1('H*')

  opts = {
    create_address_request: {
      public_key: public_key,
      attestation: attestation
    }
  }
  address_model = Coinbase.call_api do
    addresses_api.create_address(id, opts)
  end

  cache_address(address_model, key)
end

#default_addressAddress

Returns the default address of the Wallet.

Returns:

  • (Address)

    The default address



113
114
115
# File 'lib/coinbase/wallet.rb', line 113

def default_address
  address(@model.default_address.address_id)
end

#exportData

Exports the Wallet’s data to a Data object.

Returns:

  • (Data)

    The Wallet data



170
171
172
# File 'lib/coinbase/wallet.rb', line 170

def export
  Data.new(wallet_id: id, seed: @master.seed_hex)
end

#faucetCoinbase::FaucetTransaction

Requests funds from the faucet for the Wallet’s default address and returns the faucet transaction. This is only supported on testnet networks.

Returns:

Raises:



179
180
181
182
183
# File 'lib/coinbase/wallet.rb', line 179

def faucet
  Coinbase.call_api do
    Coinbase::FaucetTransaction.new(addresses_api.request_faucet_funds(id, default_address.id))
  end
end

#idString

Returns the Wallet ID.

Returns:

  • (String)

    The Wallet ID



81
82
83
# File 'lib/coinbase/wallet.rb', line 81

def id
  @model.id
end

#inspectString

Same as to_s.

Returns:

  • (String)

    a String representation of the Wallet



194
195
196
# File 'lib/coinbase/wallet.rb', line 194

def inspect
  to_s
end

#network_idSymbol

Returns the Network ID of the Wallet.

Returns:

  • (Symbol)

    The Network ID



87
88
89
# File 'lib/coinbase/wallet.rb', line 87

def network_id
  Coinbase.to_sym(@model.network_id)
end

#to_sString

Returns a String representation of the Wallet.

Returns:

  • (String)

    a String representation of the Wallet



187
188
189
190
# File 'lib/coinbase/wallet.rb', line 187

def to_s
  "Coinbase::Wallet{wallet_id: '#{id}', network_id: '#{network_id}', " \
    "default_address: '#{default_address.id}'}"
end

#transfer(amount, asset_id, destination) ⇒ Transfer

Transfers the given amount of the given Asset to the given address. Only same-Network Transfers are supported. Currently only the default_address is used to source the Transfer.

Parameters:

  • amount (Integer, Float, BigDecimal)

    The amount of the Asset to send

  • asset_id (Symbol)

    The ID of the Asset to send

  • destination (Wallet | Address | String)

    The destination of the transfer. If a Wallet, sends to the Wallet’s default address. If a String, interprets it as the address ID.

Returns:

  • (Transfer)

    The hash of the Transfer transaction.



154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/coinbase/wallet.rb', line 154

def transfer(amount, asset_id, destination)
  if destination.is_a?(Wallet)
    raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != @network_id

    destination = destination.default_address.id
  elsif destination.is_a?(Address)
    raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != @network_id

    destination = destination.id
  end

  default_address.transfer(amount, asset_id, destination)
end