Class: Coinbase::Trade

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

Overview

A representation of a Trade, which trades an amount of an Asset to another Asset on a Network. The fee is assumed to be paid in the native Asset of the Network. Trades should be created through Wallet#trade or # Address#trade.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model) ⇒ Trade

Returns a new Trade object. Do not use this method directly. Instead, use Wallet#trade or Address#trade.

Parameters:



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

def initialize(model)
  raise unless model.is_a?(Coinbase::Client::Trade)

  @model = model
end

Class Method Details

.create(address_id:, from_asset_id:, to_asset_id:, amount:, network:, wallet_id:) ⇒ Send

Creates a new Trade object.

Parameters:

  • address_id (String)

    The Address ID of the sending Address

  • from_asset_id (Symbol)

    The Asset ID of the Asset to trade from

  • to_asset_id (Symbol)

    The Asset ID of the Asset to trade to

  • amount (BigDecimal)

    The amount of the Asset to send

  • network (Coinbase::Network, Symbol)

    The Network or Network ID of the Asset

  • wallet_id (String)

    The Wallet ID of the sending Wallet

Returns:

  • (Send)

    The new pending Send object



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

def create(address_id:, from_asset_id:, to_asset_id:, amount:, network:, wallet_id:)
  network = Coinbase::Network.from_id(network)
  from_asset = network.get_asset(from_asset_id)
  to_asset = network.get_asset(to_asset_id)

  model = Coinbase.call_api do
    trades_api.create_trade(
      wallet_id,
      address_id,
      {
        amount: from_asset.to_atomic_amount(amount).to_i.to_s,
        from_asset_id: from_asset.primary_denomination.to_s,
        to_asset_id: to_asset.primary_denomination.to_s
      }
    )
  end

  new(model)
end

.list(wallet_id:, address_id:) ⇒ Enumerable<Coinbase::Trade>

Enumerates the trades for a given address belonging to a wallet. The result is an enumerator that lazily fetches from the server, and can be iterated over, converted to an array, etc…

Returns:



45
46
47
48
49
50
51
# File 'lib/coinbase/trade.rb', line 45

def list(wallet_id:, address_id:)
  Coinbase::Pagination.enumerate(
    ->(page) { fetch_page(wallet_id, address_id, page) }
  ) do |trade|
    new(trade)
  end
end

Instance Method Details

#address_idString

Returns the Address ID of the Trade.

Returns:

  • (String)

    The Address ID



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

def address_id
  @model.address_id
end

#approve_transactionObject



127
128
129
# File 'lib/coinbase/trade.rb', line 127

def approve_transaction
  @approve_transaction ||= @model.approve_transaction ? Coinbase::Transaction.new(@model.approve_transaction) : nil
end

#broadcast!Trade

Broadcasts the Trade to the Network. This raises an error if the Trade is not signed.

Returns:

  • (Trade)

    The Trade object

Raises:

  • (RuntimeError)

    If the Trade is not signed



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/coinbase/trade.rb', line 146

def broadcast!
  raise TransactionNotSignedError unless transactions.all?(&:signed?)

  payloads = { signed_payload: transaction.raw.hex }

  payloads[:approve_transaction_signed_payload] = approve_transaction.raw.hex unless approve_transaction.nil?

  @model = Coinbase.call_api do
    trades_api.broadcast_trade(wallet_id, address_id, id, payloads)
  end

  update_transactions(@model)

  self
end

#from_amountBigDecimal

Returns the amount of the from asset for the Trade.

Returns:

  • (BigDecimal)

    The amount of the from asset



105
106
107
# File 'lib/coinbase/trade.rb', line 105

def from_amount
  BigDecimal(@model.from_amount) / BigDecimal(10).power(@model.from_asset.decimals)
end

#from_asset_idSymbol

Returns the From Asset ID of the Trade.

Returns:

  • (Symbol)

    The From Asset ID



99
100
101
# File 'lib/coinbase/trade.rb', line 99

def from_asset_id
  @model.from_asset.asset_id.to_sym
