coinbase 0.0.1 → 4.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +7 -0
- data/CONTRIBUTING.md +53 -0
- data/Gemfile +4 -0
- data/LICENSE +201 -0
- data/README.md +621 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/coinbase.gemspec +26 -0
- data/lib/coinbase/util.rb +16 -0
- data/lib/coinbase/wallet/adapters/em_http.rb +78 -0
- data/lib/coinbase/wallet/adapters/net_http.rb +68 -0
- data/lib/coinbase/wallet/api_client.rb +755 -0
- data/lib/coinbase/wallet/api_errors.rb +120 -0
- data/lib/coinbase/wallet/api_response.rb +41 -0
- data/lib/coinbase/wallet/ca-coinbase.crt +101 -0
- data/lib/coinbase/wallet/client.rb +101 -0
- data/lib/coinbase/wallet/coinbase-callback.pub +14 -0
- data/lib/coinbase/wallet/models/account.rb +193 -0
- data/lib/coinbase/wallet/models/address.rb +12 -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 +24 -156
- data/spec/account_spec.rb +199 -0
- data/spec/callback_signature_verification_spec.rb +16 -0
- data/spec/clients/client_spec.rb +34 -0
- data/spec/clients/oauth_client_spec.rb +56 -0
- data/spec/endpoints_spec.rb +352 -0
- data/spec/error_spec.rb +137 -0
- data/spec/models/address_spec.rb +26 -0
- data/spec/models/api_object_spec.rb +70 -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 +67 -112
- 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
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
|
data/lib/coinbase/transfer.rb
DELETED
@@ -1,153 +0,0 @@
|
|
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 Transfer, which moves an amount of an Asset from
|
9
|
-
# a user-controlled Wallet to another address. The fee is assumed to be paid
|
10
|
-
# in the native Asset of the Network. Currently only ETH transfers are supported. Transfers
|
11
|
-
# should be created through {link:Wallet#transfer} or {link:Address#transfer}.
|
12
|
-
class Transfer
|
13
|
-
attr_reader :network_id, :wallet_id, :from_address_id, :amount, :asset_id, :to_address_id
|
14
|
-
|
15
|
-
# A representation of a Transfer status.
|
16
|
-
module Status
|
17
|
-
# The Transfer is awaiting being broadcast to the Network. At this point, transaction
|
18
|
-
# hashes may not yet be assigned.
|
19
|
-
PENDING = :pending
|
20
|
-
|
21
|
-
# The Transfer has been broadcast to the Network. At this point, at least the transaction hash
|
22
|
-
# should be assigned.
|
23
|
-
BROADCAST = :broadcast
|
24
|
-
|
25
|
-
# The Transfer is complete, and has confirmed on the Network.
|
26
|
-
COMPLETE = :complete
|
27
|
-
|
28
|
-
# The Transfer has failed for some reason.
|
29
|
-
FAILED = :failed
|
30
|
-
end
|
31
|
-
|
32
|
-
# Returns a new Transfer object.
|
33
|
-
# @param network_id [Symbol] The ID of the Network on which the Transfer originated
|
34
|
-
# @param wallet_id [String] The ID of the Wallet from which the Transfer originated
|
35
|
-
# @param from_address_id [String] The ID of the address from which the Transfer originated
|
36
|
-
# @param amount [Integer, Float, BigDecimal] The amount of the Asset to send. Integers are interpreted as
|
37
|
-
# the smallest denomination of the Asset (e.g. Wei for Ether). Floats and BigDecimals are interpreted as the Asset
|
38
|
-
# itself (e.g. Ether).
|
39
|
-
# @param asset_id [Symbol] The ID of the Asset being transferred. Currently only ETH is supported.
|
40
|
-
# @param to_address_id [String] The address to which the Transfer is being sent
|
41
|
-
# @param client [Jimson::Client] (Optional) The JSON RPC client to use for interacting with the Network
|
42
|
-
def initialize(network_id, wallet_id, from_address_id, amount, asset_id, to_address_id,
|
43
|
-
client: Jimson::Client.new(ENV.fetch('BASE_SEPOLIA_RPC_URL', nil)))
|
44
|
-
|
45
|
-
raise ArgumentError, "Unsupported asset: #{asset_id}" if asset_id != :eth
|
46
|
-
|
47
|
-
@network_id = network_id
|
48
|
-
@wallet_id = wallet_id
|
49
|
-
@from_address_id = from_address_id
|
50
|
-
@amount = normalize_eth_amount(amount)
|
51
|
-
@asset_id = asset_id
|
52
|
-
@to_address_id = to_address_id
|
53
|
-
@client = client
|
54
|
-
end
|
55
|
-
|
56
|
-
# Returns the underlying Transfer transaction, creating it if it has not been yet.
|
57
|
-
# @return [Eth::Tx::Eip1559] The Transfer transaction
|
58
|
-
def transaction
|
59
|
-
return @transaction unless @transaction.nil?
|
60
|
-
|
61
|
-
nonce = @client.eth_getTransactionCount(@from_address_id.to_s, 'latest').to_i(16)
|
62
|
-
gas_price = @client.eth_gasPrice.to_i(16)
|
63
|
-
|
64
|
-
params = {
|
65
|
-
chain_id: BASE_SEPOLIA.chain_id, # TODO: Don't hardcode Base Sepolia.
|
66
|
-
nonce: nonce,
|
67
|
-
priority_fee: gas_price, # TODO: Optimize this.
|
68
|
-
max_gas_fee: gas_price,
|
69
|
-
gas_limit: 21_000, # TODO: Handle multiple currencies.
|
70
|
-
from: Eth::Address.new(@from_address_id),
|
71
|
-
to: Eth::Address.new(@to_address_id),
|
72
|
-
value: (@amount * Coinbase::WEI_PER_ETHER).to_i
|
73
|
-
}
|
74
|
-
|
75
|
-
@transaction = Eth::Tx::Eip1559.new(Eth::Tx.validate_eip1559_params(params))
|
76
|
-
@transaction
|
77
|
-
end
|
78
|
-
|
79
|
-
# Returns the status of the Transfer.
|
80
|
-
# @return [Symbol] The status
|
81
|
-
def status
|
82
|
-
begin
|
83
|
-
# Create the transaction, and attempt to get the hash to see if it has been signed.
|
84
|
-
transaction.hash
|
85
|
-
rescue Eth::Signature::SignatureError
|
86
|
-
# If the transaction has not been signed, it is still pending.
|
87
|
-
return Status::PENDING
|
88
|
-
end
|
89
|
-
|
90
|
-
onchain_transaction = @client.eth_getTransactionByHash(transaction_hash)
|
91
|
-
|
92
|
-
if onchain_transaction.nil?
|
93
|
-
# If the transaction has not been broadcast, it is still pending.
|
94
|
-
Status::PENDING
|
95
|
-
elsif onchain_transaction['blockHash'].nil?
|
96
|
-
# If the transaction has been broadcast but hasn't been included in a block, it is
|
97
|
-
# broadcast.
|
98
|
-
Status::BROADCAST
|
99
|
-
else
|
100
|
-
transaction_receipt = @client.eth_getTransactionReceipt(transaction_hash)
|
101
|
-
|
102
|
-
if transaction_receipt['status'].to_i(16) == 1
|
103
|
-
Status::COMPLETE
|
104
|
-
else
|
105
|
-
Status::FAILED
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# Waits until the Transfer is completed or failed by polling the Network at the given interval. Raises a
|
111
|
-
# Timeout::Error if the Transfer takes longer than the given timeout.
|
112
|
-
# @param interval_seconds [Integer] The interval at which to poll the Network, in seconds
|
113
|
-
# @param timeout_seconds [Integer] The maximum amount of time to wait for the Transfer to complete, in seconds
|
114
|
-
# @return [Transfer] The completed Transfer object
|
115
|
-
def wait!(interval_seconds = 0.2, timeout_seconds = 10)
|
116
|
-
start_time = Time.now
|
117
|
-
|
118
|
-
loop do
|
119
|
-
return self if status == Status::COMPLETE || status == Status::FAILED
|
120
|
-
|
121
|
-
raise Timeout::Error, 'Transfer timed out' if Time.now - start_time > timeout_seconds
|
122
|
-
|
123
|
-
self.sleep interval_seconds
|
124
|
-
end
|
125
|
-
|
126
|
-
self
|
127
|
-
end
|
128
|
-
|
129
|
-
# Returns the transaction hash of the Transfer, or nil if not yet available.
|
130
|
-
# @return [String] The transaction hash
|
131
|
-
def transaction_hash
|
132
|
-
"0x#{transaction.hash}"
|
133
|
-
rescue Eth::Signature::SignatureError
|
134
|
-
nil
|
135
|
-
end
|
136
|
-
|
137
|
-
private
|
138
|
-
|
139
|
-
# Normalizes the given Ether amount into a BigDecimal.
|
140
|
-
# @param amount [Integer, Float, BigDecimal] The amount to normalize
|
141
|
-
# @return [BigDecimal] The normalized amount
|
142
|
-
def normalize_eth_amount(amount)
|
143
|
-
case amount
|
144
|
-
when BigDecimal
|
145
|
-
amount
|
146
|
-
when Integer, Float
|
147
|
-
BigDecimal(amount.to_s)
|
148
|
-
else
|
149
|
-
raise ArgumentError, "Invalid amount: #{amount}"
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
data/lib/coinbase.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'coinbase/address'
|
4
|
-
require_relative 'coinbase/asset'
|
5
|
-
require_relative 'coinbase/balance_map'
|
6
|
-
require_relative 'coinbase/constants'
|
7
|
-
require_relative 'coinbase/network'
|
8
|
-
require_relative 'coinbase/transfer'
|
9
|
-
require_relative 'coinbase/wallet'
|
10
|
-
require 'dotenv'
|
11
|
-
|
12
|
-
# The Coinbase SDK.
|
13
|
-
module Coinbase
|
14
|
-
# Initializes the Coinbase SDK.
|
15
|
-
def self.init
|
16
|
-
Dotenv.load
|
17
|
-
end
|
18
|
-
end
|