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.

Defined Under Namespace

Classes: WalletData

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(seed: nil, address_count: 1, client: Jimson::Client.new(Coinbase.base_sepolia_rpc_url)) ⇒ Wallet

Returns a new Wallet object.

Raises:

  • (ArgumentError)


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

def initialize(seed: nil, address_count: 1, client: Jimson::Client.new(Coinbase.base_sepolia_rpc_url))
  raise ArgumentError, 'Seed must be 32 bytes' if !seed.nil? && seed.length != 64
  raise ArgumentError, 'Address count must be positive' if address_count < 1

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

  @wallet_id = SecureRandom.uuid
  # 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

  @client = client

  address_count.times { create_address }
end

Instance Attribute Details

#network_idObject (readonly)

Returns the value of attribute network_id.



12
13
14
# File 'lib/coinbase/wallet.rb', line 12

def network_id
  @network_id
end

#wallet_idObject (readonly)

Returns the value of attribute wallet_id.



12
13
14
# File 'lib/coinbase/wallet.rb', line 12

def wallet_id
  @wallet_id
end

Instance Method Details

#create_addressAddress

Creates a new Address in the Wallet.



42
43
44
45
46
47
48
49
50
51
# File 'lib/coinbase/wallet.rb', line 42

def create_address
  # TODO: Register with server.
  path = "#{@address_path_prefix}/#{@address_index}"
  private_key = @master.node_for_path(path).private_key.to_hex
  key = Eth::Key.new(priv: private_key)
  address = Address.new(@network_id, key.address.address, @wallet_id, key, client: @client)
  @addresses << address
  @address_index += 1
  address
end

#default_addressAddress

Returns the default address of the Wallet.



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

def default_address
  @addresses.first
end

#exportWalletData

Exports the Wallet’s data to a WalletData object.



137
138
139
# File 'lib/coinbase/wallet.rb', line 137

def export
  WalletData.new(@master.seed_hex, @addresses.length)
end

#get_address(address_id) ⇒ Address

Returns the Address with the given ID.



62
63
64
# File 'lib/coinbase/wallet.rb', line 62

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.



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

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

  eth_balance = list_balances[normalized_asset_id] || BigDecimal(0)

  case asset_id
  when :eth
    eth_balance
  when :gwei
    eth_balance * Coinbase::GWEI_PER_ETHER
  when :wei
    eth_balance * Coinbase::WEI_PER_ETHER
  else
    BigDecimal(0)
  end
end

#list_addressesArray<Address>

Returns the list of Addresses in the Wallet.



68
69
70
71
# File 'lib/coinbase/wallet.rb', line 68

def list_addresses
  # TODO: Register with server.
  @addresses
end

#list_balancesBalanceMap

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



75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/coinbase/wallet.rb', line 75

def list_balances
  balance_map = BalanceMap.new

  @addresses.each do |address|
    address.list_balances.each do |asset_id, balance|
      balance_map[asset_id] ||= BigDecimal(0)
      current_balance = balance_map[asset_id]
      new_balance = balance + current_balance
      balance_map[asset_id] = new_balance
    end
  end

  balance_map
end

#to_dataWalletData

Returns the data required to recreate the Wallet.



156
157
158
# File 'lib/coinbase/wallet.rb', line 156

def to_data
  WalletData.new(@master.seed_hex, @addresses.length)
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.



121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/coinbase/wallet.rb', line 121

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