end

#idString

Returns the Trade ID.

Returns:

  • (String)

    The Trade ID



75
76
77
# File 'lib/coinbase/trade.rb', line 75

def id
  @model.trade_id
end

#inspectString

Same as to_s.

Returns:

  • (String)

    a String representation of the Trade



210
211
212
# File 'lib/coinbase/trade.rb', line 210

def inspect
  to_s
end

#networkCoinbase::Network

Returns the Network of the Trade.

Returns:



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

def network
  @network ||= Coinbase::Network.from_id(@model.network_id)
end

#reloadTrade

Reloads the Trade model with the latest version from the server side.

Returns:

  • (Trade)

    The most recent version of Trade from the server.



189
190
191
192
193
194
195
196
197
# File 'lib/coinbase/trade.rb', line 189

def reload
  @model = Coinbase.call_api do
    trades_api.get_trade(wallet_id, address_id, id)
  end

  update_transactions(@model)

  self
end

#statusSymbol

Returns the status of the Trade.

Returns:

  • (Symbol)

    The status



138
139
140
# File 'lib/coinbase/trade.rb', line 138

def status
  transaction.status
end

#to_amountBigDecimal

Returns the amount of the to asset for the Trade.

Returns:

  • (BigDecimal)

    The amount of the to asset



117
118
119
# File 'lib/coinbase/trade.rb', line 117

def to_amount
  BigDecimal(@model.to_amount) / BigDecimal(10).power(@model.to_asset.decimals)
end

#to_asset_idSymbol

Returns the To Asset ID of the Trade.

Returns:

  • (Symbol)

    The To Asset ID



111
112
113
# File 'lib/coinbase/trade.rb', line 111

def to_asset_id
  @model.to_asset.asset_id.to_sym
end

#to_sString

Returns a String representation of the Trade.

Returns:

  • (String)

    a String representation of the Trade



201
202
203
204
205
206
# File 'lib/coinbase/trade.rb', line 201

def to_s
  "Coinbase::Trade{transfer_id: '#{id}', network_id: '#{network.id}', " \
    "address_id: '#{address_id}', from_asset_id: '#{from_asset_id}', " \
    "to_asset_id: '#{to_asset_id}', from_amount: '#{from_amount}', " \
    "to_amount: '#{to_amount}' status: '#{status}'}"
end

#transactionCoinbase::Transaction

Returns the Trade transaction.

Returns:



123
124
125
# File 'lib/coinbase/trade.rb', line 123

def transaction
  @transaction ||= Coinbase::Transaction.new(@model.transaction)
end

#transactionsObject

Returns the list of Transactions for the Trade.



132
133
134
# File 'lib/coinbase/trade.rb', line 132

def transactions
  [approve_transaction, transaction].compact
end

#wait!(interval_seconds = 0.2, timeout_seconds = 10) ⇒ Trade

Waits until the Trade is completed or failed by polling the Network at the given interval. Raises a Timeout::Error if the Trade takes longer than the given timeout.

Parameters:

  • interval_seconds (Integer) (defaults to: 0.2)

    The interval at which to poll the Network, in seconds

  • timeout_seconds (Integer) (defaults to: 10)

    The maximum amount of time to wait for the Trade to complete, in seconds

Returns:

  • (Trade)

    The completed Trade object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/coinbase/trade.rb', line 167

def wait!(interval_seconds = 0.2, timeout_seconds = 10)
  start_time = Time.now

  loop do
    reload

    # Wait for the trade transaction to be in a terminal state.
    # The approve transaction is optional and must last first, so we don't need to wait for it.
    # We may want to handle a situation where the approve transaction fails and the
    # trade transaction does not ever get broadcast.
    break if transaction.terminal_state?

    raise Timeout::Error, 'Trade timed out' if Time.now - start_time > timeout_seconds

    self.sleep interval_seconds
  end

  self
end

#wallet_idString

Returns the Wallet ID of the Trade.

Returns:

  • (String)

    The Wallet ID



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

def wallet_id
  @model.wallet_id
end