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 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)


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/coinbase/wallet.rb', line 22

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 Method Details

#create_addressAddress

Creates a new Address in the Wallet.

Returns:



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

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(wallet_id, opts)
  end

  cache_address(address_model, key)
end

#default_addressAddress

Returns the default address of the Wallet.

Returns:

  • (Address)

    The default address



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

def default_address
  @addresses.find { |address| address.address_id == @model.default_address.address_id }
end

#exportData

Exports the Wallet’s data to a Data object.

Returns:

  • (Data)

    The Wallet data



160
161
162
# File 'lib/coinbase/wallet.rb', line 160

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

#get_address(address_id) ⇒ Address

Returns the Address with the given ID.

Parameters:

  • address_id (String)

    The ID of the Address to retrieve

Returns:



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

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

#get_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



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/coinbase/wallet.rb', line 110

def get_balance(asset_id)
  normalized_asset_id = if %i[wei gwei].include?(asset_id)
                          :eth
                        else
                          asset_id
                        end

  response = Coinbase.call_api do
    wallets_api.get_wallet_balance(wallet_id, normalized_asset_id.to_s)
  end

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

  amount = BigDecimal(response.amount)

  case asset_id
  when :eth
    amount / BigDecimal(Coinbase::WEI_PER_ETHER.to_s)
  when :gwei
    amount / BigDecimal(Coinbase::GWEI_PER_ETHER.to_s)
  when :usdc
    amount / BigDecimal(Coinbase::ATOMIC_UNITS_PER_USDC.to_s)
  else
    amount
  end
end

#inspectString

Same as to_s.

Returns:

  • (String)

    a String representation of the Wallet



173
174
175
# File 'lib/coinbase/wallet.rb', line 173

def inspect
  to_s
end

#list_addressesArray<Address>

Returns the list of Addresses in the Wallet.

Returns:

  • (Array<Address>)

    The list of Addresses



93
94
95
# File 'lib/coinbase/wallet.rb', line 93

def list_addresses
  @addresses
end

#list_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.



99
100
101
102
103
104
105
# File 'lib/coinbase/wallet.rb', line 99

def list_balances
  response = Coinbase.call_api do
    wallets_api.list_wallet_balances(wallet_id)
  end

  Coinbase.to_balance_map(response)
end

#network_idSymbol

Returns the Network ID of the Wallet.

Returns:

  • (Symbol)

    The Network ID



54
55
56
# File 'lib/coinbase/wallet.rb', line 54

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



166
167
168
169
# File 'lib/coinbase/wallet.rb', line 166

def to_s
  "Coinbase::Wallet{wallet_id: '#{wallet_id}', network_id: '#{network_id}', " \
    "default_address: '#{default_address.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.



144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/coinbase/wallet.rb', line 144

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.address_id
  elsif destination.is_a?(Address)
    raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != @network_id

    destination = destination.address_id
  end

  default_address.transfer(amount, asset_id, destination)
end

#wallet_idString

Returns the Wallet ID.

Returns:

  • (String)

    The Wallet ID



48
49
50
# File 'lib/coinbase/wallet.rb', line 48

def wallet_id
  @model.id
end