coinbase 0.0.1 → 4.0.0
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.
Potentially problematic release.
This version of coinbase might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +67 -0
- data/LICENSE.txt +21 -0
- data/README.md +578 -0
- data/Rakefile +7 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/coinbase.gemspec +30 -0
- data/lib/coinbase/wallet/adapters/em_http.rb +64 -0
- data/lib/coinbase/wallet/adapters/net_http.rb +62 -0
- data/lib/coinbase/wallet/api_client.rb +659 -0
- data/lib/coinbase/wallet/api_errors.rb +112 -0
- data/lib/coinbase/wallet/api_response.rb +37 -0
- data/lib/coinbase/wallet/client.rb +98 -0
- data/lib/coinbase/wallet/models/account.rb +187 -0
- data/lib/coinbase/wallet/models/api_object.rb +46 -0
- data/lib/coinbase/wallet/models/checkout.rb +19 -0
- data/lib/coinbase/wallet/models/order.rb +12 -0
- data/lib/coinbase/wallet/models/transaction.rb +21 -0
- data/lib/coinbase/wallet/models/transfer.rb +13 -0
- data/lib/coinbase/wallet/models/user.rb +15 -0
- data/lib/coinbase/wallet/version.rb +5 -0
- data/lib/coinbase/wallet.rb +23 -156
- data/spec/account_spec.rb +193 -0
- data/spec/clients/client_spec.rb +34 -0
- data/spec/clients/oauth_client_spec.rb +56 -0
- data/spec/endpoints_spec.rb +346 -0
- data/spec/error_spec.rb +130 -0
- data/spec/models/api_object_spec.rb +63 -0
- data/spec/models/checkout_spec.rb +52 -0
- data/spec/models/current_user_spec.rb +29 -0
- data/spec/models/order_spec.rb +52 -0
- data/spec/models/request_spec.rb +47 -0
- data/spec/models/transfer_spec.rb +64 -0
- data/spec/models/user_spec.rb +24 -0
- data/spec/spec_helper.rb +13 -0
- metadata +72 -82
- data/lib/coinbase/address.rb +0 -127
- data/lib/coinbase/asset.rb +0 -20
- data/lib/coinbase/balance_map.rb +0 -48
- data/lib/coinbase/constants.rb +0 -38
- data/lib/coinbase/network.rb +0 -55
- data/lib/coinbase/transfer.rb +0 -153
- data/lib/coinbase.rb +0 -18
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coinbase::Wallet::Request do
|
4
|
+
before :all do
|
5
|
+
@object_data = {
|
6
|
+
"id" => "2e9f48cd-0b05-5f7c-9056-17a8acb408ad",
|
7
|
+
"type" => "request",
|
8
|
+
"status" => "pending",
|
9
|
+
"amount" => {
|
10
|
+
"amount" => "1.00000000",
|
11
|
+
"currency" => "BTC"
|
12
|
+
},
|
13
|
+
"native_amount" => {
|
14
|
+
"amount" => "10.00",
|
15
|
+
"currency" => "USD"
|
16
|
+
},
|
17
|
+
"description" => nil,
|
18
|
+
"created_at" => "2015-04-01T10:37:11-07:00",
|
19
|
+
"updated_at" => "2015-04-01T10:37:11-07:00",
|
20
|
+
"resource" => "transaction",
|
21
|
+
"resource_path" => "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/transactions/2e9f48cd-0b05-5f7c-9056-17a8acb408ad",
|
22
|
+
"to" => {
|
23
|
+
"resource" => "email",
|
24
|
+
"email" => "email@example.com"
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
@client = Coinbase::Wallet::Client.new(api_key: 'api_key', api_secret: 'api_secret')
|
29
|
+
@object = Coinbase::Wallet::Request.new(@client, @object_data)
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#resend!' do
|
33
|
+
it 'should resend an order' do
|
34
|
+
stub_request(:post, 'https://api.coinbase.com' + @object_data['resource_path'] + '/resend')
|
35
|
+
.to_return(body: { data: mock_item }.to_json)
|
36
|
+
expect(@object.resend!).to eq mock_item
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#cancel!' do
|
41
|
+
it 'should cancel an order' do
|
42
|
+
stub_request(:delete, 'https://api.coinbase.com' + @object_data['resource_path'])
|
43
|
+
.to_return(body: { data: mock_item }.to_json)
|
44
|
+
expect(@object.cancel!).to eq mock_item
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coinbase::Wallet::Transfer do
|
4
|
+
before :all do
|
5
|
+
@object_data = {
|
6
|
+
'id' => '67e0eaec-07d7-54c4-a72c-2e92826897df',
|
7
|
+
'status' => 'pending',
|
8
|
+
'payment_method' => {
|
9
|
+
'id' => '83562370-3e5c-51db-87da-752af5ab9559',
|
10
|
+
'resource' => 'payment_method'
|
11
|
+
},
|
12
|
+
'transaction' => {
|
13
|
+
'id' => '441b9494-b3f0-5b98-b9b0-4d82c21c252a',
|
14
|
+
'resource' => 'transaction'
|
15
|
+
},
|
16
|
+
'amount' => {
|
17
|
+
'amount' => '1.00000000',
|
18
|
+
'currency' => 'BTC'
|
19
|
+
},
|
20
|
+
'total' => {
|
21
|
+
'amount' => '10.25',
|
22
|
+
'currency' => 'USD'
|
23
|
+
},
|
24
|
+
'subtotal' => {
|
25
|
+
'amount' => '10.10',
|
26
|
+
'currency' => 'USD'
|
27
|
+
},
|
28
|
+
'created_at' => '2015-01-31T20:49:02Z',
|
29
|
+
'updated_at' => '2015-01-31T20:49:02Z',
|
30
|
+
'resource' => 'buy',
|
31
|
+
'resource_path' => '/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/buys/67e0eaec-07d7-54c4-a72c-2e92826897df',
|
32
|
+
'committed' => false,
|
33
|
+
'instant' => false,
|
34
|
+
'fees' => [
|
35
|
+
{
|
36
|
+
'type' => 'coinbase',
|
37
|
+
'amount' => {
|
38
|
+
'amount' => '0.00',
|
39
|
+
'currency' => 'USD'
|
40
|
+
}
|
41
|
+
},
|
42
|
+
{
|
43
|
+
'type' => 'bank',
|
44
|
+
'amount' => {
|
45
|
+
'amount' => '0.15',
|
46
|
+
'currency' => 'USD'
|
47
|
+
}
|
48
|
+
}
|
49
|
+
],
|
50
|
+
'payout_at' => '2015-02-18T16 =>54 =>00-08 =>00'
|
51
|
+
}
|
52
|
+
|
53
|
+
@client = Coinbase::Wallet::Client.new(api_key: 'api_key', api_secret: 'api_secret')
|
54
|
+
@object = Coinbase::Wallet::Transfer.new(@client, @object_data)
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#commit!' do
|
58
|
+
it 'should commit an transfer (buy/sell/deposit/withdrawal)' do
|
59
|
+
stub_request(:post, 'https://api.coinbase.com' + @object_data['resource_path'] + '/commit')
|
60
|
+
.to_return(body: { data: mock_item }.to_json)
|
61
|
+
expect(@object.commit!).to eq mock_item
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coinbase::Wallet::User do
|
4
|
+
before :all do
|
5
|
+
@user_data = {
|
6
|
+
'id' => '9da7a204-544e-5fd1-9a12-61176c5d4cd8',
|
7
|
+
'name' => 'User One',
|
8
|
+
'username' => 'user1',
|
9
|
+
'profile_location' => nil,
|
10
|
+
'profile_bio' => nil,
|
11
|
+
'profile_url' => 'https://coinbase.com/user1',
|
12
|
+
'avatar_url' => 'https://images.coinbase.com/avatar?h=vR%2FY8igBoPwuwGren5JMwvDNGpURAY%2F0nRIOgH%2FY2Qh%2BQ6nomR3qusA%2Bh6o2%0Af9rH&s=128',
|
13
|
+
'resource' => 'user',
|
14
|
+
'resource_path' => '/v2/user/9da7a204-544e-5fd1-9a12-61176c5d4cd8'
|
15
|
+
}
|
16
|
+
|
17
|
+
@client = Coinbase::Wallet::Client.new(api_key: 'api_key', api_secret: 'api_secret')
|
18
|
+
@user = Coinbase::Wallet::User.new(@client, @user_data)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should access attributes' do
|
22
|
+
expect(@user.id).to eq @user_data['id']
|
23
|
+
end
|
24
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coinbase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- John Duhamel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bigdecimal
|
@@ -25,21 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - '='
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 2.8.1
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - '='
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 2.8.1
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: eth
|
28
|
+
name: em-http-request
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
31
|
- - ">="
|
@@ -53,41 +39,41 @@ dependencies:
|
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
version: '0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
42
|
+
name: bundler
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
|
-
- - "
|
45
|
+
- - "~>"
|
60
46
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
62
|
-
type: :
|
47
|
+
version: '1.10'
|
48
|
+
type: :development
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
|
-
- - "
|
52
|
+
- - "~>"
|
67
53
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
54
|
+
version: '1.10'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
56
|
+
name: rake
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
|
-
- - "
|
59
|
+
- - "~>"
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
|
-
- - "
|
66
|
+
- - "~>"
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
68
|
+
version: '10.0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
70
|
+
name: rgem
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
73
|
- - ">="
|
88
74
|
- !ruby/object:Gem::Version
|
89
75
|
version: '0'
|
90
|
-
type: :
|
76
|
+
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
@@ -95,7 +81,7 @@ dependencies:
|
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '0'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
84
|
+
name: webmock
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
87
|
- - ">="
|
@@ -109,7 +95,7 @@ dependencies:
|
|
109
95
|
- !ruby/object:Gem::Version
|
110
96
|
version: '0'
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
98
|
+
name: timecop
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
114
100
|
requirements:
|
115
101
|
- - ">="
|
@@ -123,66 +109,69 @@ dependencies:
|
|
123
109
|
- !ruby/object:Gem::Version
|
124
110
|
version: '0'
|
125
111
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
112
|
+
name: pry
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
128
114
|
requirements:
|
129
|
-
- - "
|
115
|
+
- - "~>"
|
130
116
|
- !ruby/object:Gem::Version
|
131
117
|
version: '0'
|
132
118
|
type: :development
|
133
119
|
prerelease: false
|
134
120
|
version_requirements: !ruby/object:Gem::Requirement
|
135
121
|
requirements:
|
136
|
-
- - "
|
122
|
+
- - "~>"
|
137
123
|
- !ruby/object:Gem::Version
|
138
124
|
version: '0'
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
version: 1.63.1
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - '='
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: 1.63.1
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: yard
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - '='
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: 0.9.36
|
160
|
-
type: :development
|
161
|
-
prerelease: false
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
163
|
-
requirements:
|
164
|
-
- - '='
|
165
|
-
- !ruby/object:Gem::Version
|
166
|
-
version: 0.9.36
|
167
|
-
description: Coinbase Ruby SDK for accessing Coinbase Platform APIs
|
168
|
-
email: yuga.cohler@coinbase.com
|
169
|
-
executables: []
|
125
|
+
description: '["An easy way to buy, send, and accept bitcoin."]'
|
126
|
+
email:
|
127
|
+
- jjd@coinbase.com
|
128
|
+
executables:
|
129
|
+
- console
|
130
|
+
- setup
|
170
131
|
extensions: []
|
171
132
|
extra_rdoc_files: []
|
172
133
|
files:
|
173
|
-
-
|
174
|
-
-
|
175
|
-
-
|
176
|
-
-
|
177
|
-
-
|
178
|
-
-
|
179
|
-
-
|
134
|
+
- ".gitignore"
|
135
|
+
- Gemfile
|
136
|
+
- Gemfile.lock
|
137
|
+
- LICENSE.txt
|
138
|
+
- README.md
|
139
|
+
- Rakefile
|
140
|
+
- bin/console
|
141
|
+
- bin/setup
|
142
|
+
- coinbase.gemspec
|
180
143
|
- lib/coinbase/wallet.rb
|
181
|
-
|
144
|
+
- lib/coinbase/wallet/adapters/em_http.rb
|
145
|
+
- lib/coinbase/wallet/adapters/net_http.rb
|
146
|
+
- lib/coinbase/wallet/api_client.rb
|
147
|
+
- lib/coinbase/wallet/api_errors.rb
|
148
|
+
- lib/coinbase/wallet/api_response.rb
|
149
|
+
- lib/coinbase/wallet/client.rb
|
150
|
+
- lib/coinbase/wallet/models/account.rb
|
151
|
+
- lib/coinbase/wallet/models/api_object.rb
|
152
|
+
- lib/coinbase/wallet/models/checkout.rb
|
153
|
+
- lib/coinbase/wallet/models/order.rb
|
154
|
+
- lib/coinbase/wallet/models/transaction.rb
|
155
|
+
- lib/coinbase/wallet/models/transfer.rb
|
156
|
+
- lib/coinbase/wallet/models/user.rb
|
157
|
+
- lib/coinbase/wallet/version.rb
|
158
|
+
- spec/account_spec.rb
|
159
|
+
- spec/clients/client_spec.rb
|
160
|
+
- spec/clients/oauth_client_spec.rb
|
161
|
+
- spec/endpoints_spec.rb
|
162
|
+
- spec/error_spec.rb
|
163
|
+
- spec/models/api_object_spec.rb
|
164
|
+
- spec/models/checkout_spec.rb
|
165
|
+
- spec/models/current_user_spec.rb
|
166
|
+
- spec/models/order_spec.rb
|
167
|
+
- spec/models/request_spec.rb
|
168
|
+
- spec/models/transfer_spec.rb
|
169
|
+
- spec/models/user_spec.rb
|
170
|
+
- spec/spec_helper.rb
|
171
|
+
homepage: https://developers.coinbase.com/api/v2
|
182
172
|
licenses:
|
183
|
-
-
|
184
|
-
metadata:
|
185
|
-
rubygems_mfa_required: 'true'
|
173
|
+
- MIT
|
174
|
+
metadata: {}
|
186
175
|
post_install_message:
|
187
176
|
rdoc_options: []
|
188
177
|
require_paths:
|
@@ -191,15 +180,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
191
180
|
requirements:
|
192
181
|
- - ">="
|
193
182
|
- !ruby/object:Gem::Version
|
194
|
-
version:
|
183
|
+
version: '0'
|
195
184
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
185
|
requirements:
|
197
186
|
- - ">="
|
198
187
|
- !ruby/object:Gem::Version
|
199
188
|
version: '0'
|
200
189
|
requirements: []
|
201
|
-
|
190
|
+
rubyforge_project:
|
191
|
+
rubygems_version: 2.2.2
|
202
192
|
signing_key:
|
203
193
|
specification_version: 4
|
204
|
-
summary:
|
194
|
+
summary: '["An easy way to buy, send, and accept bitcoin."]'
|
205
195
|
test_files: []
|
data/lib/coinbase/address.rb
DELETED
@@ -1,127 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'balance_map'
|
4
|
-
require_relative 'constants'
|
5
|
-
require 'bigdecimal'
|
6
|
-
require 'eth'
|
7
|
-
require 'jimson'
|
8
|
-
|
9
|
-
module Coinbase
|
10
|
-
# A representation of a blockchain Address, which is a user-controlled account on a Network. Addresses are used to
|
11
|
-
# send and receive Assets, and should be created using {link:Wallet#create_address}. Addresses require a
|
12
|
-
# {link:Eth::Key} to sign transaction data.
|
13
|
-
class Address
|
14
|
-
attr_reader :network_id, :address_id, :wallet_id
|
15
|
-
|
16
|
-
# Returns a new Address object.
|
17
|
-
# @param network_id [Symbol] The ID of the Network on which the Address exists
|
18
|
-
# @param address_id [String] The ID of the Address. On EVM Networks, for example, this is a hash of the public key.
|
19
|
-
# @param wallet_id [String] The ID of the Wallet to which the Address belongs
|
20
|
-
# @param key [Eth::Key] The key backing the Address
|
21
|
-
# @param client [Jimson::Client] (Optional) The JSON RPC client to use for interacting with the Network
|
22
|
-
def initialize(network_id, address_id, wallet_id, key,
|
23
|
-
client: Jimson::Client.new(ENV.fetch('BASE_SEPOLIA_RPC_URL', nil)))
|
24
|
-
# TODO: Don't require key.
|
25
|
-
@network_id = network_id
|
26
|
-
@address_id = address_id
|
27
|
-
@wallet_id = wallet_id
|
28
|
-
@key = key
|
29
|
-
@client = client
|
30
|
-
end
|
31
|
-
|
32
|
-
# Returns the balances of the Address. Currently only ETH balances are supported.
|
33
|
-
# @return [BalanceMap] The balances of the Address, keyed by asset ID. Ether balances are denominated
|
34
|
-
# in ETH.
|
35
|
-
def list_balances
|
36
|
-
# TODO: Handle multiple currencies.
|
37
|
-
eth_balance_in_wei = BigDecimal(@client.eth_getBalance(@address_id, 'latest').to_i(16).to_s)
|
38
|
-
eth_balance = BigDecimal(eth_balance_in_wei / BigDecimal(Coinbase::WEI_PER_ETHER.to_s))
|
39
|
-
|
40
|
-
BalanceMap.new({ eth: eth_balance })
|
41
|
-
end
|
42
|
-
|
43
|
-
# Returns the balance of the provided Asset. Currently only ETH is supported.
|
44
|
-
# @param asset_id [Symbol] The Asset to retrieve the balance for
|
45
|
-
# @return [BigDecimal] The balance of the Asset
|
46
|
-
def get_balance(asset_id)
|
47
|
-
normalized_asset_id = if %i[wei gwei].include?(asset_id)
|
48
|
-
:eth
|
49
|
-
else
|
50
|
-
asset_id
|
51
|
-
end
|
52
|
-
|
53
|
-
eth_balance = list_balances[normalized_asset_id] || BigDecimal(0)
|
54
|
-
|
55
|
-
case asset_id
|
56
|
-
when :eth
|
57
|
-
eth_balance
|
58
|
-
when :gwei
|
59
|
-
eth_balance * Coinbase::GWEI_PER_ETHER
|
60
|
-
when :wei
|
61
|
-
eth_balance * Coinbase::WEI_PER_ETHER
|
62
|
-
else
|
63
|
-
BigDecimal(0)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Transfers the given amount of the given Asset to the given address. Only same-Network Transfers are supported.
|
68
|
-
# @param amount [Integer, Float, BigDecimal] The amount of the Asset to send.
|
69
|
-
# @param asset_id [Symbol] The ID of the Asset to send. For Ether, :eth, :gwei, and :wei are supported.
|
70
|
-
# @param destination [Wallet | Address | String] The destination of the transfer. If a Wallet, sends to the Wallet's
|
71
|
-
# default address. If a String, interprets it as the address ID.
|
72
|
-
# @return [String] The hash of the Transfer transaction.
|
73
|
-
def transfer(amount, asset_id, destination)
|
74
|
-
# TODO: Handle multiple currencies.
|
75
|
-
raise ArgumentError, "Unsupported asset: #{asset_id}" unless Coinbase::SUPPORTED_ASSET_IDS[asset_id]
|
76
|
-
|
77
|
-
if destination.is_a?(Wallet)
|
78
|
-
raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != @network_id
|
79
|
-
|
80
|
-
destination = destination.default_address.address_id
|
81
|
-
elsif destination.is_a?(Address)
|
82
|
-
raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != @network_id
|
83
|
-
|
84
|
-
destination = destination.address_id
|
85
|
-
end
|
86
|
-
|
87
|
-
current_balance = get_balance(asset_id)
|
88
|
-
if current_balance < amount
|
89
|
-
raise ArgumentError, "Insufficient funds: #{amount} requested, but only #{current_balance} available"
|
90
|
-
end
|
91
|
-
|
92
|
-
transfer = Coinbase::Transfer.new(@network_id, @wallet_id, @address_id, amount, asset_id, destination,
|
93
|
-
client: @client)
|
94
|
-
|
95
|
-
transaction = transfer.transaction
|
96
|
-
transaction.sign(@key)
|
97
|
-
@client.eth_sendRawTransaction("0x#{transaction.hex}")
|
98
|
-
|
99
|
-
transfer
|
100
|
-
end
|
101
|
-
|
102
|
-
# Returns the address as a string.
|
103
|
-
# @return [String] The address
|
104
|
-
def to_s
|
105
|
-
@address_id
|
106
|
-
end
|
107
|
-
|
108
|
-
private
|
109
|
-
|
110
|
-
# Normalizes the amount of ETH to send based on the asset ID.
|
111
|
-
# @param amount [Integer, Float, BigDecimal] The amount to normalize
|
112
|
-
# @param asset_id [Symbol] The ID of the Asset being transferred
|
113
|
-
# @return [BigDecimal] The normalized amount in units of ETH
|
114
|
-
def normalize_eth_amount(amount, asset_id)
|
115
|
-
case asset_id
|
116
|
-
when :eth
|
117
|
-
amount.is_a?(BigDecimal) ? amount : BigDecimal(amount.to_s)
|
118
|
-
when :gwei
|
119
|
-
BigDecimal(amount / Coinbase::GWEI_PER_ETHER)
|
120
|
-
when :wei
|
121
|
-
BigDecimal(amount / Coinbase::WEI_PER_ETHER)
|
122
|
-
else
|
123
|
-
raise ArgumentError, "Unsupported asset: #{asset_id}"
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
data/lib/coinbase/asset.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Coinbase
|
4
|
-
# A representation of an Asset.
|
5
|
-
class Asset
|
6
|
-
attr_reader :network_id, :asset_id, :display_name, :address_id
|
7
|
-
|
8
|
-
# Returns a new Asset object.
|
9
|
-
# @param network_id [Symbol] The ID of the Network to which the Asset belongs
|
10
|
-
# @param asset_id [Symbol] The Asset ID
|
11
|
-
# @param display_name [String] The Asset's display name
|
12
|
-
# @param address_id [String] (Optional) The Asset's address ID, if one exists
|
13
|
-
def initialize(network_id:, asset_id:, display_name:, address_id: nil)
|
14
|
-
@network_id = network_id
|
15
|
-
@asset_id = asset_id
|
16
|
-
@display_name = display_name
|
17
|
-
@address_id = address_id
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
data/lib/coinbase/balance_map.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'bigdecimal'
|
4
|
-
|
5
|
-
module Coinbase
|
6
|
-
# A convenience class for printing out crypto asset balances in a human-readable format.
|
7
|
-
class BalanceMap < Hash
|
8
|
-
# Returns a new BalanceMap object.
|
9
|
-
# @param hash [Map<Symbol, BigDecimal>] The hash to initialize with
|
10
|
-
def initialize(hash = {})
|
11
|
-
super()
|
12
|
-
hash.each do |key, value|
|
13
|
-
self[key] = value
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# Returns a string representation of the balance map.
|
18
|
-
# @return [String] The string representation of the balance
|
19
|
-
def to_s
|
20
|
-
to_string
|
21
|
-
end
|
22
|
-
|
23
|
-
# Returns a string representation of the balance map.
|
24
|
-
# @return [String] The string representation of the balance
|
25
|
-
def inspect
|
26
|
-
to_string
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
# Returns a string representation of the balance.
|
32
|
-
# @return [String] The string representation of the balance
|
33
|
-
def to_string
|
34
|
-
result = {}
|
35
|
-
|
36
|
-
each do |asset_id, balance|
|
37
|
-
# Convert to floating-point number (not scientific notation)
|
38
|
-
str = balance.to_s('F')
|
39
|
-
|
40
|
-
str = balance.to_i.to_s if balance.frac.zero?
|
41
|
-
|
42
|
-
result[asset_id] = str
|
43
|
-
end
|
44
|
-
|
45
|
-
result
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
data/lib/coinbase/constants.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'asset'
|
4
|
-
require_relative 'network'
|
5
|
-
|
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
|
-
|
12
|
-
# The Base Sepolia Network.
|
13
|
-
BASE_SEPOLIA = Network.new(
|
14
|
-
network_id: :base_sepolia,
|
15
|
-
display_name: 'Base Sepolia',
|
16
|
-
protocol_family: :evm,
|
17
|
-
is_testnet: true,
|
18
|
-
assets: [ETH, USDC],
|
19
|
-
native_asset_id: :eth,
|
20
|
-
chain_id: 84_532
|
21
|
-
)
|
22
|
-
|
23
|
-
# The amount of Wei per Ether.
|
24
|
-
WEI_PER_ETHER = 1_000_000_000_000_000_000
|
25
|
-
|
26
|
-
# The amount of Wei per Gwei.
|
27
|
-
WEI_PER_GWEI = 1_000_000_000
|
28
|
-
|
29
|
-
# The amount of Gwei per Ether.
|
30
|
-
GWEI_PER_ETHER = 1_000_000_000
|
31
|
-
|
32
|
-
# A map of supported Asset IDs.
|
33
|
-
SUPPORTED_ASSET_IDS = {
|
34
|
-
eth: true, # Ether, the native asset of most EVM networks.
|
35
|
-
gwei: true, # A medium denomination of Ether, typically used in gas prices.
|
36
|
-
wei: true # The smallest denomination of Ether.
|
37
|
-
}.freeze
|
38
|
-
end
|
data/lib/coinbase/network.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Coinbase
|
4
|
-
# A blockchain network.
|
5
|
-
class Network
|
6
|
-
attr_reader :chain_id
|
7
|
-
|
8
|
-
# Returns a new Network object.
|
9
|
-
#
|
10
|
-
# @param network_id [Symbol] The Network ID
|
11
|
-
# @param display_name [String] The Network's display name
|
12
|
-
# @param protocol_family [String] The protocol family to which the Network belongs
|
13
|
-
# (e.g., "evm")
|
14
|
-
# @param is_testnet [Boolean] Whether the Network is a testnet
|
15
|
-
# @param assets [Array<Asset>] The Assets supported by the Network
|
16
|
-
# @param native_asset_id [String] The ID of the Network's native Asset
|
17
|
-
# @param chain_id [Integer] The Chain ID of the Network
|
18
|
-
def initialize(network_id:, display_name:, protocol_family:, is_testnet:, assets:, native_asset_id:, chain_id:)
|
19
|
-
@network_id = network_id
|
20
|
-
@display_name = display_name
|
21
|
-
@protocol_family = protocol_family
|
22
|
-
@is_testnet = is_testnet
|
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
|
-
end
|
41
|
-
|
42
|
-
# Gets the Asset with the given ID.
|
43
|
-
#
|
44
|
-
# @param asset_id [Symbol] The ID of the Asset
|
45
|
-
# @return [Asset] The Asset with the given ID
|
46
|
-
def get_asset(asset_id)
|
47
|
-
@asset_map[asset_id]
|
48
|
-
end
|
49
|
-
|
50
|
-
# Gets the native Asset of the Network.
|
51
|
-
#
|
52
|
-
# @return [Asset] The native Asset of the Network
|
53
|
-
attr_reader :native_asset
|
54
|
-
end
|
55
|
-
end
|