coinbase-sdk 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/coinbase/address.rb +73 -19
- data/lib/coinbase/asset.rb +80 -56
- data/lib/coinbase/balance.rb +10 -6
- data/lib/coinbase/client/api/assets_api.rb +91 -0
- data/lib/coinbase/client/api/balances_api.rb +97 -0
- data/lib/coinbase/client/api/external_addresses_api.rb +242 -0
- data/lib/coinbase/client/api/server_signers_api.rb +13 -3
- data/lib/coinbase/client/api/stake_api.rb +236 -0
- data/lib/coinbase/client/api/transfer_api.rb +114 -0
- data/lib/coinbase/client/models/broadcast_trade_request.rb +14 -4
- data/lib/coinbase/client/models/build_staking_operation_request.rb +291 -0
- data/lib/coinbase/client/models/feature.rb +42 -0
- data/lib/coinbase/client/models/fetch_staking_rewards200_response.rb +258 -0
- data/lib/coinbase/client/models/fetch_staking_rewards_request.rb +343 -0
- data/lib/coinbase/client/models/get_staking_context_request.rb +274 -0
- data/lib/coinbase/client/models/partial_eth_staking_context.rb +257 -0
- data/lib/coinbase/client/models/request_faucet_funds200_response.rb +222 -0
- data/lib/coinbase/client/models/server_signer_list.rb +275 -0
- data/lib/coinbase/client/models/staking_context.rb +222 -0
- data/lib/coinbase/client/models/staking_context_context.rb +104 -0
- data/lib/coinbase/client/models/staking_operation.rb +222 -0
- data/lib/coinbase/client/models/staking_reward.rb +308 -0
- data/lib/coinbase/client/models/trade.rb +13 -4
- data/lib/coinbase/client/models/transaction.rb +45 -1
- data/lib/coinbase/client/models/transfer.rb +33 -1
- data/lib/coinbase/client/models/wallet.rb +20 -1
- data/lib/coinbase/client.rb +14 -0
- data/lib/coinbase/constants.rb +2 -27
- data/lib/coinbase/errors.rb +50 -62
- data/lib/coinbase/network.rb +6 -20
- data/lib/coinbase/server_signer.rb +57 -0
- data/lib/coinbase/trade.rb +147 -0
- data/lib/coinbase/transaction.rb +125 -0
- data/lib/coinbase/transfer.rb +22 -55
- data/lib/coinbase/wallet.rb +14 -3
- data/lib/coinbase.rb +11 -11
- metadata +22 -2
@@ -34,9 +34,13 @@ module Coinbase::Client
|
|
34
34
|
# The ID of the asset being transferred
|
35
35
|
attr_accessor :asset_id
|
36
36
|
|
37
|
+
attr_accessor :asset
|
38
|
+
|
37
39
|
# The ID of the transfer
|
38
40
|
attr_accessor :transfer_id
|
39
41
|
|
42
|
+
attr_accessor :transaction
|
43
|
+
|
40
44
|
# The unsigned payload of the transfer. This is the payload that needs to be signed by the sender.
|
41
45
|
attr_accessor :unsigned_payload
|
42
46
|
|
@@ -80,7 +84,9 @@ module Coinbase::Client
|
|
80
84
|
:'destination' => :'destination',
|
81
85
|
:'amount' => :'amount',
|
82
86
|
:'asset_id' => :'asset_id',
|
87
|
+
:'asset' => :'asset',
|
83
88
|
:'transfer_id' => :'transfer_id',
|
89
|
+
:'transaction' => :'transaction',
|
84
90
|
:'unsigned_payload' => :'unsigned_payload',
|
85
91
|
:'signed_payload' => :'signed_payload',
|
86
92
|
:'transaction_hash' => :'transaction_hash',
|
@@ -102,7 +108,9 @@ module Coinbase::Client
|
|
102
108
|
:'destination' => :'String',
|
103
109
|
:'amount' => :'String',
|
104
110
|
:'asset_id' => :'String',
|
111
|
+
:'asset' => :'Asset',
|
105
112
|
:'transfer_id' => :'String',
|
113
|
+
:'transaction' => :'Transaction',
|
106
114
|
:'unsigned_payload' => :'String',
|
107
115
|
:'signed_payload' => :'String',
|
108
116
|
:'transaction_hash' => :'String',
|
@@ -167,12 +175,24 @@ module Coinbase::Client
|
|
167
175
|
self.asset_id = nil
|
168
176
|
end
|
169
177
|
|
178
|
+
if attributes.key?(:'asset')
|
179
|
+
self.asset = attributes[:'asset']
|
180
|
+
else
|
181
|
+
self.asset = nil
|
182
|
+
end
|
183
|
+
|
170
184
|
if attributes.key?(:'transfer_id')
|
171
185
|
self.transfer_id = attributes[:'transfer_id']
|
172
186
|
else
|
173
187
|
self.transfer_id = nil
|
174
188
|
end
|
175
189
|
|
190
|
+
if attributes.key?(:'transaction')
|
191
|
+
self.transaction = attributes[:'transaction']
|
192
|
+
else
|
193
|
+
self.transaction = nil
|
194
|
+
end
|
195
|
+
|
176
196
|
if attributes.key?(:'unsigned_payload')
|
177
197
|
self.unsigned_payload = attributes[:'unsigned_payload']
|
178
198
|
else
|
@@ -223,10 +243,18 @@ module Coinbase::Client
|
|
223
243
|
invalid_properties.push('invalid value for "asset_id", asset_id cannot be nil.')
|
224
244
|
end
|
225
245
|
|
246
|
+
if @asset.nil?
|
247
|
+
invalid_properties.push('invalid value for "asset", asset cannot be nil.')
|
248
|
+
end
|
249
|
+
|
226
250
|
if @transfer_id.nil?
|
227
251
|
invalid_properties.push('invalid value for "transfer_id", transfer_id cannot be nil.')
|
228
252
|
end
|
229
253
|
|
254
|
+
if @transaction.nil?
|
255
|
+
invalid_properties.push('invalid value for "transaction", transaction cannot be nil.')
|
256
|
+
end
|
257
|
+
|
230
258
|
if @unsigned_payload.nil?
|
231
259
|
invalid_properties.push('invalid value for "unsigned_payload", unsigned_payload cannot be nil.')
|
232
260
|
end
|
@@ -248,7 +276,9 @@ module Coinbase::Client
|
|
248
276
|
return false if @destination.nil?
|
249
277
|
return false if @amount.nil?
|
250
278
|
return false if @asset_id.nil?
|
279
|
+
return false if @asset.nil?
|
251
280
|
return false if @transfer_id.nil?
|
281
|
+
return false if @transaction.nil?
|
252
282
|
return false if @unsigned_payload.nil?
|
253
283
|
return false if @status.nil?
|
254
284
|
status_validator = EnumAttributeValidator.new('String', ["pending", "broadcast", "complete", "failed"])
|
@@ -277,7 +307,9 @@ module Coinbase::Client
|
|
277
307
|
destination == o.destination &&
|
278
308
|
amount == o.amount &&
|
279
309
|
asset_id == o.asset_id &&
|
310
|
+
asset == o.asset &&
|
280
311
|
transfer_id == o.transfer_id &&
|
312
|
+
transaction == o.transaction &&
|
281
313
|
unsigned_payload == o.unsigned_payload &&
|
282
314
|
signed_payload == o.signed_payload &&
|
283
315
|
transaction_hash == o.transaction_hash &&
|
@@ -293,7 +325,7 @@ module Coinbase::Client
|
|
293
325
|
# Calculates hash code according to all attributes.
|
294
326
|
# @return [Integer] Hash code
|
295
327
|
def hash
|
296
|
-
[network_id, wallet_id, address_id, destination, amount, asset_id, transfer_id, unsigned_payload, signed_payload, transaction_hash, status].hash
|
328
|
+
[network_id, wallet_id, address_id, destination, amount, asset_id, asset, transfer_id, transaction, unsigned_payload, signed_payload, transaction_hash, status].hash
|
297
329
|
end
|
298
330
|
|
299
331
|
# Builds the object from hash
|
@@ -23,6 +23,9 @@ module Coinbase::Client
|
|
23
23
|
|
24
24
|
attr_accessor :default_address
|
25
25
|
|
26
|
+
# The features enabled for the wallet
|
27
|
+
attr_accessor :enabled_features
|
28
|
+
|
26
29
|
# The status of the Server-Signer for the wallet if present.
|
27
30
|
attr_accessor :server_signer_status
|
28
31
|
|
@@ -54,6 +57,7 @@ module Coinbase::Client
|
|
54
57
|
:'id' => :'id',
|
55
58
|
:'network_id' => :'network_id',
|
56
59
|
:'default_address' => :'default_address',
|
60
|
+
:'enabled_features' => :'enabled_features',
|
57
61
|
:'server_signer_status' => :'server_signer_status'
|
58
62
|
}
|
59
63
|
end
|
@@ -69,6 +73,7 @@ module Coinbase::Client
|
|
69
73
|
:'id' => :'String',
|
70
74
|
:'network_id' => :'String',
|
71
75
|
:'default_address' => :'Address',
|
76
|
+
:'enabled_features' => :'Array<Feature>',
|
72
77
|
:'server_signer_status' => :'String'
|
73
78
|
}
|
74
79
|
end
|
@@ -110,6 +115,14 @@ module Coinbase::Client
|
|
110
115
|
self.default_address = attributes[:'default_address']
|
111
116
|
end
|
112
117
|
|
118
|
+
if attributes.key?(:'enabled_features')
|
119
|
+
if (value = attributes[:'enabled_features']).is_a?(Array)
|
120
|
+
self.enabled_features = value
|
121
|
+
end
|
122
|
+
else
|
123
|
+
self.enabled_features = nil
|
124
|
+
end
|
125
|
+
|
113
126
|
if attributes.key?(:'server_signer_status')
|
114
127
|
self.server_signer_status = attributes[:'server_signer_status']
|
115
128
|
end
|
@@ -128,6 +141,10 @@ module Coinbase::Client
|
|
128
141
|
invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')
|
129
142
|
end
|
130
143
|
|
144
|
+
if @enabled_features.nil?
|
145
|
+
invalid_properties.push('invalid value for "enabled_features", enabled_features cannot be nil.')
|
146
|
+
end
|
147
|
+
|
131
148
|
invalid_properties
|
132
149
|
end
|
133
150
|
|
@@ -137,6 +154,7 @@ module Coinbase::Client
|
|
137
154
|
warn '[DEPRECATED] the `valid?` method is obsolete'
|
138
155
|
return false if @id.nil?
|
139
156
|
return false if @network_id.nil?
|
157
|
+
return false if @enabled_features.nil?
|
140
158
|
server_signer_status_validator = EnumAttributeValidator.new('String', ["pending_seed_creation", "active_seed"])
|
141
159
|
return false unless server_signer_status_validator.valid?(@server_signer_status)
|
142
160
|
true
|
@@ -160,6 +178,7 @@ module Coinbase::Client
|
|
160
178
|
id == o.id &&
|
161
179
|
network_id == o.network_id &&
|
162
180
|
default_address == o.default_address &&
|
181
|
+
enabled_features == o.enabled_features &&
|
163
182
|
server_signer_status == o.server_signer_status
|
164
183
|
end
|
165
184
|
|
@@ -172,7 +191,7 @@ module Coinbase::Client
|
|
172
191
|
# Calculates hash code according to all attributes.
|
173
192
|
# @return [Integer] Hash code
|
174
193
|
def hash
|
175
|
-
[id, network_id, default_address, server_signer_status].hash
|
194
|
+
[id, network_id, default_address, enabled_features, server_signer_status].hash
|
176
195
|
end
|
177
196
|
|
178
197
|
# Builds the object from hash
|
data/lib/coinbase/client.rb
CHANGED
@@ -24,6 +24,7 @@ Coinbase::Client.autoload :Asset, 'coinbase/client/models/asset'
|
|
24
24
|
Coinbase::Client.autoload :Balance, 'coinbase/client/models/balance'
|
25
25
|
Coinbase::Client.autoload :BroadcastTradeRequest, 'coinbase/client/models/broadcast_trade_request'
|
26
26
|
Coinbase::Client.autoload :BroadcastTransferRequest, 'coinbase/client/models/broadcast_transfer_request'
|
27
|
+
Coinbase::Client.autoload :BuildStakingOperationRequest, 'coinbase/client/models/build_staking_operation_request'
|
27
28
|
Coinbase::Client.autoload :CreateAddressRequest, 'coinbase/client/models/create_address_request'
|
28
29
|
Coinbase::Client.autoload :CreateServerSignerRequest, 'coinbase/client/models/create_server_signer_request'
|
29
30
|
Coinbase::Client.autoload :CreateTradeRequest, 'coinbase/client/models/create_trade_request'
|
@@ -32,14 +33,24 @@ Coinbase::Client.autoload :CreateWalletRequest, 'coinbase/client/models/create_w
|
|
32
33
|
Coinbase::Client.autoload :CreateWalletRequestWallet, 'coinbase/client/models/create_wallet_request_wallet'
|
33
34
|
Coinbase::Client.autoload :Error, 'coinbase/client/models/error'
|
34
35
|
Coinbase::Client.autoload :FaucetTransaction, 'coinbase/client/models/faucet_transaction'
|
36
|
+
Coinbase::Client.autoload :Feature, 'coinbase/client/models/feature'
|
37
|
+
Coinbase::Client.autoload :FetchStakingRewards200Response, 'coinbase/client/models/fetch_staking_rewards200_response'
|
38
|
+
Coinbase::Client.autoload :FetchStakingRewardsRequest, 'coinbase/client/models/fetch_staking_rewards_request'
|
39
|
+
Coinbase::Client.autoload :GetStakingContextRequest, 'coinbase/client/models/get_staking_context_request'
|
40
|
+
Coinbase::Client.autoload :PartialEthStakingContext, 'coinbase/client/models/partial_eth_staking_context'
|
35
41
|
Coinbase::Client.autoload :SeedCreationEvent, 'coinbase/client/models/seed_creation_event'
|
36
42
|
Coinbase::Client.autoload :SeedCreationEventResult, 'coinbase/client/models/seed_creation_event_result'
|
37
43
|
Coinbase::Client.autoload :ServerSigner, 'coinbase/client/models/server_signer'
|
38
44
|
Coinbase::Client.autoload :ServerSignerEvent, 'coinbase/client/models/server_signer_event'
|
39
45
|
Coinbase::Client.autoload :ServerSignerEventEvent, 'coinbase/client/models/server_signer_event_event'
|
40
46
|
Coinbase::Client.autoload :ServerSignerEventList, 'coinbase/client/models/server_signer_event_list'
|
47
|
+
Coinbase::Client.autoload :ServerSignerList, 'coinbase/client/models/server_signer_list'
|
41
48
|
Coinbase::Client.autoload :SignatureCreationEvent, 'coinbase/client/models/signature_creation_event'
|
42
49
|
Coinbase::Client.autoload :SignatureCreationEventResult, 'coinbase/client/models/signature_creation_event_result'
|
50
|
+
Coinbase::Client.autoload :StakingContext, 'coinbase/client/models/staking_context'
|
51
|
+
Coinbase::Client.autoload :StakingContextContext, 'coinbase/client/models/staking_context_context'
|
52
|
+
Coinbase::Client.autoload :StakingOperation, 'coinbase/client/models/staking_operation'
|
53
|
+
Coinbase::Client.autoload :StakingReward, 'coinbase/client/models/staking_reward'
|
43
54
|
Coinbase::Client.autoload :Trade, 'coinbase/client/models/trade'
|
44
55
|
Coinbase::Client.autoload :TradeList, 'coinbase/client/models/trade_list'
|
45
56
|
Coinbase::Client.autoload :Transaction, 'coinbase/client/models/transaction'
|
@@ -52,7 +63,10 @@ Coinbase::Client.autoload :WalletList, 'coinbase/client/models/wallet_list'
|
|
52
63
|
|
53
64
|
# APIs
|
54
65
|
Coinbase::Client.autoload :AddressesApi, 'coinbase/client/api/addresses_api'
|
66
|
+
Coinbase::Client.autoload :AssetsApi, 'coinbase/client/api/assets_api'
|
67
|
+
Coinbase::Client.autoload :ExternalAddressesApi, 'coinbase/client/api/external_addresses_api'
|
55
68
|
Coinbase::Client.autoload :ServerSignersApi, 'coinbase/client/api/server_signers_api'
|
69
|
+
Coinbase::Client.autoload :StakeApi, 'coinbase/client/api/stake_api'
|
56
70
|
Coinbase::Client.autoload :TradesApi, 'coinbase/client/api/trades_api'
|
57
71
|
Coinbase::Client.autoload :TransfersApi, 'coinbase/client/api/transfers_api'
|
58
72
|
Coinbase::Client.autoload :UsersApi, 'coinbase/client/api/users_api'
|
data/lib/coinbase/constants.rb
CHANGED
@@ -4,41 +4,16 @@ require_relative 'asset'
|
|
4
4
|
require_relative 'network'
|
5
5
|
|
6
6
|
module Coinbase
|
7
|
-
# The Assets supported on Base Sepolia by the Coinbase SDK.
|
8
|
-
ETH = Asset.new(network_id: :base_sepolia, asset_id: :eth, display_name: 'Ether')
|
9
|
-
USDC = Asset.new(network_id: :base_sepolia, asset_id: :usdc, display_name: 'USD Coin',
|
10
|
-
address_id: '0x036CbD53842c5426634e7929541eC2318f3dCF7e')
|
11
|
-
WETH = Asset.new(network_id: :base_sepolia, asset_id: :weth, display_name: 'Wrapped Ether',
|
12
|
-
address_id: '0x4200000000000000000000000000000000000006')
|
13
7
|
# The Base Sepolia Network.
|
14
8
|
BASE_SEPOLIA = Network.new(
|
15
9
|
network_id: :base_sepolia,
|
16
10
|
display_name: 'Base Sepolia',
|
17
11
|
protocol_family: :evm,
|
18
12
|
is_testnet: true,
|
19
|
-
assets: [ETH, USDC],
|
20
13
|
native_asset_id: :eth,
|
21
14
|
chain_id: 84_532
|
22
15
|
)
|
23
16
|
|
24
|
-
# The
|
25
|
-
|
26
|
-
|
27
|
-
# The amount of Wei per Gwei.
|
28
|
-
WEI_PER_GWEI = 1_000_000_000
|
29
|
-
|
30
|
-
# The amount of Gwei per Ether.
|
31
|
-
GWEI_PER_ETHER = 1_000_000_000
|
32
|
-
|
33
|
-
# The amount of atomic units of USDC per USDC.
|
34
|
-
ATOMIC_UNITS_PER_USDC = 1_000_000
|
35
|
-
|
36
|
-
# A map of supported Asset IDs.
|
37
|
-
SUPPORTED_ASSET_IDS = {
|
38
|
-
eth: true, # Ether, the native asset of most EVM networks.
|
39
|
-
gwei: true, # A medium denomination of Ether, typically used in gas prices.
|
40
|
-
wei: true, # The smallest denomination of Ether.
|
41
|
-
usdc: true, # USD Coin, a stablecoin pegged to the US Dollar.
|
42
|
-
weth: true # Wrapped Ether, the ERC-20 compatible version of Ether.
|
43
|
-
}.freeze
|
17
|
+
# The number of decimal places in Gwei.
|
18
|
+
GWEI_DECIMALS = 9
|
44
19
|
end
|
data/lib/coinbase/errors.rb
CHANGED
@@ -6,90 +6,51 @@ require 'json'
|
|
6
6
|
module Coinbase
|
7
7
|
# A wrapper for API errors to provide more context.
|
8
8
|
class APIError < StandardError
|
9
|
-
attr_reader :http_code, :api_code, :api_message
|
9
|
+
attr_reader :http_code, :api_code, :api_message, :handled
|
10
10
|
|
11
11
|
# Initializes a new APIError object.
|
12
12
|
# @param err [Coinbase::Client::APIError] The underlying error object.
|
13
|
-
def initialize(err)
|
14
|
-
super
|
13
|
+
def initialize(err, code: nil, message: nil, unhandled: false)
|
15
14
|
@http_code = err.code
|
15
|
+
@api_code = code
|
16
|
+
@api_message = message
|
17
|
+
@handled = code && message && !unhandled
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
-
body = JSON.parse(err.response_body)
|
20
|
-
@api_code = body['code']
|
21
|
-
@api_message = body['message']
|
19
|
+
super(err)
|
22
20
|
end
|
23
21
|
|
24
22
|
# Creates a specific APIError based on the API error code.
|
25
23
|
# @param err [Coinbase::Client::APIError] The underlying error object.
|
26
24
|
# @return [APIError] The specific APIError object.
|
27
|
-
# rubocop:disable Metrics/MethodLength
|
28
25
|
def self.from_error(err)
|
29
26
|
raise ArgumentError, 'Argument must be a Coinbase::Client::APIError' unless err.is_a? Coinbase::Client::ApiError
|
30
27
|
return APIError.new(err) unless err.response_body
|
31
28
|
|
32
|
-
|
29
|
+
begin
|
30
|
+
body = JSON.parse(err.response_body)
|
31
|
+
rescue JSON::ParserError
|
32
|
+
return APIError.new(err)
|
33
|
+
end
|
34
|
+
|
35
|
+
message = body['message']
|
36
|
+
code = body['code']
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
UnimplementedError.new(err)
|
37
|
-
when 'unauthorized'
|
38
|
-
UnauthorizedError.new(err)
|
39
|
-
when 'internal'
|
40
|
-
InternalError.new(err)
|
41
|
-
when 'not_found'
|
42
|
-
NotFoundError.new(err)
|
43
|
-
when 'invalid_wallet_id'
|
44
|
-
InvalidWalletIDError.new(err)
|
45
|
-
when 'invalid_address_id'
|
46
|
-
InvalidAddressIDError.new(err)
|
47
|
-
when 'invalid_wallet'
|
48
|
-
InvalidWalletError.new(err)
|
49
|
-
when 'invalid_address'
|
50
|
-
InvalidAddressError.new(err)
|
51
|
-
when 'invalid_amount'
|
52
|
-
InvalidAmountError.new(err)
|
53
|
-
when 'invalid_transfer_id'
|
54
|
-
InvalidTransferIDError.new(err)
|
55
|
-
when 'invalid_page_token'
|
56
|
-
InvalidPageError.new(err)
|
57
|
-
when 'invalid_page_limit'
|
58
|
-
InvalidLimitError.new(err)
|
59
|
-
when 'already_exists'
|
60
|
-
AlreadyExistsError.new(err)
|
61
|
-
when 'malformed_request'
|
62
|
-
MalformedRequestError.new(err)
|
63
|
-
when 'unsupported_asset'
|
64
|
-
UnsupportedAssetError.new(err)
|
65
|
-
when 'invalid_asset_id'
|
66
|
-
InvalidAssetIDError.new(err)
|
67
|
-
when 'invalid_destination'
|
68
|
-
InvalidDestinationError.new(err)
|
69
|
-
when 'invalid_network_id'
|
70
|
-
InvalidNetworkIDError.new(err)
|
71
|
-
when 'resource_exhausted'
|
72
|
-
ResourceExhaustedError.new(err)
|
73
|
-
when 'faucet_limit_reached'
|
74
|
-
FaucetLimitReachedError.new(err)
|
75
|
-
when 'invalid_signed_payload'
|
76
|
-
InvalidSignedPayloadError.new(err)
|
77
|
-
when 'invalid_transfer_status'
|
78
|
-
InvalidTransferStatusError.new(err)
|
38
|
+
if ERROR_CODE_TO_ERROR_CLASS.key?(code)
|
39
|
+
ERROR_CODE_TO_ERROR_CLASS[code].new(err, code: code, message: message)
|
79
40
|
else
|
80
|
-
APIError.new(err)
|
41
|
+
APIError.new(err, code: code, message: message, unhandled: true)
|
81
42
|
end
|
82
43
|
end
|
83
|
-
# rubocop:enable Metrics/MethodLength
|
84
44
|
|
85
|
-
#
|
86
|
-
# @return [String] a String representation of the APIError
|
45
|
+
# Override to_s to display a friendly error message
|
87
46
|
def to_s
|
88
|
-
|
47
|
+
# For handled errors, display just the API message as that provides sufficient context.
|
48
|
+
return api_message if handled
|
49
|
+
|
50
|
+
# For unhandled errors, display the full error message
|
51
|
+
super
|
89
52
|
end
|
90
53
|
|
91
|
-
# Same as to_s.
|
92
|
-
# @return [String] a String representation of the APIError
|
93
54
|
def inspect
|
94
55
|
to_s
|
95
56
|
end
|
@@ -117,4 +78,31 @@ module Coinbase
|
|
117
78
|
class FaucetLimitReachedError < APIError; end
|
118
79
|
class InvalidSignedPayloadError < APIError; end
|
119
80
|
class InvalidTransferStatusError < APIError; end
|
81
|
+
class NetworkFeatureUnsupportedError < APIError; end
|
82
|
+
|
83
|
+
ERROR_CODE_TO_ERROR_CLASS = {
|
84
|
+
'unimplemented' => UnimplementedError,
|
85
|
+
'unauthorized' => UnauthorizedError,
|
86
|
+
'internal' => InternalError,
|
87
|
+
'not_found' => NotFoundError,
|
88
|
+
'invalid_wallet_id' => InvalidWalletIDError,
|
89
|
+
'invalid_address_id' => InvalidAddressIDError,
|
90
|
+
'invalid_wallet' => InvalidWalletError,
|
91
|
+
'invalid_address' => InvalidAddressError,
|
92
|
+
'invalid_amount' => InvalidAmountError,
|
93
|
+
'invalid_transfer_id' => InvalidTransferIDError,
|
94
|
+
'invalid_page_token' => InvalidPageError,
|
95
|
+
'invalid_page_limit' => InvalidLimitError,
|
96
|
+
'already_exists' => AlreadyExistsError,
|
97
|
+
'malformed_request' => MalformedRequestError,
|
98
|
+
'unsupported_asset' => UnsupportedAssetError,
|
99
|
+
'invalid_asset_id' => InvalidAssetIDError,
|
100
|
+
'invalid_destination' => InvalidDestinationError,
|
101
|
+
'invalid_network_id' => InvalidNetworkIDError,
|
102
|
+
'resource_exhausted' => ResourceExhaustedError,
|
103
|
+
'faucet_limit_reached' => FaucetLimitReachedError,
|
104
|
+
'invalid_signed_payload' => InvalidSignedPayloadError,
|
105
|
+
'invalid_transfer_status' => InvalidTransferStatusError,
|
106
|
+
'network_feature_unsupported' => NetworkFeatureUnsupportedError
|
107
|
+
}.freeze
|
120
108
|
end
|
data/lib/coinbase/network.rb
CHANGED
@@ -12,31 +12,15 @@ module Coinbase
|
|
12
12
|
# @param protocol_family [String] The protocol family to which the Network belongs
|
13
13
|
# (e.g., "evm")
|
14
14
|
# @param is_testnet [Boolean] Whether the Network is a testnet
|
15
|
-
# @param assets [Array<Asset>] The Assets supported by the Network
|
16
15
|
# @param native_asset_id [String] The ID of the Network's native Asset
|
17
16
|
# @param chain_id [Integer] The Chain ID of the Network
|
18
|
-
def initialize(network_id:, display_name:, protocol_family:, is_testnet:,
|
17
|
+
def initialize(network_id:, display_name:, protocol_family:, is_testnet:, native_asset_id:, chain_id:)
|
19
18
|
@network_id = network_id
|
20
19
|
@display_name = display_name
|
21
20
|
@protocol_family = protocol_family
|
22
21
|
@is_testnet = is_testnet
|
22
|
+
@native_asset_id = native_asset_id
|
23
23
|
@chain_id = chain_id
|
24
|
-
|
25
|
-
@asset_map = {}
|
26
|
-
assets.each do |asset|
|
27
|
-
@asset_map[asset.asset_id] = asset
|
28
|
-
end
|
29
|
-
|
30
|
-
raise ArgumentError, 'Native Asset not found' unless @asset_map.key?(native_asset_id)
|
31
|
-
|
32
|
-
@native_asset = @asset_map[native_asset_id]
|
33
|
-
end
|
34
|
-
|
35
|
-
# Lists the Assets supported by the Network.
|
36
|
-
#
|
37
|
-
# @return [Array<Asset>] The Assets supported by the Network
|
38
|
-
def list_assets
|
39
|
-
@asset_map.values
|
40
24
|
end
|
41
25
|
|
42
26
|
# Gets the Asset with the given ID.
|
@@ -44,12 +28,14 @@ module Coinbase
|
|
44
28
|
# @param asset_id [Symbol] The ID of the Asset
|
45
29
|
# @return [Asset] The Asset with the given ID
|
46
30
|
def get_asset(asset_id)
|
47
|
-
@
|
31
|
+
Asset.fetch(@network_id, asset_id)
|
48
32
|
end
|
49
33
|
|
50
34
|
# Gets the native Asset of the Network.
|
51
35
|
#
|
52
36
|
# @return [Asset] The native Asset of the Network
|
53
|
-
|
37
|
+
def native_asset
|
38
|
+
@native_asset ||= get_asset(@native_asset_id)
|
39
|
+
end
|
54
40
|
end
|
55
41
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'client'
|
4
|
+
|
5
|
+
module Coinbase
|
6
|
+
# A representation of a Server-Signer. Server-Signers are assigned to sign transactions for a Wallet.
|
7
|
+
class ServerSigner
|
8
|
+
# Returns a new Server-Signer object. Do not use this method directly. Instead, use ServerSigner.default.
|
9
|
+
def initialize(model)
|
10
|
+
@model = model
|
11
|
+
end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
# Returns the default ServerSigner for the CDP Project.
|
15
|
+
# @return [Coinbase::ServerSigner] the default Server-Signer
|
16
|
+
def default
|
17
|
+
response = Coinbase.call_api do
|
18
|
+
server_signers_api.list_server_signers
|
19
|
+
end
|
20
|
+
|
21
|
+
raise 'No Server-Signer is associated with the project' if response.data.empty?
|
22
|
+
|
23
|
+
new(response.data.first)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def server_signers_api
|
29
|
+
Coinbase::Client::ServerSignersApi.new(Coinbase.configuration.api_client)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the Server-Signer ID.
|
34
|
+
# @return [String] the Server-Signer ID
|
35
|
+
def id
|
36
|
+
@model.server_signer_id
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the IDs of the Wallet's the Server-Signer can sign for.
|
40
|
+
# @return [Array<String>] the wallet IDs
|
41
|
+
def wallets
|
42
|
+
@model.wallets
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns a string representation of the Server-Signer.
|
46
|
+
# @return [String] a string representation of the Server-Signer
|
47
|
+
def to_s
|
48
|
+
"Coinbase::ServerSigner{server_signer_id: '#{id}', wallets: [#{wallets.join(', ')}]}"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Same as to_s.
|
52
|
+
# @return [String] a string representation of the Server-Signer
|
53
|
+
def inspect
|
54
|
+
to_s
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'constants'
|
4
|
+
require 'bigdecimal'
|
5
|
+
require 'eth'
|
6
|
+
|
7
|
+
module Coinbase
|
8
|
+
# A representation of a Trade, which trades an amount of an Asset to another Asset on a Network.
|
9
|
+
# The fee is assumed to be paid in the native Asset of the Network.
|
10
|
+
# Trades should be created through Wallet#trade or # Address#trade.
|
11
|
+
class Trade
|
12
|
+
# Returns a new Trade object. Do not use this method directly. Instead, use Wallet#trade or
|
13
|
+
# Address#trade.
|
14
|
+
# @param model [Coinbase::Client::Trade] The underlying Trade object
|
15
|
+
def initialize(model)
|
16
|
+
raise unless model.is_a?(Coinbase::Client::Trade)
|
17
|
+
|
18
|
+
@model = model
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the Trade ID.
|
22
|
+
# @return [String] The Trade ID
|
23
|
+
def id
|
24
|
+
@model.trade_id
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the Network ID of the Trade.
|
28
|
+
# @return [Symbol] The Network ID
|
29
|
+
def network_id
|
30
|
+
Coinbase.to_sym(@model.network_id)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the Wallet ID of the Trade.
|
34
|
+
# @return [String] The Wallet ID
|
35
|
+
def wallet_id
|
36
|
+
@model.wallet_id
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the Address ID of the Trade.
|
40
|
+
# @return [String] The Address ID
|
41
|
+
def address_id
|
42
|
+
@model.address_id
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the From Asset ID of the Trade.
|
46
|
+
# @return [Symbol] The From Asset ID
|
47
|
+
def from_asset_id
|
48
|
+
@model.from_asset.asset_id.to_sym
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the amount of the from asset for the Trade.
|
52
|
+
# @return [BigDecimal] The amount of the from asset
|
53
|
+
def from_amount
|
54
|
+
BigDecimal(@model.from_amount) / BigDecimal(10).power(@model.from_asset.decimals)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns the To Asset ID of the Trade.
|
58
|
+
# @return [Symbol] The To Asset ID
|
59
|
+
def to_asset_id
|
60
|
+
@model.to_asset.asset_id.to_sym
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns the amount of the to asset for the Trade.
|
64
|
+
# @return [BigDecimal] The amount of the to asset
|
65
|
+
def to_amount
|
66
|
+
BigDecimal(@model.to_amount) / BigDecimal(10).power(@model.to_asset.decimals)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns the Trade transaction.
|
70
|
+
# @return [Coinbase::Transaction] The Trade transaction
|
71
|
+
def transaction
|
72
|
+
@transaction ||= Coinbase::Transaction.new(@model.transaction)
|
73
|
+
end
|
74
|
+
|
75
|
+
def approve_transaction
|
76
|
+
@approve_transaction ||= @model.approve_transaction ? Coinbase::Transaction.new(@model.approve_transaction) : nil
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns the status of the Trade.
|
80
|
+
# @return [Symbol] The status
|
81
|
+
def status
|
82
|
+
transaction.status
|
83
|
+
end
|
84
|
+
|
85
|
+
# Waits until the Trade is completed or failed by polling the Network at the given interval. Raises a
|
86
|
+
# Timeout::Error if the Trade takes longer than the given timeout.
|
87
|
+
# @param interval_seconds [Integer] The interval at which to poll the Network, in seconds
|
88
|
+
# @param timeout_seconds [Integer] The maximum amount of time to wait for the Trade to complete, in seconds
|
89
|
+
# @return [Trade] The completed Trade object
|
90
|
+
def wait!(interval_seconds = 0.2, timeout_seconds = 10)
|
91
|
+
start_time = Time.now
|
92
|
+
|
93
|
+
loop do
|
94
|
+
reload
|
95
|
+
|
96
|
+
# Wait for the trade transaction to be in a terminal state.
|
97
|
+
# The approve transaction is optional and must last first, so we don't need to wait for it.
|
98
|
+
# We may want to handle a situation where the approve transaction fails and the
|
99
|
+
# trade transaction does not ever get broadcast.
|
100
|
+
break if transaction.terminal_state?
|
101
|
+
|
102
|
+
raise Timeout::Error, 'Trade timed out' if Time.now - start_time > timeout_seconds
|
103
|
+
|
104
|
+
self.sleep interval_seconds
|
105
|
+
end
|
106
|
+
|
107
|
+
self
|
108
|
+
end
|
109
|
+
|
110
|
+
# Reloads the Trade model with the latest version from the server side.
|
111
|
+
# @return [Trade] The most recent version of Trade from the server.
|
112
|
+
def reload
|
113
|
+
@model = Coinbase.call_api do
|
114
|
+
trades_api.get_trade(wallet_id, address_id, id)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Update the memoized transaction.
|
118
|
+
@transaction = Coinbase::Transaction.new(@model.transaction)
|
119
|
+
|
120
|
+
# Update the memoized approve transaction if it exists.
|
121
|
+
@approve_transaction = @model.approve_transaction ? Coinbase::Transaction.new(@model.approve_transaction) : nil
|
122
|
+
|
123
|
+
self
|
124
|
+
end
|
125
|
+
|
126
|
+
# Returns a String representation of the Trade.
|
127
|
+
# @return [String] a String representation of the Trade
|
128
|
+
def to_s
|
129
|
+
"Coinbase::Trade{transfer_id: '#{id}', network_id: '#{network_id}', " \
|
130
|
+
"address_id: '#{address_id}', from_asset_id: '#{from_asset_id}', " \
|
131
|
+
"to_asset_id: '#{to_asset_id}', from_amount: '#{from_amount}', " \
|
132
|
+
"to_amount: '#{to_amount}' status: '#{status}'}"
|
133
|
+
end
|
134
|
+
|
135
|
+
# Same as to_s.
|
136
|
+
# @return [String] a String representation of the Trade
|
137
|
+
def inspect
|
138
|
+
to_s
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def trades_api
|
144
|
+
@trades_api ||= Coinbase::Client::TradesApi.new(Coinbase.configuration.api_client)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|