Class: Coinbase::User

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

Overview

A representation of a User. Users have Wallets, which can hold balances of Assets. Access the default User through Coinbase#default_user.

Instance Method Summary collapse

Constructor Details

#initialize(model) ⇒ User

Returns a new User object. Do not use this method directly. Instead, use Coinbase#default_user.

Parameters:



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

def initialize(model)
  @model = model
end

Instance Method Details

#create_wallet(create_wallet_options = {}) ⇒ Coinbase::Wallet

Creates a new Wallet belonging to the User.

Parameters:

  • network_id (String)

    (Optional) the ID of the blockchain network. Defaults to ‘base-sepolia’.

Returns:



25
26
27
28
29
30
31
# File 'lib/coinbase/user.rb', line 25

def create_wallet(create_wallet_options = {})
  # For ruby 2.7 compatibility we cannot pass in keyword args when the create wallet
  # options is empty
  return Wallet.create if create_wallet_options.empty?

  Wallet.create(**create_wallet_options)
end

#idString

Returns the User ID.

Returns:

  • (String)

    the User ID



18
19
20
# File 'lib/coinbase/user.rb', line 18

def id
  @model.id
end

#import_wallet(data) ⇒ Coinbase::Wallet

Imports a Wallet belonging to the User.

Parameters:

Returns:



36
37
38
# File 'lib/coinbase/user.rb', line 36

def import_wallet(data)
  Wallet.import(data)
end

#inspectString

Same as to_s.

Returns:

  • (String)

    a string representation of the User



155
156
157
# File 'lib/coinbase/user.rb', line 155

def inspect
  to_s
end

#load_wallets_from_localMap<String>Coinbase::Wallet

Loads all wallets belonging to the User with backup persisted to the local file system.

Returns:

Raises:

  • (ArgumentError)


116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/coinbase/user.rb', line 116

def load_wallets_from_local
  existing_seeds_in_store = existing_seeds
  raise ArgumentError, 'Backup file not found' if existing_seeds_in_store == {}

  wallets = {}
  existing_seeds_in_store.each do |wallet_id, seed_data|
    seed = seed_data['seed']
    raise ArgumentError, 'Malformed backup data' if seed.nil? || seed == ''

    if seed_data['encrypted']
      shared_secret = store_encryption_key
      raise ArgumentError, 'Malformed encrypted seed data' if seed_data['iv'] == '' ||
                                                              seed_data['auth_tag'] == ''

      cipher = OpenSSL::Cipher.new('aes-256-gcm').decrypt
      cipher.key = OpenSSL::Digest.digest('SHA256', shared_secret)
      iv = [seed_data['iv']].pack('H*')
      cipher.iv = iv
      auth_tag = [seed_data['auth_tag']].pack('H*')
      cipher.auth_tag = auth_tag
      cipher.auth_data = ''
      hex_decoded_data = [seed_data['seed']].pack('H*')
      seed = cipher.update(hex_decoded_data) + cipher.final
    end

    data = Coinbase::Wallet::Data.new(wallet_id: wallet_id, seed: seed)
    wallets[wallet_id] = import_wallet(data)
  end
  wallets
end

#save_wallet_locally!(wallet, encrypt: false) ⇒ Coinbase::Wallet

Saves a wallet to local file system. Wallet saved this way can be re-instantiated with load_wallets_from_local function, provided the backup_file is available. This is an insecure method of storing wallet seeds and should only be used for development purposes. If you call save_wallet_locally! twice with wallets containing the same wallet_id, the backup will be overwritten during the second attempt. The default backup_file is seeds.json in the root folder. It can be configured by changing Coinbase.configuration.backup_file_path.

encrypted or not. Data is unencrypted by default.

Parameters:

  • wallet (Coinbase::Wallet)

    The wallet model to save.

  • encrypt (bool) (defaults to: false)

    (Optional) Boolean representing whether the backup persisted to local file system should be

Returns:



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
109
110
111
112
# File 'lib/coinbase/user.rb', line 82

def save_wallet_locally!(wallet, encrypt: false)
  existing_seeds_in_store = existing_seeds
  data = wallet.export
  seed_to_store = data.seed
  auth_tag = ''
  iv = ''
  if encrypt
    shared_secret = store_encryption_key
    cipher = OpenSSL::Cipher.new('aes-256-gcm').encrypt
    cipher.key = OpenSSL::Digest.digest('SHA256', shared_secret)
    iv = cipher.random_iv
    cipher.iv = iv
    cipher.auth_data = ''
    encrypted_data = cipher.update(data.seed) + cipher.final
    auth_tag = cipher.auth_tag.unpack1('H*')
    iv = iv.unpack1('H*')
    seed_to_store = encrypted_data.unpack1('H*')
  end

  existing_seeds_in_store[data.wallet_id] = {
    seed: seed_to_store,
    encrypted: encrypt,
    auth_tag: auth_tag,
    iv: iv
  }

  File.open(Coinbase.configuration.backup_file_path, 'w') do |file|
    file.write(JSON.pretty_generate(existing_seeds_in_store))
  end
  wallet
end

#to_sString

Returns a string representation of the User.

Returns:

  • (String)

    a string representation of the User



149
150
151
# File 'lib/coinbase/user.rb', line 149

def to_s
  "Coinbase::User{user_id: '#{id}'}"
end

#wallets(page_size: 10, next_page_token: nil) ⇒ Coinbase::Wallet

Lists the Wallets belonging to the User.

Parameters:

  • page_size (Integer) (defaults to: 10)

    (Optional) the number of Wallets to return per page. Defaults to 10

  • next_page_token (String) (defaults to: nil)

    (Optional) the token for the next page of Wallets

Returns:



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/coinbase/user.rb', line 44

def wallets(page_size: 10, next_page_token: nil)
  opts = {
    limit: page_size
  }

  opts[:page] = next_page_token unless next_page_token.nil?

  wallet_list = Coinbase.call_api do
    wallets_api.list_wallets(opts)
  end

  # A map from wallet_id to address models.
  address_model_map = {}

  wallet_list.data.each do |wallet_model|
    addresses_list = Coinbase.call_api do
      addresses_api.list_addresses(wallet_model.id, { limit: Coinbase::Wallet::MAX_ADDRESSES })
    end

    address_model_map[wallet_model.id] = addresses_list.data
  end

  wallet_list.data.map do |wallet_model|
    Wallet.new(wallet_model, seed: '', address_models: address_model_map[wallet_model.id])
  end
end