diff --git a/.DS_Store b/.DS_Store
deleted file mode 100644
index 787cce81..00000000
Binary files a/.DS_Store and /dev/null differ
diff --git a/.github/workflows/e2e_test.yml b/.github/workflows/e2e_test.yml
new file mode 100644
index 00000000..6f9e49bd
--- /dev/null
+++ b/.github/workflows/e2e_test.yml
@@ -0,0 +1,27 @@
+name: Run End-To-End Tests
+
+on: [pull_request]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: 2.7
+
+ - name: Install dependencies
+ run: |
+ gem install bundler -v 2.4.22
+ bundle install --jobs 4 --retry 3
+
+ - name: Run e2e tests
+ env:
+ API_KEY_NAME: ${{ secrets.API_KEY_NAME }}
+ API_KEY_PRIVATE_KEY: ${{ secrets.API_KEY_PRIVATE_KEY }}
+ WALLET_DATA: ${{ secrets.WALLET_DATA }}
+ run: bundle exec rspec spec/e2e/production.rb
\ No newline at end of file
diff --git a/.github/workflows/tests.yml b/.github/workflows/unit_tests.yml
similarity index 88%
rename from .github/workflows/tests.yml
rename to .github/workflows/unit_tests.yml
index 03a3f40f..0dbf4435 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/unit_tests.yml
@@ -1,4 +1,4 @@
-name: Run Tests
+name: Run Unit Tests
on: [pull_request]
@@ -19,5 +19,5 @@ jobs:
gem install bundler -v 2.4.22
bundle install --jobs 4 --retry 3
- - name: Run tests
+ - name: Run unit tests
run: bundle exec rake test
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 283c9376..24212ac3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
Gemfile.lock
-coinbase_cloud_api_key.json
-.yardoc
\ No newline at end of file
+.yardoc
+lib/**/.DS_Store
+.idea
+.DS_Store
\ No newline at end of file
diff --git a/.rubocop.yml b/.rubocop.yml
index ddf66f9b..38c86f91 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -2,9 +2,16 @@ AllCops:
NewCops: disable
SuggestExtensions: false
TargetRubyVersion: 2.7
+ Exclude:
+ # Exclude autogenerated files.
+ - 'lib/coinbase/client.rb'
+ - 'lib/coinbase/client/**/*'
# Tests can be long.
Metrics/BlockLength:
Enabled: false
+# Classes can be long.
+Metrics/ClassLength:
+ Max: 1000
Metrics/MethodLength:
Max: 50
# Methods can have many parameters.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0678c644..b963c33a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,12 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
+- Faucet
+- Trade
+- Individual private key export
+- Allow disabling debug tracing
+- Error specifications
+
+## [0.0.2] - 2024-05-01
+
+### Added
+
+- Configuration via Config object
+- API Key-based authentication
+- API clients to use server-side architecture
+- User object and default_user
+- Send and receive ERC-20s
+
## [0.0.1] - 2024-04-19
Initial release of the Coinbase Ruby SDK. Purely client-side implementation.
### Added
+
- Wallet creation and export
- Address creation
- Send and receive ETH
-- Supported networks: Base Sepolia
\ No newline at end of file
+- Supported networks: Base Sepolia
diff --git a/Makefile b/Makefile
index e249a8bd..c2a8fa16 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
.PHONY: format
format:
- bundle exec rubocop -a
+ bundle exec rubocop -A
.PHONY: lint
lint:
diff --git a/README.md b/README.md
index 5e5651b1..81aadc29 100644
--- a/README.md
+++ b/README.md
@@ -8,16 +8,17 @@ one asset into another.
The SDK currently supports Customer-custodied Wallets on the Base Sepolia test network.
**NOTE: The Coinbase SDK is currently in Alpha. The SDK:**
+
- **may make backwards-incompatible changes between releases**
- **should not be used on Mainnet (i.e. with real funds)**
-
Currently, the SDK is intended for use on testnet for quick bootstrapping of crypto wallets at
hackathons, code academies, and other development settings.
-
## Documentation
-[Click here for full SDK documentation](https://coinbase.github.io/coinbase-sdk-ruby/)
+
+- [Platform API Documentation](https://docs.cdp.coinbase.com/platform-apis/docs/welcome)
+- [Ruby SDK Documentation](https://coinbase.github.io/coinbase-sdk-ruby/)
## Installation
@@ -65,61 +66,75 @@ require 'coinbase'
### Initialization
-The SDK requires a Base Sepolia RPC node, and uses the public instance (https://sepolia.base.org) by default.
-This instance is rate-limited, but you can also provision your own on the
-[Coinbase Developer Platform](https://portal.cloud.coinbase.com/products/base).
+To start, [create a CDP API Key](https://portal.cdp.coinbase.com/access/api). Then, initialize the Platform SDK by passing your API Key name and API Key's private key via the `configure` method:
+```ruby
+api_key_name = 'Copy your API Key name here.'
+api_key_private_key = 'Copy your API Key\'s private key here.'
-You can configure the SDK with your Base Sepolia RPC node by copying your node URL from the CDP portal
-and setting the following:
+Coinbase.configure do |config|
+ config.api_key_name = api_key_name
+ config.api_key_private_key = api_key_private_key
+end
+```
+
+This will allow you to authenticate with the Platform APIs and get access to the `default_user`.
```ruby
-Coinbase.base_sepolia_rpc_url = 'https://api.developer.coinbase.com/rpc/v1/base/your-node-id'
+u = Coinbase.default_user
```
-### Wallets and Addresses
-
-A Wallet is a collection of Addresses on the Base Sepolia Network, which can be used to send and receive crypto.
+### Wallets, Addresses, and Transfers
-The SDK provides customer-custodied wallets, which means that you are responsible for securely storing the data required
-to re-create wallets. The following code snippet demonstrates this:
+Now, create a Wallet from the User. Wallets are created with a single default Address.
```ruby
# Create a Wallet with one Address by default.
-w1 = Coinbase::Wallet.new
+w1 = u.create_wallet
+```
-# Export the data required to re-create the wallet.
-data = w1.export
+Next, view the default Address of your Wallet. You will need this default Address in order to fund the Wallet for your first Transfer.
-# At this point, you should implement your own "store" method to securely persist
-# the data required to re-create the wallet at a later time.
-store(data)
+```ruby
+# A Wallet has a default Address.
+a = w1.default_address
+a.to_s
+```
-# The wallet can be re-created using the exported data.
-# w2 will be equivalent to w1.
-w2 = Wallet.new(seed: data.seed, address_count: data.address_count)
+Wallets do not have funds on them to start. In order to fund the Address, you will need to send funds to the Wallet you generated above. If you don't have testnet funds, get funds from a [faucet](https://docs.base.org/docs/tools/network-faucets/).
+
+```ruby
+# Create a new Wallet to transfer funds to.
+# Then, we can transfer 0.00001 ETH out of the Wallet to another Wallet.
+w2 = u.create_wallet
+w1.transfer(0.00001, :eth, w2).wait!
```
-### Transfers
+### Re-Instantiating Wallets
-The following creates an in-memory wallet. After the wallet is funded with ETH, it transfers 0.00001 ETH to a different wallet.
+The SDK creates Wallets with developer managed keys, which means you are responsible for securely storing the keys required to re-instantiate Wallets. The below code walks you through how to export a Wallets and store it in a secure location.
```ruby
-# Wallets are self-custodial with in-memory key management on Base Sepolia.
-# This should NOT be used in mainnet with real funds.
-w1 = Coinbase::Wallet.new
+# Optional: Create a new Wallet if you do not already have one.
+# Export the data required to re-instantiate the Wallet.
+w3 = u.create_wallet
+data = w3.export
+```
-# A wallet has a default address.
-a = w1.default_address
-a.to_s
+In order to persist the data for the Wallet, you will need to implement a store method to store the data export in a secure location. If you do not store the Wallet in a secure location you will lose access to the Wallet and all of the funds on it.
-# At this point, fund the wallet out-of-band.
-# Then, we can transfer 0.00001 ETH out of the wallet to another wallet.
-w2 = Coinbase::Wallet.new
+```ruby
+# At this point, you should implement your own "store" method to securely persist
+# the data required to re-instantiate the Wallet at a later time.
+store(data)
+```
-# We wait for the transfer to complete.
-# Base Sepolia is fast, so it should take only a few seconds.
-w1.transfer(0.00001, :eth, w2).wait!
+The below code demonstrates how to re-instantiate a Wallet from the data export.
+
+```ruby
+# The Wallet can be re-instantiated using the exported data.
+# w2 will be equivalent to w1.
+w4 = u.import_wallet(data)
```
## Development
@@ -134,6 +149,7 @@ RUBY_CFLAGS=-DUSE_FFI_CLOSURE_ALLOC rbenv install 2.7.0
```
### Set-up
+
Clone the repo by running:
```bash
@@ -174,6 +190,7 @@ make lint
```
### Testing
+
To run all tests, run:
```bash
@@ -201,4 +218,4 @@ To generate documentation from the Ruby comments, run:
```bash
make docs
-```
\ No newline at end of file
+```
diff --git a/coinbase.gemspec b/coinbase.gemspec
index 05508d4e..5df26baa 100644
--- a/coinbase.gemspec
+++ b/coinbase.gemspec
@@ -2,7 +2,7 @@
Gem::Specification.new do |spec|
spec.name = 'coinbase-sdk'
- spec.version = '0.0.1'
+ spec.version = '0.0.2'
spec.authors = ['Yuga Cohler']
spec.files = Dir['lib/**/*.rb']
spec.summary = 'Coinbase Ruby SDK'
@@ -15,12 +15,15 @@ Gem::Specification.new do |spec|
spec.metadata['rubygems_mfa_required'] = 'true'
- spec.add_runtime_dependency 'bigdecimal'
spec.add_runtime_dependency 'eth'
+ spec.add_runtime_dependency 'faraday'
+ spec.add_runtime_dependency 'faraday-multipart'
spec.add_runtime_dependency 'jimson'
+ spec.add_runtime_dependency 'jwt'
+ spec.add_runtime_dependency 'marcel'
spec.add_runtime_dependency 'money-tree'
- spec.add_runtime_dependency 'securerandom'
+ spec.add_development_dependency 'dotenv'
spec.add_development_dependency 'pry'
spec.add_development_dependency 'rake'
spec.add_development_dependency 'rspec'
diff --git a/docs/Coinbase.html b/docs/Coinbase.html
index 8fb623a6..0e81add8 100644
--- a/docs/Coinbase.html
+++ b/docs/Coinbase.html
@@ -79,7 +79,7 @@
{eth:true,# Ether, the native asset of most EVM networks.
gwei:true,# A medium denomination of Ether, typically used in gas prices.
-wei:true# The smallest denomination of Ether.
+wei:true,# The smallest denomination of Ether.
+usdc:true# USD Coin, a stablecoin pegged to the US Dollar.
}.freeze
# File 'lib/coinbase.rb', line 23
+
+defself.configure
+ yield(configuration)
+
+ raiseInvalidConfiguration,'API key private key is not set'unlessconfiguration.api_key_private_key
+ raiseInvalidConfiguration,'API key name is not set'unlessconfiguration.api_key_name
+end
A representation of a blockchain Address, which is a user-controlled account on a Network. Addresses are used to send and receive Assets, and should be created using Wallet#create_address. Addresses require a Eth::Key to sign transaction data.
+
A representation of a blockchain Address, which is a user-controlled account on a Network. Addresses are used to send and receive Assets, and should be created using Wallet#create_address. Addresses require an Eth::Key to sign transaction data.
# File 'lib/coinbase/address.rb', line 78deftransfer(amount,asset_id,destination)
- # TODO: Handle multiple currencies.
-raiseArgumentError,"Unsupported asset: #{asset_id}"unlessCoinbase::SUPPORTED_ASSET_IDS[asset_id]
+ raiseArgumentError,"Unsupported asset: #{asset_id}"unlessCoinbase::SUPPORTED_ASSET_IDS[asset_id]ifdestination.is_a?(Wallet)
- raiseArgumentError,'Transfer must be on the same Network'ifdestination.network_id!=@network_id
+ raiseArgumentError,'Transfer must be on the same Network'ifdestination.network_id!=network_iddestination=destination.default_address.address_idelsifdestination.is_a?(Address)
- raiseArgumentError,'Transfer must be on the same Network'ifdestination.network_id!=@network_id
+ raiseArgumentError,'Transfer must be on the same Network'ifdestination.network_id!=network_iddestination=destination.address_idend
@@ -1024,18 +928,89 @@
+
+
\ No newline at end of file
diff --git a/docs/Coinbase/BalanceMap.html b/docs/Coinbase/BalanceMap.html
index 7f459e2d..07583dc4 100644
--- a/docs/Coinbase/BalanceMap.html
+++ b/docs/Coinbase/BalanceMap.html
@@ -104,7 +104,7 @@
Overview
-
A convenience class for printing out crypto asset balances in a human-readable format.
+
A convenience class for printing out Asset balances in a human-readable format.
# File 'lib/coinbase/client/models/address.rb', line 63
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::Address` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+attributes=attributes.each_with_object({}){|(k,v),h|
+ if(!self.class.attribute_map.key?(k.to_sym))
+ failArgumentError,"`#{k}` is not a valid attribute in `Coinbase::Client::Address`. Please check the name to make sure it's valid. List of attributes: "+self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym]=v
+ }
+
+ ifattributes.key?(:'wallet_id')
+ self.wallet_id=attributes[:'wallet_id']
+ else
+ self.wallet_id=nil
+ end
+
+ ifattributes.key?(:'network_id')
+ self.network_id=attributes[:'network_id']
+ else
+ self.network_id=nil
+ end
+
+ ifattributes.key?(:'public_key')
+ self.public_key=attributes[:'public_key']
+ else
+ self.public_key=nil
+ end
+
+ ifattributes.key?(:'address_id')
+ self.address_id=attributes[:'address_id']
+ else
+ self.address_id=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #address_id ⇒ Object
+
+
+
+
+
+
+
+
+
The onchain address derived on the server-side.
+
+
+
+
+
+
+
+
+
+
+
+
+
+28
+29
+30
+
+
+
# File 'lib/coinbase/client/models/address.rb', line 28
+
+defaddress_id
+ @address_id
+end
+
+
+
+
+
+
+
+
+
+
+ #network_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the blockchain network
+
+
+
+
+
+
+
+
+
+
+
+
+
+22
+23
+24
+
+
+
# File 'lib/coinbase/client/models/address.rb', line 22
+
+defnetwork_id
+ @network_id
+end
+
+
+
+
+
+
+
+
+
+
+ #public_key ⇒ Object
+
+
+
+
+
+
+
+
+
The public key from which the address is derived.
+
+
+
+
+
+
+
+
+
+
+
+
+
+25
+26
+27
+
+
+
# File 'lib/coinbase/client/models/address.rb', line 25
+
+defpublic_key
+ @public_key
+end
+
+
+
+
+
+
+
+
+
+
+ #wallet_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the wallet that owns the address
+
+
+
+
+
+
+
+
+
+
+
+
+
+19
+20
+21
+
+
+
# File 'lib/coinbase/client/models/address.rb', line 19
+
+defwallet_id
+ @wallet_id
+end
# File 'lib/coinbase/client/models/address.rb', line 162
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/address.rb', line 103
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@wallet_id.nil?
+ invalid_properties.push('invalid value for "wallet_id", wallet_id cannot be nil.')
+ end
+
+ if@network_id.nil?
+ invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')
+ end
+
+ if@public_key.nil?
+ invalid_properties.push('invalid value for "public_key", public_key cannot be nil.')
+ end
+
+ if@address_id.nil?
+ invalid_properties.push('invalid value for "address_id", address_id cannot be nil.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+233
+234
+235
+
+
+
# File 'lib/coinbase/client/models/address.rb', line 233
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/address_balance_list.rb', line 63
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::AddressBalanceList` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+attributes=attributes.each_with_object({}){|(k,v),h|
+ if(!self.class.attribute_map.key?(k.to_sym))
+ failArgumentError,"`#{k}` is not a valid attribute in `Coinbase::Client::AddressBalanceList`. Please check the name to make sure it's valid. List of attributes: "+self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym]=v
+ }
+
+ ifattributes.key?(:'data')
+ if(value=attributes[:'data']).is_a?(Array)
+ self.data=value
+ end
+ else
+ self.data=nil
+ end
+
+ ifattributes.key?(:'has_more')
+ self.has_more=attributes[:'has_more']
+ else
+ self.has_more=nil
+ end
+
+ ifattributes.key?(:'next_page')
+ self.next_page=attributes[:'next_page']
+ else
+ self.next_page=nil
+ end
+
+ ifattributes.key?(:'total_count')
+ self.total_count=attributes[:'total_count']
+ else
+ self.total_count=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #data ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the value of attribute data.
+
+
+
+
+
+
+
+
+
+
+
+
+
+19
+20
+21
+
+
+
# File 'lib/coinbase/client/models/address_balance_list.rb', line 19
+
+defdata
+ @data
+end
+
+
+
+
+
+
+
+
+
+
+ #has_more ⇒ Object
+
+
+
+
+
+
+
+
+
True if this list has another page of items after this one that can be fetched.
+
+
+
+
+
+
+
+
+
+
+
+
+
+22
+23
+24
+
+
+
# File 'lib/coinbase/client/models/address_balance_list.rb', line 22
+
+defhas_more
+ @has_more
+end
+
+
+
+
+
+
+
+
+
+
+ #next_page ⇒ Object
+
+
+
+
+
+
+
+
+
The page token to be used to fetch the next page.
+
+
+
+
+
+
+
+
+
+
+
+
+
+25
+26
+27
+
+
+
# File 'lib/coinbase/client/models/address_balance_list.rb', line 25
+
+defnext_page
+ @next_page
+end
+
+
+
+
+
+
+
+
+
+
+ #total_count ⇒ Object
+
+
+
+
+
+
+
+
+
The total number of balances for the wallet.
+
+
+
+
+
+
+
+
+
+
+
+
+
+28
+29
+30
+
+
+
# File 'lib/coinbase/client/models/address_balance_list.rb', line 28
+
+deftotal_count
+ @total_count
+end
# File 'lib/coinbase/client/models/address_balance_list.rb', line 164
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/address_balance_list.rb', line 105
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@data.nil?
+ invalid_properties.push('invalid value for "data", data cannot be nil.')
+ end
+
+ if@has_more.nil?
+ invalid_properties.push('invalid value for "has_more", has_more cannot be nil.')
+ end
+
+ if@next_page.nil?
+ invalid_properties.push('invalid value for "next_page", next_page cannot be nil.')
+ end
+
+ if@total_count.nil?
+ invalid_properties.push('invalid value for "total_count", total_count cannot be nil.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+235
+236
+237
+
+
+
# File 'lib/coinbase/client/models/address_balance_list.rb', line 235
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/address_list.rb', line 63
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::AddressList` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+attributes=attributes.each_with_object({}){|(k,v),h|
+ if(!self.class.attribute_map.key?(k.to_sym))
+ failArgumentError,"`#{k}` is not a valid attribute in `Coinbase::Client::AddressList`. Please check the name to make sure it's valid. List of attributes: "+self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym]=v
+ }
+
+ ifattributes.key?(:'data')
+ if(value=attributes[:'data']).is_a?(Array)
+ self.data=value
+ end
+ else
+ self.data=nil
+ end
+
+ ifattributes.key?(:'has_more')
+ self.has_more=attributes[:'has_more']
+ else
+ self.has_more=nil
+ end
+
+ ifattributes.key?(:'next_page')
+ self.next_page=attributes[:'next_page']
+ else
+ self.next_page=nil
+ end
+
+ ifattributes.key?(:'total_count')
+ self.total_count=attributes[:'total_count']
+ else
+ self.total_count=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #data ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the value of attribute data.
+
+
+
+
+
+
+
+
+
+
+
+
+
+19
+20
+21
+
+
+
# File 'lib/coinbase/client/models/address_list.rb', line 19
+
+defdata
+ @data
+end
+
+
+
+
+
+
+
+
+
+
+ #has_more ⇒ Object
+
+
+
+
+
+
+
+
+
True if this list has another page of items after this one that can be fetched.
+
+
+
+
+
+
+
+
+
+
+
+
+
+22
+23
+24
+
+
+
# File 'lib/coinbase/client/models/address_list.rb', line 22
+
+defhas_more
+ @has_more
+end
+
+
+
+
+
+
+
+
+
+
+ #next_page ⇒ Object
+
+
+
+
+
+
+
+
+
The page token to be used to fetch the next page.
+
+
+
+
+
+
+
+
+
+
+
+
+
+25
+26
+27
+
+
+
# File 'lib/coinbase/client/models/address_list.rb', line 25
+
+defnext_page
+ @next_page
+end
+
+
+
+
+
+
+
+
+
+
+ #total_count ⇒ Object
+
+
+
+
+
+
+
+
+
The total number of addresses for the wallet.
+
+
+
+
+
+
+
+
+
+
+
+
+
+28
+29
+30
+
+
+
# File 'lib/coinbase/client/models/address_list.rb', line 28
+
+deftotal_count
+ @total_count
+end
# File 'lib/coinbase/client/models/address_list.rb', line 164
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/address_list.rb', line 105
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@data.nil?
+ invalid_properties.push('invalid value for "data", data cannot be nil.')
+ end
+
+ if@has_more.nil?
+ invalid_properties.push('invalid value for "has_more", has_more cannot be nil.')
+ end
+
+ if@next_page.nil?
+ invalid_properties.push('invalid value for "next_page", next_page cannot be nil.')
+ end
+
+ if@total_count.nil?
+ invalid_properties.push('invalid value for "total_count", total_count cannot be nil.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+235
+236
+237
+
+
+
# File 'lib/coinbase/client/models/address_list.rb', line 235
+
+defto_body
+ to_hash
+end
A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
+
+
+
+
+
+ :page
+ (String)
+
+
+
+
+ —
+
A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
+
+
+
+
+
+ :page
+ (String)
+
+
+
+
+ —
+
A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
# File 'lib/coinbase/client/api_client.rb', line 334
+
+defbuild_request_url(path,opts={})
+ # Add leading and trailing slashes to path
+path="/#{path}".gsub(/\/+/,'/')
+ @config.base_url(opts[:operation])+path
+end
Return Accept header based on an array of accepts provided.
+
+
+
+
+
+
Parameters:
+
+
+
+
+ accepts
+
+
+ (Array)
+
+
+
+ —
+
+
array for Accept
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (String)
+
+
+
+ —
+
+
the Accept header (e.g. application/json)
+
+
+
+
+
+
+
+
+
+
+
+
+368
+369
+370
+371
+372
+373
+
+
+
# File 'lib/coinbase/client/api_client.rb', line 368
+
+defselect_header_accept(accepts)
+ returnnilifaccepts.nil?||accepts.empty?
+ # use JSON when present, otherwise use all of the provided
+json_accept=accepts.find{|s|json_mime?(s)}
+ json_accept||accepts.join(',')
+end
Return Content-Type header based on an array of content types provided.
+
+
+
+
+
+
Parameters:
+
+
+
+
+ content_types
+
+
+ (Array)
+
+
+
+ —
+
+
array for Content-Type
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (String)
+
+
+
+ —
+
+
the Content-Type header (e.g. application/json)
+
+
+
+
+
+
+
+
+
+
+
+
+378
+379
+380
+381
+382
+383
+384
+
+
+
# File 'lib/coinbase/client/api_client.rb', line 378
+
+defselect_header_content_type(content_types)
+ # return nil by default
+returnifcontent_types.nil?||content_types.empty?
+ # use JSON when present, otherwise use the first one
+json_content_type=content_types.find{|s|json_mime?(s)}
+ json_content_type||content_types.first
+end
# File 'lib/coinbase/client/api_client.rb', line 345
+
+defupdate_params_for_auth!(header_params,query_params,auth_names)
+ Array(auth_names).eachdo|auth_name|
+ auth_setting=@config.auth_settings[auth_name]
+ nextunlessauth_setting
+ caseauth_setting[:in]
+ when'header'thenheader_params[auth_setting[:key]]=auth_setting[:value]
+ when'query'thenquery_params[auth_setting[:key]]=auth_setting[:value]
+ elsefailArgumentError,'Authentication token must be in `query` or `header`'
+ end
+ end
+end
# File 'lib/coinbase/client/models/asset.rb', line 64
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::Asset` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+attributes=attributes.each_with_object({}){|(k,v),h|
+ if(!self.class.attribute_map.key?(k.to_sym))
+ failArgumentError,"`#{k}` is not a valid attribute in `Coinbase::Client::Asset`. Please check the name to make sure it's valid. List of attributes: "+self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym]=v
+ }
+
+ ifattributes.key?(:'network_id')
+ self.network_id=attributes[:'network_id']
+ else
+ self.network_id=nil
+ end
+
+ ifattributes.key?(:'asset_id')
+ self.asset_id=attributes[:'asset_id']
+ else
+ self.asset_id=nil
+ end
+
+ ifattributes.key?(:'decimals')
+ self.decimals=attributes[:'decimals']
+ end
+
+ ifattributes.key?(:'contract_address')
+ self.contract_address=attributes[:'contract_address']
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #asset_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID for the asset on the network
+
+
+
+
+
+
+
+
+
+
+
+
+
+23
+24
+25
+
+
+
# File 'lib/coinbase/client/models/asset.rb', line 23
+
+defasset_id
+ @asset_id
+end
+
+
+
+
+
+
+
+
+
+
+ #contract_address ⇒ Object
+
+
+
+
+
+
+
+
+
The optional contract address for the asset. This will be specified for smart contract-based assets, for example ERC20s.
+
+
+
+
+
+
+
+
+
+
+
+
+
+29
+30
+31
+
+
+
# File 'lib/coinbase/client/models/asset.rb', line 29
+
+defcontract_address
+ @contract_address
+end
+
+
+
+
+
+
+
+
+
+
+ #decimals ⇒ Object
+
+
+
+
+
+
+
+
+
The number of decimals the asset supports. This is used to convert from atomic units to base units.
+
+
+
+
+
+
+
+
+
+
+
+
+
+26
+27
+28
+
+
+
# File 'lib/coinbase/client/models/asset.rb', line 26
+
+defdecimals
+ @decimals
+end
+
+
+
+
+
+
+
+
+
+
+ #network_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the blockchain network
+
+
+
+
+
+
+
+
+
+
+
+
+
+20
+21
+22
+
+
+
# File 'lib/coinbase/client/models/asset.rb', line 20
+
+defnetwork_id
+ @network_id
+end
# File 'lib/coinbase/client/models/asset.rb', line 149
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/asset.rb', line 100
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@network_id.nil?
+ invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')
+ end
+
+ if@asset_id.nil?
+ invalid_properties.push('invalid value for "asset_id", asset_id cannot be nil.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+220
+221
+222
+
+
+
# File 'lib/coinbase/client/models/asset.rb', line 220
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/balance.rb', line 53
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::Balance` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+attributes=attributes.each_with_object({}){|(k,v),h|
+ if(!self.class.attribute_map.key?(k.to_sym))
+ failArgumentError,"`#{k}` is not a valid attribute in `Coinbase::Client::Balance`. Please check the name to make sure it's valid. List of attributes: "+self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym]=v
+ }
+
+ ifattributes.key?(:'amount')
+ self.amount=attributes[:'amount']
+ else
+ self.amount=nil
+ end
+
+ ifattributes.key?(:'asset')
+ self.asset=attributes[:'asset']
+ else
+ self.asset=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #amount ⇒ Object
+
+
+
+
+
+
+
+
+
The amount in the atomic units of the asset
+
+
+
+
+
+
+
+
+
+
+
+
+
+20
+21
+22
+
+
+
# File 'lib/coinbase/client/models/balance.rb', line 20
+
+defamount
+ @amount
+end
+
+
+
+
+
+
+
+
+
+
+ #asset ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the value of attribute asset.
+
+
+
+
+
+
+
+
+
+
+
+
+
+22
+23
+24
+
+
+
# File 'lib/coinbase/client/models/balance.rb', line 22
+
+defasset
+ @asset
+end
# File 'lib/coinbase/client/models/balance.rb', line 128
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/balance.rb', line 81
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@amount.nil?
+ invalid_properties.push('invalid value for "amount", amount cannot be nil.')
+ end
+
+ if@asset.nil?
+ invalid_properties.push('invalid value for "asset", asset cannot be nil.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+199
+200
+201
+
+
+
# File 'lib/coinbase/client/models/balance.rb', line 199
+
+defto_body
+ to_hash
+end
Set this to false to skip client side validation in the operation. Default to true.
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (true, false)
+
+
+
+
+
+
+
+
+
+
+
+
+
+102
+103
+104
+
+
+
# File 'lib/coinbase/client/configuration.rb', line 102
+
+defclient_side_validation
+ @client_side_validation
+end
+
+
+
+
+
+
+
+
+
+
+ #debugging ⇒ true, false
+
+
+
+
+
+
+
+
+
Set this to enable/disable debugging. When enabled (set to true), HTTP request/response details will be logged with `logger.debug` (see the `logger` attribute). Default to false.
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (true, false)
+
+
+
+
+
+
+
+
+
+
+
+
+
+80
+81
+82
+
+
+
# File 'lib/coinbase/client/configuration.rb', line 80
+
+defdebugging
+ @debugging
+end
+
+
+
+
+
+
+
+
+
+
+ #force_ending_format ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the value of attribute force_ending_format.
+
+
+
+
+
+
+
+
+
+
+
+
+
+148
+149
+150
+
+
+
# File 'lib/coinbase/client/configuration.rb', line 148
+
+defforce_ending_format
+ @force_ending_format
+end
+
+
+
+
+
+
+
+
+
+
+ #host ⇒ Object
+
+
+
+
+
+
+
+
+
Defines url host
+
+
+
+
+
+
+
+
+
+
+
+
+
+19
+20
+21
+
+
+
# File 'lib/coinbase/client/configuration.rb', line 19
+
+defhost
+ @host
+end
+
+
+
+
+
+
+
+
+
+
+ #inject_format ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the value of attribute inject_format.
+
+
+
+
+
+
+
+
+
+
+
+
+
+146
+147
+148
+
+
+
# File 'lib/coinbase/client/configuration.rb', line 146
+
+definject_format
+ @inject_format
+end
+
+
+
+
+
+
+
+
+
+
+ #logger ⇒ #debug
+
+
+
+
+
+
+
+
+
Defines the logger used for debugging. Default to `Rails.logger` (when in Rails) or logging to STDOUT.
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (#debug)
+
+
+
+
+
+
+
+
+
+
+
+
+
+86
+87
+88
+
+
+
# File 'lib/coinbase/client/configuration.rb', line 86
+
+deflogger
+ @logger
+end
+
+
+
+
+
+
+
+
+
+
+ #params_encoder ⇒ Object
+
+
+
+
+
+
+
+
+
Set this to customize parameters encoder of array parameter. Default to nil. Faraday uses NestedParamsEncoder when nil.
params_encoder option of Faraday. Related source code:
+
+
+
+
+
+
+
+
+
+143
+144
+145
+
+
+
# File 'lib/coinbase/client/configuration.rb', line 143
+
+defparams_encoder
+ @params_encoder
+end
+
+
+
+
+
+
+
+
+
+
+ #password ⇒ String
+
+
+
+
+
+
+
+
+
Defines the password used with HTTP basic authentication.
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (String)
+
+
+
+
+
+
+
+
+
+
+
+
+
+60
+61
+62
+
+
+
# File 'lib/coinbase/client/configuration.rb', line 60
+
+defpassword
+ @password
+end
+
+
+
+
+
+
+
+
+
+
+ #proxy ⇒ Object
+
+
+
+
+
+
+
+
+
Proxy setting HTTP Proxy settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+136
+137
+138
+
+
+
# File 'lib/coinbase/client/configuration.rb', line 136
+
+defproxy
+ @proxy
+end
+
+
+
+
+
+
+
+
+
+
+ #return_binary_data ⇒ Object
+
+
+
+
+
+
+
+
+
Set this to return data as binary instead of downloading a temp file. When enabled (set to true) HTTP responses with return type `File` will be returned as a stream of binary data. Default to false.
+
+
+
+
+
+
+
+
+
+
+
+
+
+73
+74
+75
+
+
+
# File 'lib/coinbase/client/configuration.rb', line 73
+
+defreturn_binary_data
+ @return_binary_data
+end
+
+
+
+
+
+
+
+
+
+
+ #scheme ⇒ Object
+
+
+
+
+
+
+
+
+
Defines url scheme
+
+
+
+
+
+
+
+
+
+
+
+
+
+16
+17
+18
+
+
+
# File 'lib/coinbase/client/configuration.rb', line 16
+
+defscheme
+ @scheme
+end
+
+
+
+
+
+
+
+
+
+
+ #server_index ⇒ Object
+
+
+
+
+
+
+
+
+
Define server configuration index
+
+
+
+
+
+
+
+
+
+
+
+
+
+25
+26
+27
+
+
+
# File 'lib/coinbase/client/configuration.rb', line 25
+
+defserver_index
+ @server_index
+end
+
+
+
+
+
+
+
+
+
+
+ #server_operation_index ⇒ Object
+
+
+
+
+
+
+
+
+
Define server operation configuration index
+
+
+
+
+
+
+
+
+
+
+
+
+
+28
+29
+30
+
+
+
# File 'lib/coinbase/client/configuration.rb', line 28
+
+defserver_operation_index
+ @server_operation_index
+end
# File 'lib/coinbase/client/configuration.rb', line 263
+
+defserver_url(index,variables={},servers=nil)
+ servers=server_settingsifservers==nil
+
+ # check array index out of bound
+if(index.nil?||index<0||index>=servers.size)
+ failArgumentError,"Invalid index #{index} when selecting the server. Must not be nil and must be less than #{servers.size}"
+ end
+
+ server=servers[index]
+ url=server[:url]
+
+ returnurlunlessserver.key?:variables
+
+ # go through variable and assign a value
+server[:variables].eachdo|name,variable|
+ ifvariables.key?(name)
+ if(!server[:variables][name].key?(:enum_values)||server[:variables][name][:enum_values].include?(variables[name]))
+ url.gsub!"{"+name.to_s+"}",variables[name]
+ else
+ failArgumentError,"The variable `#{name}` in the server URL has invalid value #{variables[name]}. Must be #{server[:variables][name][:enum_values]}."
+ end
+ else
+ # use default value
+url.gsub!"{"+name.to_s+"}",server[:variables][name][:default_value]
+ end
+ end
+
+ url
+end
# File 'lib/coinbase/client/models/create_address_request.rb', line 53
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::CreateAddressRequest` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+attributes=attributes.each_with_object({}){|(k,v),h|
+ if(!self.class.attribute_map.key?(k.to_sym))
+ failArgumentError,"`#{k}` is not a valid attribute in `Coinbase::Client::CreateAddressRequest`. Please check the name to make sure it's valid. List of attributes: "+self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym]=v
+ }
+
+ ifattributes.key?(:'public_key')
+ self.public_key=attributes[:'public_key']
+ else
+ self.public_key=nil
+ end
+
+ ifattributes.key?(:'attestation')
+ self.attestation=attributes[:'attestation']
+ else
+ self.attestation=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #attestation ⇒ Object
+
+
+
+
+
+
+
+
+
An attestation signed by the private key that is associated with the wallet. The attestation will be a hex-encoded signature of a json payload with fields `wallet_id` and `public_key`, signed by the private key associated with the public_key set in the request.
+
+
+
+
+
+
+
+
+
+
+
+
+
+22
+23
+24
+
+
+
# File 'lib/coinbase/client/models/create_address_request.rb', line 22
+
+defattestation
+ @attestation
+end
+
+
+
+
+
+
+
+
+
+
+ #public_key ⇒ Object
+
+
+
+
+
+
+
+
+
The public key from which the address will be derived.
+
+
+
+
+
+
+
+
+
+
+
+
+
+19
+20
+21
+
+
+
# File 'lib/coinbase/client/models/create_address_request.rb', line 19
+
+defpublic_key
+ @public_key
+end
# File 'lib/coinbase/client/models/create_address_request.rb', line 128
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/create_address_request.rb', line 81
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@public_key.nil?
+ invalid_properties.push('invalid value for "public_key", public_key cannot be nil.')
+ end
+
+ if@attestation.nil?
+ invalid_properties.push('invalid value for "attestation", attestation cannot be nil.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+199
+200
+201
+
+
+
# File 'lib/coinbase/client/models/create_address_request.rb', line 199
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/create_transfer_request.rb', line 63
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::CreateTransferRequest` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+attributes=attributes.each_with_object({}){|(k,v),h|
+ if(!self.class.attribute_map.key?(k.to_sym))
+ failArgumentError,"`#{k}` is not a valid attribute in `Coinbase::Client::CreateTransferRequest`. Please check the name to make sure it's valid. List of attributes: "+self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym]=v
+ }
+
+ ifattributes.key?(:'amount')
+ self.amount=attributes[:'amount']
+ else
+ self.amount=nil
+ end
+
+ ifattributes.key?(:'network_id')
+ self.network_id=attributes[:'network_id']
+ else
+ self.network_id=nil
+ end
+
+ ifattributes.key?(:'asset_id')
+ self.asset_id=attributes[:'asset_id']
+ else
+ self.asset_id=nil
+ end
+
+ ifattributes.key?(:'destination')
+ self.destination=attributes[:'destination']
+ else
+ self.destination=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #amount ⇒ Object
+
+
+
+
+
+
+
+
+
The amount to transfer
+
+
+
+
+
+
+
+
+
+
+
+
+
+19
+20
+21
+
+
+
# File 'lib/coinbase/client/models/create_transfer_request.rb', line 19
+
+defamount
+ @amount
+end
+
+
+
+
+
+
+
+
+
+
+ #asset_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the asset to transfer
+
+
+
+
+
+
+
+
+
+
+
+
+
+25
+26
+27
+
+
+
# File 'lib/coinbase/client/models/create_transfer_request.rb', line 25
+
+defasset_id
+ @asset_id
+end
+
+
+
+
+
+
+
+
+
+
+ #destination ⇒ Object
+
+
+
+
+
+
+
+
+
The destination address
+
+
+
+
+
+
+
+
+
+
+
+
+
+28
+29
+30
+
+
+
# File 'lib/coinbase/client/models/create_transfer_request.rb', line 28
+
+defdestination
+ @destination
+end
+
+
+
+
+
+
+
+
+
+
+ #network_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the blockchain network
+
+
+
+
+
+
+
+
+
+
+
+
+
+22
+23
+24
+
+
+
# File 'lib/coinbase/client/models/create_transfer_request.rb', line 22
+
+defnetwork_id
+ @network_id
+end
# File 'lib/coinbase/client/models/create_transfer_request.rb', line 162
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/create_transfer_request.rb', line 103
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@amount.nil?
+ invalid_properties.push('invalid value for "amount", amount cannot be nil.')
+ end
+
+ if@network_id.nil?
+ invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')
+ end
+
+ if@asset_id.nil?
+ invalid_properties.push('invalid value for "asset_id", asset_id cannot be nil.')
+ end
+
+ if@destination.nil?
+ invalid_properties.push('invalid value for "destination", destination cannot be nil.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+233
+234
+235
+
+
+
# File 'lib/coinbase/client/models/create_transfer_request.rb', line 233
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/create_wallet_request.rb', line 47
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::CreateWalletRequest` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+attributes=attributes.each_with_object({}){|(k,v),h|
+ if(!self.class.attribute_map.key?(k.to_sym))
+ failArgumentError,"`#{k}` is not a valid attribute in `Coinbase::Client::CreateWalletRequest`. Please check the name to make sure it's valid. List of attributes: "+self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym]=v
+ }
+
+ ifattributes.key?(:'wallet')
+ self.wallet=attributes[:'wallet']
+ else
+ self.wallet=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #wallet ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the value of attribute wallet.
+
+
+
+
+
+
+
+
+
+
+
+
+
+18
+19
+20
+
+
+
# File 'lib/coinbase/client/models/create_wallet_request.rb', line 18
+
+defwallet
+ @wallet
+end
# File 'lib/coinbase/client/models/create_wallet_request.rb', line 110
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/create_wallet_request.rb', line 205
+
+def_to_hash(value)
+ ifvalue.is_a?(Array)
+ value.compact.map{|v|_to_hash(v)}
+ elsifvalue.is_a?(Hash)
+ {}.tapdo|hash|
+ value.each{|k,v|hash[k]=_to_hash(v)}
+ end
+ elsifvalue.respond_to?:to_hash
+ value.to_hash
+ else
+ value
+ end
+end
+
+
+
+
+
+
+
+
+ #eql?(o) ⇒ Boolean
+
+
+
+
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+ Object
+
+
+ (Object)
+
+
+
+ —
+
+
to be compared
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Boolean)
+
+
+
+
+
+
+
+
See Also:
+
+
+
`==` method
+
+
+
+
+
+
+
+
+
+97
+98
+99
+
+
+
# File 'lib/coinbase/client/models/create_wallet_request.rb', line 97
+
+defeql?(o)
+ self==o
+end
+
+
+
+
+
+
+
+
+ #hash ⇒ Integer
+
+
+
+
+
+
+
+
+
Calculates hash code according to all attributes.
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Integer)
+
+
+
+ —
+
+
Hash code
+
+
+
+
+
+
+
+
+
+
+
+
+103
+104
+105
+
+
+
# File 'lib/coinbase/client/models/create_wallet_request.rb', line 103
+
+defhash
+ [wallet].hash
+end
+
+
+
+
+
+
+
+
+ #list_invalid_properties ⇒ Object
+
+
+
+
+
+
+
+
+
Show invalid properties with the reasons. Usually used together with valid?
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+
+
+
+
+
+
+
Array for valid properties with the reasons
+
+
+
+
+
+
+
+
+
+
+
+
+69
+70
+71
+72
+73
+74
+75
+76
+77
+
+
+
# File 'lib/coinbase/client/models/create_wallet_request.rb', line 69
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@wallet.nil?
+ invalid_properties.push('invalid value for "wallet", wallet cannot be nil.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+181
+182
+183
+
+
+
# File 'lib/coinbase/client/models/create_wallet_request.rb', line 181
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/error.rb', line 54
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::Error` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+attributes=attributes.each_with_object({}){|(k,v),h|
+ if(!self.class.attribute_map.key?(k.to_sym))
+ failArgumentError,"`#{k}` is not a valid attribute in `Coinbase::Client::Error`. Please check the name to make sure it's valid. List of attributes: "+self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym]=v
+ }
+
+ ifattributes.key?(:'code')
+ self.code=attributes[:'code']
+ else
+ self.code=nil
+ end
+
+ ifattributes.key?(:'message')
+ self.message=attributes[:'message']
+ else
+ self.message=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #code ⇒ Object
+
+
+
+
+
+
+
+
+
A short string representing the reported error. Can be use to handle errors programmatically.
+
+
+
+
+
+
+
+
+
+
+
+
+
+20
+21
+22
+
+
+
# File 'lib/coinbase/client/models/error.rb', line 20
+
+defcode
+ @code
+end
+
+
+
+
+
+
+
+
+
+
+ #message ⇒ Object
+
+
+
+
+
+
+
+
+
A human-readable message providing more details about the error.
+
+
+
+
+
+
+
+
+
+
+
+
+
+23
+24
+25
+
+
+
# File 'lib/coinbase/client/models/error.rb', line 23
+
+defmessage
+ @message
+end
# File 'lib/coinbase/client/models/error.rb', line 167
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/error.rb', line 82
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@code.nil?
+ invalid_properties.push('invalid value for "code", code cannot be nil.')
+ end
+
+ if@code.to_s.length>5000
+ invalid_properties.push('invalid value for "code", the character length must be smaller than or equal to 5000.')
+ end
+
+ if@message.nil?
+ invalid_properties.push('invalid value for "message", message cannot be nil.')
+ end
+
+ if@message.to_s.length>5000
+ invalid_properties.push('invalid value for "message", the character length must be smaller than or equal to 5000.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+238
+239
+240
+
+
+
# File 'lib/coinbase/client/models/error.rb', line 238
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/transfer.rb', line 282
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/transfer.rb', line 181
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@network_id.nil?
+ invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')
+ end
+
+ if@wallet_id.nil?
+ invalid_properties.push('invalid value for "wallet_id", wallet_id cannot be nil.')
+ end
+
+ if@address_id.nil?
+ invalid_properties.push('invalid value for "address_id", address_id cannot be nil.')
+ end
+
+ if@destination.nil?
+ invalid_properties.push('invalid value for "destination", destination cannot be nil.')
+ end
+
+ if@amount.nil?
+ invalid_properties.push('invalid value for "amount", amount cannot be nil.')
+ end
+
+ if@asset_id.nil?
+ invalid_properties.push('invalid value for "asset_id", asset_id cannot be nil.')
+ end
+
+ if@transfer_id.nil?
+ invalid_properties.push('invalid value for "transfer_id", transfer_id cannot be nil.')
+ end
+
+ if@unsigned_payload.nil?
+ invalid_properties.push('invalid value for "unsigned_payload", unsigned_payload cannot be nil.')
+ end
+
+ if@status.nil?
+ invalid_properties.push('invalid value for "status", status cannot be nil.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+353
+354
+355
+
+
+
# File 'lib/coinbase/client/models/transfer.rb', line 353
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/transfer_list.rb', line 63
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::TransferList` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+attributes=attributes.each_with_object({}){|(k,v),h|
+ if(!self.class.attribute_map.key?(k.to_sym))
+ failArgumentError,"`#{k}` is not a valid attribute in `Coinbase::Client::TransferList`. Please check the name to make sure it's valid. List of attributes: "+self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym]=v
+ }
+
+ ifattributes.key?(:'data')
+ if(value=attributes[:'data']).is_a?(Array)
+ self.data=value
+ end
+ else
+ self.data=nil
+ end
+
+ ifattributes.key?(:'has_more')
+ self.has_more=attributes[:'has_more']
+ else
+ self.has_more=nil
+ end
+
+ ifattributes.key?(:'next_page')
+ self.next_page=attributes[:'next_page']
+ else
+ self.next_page=nil
+ end
+
+ ifattributes.key?(:'total_count')
+ self.total_count=attributes[:'total_count']
+ else
+ self.total_count=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #data ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the value of attribute data.
+
+
+
+
+
+
+
+
+
+
+
+
+
+19
+20
+21
+
+
+
# File 'lib/coinbase/client/models/transfer_list.rb', line 19
+
+defdata
+ @data
+end
+
+
+
+
+
+
+
+
+
+
+ #has_more ⇒ Object
+
+
+
+
+
+
+
+
+
True if this list has another page of items after this one that can be fetched.
+
+
+
+
+
+
+
+
+
+
+
+
+
+22
+23
+24
+
+
+
# File 'lib/coinbase/client/models/transfer_list.rb', line 22
+
+defhas_more
+ @has_more
+end
+
+
+
+
+
+
+
+
+
+
+ #next_page ⇒ Object
+
+
+
+
+
+
+
+
+
The page token to be used to fetch the next page.
+
+
+
+
+
+
+
+
+
+
+
+
+
+25
+26
+27
+
+
+
# File 'lib/coinbase/client/models/transfer_list.rb', line 25
+
+defnext_page
+ @next_page
+end
+
+
+
+
+
+
+
+
+
+
+ #total_count ⇒ Object
+
+
+
+
+
+
+
+
+
The total number of transfers for the address in the wallet.
+
+
+
+
+
+
+
+
+
+
+
+
+
+28
+29
+30
+
+
+
# File 'lib/coinbase/client/models/transfer_list.rb', line 28
+
+deftotal_count
+ @total_count
+end
# File 'lib/coinbase/client/models/transfer_list.rb', line 164
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/transfer_list.rb', line 105
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@data.nil?
+ invalid_properties.push('invalid value for "data", data cannot be nil.')
+ end
+
+ if@has_more.nil?
+ invalid_properties.push('invalid value for "has_more", has_more cannot be nil.')
+ end
+
+ if@next_page.nil?
+ invalid_properties.push('invalid value for "next_page", next_page cannot be nil.')
+ end
+
+ if@total_count.nil?
+ invalid_properties.push('invalid value for "total_count", total_count cannot be nil.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+235
+236
+237
+
+
+
# File 'lib/coinbase/client/models/transfer_list.rb', line 235
+
+defto_body
+ to_hash
+end
A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
+
+
+
+
+
+ :page
+ (String)
+
+
+
+
+ —
+
A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
+
+
+
+
+
+ :page
+ (String)
+
+
+
+
+ —
+
A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
# File 'lib/coinbase/client/models/user.rb', line 52
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::User` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+attributes=attributes.each_with_object({}){|(k,v),h|
+ if(!self.class.attribute_map.key?(k.to_sym))
+ failArgumentError,"`#{k}` is not a valid attribute in `Coinbase::Client::User`. Please check the name to make sure it's valid. List of attributes: "+self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym]=v
+ }
+
+ ifattributes.key?(:'id')
+ self.id=attributes[:'id']
+ else
+ self.id=nil
+ end
+
+ ifattributes.key?(:'display_name')
+ self.display_name=attributes[:'display_name']
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #display_name ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the value of attribute display_name.
+
+
+
+
+
+
+
+
+
+
+
+
+
+21
+22
+23
+
+
+
# File 'lib/coinbase/client/models/user.rb', line 21
+
+defdisplay_name
+ @display_name
+end
+
+
+
+
+
+
+
+
+
+
+ #id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the user
+
+
+
+
+
+
+
+
+
+
+
+
+
+19
+20
+21
+
+
+
# File 'lib/coinbase/client/models/user.rb', line 19
+
+defid
+ @id
+end
# File 'lib/coinbase/client/models/user.rb', line 120
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/user.rb', line 215
+
+def_to_hash(value)
+ ifvalue.is_a?(Array)
+ value.compact.map{|v|_to_hash(v)}
+ elsifvalue.is_a?(Hash)
+ {}.tapdo|hash|
+ value.each{|k,v|hash[k]=_to_hash(v)}
+ end
+ elsifvalue.respond_to?:to_hash
+ value.to_hash
+ else
+ value
+ end
+end
+
+
+
+
+
+
+
+
+ #eql?(o) ⇒ Boolean
+
+
+
+
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+ Object
+
+
+ (Object)
+
+
+
+ —
+
+
to be compared
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Boolean)
+
+
+
+
+
+
+
+
See Also:
+
+
+
`==` method
+
+
+
+
+
+
+
+
+
+107
+108
+109
+
+
+
# File 'lib/coinbase/client/models/user.rb', line 107
+
+defeql?(o)
+ self==o
+end
+
+
+
+
+
+
+
+
+ #hash ⇒ Integer
+
+
+
+
+
+
+
+
+
Calculates hash code according to all attributes.
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Integer)
+
+
+
+ —
+
+
Hash code
+
+
+
+
+
+
+
+
+
+
+
+
+113
+114
+115
+
+
+
# File 'lib/coinbase/client/models/user.rb', line 113
+
+defhash
+ [id,display_name].hash
+end
+
+
+
+
+
+
+
+
+ #list_invalid_properties ⇒ Object
+
+
+
+
+
+
+
+
+
Show invalid properties with the reasons. Usually used together with valid?
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+
+
+
+
+
+
+
Array for valid properties with the reasons
+
+
+
+
+
+
+
+
+
+
+
+
+78
+79
+80
+81
+82
+83
+84
+85
+86
+
+
+
# File 'lib/coinbase/client/models/user.rb', line 78
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@id.nil?
+ invalid_properties.push('invalid value for "id", id cannot be nil.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+191
+192
+193
+
+
+
# File 'lib/coinbase/client/models/user.rb', line 191
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/wallet.rb', line 57
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::Wallet` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+attributes=attributes.each_with_object({}){|(k,v),h|
+ if(!self.class.attribute_map.key?(k.to_sym))
+ failArgumentError,"`#{k}` is not a valid attribute in `Coinbase::Client::Wallet`. Please check the name to make sure it's valid. List of attributes: "+self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym]=v
+ }
+
+ ifattributes.key?(:'id')
+ self.id=attributes[:'id']
+ end
+
+ ifattributes.key?(:'network_id')
+ self.network_id=attributes[:'network_id']
+ else
+ self.network_id=nil
+ end
+
+ ifattributes.key?(:'default_address')
+ self.default_address=attributes[:'default_address']
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #default_address ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the value of attribute default_address.
+
+
+
+
+
+
+
+
+
+
+
+
+
+24
+25
+26
+
+
+
# File 'lib/coinbase/client/models/wallet.rb', line 24
+
+defdefault_address
+ @default_address
+end
+
+
+
+
+
+
+
+
+
+
+ #id ⇒ Object
+
+
+
+
+
+
+
+
+
The server-assigned ID for the wallet.
+
+
+
+
+
+
+
+
+
+
+
+
+
+19
+20
+21
+
+
+
# File 'lib/coinbase/client/models/wallet.rb', line 19
+
+defid
+ @id
+end
+
+
+
+
+
+
+
+
+
+
+ #network_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the blockchain network
+
+
+
+
+
+
+
+
+
+
+
+
+
+22
+23
+24
+
+
+
# File 'lib/coinbase/client/models/wallet.rb', line 22
+
+defnetwork_id
+ @network_id
+end
# File 'lib/coinbase/client/models/wallet.rb', line 130
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/wallet.rb', line 225
+
+def_to_hash(value)
+ ifvalue.is_a?(Array)
+ value.compact.map{|v|_to_hash(v)}
+ elsifvalue.is_a?(Hash)
+ {}.tapdo|hash|
+ value.each{|k,v|hash[k]=_to_hash(v)}
+ end
+ elsifvalue.respond_to?:to_hash
+ value.to_hash
+ else
+ value
+ end
+end
+
+
+
+
+
+
+
+
+ #eql?(o) ⇒ Boolean
+
+
+
+
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+ Object
+
+
+ (Object)
+
+
+
+ —
+
+
to be compared
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Boolean)
+
+
+
+
+
+
+
+
See Also:
+
+
+
`==` method
+
+
+
+
+
+
+
+
+
+117
+118
+119
+
+
+
# File 'lib/coinbase/client/models/wallet.rb', line 117
+
+defeql?(o)
+ self==o
+end
+
+
+
+
+
+
+
+
+ #hash ⇒ Integer
+
+
+
+
+
+
+
+
+
Calculates hash code according to all attributes.
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Integer)
+
+
+
+ —
+
+
Hash code
+
+
+
+
+
+
+
+
+
+
+
+
+123
+124
+125
+
+
+
# File 'lib/coinbase/client/models/wallet.rb', line 123
+
+defhash
+ [id,network_id,default_address].hash
+end
+
+
+
+
+
+
+
+
+ #list_invalid_properties ⇒ Object
+
+
+
+
+
+
+
+
+
Show invalid properties with the reasons. Usually used together with valid?
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+
+
+
+
+
+
+
Array for valid properties with the reasons
+
+
+
+
+
+
+
+
+
+
+
+
+87
+88
+89
+90
+91
+92
+93
+94
+95
+
+
+
# File 'lib/coinbase/client/models/wallet.rb', line 87
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@network_id.nil?
+ invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+201
+202
+203
+
+
+
# File 'lib/coinbase/client/models/wallet.rb', line 201
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/wallet_list.rb', line 63
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::WalletList` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+attributes=attributes.each_with_object({}){|(k,v),h|
+ if(!self.class.attribute_map.key?(k.to_sym))
+ failArgumentError,"`#{k}` is not a valid attribute in `Coinbase::Client::WalletList`. Please check the name to make sure it's valid. List of attributes: "+self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym]=v
+ }
+
+ ifattributes.key?(:'data')
+ if(value=attributes[:'data']).is_a?(Array)
+ self.data=value
+ end
+ else
+ self.data=nil
+ end
+
+ ifattributes.key?(:'has_more')
+ self.has_more=attributes[:'has_more']
+ else
+ self.has_more=nil
+ end
+
+ ifattributes.key?(:'next_page')
+ self.next_page=attributes[:'next_page']
+ else
+ self.next_page=nil
+ end
+
+ ifattributes.key?(:'total_count')
+ self.total_count=attributes[:'total_count']
+ else
+ self.total_count=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #data ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the value of attribute data.
+
+
+
+
+
+
+
+
+
+
+
+
+
+19
+20
+21
+
+
+
# File 'lib/coinbase/client/models/wallet_list.rb', line 19
+
+defdata
+ @data
+end
+
+
+
+
+
+
+
+
+
+
+ #has_more ⇒ Object
+
+
+
+
+
+
+
+
+
True if this list has another page of items after this one that can be fetched.
+
+
+
+
+
+
+
+
+
+
+
+
+
+22
+23
+24
+
+
+
# File 'lib/coinbase/client/models/wallet_list.rb', line 22
+
+defhas_more
+ @has_more
+end
+
+
+
+
+
+
+
+
+
+
+ #next_page ⇒ Object
+
+
+
+
+
+
+
+
+
The page token to be used to fetch the next page.
+
+
+
+
+
+
+
+
+
+
+
+
+
+25
+26
+27
+
+
+
# File 'lib/coinbase/client/models/wallet_list.rb', line 25
+
+defnext_page
+ @next_page
+end
+
+
+
+
+
+
+
+
+
+
+ #total_count ⇒ Object
+
+
+
+
+
+
+
+
+
The total number of wallets
+
+
+
+
+
+
+
+
+
+
+
+
+
+28
+29
+30
+
+
+
# File 'lib/coinbase/client/models/wallet_list.rb', line 28
+
+deftotal_count
+ @total_count
+end
# File 'lib/coinbase/client/models/wallet_list.rb', line 164
+
+defself.build_from_hash(attributes)
+ returnnilunlessattributes.is_a?(Hash)
+ attributes=attributes.transform_keys(&:to_sym)
+ transformed_hash={}
+ openapi_types.each_pairdo|key,type|
+ ifattributes.key?(attribute_map[key])&&attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=nil
+ elsiftype=~/\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+# is documented as an array but the input is not
+ifattributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"]=attributes[attribute_map[key]].map{|v|_deserialize($1,v)}
+ end
+ elsif!attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"]=_deserialize(type,attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+end
# File 'lib/coinbase/client/models/wallet_list.rb', line 105
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@data.nil?
+ invalid_properties.push('invalid value for "data", data cannot be nil.')
+ end
+
+ if@has_more.nil?
+ invalid_properties.push('invalid value for "has_more", has_more cannot be nil.')
+ end
+
+ if@next_page.nil?
+ invalid_properties.push('invalid value for "next_page", next_page cannot be nil.')
+ end
+
+ if@total_count.nil?
+ invalid_properties.push('invalid value for "total_count", total_count cannot be nil.')
+ end
+
+ invalid_properties
+end
+
+
+
+
+
+
+
+
+ #to_body ⇒ Hash
+
+
+
+
+
+
+
+
+
to_body is an alias to to_hash (backward compatibility)
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
Returns the object in the form of hash
+
+
+
+
+
+
+
+
+
+
+
+
+235
+236
+237
+
+
+
# File 'lib/coinbase/client/models/wallet_list.rb', line 235
+
+defto_body
+ to_hash
+end
A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
+
+
+
+
+
+ :page
+ (String)
+
+
+
+
+ —
+
A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
+
+
+
+
+
+ :page
+ (String)
+
+
+
+
+ —
+
A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
Returns the default middleware configuration for the Coinbase SDK.
+
+
+
+
+
+
+
+
+
+
+
+
Class Method Details
+
+
+
+
+
+ .config ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the default middleware configuration for the Coinbase SDK.
+
+
+
+
+
+
+
+
+
+
+
+
+
+13
+14
+15
+16
+17
+18
+19
+
+
+
# File 'lib/coinbase/middleware.rb', line 13
+
+defself.config
+ Coinbase::Client::Configuration.default.tapdo|config|
+ config.debugging=true
+ config.host=Coinbase.configuration.api_url
+ config.request(:authenticator)
+ end
+end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/Coinbase/Network.html b/docs/Coinbase/Network.html
index 46a03359..31652729 100644
--- a/docs/Coinbase/Network.html
+++ b/docs/Coinbase/Network.html
@@ -280,7 +280,7 @@
-
Returns a new Network object.
+
Returns a new Network object. Do not use this method directly. Instead, use the Network constants defined in the Coinbase module.
A representation of a Transfer, which moves an amount of an Asset from a user-controlled Wallet to another address. The fee is assumed to be paid in the native Asset of the Network. Currently only ETH transfers are supported. Transfers should be created through Wallet#transfer or Address#transfer.
+
A representation of a Transfer, which moves an amount of an Asset from a user-controlled Wallet to another address. The fee is assumed to be paid in the native Asset of the Network. Transfers should be created through Wallet#transfer or Address#transfer.
The amount of the Asset to send. Integers are interpreted as the smallest denomination of the Asset (e.g. Wei for Ether). Floats and BigDecimals are interpreted as the Asset itself (e.g. Ether).
-
-
-
-
-
-
- asset_id
-
-
- (Symbol)
-
-
-
- —
-
-
The ID of the Asset being transferred. Currently only ETH is supported.
-
-
-
-
-
-
- to_address_id
-
-
- (String)
-
-
-
- —
-
-
The address to which the Transfer is being sent
-
-
-
-
-
-
- client
+ model
- (Jimson::Client)
+ (Coinbase::Client::Transfer)
- (defaults to: Jimson::Client.new(Coinbase.base_sepolia_rpc_url))
-
—
-
(Optional) The JSON RPC client to use for interacting with the Network
# File 'lib/coinbase/transfer.rb', line 112
-defwallet_id
- @wallet_id
+defstatus
+ begin
+ # Create the transaction, and attempt to get the hash to see if it has been signed.
+transaction.hash
+ rescueEth::Signature::SignatureError
+ # If the transaction has not been signed, it is still pending.
+returnStatus::PENDING
+ end
+
+ onchain_transaction=Coinbase.configuration.base_sepolia_client.eth_getTransactionByHash(transaction_hash)
+
+ ifonchain_transaction.nil?
+ # If the transaction has not been broadcast, it is still pending.
+Status::PENDING
+ elsifonchain_transaction['blockHash'].nil?
+ # If the transaction has been broadcast but hasn't been included in a block, it is
+# broadcast.
+Status::BROADCAST
+ else
+ transaction_receipt=Coinbase.configuration.base_sepolia_client.eth_getTransactionReceipt(transaction_hash)
+
+ iftransaction_receipt['status'].to_i(16)==1
+ Status::COMPLETE
+ else
+ Status::FAILED
+ end
+ endend
# File 'lib/coinbase/transfer.rb', line 88
-defstatus
- begin
- # Create the transaction, and attempt to get the hash to see if it has been signed.
-transaction.hash
- rescueEth::Signature::SignatureError
- # If the transaction has not been signed, it is still pending.
-returnStatus::PENDING
- end
+deftransaction
+ return@transactionunless@transaction.nil?
- onchain_transaction=@client.eth_getTransactionByHash(transaction_hash)
+ raw_payload=[unsigned_payload].pack('H*')
+ parsed_payload=JSON.parse(raw_payload)
- ifonchain_transaction.nil?
- # If the transaction has not been broadcast, it is still pending.
-Status::PENDING
- elsifonchain_transaction['blockHash'].nil?
- # If the transaction has been broadcast but hasn't been included in a block, it is
-# broadcast.
-Status::BROADCAST
- else
- transaction_receipt=@client.eth_getTransactionReceipt(transaction_hash)
+ params={
+ chain_id:parsed_payload['chainId'].to_i(16),
+ nonce:parsed_payload['nonce'].to_i(16),
+ priority_fee:parsed_payload['maxPriorityFeePerGas'].to_i(16),
+ max_gas_fee:parsed_payload['maxFeePerGas'].to_i(16),
+ gas_limit:parsed_payload['gas'].to_i(16),# TODO: Handle multiple currencies.
+from:Eth::Address.new(from_address_id),
+ to:Eth::Address.new(destination_address_id),
+ value:parsed_payload['value'].to_i(16),
+ data:parsed_payload['data']||''
+ }
- iftransaction_receipt['status'].to_i(16)==1
- Status::COMPLETE
- else
- Status::FAILED
- end
- end
+ @transaction=Eth::Tx::Eip1559.new(Eth::Tx.validate_eip1559_params(params))
+ @transactionend
# File 'lib/coinbase/user.rb', line 18
+
+defuser_id
+ @model.id
+end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/Coinbase/Wallet.html b/docs/Coinbase/Wallet.html
index 00ffaf2c..fd21039a 100644
--- a/docs/Coinbase/Wallet.html
+++ b/docs/Coinbase/Wallet.html
@@ -102,7 +102,7 @@
Overview
-
A representation of a Wallet. Wallets come with a single default Address, but can expand to have a set of Addresses, each of which can hold a balance of one or more Assets. Wallets can create new Addresses, list their addresses, list their balances, and transfer Assets to other Addresses.
+
A representation of a Wallet. Wallets come with a single default Address, but can expand to have a set of Addresses, each of which can hold a balance of one or more Assets. Wallets can create new Addresses, list their addresses, list their balances, and transfer Assets to other Addresses. Wallets should be created through User#create_wallet or User#import_wallet.
(Optional) The seed to use for the Wallet. Expects a 32-byte hexadecimal. If not provided, a new seed will be generated.
+
(Optional) The seed to use for the Wallet. Expects a 32-byte hexadecimal with no 0x prefix. If not provided, a new seed will be generated.
@@ -493,12 +470,12 @@
(Integer)
- (defaults to: 1)
+ (defaults to: 0)
—
-
(Optional) The number of addresses to generate for the Wallet. If not provided, a single address will be generated.
+
(Optional) The number of addresses already registered for the Wallet.
@@ -511,8 +488,6 @@
(Jimson::Client)
- (defaults to: Jimson::Client.new(Coinbase.base_sepolia_rpc_url))
-
—
@@ -543,8 +518,6 @@
-20
-21
22
23
24
@@ -561,18 +534,24 @@
35
36
37
-38
+38
+39
+40
+41
+42
+43
+44
-
# File 'lib/coinbase/wallet.rb', line 20
+
# File 'lib/coinbase/wallet.rb', line 22
-definitialize(seed:nil,address_count:1,client:Jimson::Client.new(Coinbase.base_sepolia_rpc_url))
+definitialize(model,seed:nil,address_count:0)raiseArgumentError,'Seed must be 32 bytes'if!seed.nil?&&seed.length!=64
- raiseArgumentError,'Address count must be positive'ifaddress_count<1
+
+ @model=model@master=seed.nil??MoneyTree::Master.new:MoneyTree::Master.new(seed_hex:seed)
- @wallet_id=SecureRandom.uuid# TODO: Make Network an argument to the constructor.
@network_id=:base_sepolia@addresses=[]
@@ -581,9 +560,13 @@
@address_path_prefix="m/44'/60'/0'/0"@address_index=0
- @client=client
-
- address_count.times{create_address}
+ ifaddress_count.positive?
+ address_count.times{derive_address}
+ else
+ create_address
+ # Update the model to reflect the new default address.
+update_model
+ endend
@@ -592,97 +575,6 @@
-
-
Instance Attribute Details
-
-
-
-
-
-
- #network_id ⇒ Object(readonly)
-
-
-
-
-
-
-
-
-
Returns the value of attribute network_id.
-
-
-
-
-
-
-
-
-
-
-
-
-
-12
-13
-14
-
-
-
# File 'lib/coinbase/wallet.rb', line 12
-
-defnetwork_id
- @network_id
-end
-
-
-
-
-
-
-
-
-
-
- #wallet_id ⇒ Object(readonly)
-
-
-
-
-
-
-
-
-
Returns the value of attribute wallet_id.
-
-
-
-
-
-
-
-
-
-
-
-
-
-12
-13
-14
-
-
-
# File 'lib/coinbase/wallet.rb', line 12
-
-defwallet_id
- @wallet_id
-end
# File 'lib/coinbase/wallet.rb', line 176
+
+defself.from_hash(data)
+ Data.new(data['wallet_id'],data['seed'])
+end
+
+
+
+
+
+
+
+
+
Instance Method Details
+
+
+
+
+
+ #to_hash ⇒ Hash
+
+
+
+
+
+
+
+
+
Converts the Data object to a Hash.
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Hash)
+
+
+
+ —
+
+
The Hash representation of the Data object
+
+
+
+
+
+
+
+
+
+
+
+
+169
+170
+171
+
+
+
# File 'lib/coinbase/wallet.rb', line 169
+
+defto_hash
+ {wallet_id:wallet_id,seed:seed}
+end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/_index.html b/docs/_index.html
index 8718ee0c..3b394e76 100644
--- a/docs/_index.html
+++ b/docs/_index.html
@@ -87,6 +87,55 @@
The SDK currently supports Customer-custodied Wallets on the Base Sepolia test network.
-
NOTE: The Coinbase SDK is currently in Alpha. The SDK: - may make backwards-incompatible changes between releases - should not be used on Mainnet (i.e. with real funds)
+
NOTE: The Coinbase SDK is currently in Alpha. The SDK:
+
+
may make backwards-incompatible changes between releases
+
+
should not be used on Mainnet (i.e. with real funds)
+
Currently, the SDK is intended for use on testnet for quick bootstrapping of crypto wallets at hackathons, code academies, and other development settings.
The SDK requires a Base Sepolia RPC node, and uses the public instance (sepolia.base.org) by default. This instance is rate-limited, but you can also provision your own on the Coinbase Developer Platform.
+
To start, create a CDP API Key. Then, initialize the Platform SDK by passing your API Key name and API Key's private key via the configure method:
-
You can configure the SDK with your Base Sepolia RPC node by copying your node URL from the CDP portal and setting the following:
+
api_key_name='Copy your API Key name here.'
+api_key_private_key='Copy your API Key\'s private key here.'
-
The SDK provides customer-custodied wallets, which means that you are responsible for securely storing the data required to re-create wallets. The following code snippet demonstrates this:
+
Now, create a Wallet from the User. Wallets are created with a single default Address.
# Create a Wallet with one Address by default.
-w1=Coinbase::Wallet.new
+w1=u.create_wallet
+
-# Export the data required to re-create the wallet.
-data=w1.export
+
Next, view the default Address of your Wallet. You will need this default Address in order to fund the Wallet for your first Transfer.
-# At this point, you should implement your own "store" method to securely persist
-# the data required to re-create the wallet at a later time.
-store(data)
+
# A Wallet has a default Address.
+a=w1.default_address
+a.to_s
+
-# The wallet can be re-created using the exported data.
-# w2 will be equivalent to w1.
-w2=Wallet.new(seed:data.seed,address_count:data.address_count)
+
Wallets do not have funds on them to start. In order to fund the Address, you will need to send funds to the Wallet you generated above. If you don't have testnet funds, get funds from a faucet.
+
+
# Create a new Wallet to transfer funds to.
+# Then, we can transfer 0.00001 ETH out of the Wallet to another Wallet.
+w2=u.create_wallet
+w1.transfer(0.00001,:eth,w2).wait!
-
Transfers
+
Re-Instantiating Wallets
-
The following creates an in-memory wallet. After the wallet is funded with ETH, it transfers 0.00001 ETH to a different wallet.
+
The SDK creates Wallets with developer managed keys, which means you are responsible for securely storing the keys required to re-instantiate Wallets. The below code walks you through how to export a Wallets and store it in a secure location.
-
# Wallets are self-custodial with in-memory key management on Base Sepolia.
-# This should NOT be used in mainnet with real funds.
-w1=Coinbase::Wallet.new
+
# Optional: Create a new Wallet if you do not already have one.
+# Export the data required to re-instantiate the Wallet.
+w3=u.create_wallet
+data=w3.export
+
-# A wallet has a default address.
-a=w1.default_address
-a.to_s
+
In order to persist the data for the Wallet, you will need to implement a store method to store the data export in a secure location. If you do not store the Wallet in a secure location you will lose access to the Wallet and all of the funds on it.
-# At this point, fund the wallet out-of-band.
-# Then, we can transfer 0.00001 ETH out of the wallet to another wallet.
-w2=Coinbase::Wallet.new
+
# At this point, you should implement your own "store" method to securely persist
+# the data required to re-instantiate the Wallet at a later time.
+store(data)
+
-# We wait for the transfer to complete.
-# Base Sepolia is fast, so it should take only a few seconds.
-w1.transfer(0.00001,:eth,w2).wait!
+
The below code demonstrates how to re-instantiate a Wallet from the data export.
+
+
# The Wallet can be re-instantiated using the exported data.
+# w2 will be equivalent to w1.
+w4=u.import_wallet(data)
The SDK currently supports Customer-custodied Wallets on the Base Sepolia test network.
-
NOTE: The Coinbase SDK is currently in Alpha. The SDK: - may make backwards-incompatible changes between releases - should not be used on Mainnet (i.e. with real funds)
+
NOTE: The Coinbase SDK is currently in Alpha. The SDK:
+
+
may make backwards-incompatible changes between releases
+
+
should not be used on Mainnet (i.e. with real funds)
+
Currently, the SDK is intended for use on testnet for quick bootstrapping of crypto wallets at hackathons, code academies, and other development settings.
The SDK requires a Base Sepolia RPC node, and uses the public instance (sepolia.base.org) by default. This instance is rate-limited, but you can also provision your own on the Coinbase Developer Platform.
+
To start, create a CDP API Key. Then, initialize the Platform SDK by passing your API Key name and API Key's private key via the configure method:
-
You can configure the SDK with your Base Sepolia RPC node by copying your node URL from the CDP portal and setting the following:
+
api_key_name='Copy your API Key name here.'
+api_key_private_key='Copy your API Key\'s private key here.'
-
The SDK provides customer-custodied wallets, which means that you are responsible for securely storing the data required to re-create wallets. The following code snippet demonstrates this:
+
Now, create a Wallet from the User. Wallets are created with a single default Address.
# Create a Wallet with one Address by default.
-w1=Coinbase::Wallet.new
+w1=u.create_wallet
+
-# Export the data required to re-create the wallet.
-data=w1.export
+
Next, view the default Address of your Wallet. You will need this default Address in order to fund the Wallet for your first Transfer.
-# At this point, you should implement your own "store" method to securely persist
-# the data required to re-create the wallet at a later time.
-store(data)
+
# A Wallet has a default Address.
+a=w1.default_address
+a.to_s
+
-# The wallet can be re-created using the exported data.
-# w2 will be equivalent to w1.
-w2=Wallet.new(seed:data.seed,address_count:data.address_count)
+
Wallets do not have funds on them to start. In order to fund the Address, you will need to send funds to the Wallet you generated above. If you don't have testnet funds, get funds from a faucet.
+
+
# Create a new Wallet to transfer funds to.
+# Then, we can transfer 0.00001 ETH out of the Wallet to another Wallet.
+w2=u.create_wallet
+w1.transfer(0.00001,:eth,w2).wait!
-
Transfers
+
Re-Instantiating Wallets
-
The following creates an in-memory wallet. After the wallet is funded with ETH, it transfers 0.00001 ETH to a different wallet.
+
The SDK creates Wallets with developer managed keys, which means you are responsible for securely storing the keys required to re-instantiate Wallets. The below code walks you through how to export a Wallets and store it in a secure location.
-
# Wallets are self-custodial with in-memory key management on Base Sepolia.
-# This should NOT be used in mainnet with real funds.
-w1=Coinbase::Wallet.new
+
# Optional: Create a new Wallet if you do not already have one.
+# Export the data required to re-instantiate the Wallet.
+w3=u.create_wallet
+data=w3.export
+
-# A wallet has a default address.
-a=w1.default_address
-a.to_s
+
In order to persist the data for the Wallet, you will need to implement a store method to store the data export in a secure location. If you do not store the Wallet in a secure location you will lose access to the Wallet and all of the funds on it.
-# At this point, fund the wallet out-of-band.
-# Then, we can transfer 0.00001 ETH out of the wallet to another wallet.
-w2=Coinbase::Wallet.new
+
# At this point, you should implement your own "store" method to securely persist
+# the data required to re-instantiate the Wallet at a later time.
+store(data)
+
-# We wait for the transfer to complete.
-# Base Sepolia is fast, so it should take only a few seconds.
-w1.transfer(0.00001,:eth,w2).wait!
+
The below code demonstrates how to re-instantiate a Wallet from the data export.
+
+
# The Wallet can be re-instantiated using the exported data.
+# w2 will be equivalent to w1.
+w4=u.import_wallet(data)
diff --git a/lib/coinbase.rb b/lib/coinbase.rb
index e0021d68..aaf8e78d 100644
--- a/lib/coinbase.rb
+++ b/lib/coinbase.rb
@@ -2,25 +2,89 @@
require_relative 'coinbase/address'
require_relative 'coinbase/asset'
+require_relative 'coinbase/authenticator'
require_relative 'coinbase/balance_map'
+require_relative 'coinbase/client'
require_relative 'coinbase/constants'
+require_relative 'coinbase/middleware'
require_relative 'coinbase/network'
require_relative 'coinbase/transfer'
+require_relative 'coinbase/user'
require_relative 'coinbase/wallet'
# The Coinbase SDK.
module Coinbase
- @base_sepolia_rpc_url = 'https://sepolia.base.org'
+ class InvalidConfiguration < StandardError; end
- # Returns the Base Sepolia RPC URL.
- # @return [String] the Base Sepolia RPC URL
- def self.base_sepolia_rpc_url
- @base_sepolia_rpc_url
+ def self.configuration
+ @configuration ||= Configuration.new
end
- # Sets the Base Sepolia RPC URL.
- # @param value [String] the Base Sepolia RPC URL
- def self.base_sepolia_rpc_url=(value)
- @base_sepolia_rpc_url = value
+ def self.configure
+ yield(configuration)
+
+ raise InvalidConfiguration, 'API key private key is not set' unless configuration.api_key_private_key
+ raise InvalidConfiguration, 'API key name is not set' unless configuration.api_key_name
+ end
+
+ # Configuration object for the Coinbase SDK
+ class Configuration
+ attr_reader :base_sepolia_rpc_url, :base_sepolia_client
+ attr_accessor :api_url, :api_key_name, :api_key_private_key
+
+ def initialize
+ @base_sepolia_rpc_url = 'https://sepolia.base.org'
+ @base_sepolia_client = Jimson::Client.new(@base_sepolia_rpc_url)
+ @api_url = 'https://api.cdp.coinbase.com'
+ end
+
+ def base_sepolia_rpc_url=(new_base_sepolia_rpc_url)
+ @base_sepolia_rpc_url = new_base_sepolia_rpc_url
+ @base_sepolia_client = Jimson::Client.new(@base_sepolia_rpc_url)
+ end
+
+ def api_client
+ @api_client ||= Coinbase::Client::ApiClient.new(Middleware.config)
+ end
+ end
+
+ # Returns the default user.
+ # @return [Coinbase::User] the default user
+ def self.default_user
+ @default_user ||= load_default_user
+ end
+
+ # Converts a string to a symbol, replacing hyphens with underscores.
+ # @param string [String] the string to convert
+ # @return [Symbol] the converted symbol
+ def self.to_sym(value)
+ value.to_s.gsub('-', '_').to_sym
+ end
+
+ # Converts a Coinbase::Client::AddressBalanceList to a BalanceMap.
+ # @param address_balance_list [Coinbase::Client::AddressBalanceList] The AddressBalanceList to convert
+ # @return [BalanceMap] The converted BalanceMap
+ def self.to_balance_map(address_balance_list)
+ balances = {}
+
+ address_balance_list.data.each do |balance|
+ asset_id = Coinbase.to_sym(balance.asset.asset_id.downcase)
+ amount = if asset_id == :eth
+ BigDecimal(balance.amount) / BigDecimal(Coinbase::WEI_PER_ETHER)
+ elsif asset_id == :usdc
+ BigDecimal(balance.amount) / BigDecimal(Coinbase::ATOMIC_UNITS_PER_USDC)
+ else
+ BigDecimal(balance.amount)
+ end
+ balances[asset_id] = amount
+ end
+
+ BalanceMap.new(balances)
+ end
+
+ def self.load_default_user
+ users_api = Coinbase::Client::UsersApi.new(configuration.api_client)
+ user_model = users_api.get_current_user
+ Coinbase::User.new(user_model)
end
end
diff --git a/lib/coinbase/address.rb b/lib/coinbase/address.rb
index d2dafb70..cecbf62b 100644
--- a/lib/coinbase/address.rb
+++ b/lib/coinbase/address.rb
@@ -2,65 +2,72 @@
require_relative 'balance_map'
require_relative 'constants'
+require_relative 'wallet'
require 'bigdecimal'
require 'eth'
require 'jimson'
module Coinbase
# A representation of a blockchain Address, which is a user-controlled account on a Network. Addresses are used to
- # send and receive Assets, and should be created using {link:Wallet#create_address}. Addresses require a
- # {link:Eth::Key} to sign transaction data.
+ # send and receive Assets, and should be created using Wallet#create_address. Addresses require an
+ # Eth::Key to sign transaction data.
class Address
- attr_reader :network_id, :address_id, :wallet_id
-
- # Returns a new Address object.
- # @param network_id [Symbol] The ID of the Network on which the Address exists
- # @param address_id [String] The ID of the Address. On EVM Networks, for example, this is a hash of the public key.
- # @param wallet_id [String] The ID of the Wallet to which the Address belongs
+ # Returns a new Address object. Do not use this method directly. Instead, use Wallet#create_address, or use
+ # the Wallet's default_address.
+ # @param model [Coinbase::Client::Address] The underlying Address object
# @param key [Eth::Key] The key backing the Address
- # @param client [Jimson::Client] (Optional) The JSON RPC client to use for interacting with the Network
- def initialize(network_id, address_id, wallet_id, key,
- client: Jimson::Client.new(Coinbase.base_sepolia_rpc_url))
- # TODO: Don't require key.
- @network_id = network_id
- @address_id = address_id
- @wallet_id = wallet_id
+ def initialize(model, key)
+ @model = model
@key = key
- @client = client
end
- # Returns the balances of the Address. Currently only ETH balances are supported.
+ # Returns the Network ID of the Address.
+ # @return [Symbol] The Network ID
+ def network_id
+ Coinbase.to_sym(@model.network_id)
+ end
+
+ # Returns the Wallet ID of the Address.
+ # @return [String] The Wallet ID
+ def wallet_id
+ @model.wallet_id
+ end
+
+ # Returns the Address ID.
+ # @return [String] The Address ID
+ def address_id
+ @model.address_id
+ end
+
+ # Returns the balances of the Address.
# @return [BalanceMap] The balances of the Address, keyed by asset ID. Ether balances are denominated
# in ETH.
def list_balances
- # TODO: Handle multiple currencies.
- eth_balance_in_wei = BigDecimal(@client.eth_getBalance(@address_id, 'latest').to_i(16).to_s)
- eth_balance = BigDecimal(eth_balance_in_wei / BigDecimal(Coinbase::WEI_PER_ETHER.to_s))
-
- BalanceMap.new({ eth: eth_balance })
+ response = addresses_api.list_address_balances(wallet_id, address_id)
+ Coinbase.to_balance_map(response)
end
- # Returns the balance of the provided Asset. Currently only ETH is supported.
+ # Returns the balance of the provided Asset.
# @param asset_id [Symbol] The Asset to retrieve the balance for
# @return [BigDecimal] The balance of the Asset
def get_balance(asset_id)
- normalized_asset_id = if %i[wei gwei].include?(asset_id)
- :eth
- else
- asset_id
- end
+ normalized_asset_id = normalize_asset_id(asset_id)
+
+ response = addresses_api.get_address_balance(wallet_id, address_id, normalized_asset_id.to_s)
- eth_balance = list_balances[normalized_asset_id] || BigDecimal(0)
+ return BigDecimal('0') if response.nil?
+
+ amount = BigDecimal(response.amount)
case asset_id
when :eth
- eth_balance
+ amount / BigDecimal(Coinbase::WEI_PER_ETHER.to_s)
when :gwei
- eth_balance * Coinbase::GWEI_PER_ETHER
- when :wei
- eth_balance * Coinbase::WEI_PER_ETHER
+ amount / BigDecimal(Coinbase::GWEI_PER_ETHER.to_s)
+ when :usdc
+ amount / BigDecimal(Coinbase::ATOMIC_UNITS_PER_USDC.to_s)
else
- BigDecimal(0)
+ amount
end
end
@@ -71,15 +78,14 @@ def get_balance(asset_id)
# default address. If a String, interprets it as the address ID.
# @return [String] The hash of the Transfer transaction.
def transfer(amount, asset_id, destination)
- # TODO: Handle multiple currencies.
raise ArgumentError, "Unsupported asset: #{asset_id}" unless Coinbase::SUPPORTED_ASSET_IDS[asset_id]
if destination.is_a?(Wallet)
- raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != @network_id
+ raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != network_id
destination = destination.default_address.address_id
elsif destination.is_a?(Address)
- raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != @network_id
+ raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != network_id
destination = destination.address_id
end
@@ -89,12 +95,24 @@ def transfer(amount, asset_id, destination)
raise ArgumentError, "Insufficient funds: #{amount} requested, but only #{current_balance} available"
end
- transfer = Coinbase::Transfer.new(@network_id, @wallet_id, @address_id, amount, asset_id, destination,
- client: @client)
+ normalized_amount = normalize_asset_amount(amount, asset_id)
+
+ normalized_asset_id = normalize_asset_id(asset_id)
+
+ create_transfer_request = {
+ amount: normalized_amount.to_i.to_s,
+ network_id: network_id,
+ asset_id: normalized_asset_id.to_s,
+ destination: destination
+ }
+
+ transfer_model = transfers_api.create_transfer(wallet_id, address_id, create_transfer_request)
+
+ transfer = Coinbase::Transfer.new(transfer_model)
transaction = transfer.transaction
transaction.sign(@key)
- @client.eth_sendRawTransaction("0x#{transaction.hex}")
+ Coinbase.configuration.base_sepolia_client.eth_sendRawTransaction("0x#{transaction.hex}")
transfer
end
@@ -102,26 +120,47 @@ def transfer(amount, asset_id, destination)
# Returns the address as a string.
# @return [String] The address
def to_s
- @address_id
+ address_id
end
private
- # Normalizes the amount of ETH to send based on the asset ID.
+ # Normalizes the amount of the Asset to send to the atomic unit.
# @param amount [Integer, Float, BigDecimal] The amount to normalize
# @param asset_id [Symbol] The ID of the Asset being transferred
- # @return [BigDecimal] The normalized amount in units of ETH
- def normalize_eth_amount(amount, asset_id)
+ # @return [BigDecimal] The normalized amount in atomic units
+ def normalize_asset_amount(amount, asset_id)
+ big_amount = BigDecimal(amount.to_s)
+
case asset_id
when :eth
- amount.is_a?(BigDecimal) ? amount : BigDecimal(amount.to_s)
+ big_amount * Coinbase::WEI_PER_ETHER
when :gwei
- BigDecimal(amount / Coinbase::GWEI_PER_ETHER)
- when :wei
- BigDecimal(amount / Coinbase::WEI_PER_ETHER)
+ big_amount * Coinbase::WEI_PER_GWEI
+ when :usdc
+ big_amount * Coinbase::ATOMIC_UNITS_PER_USDC
else
- raise ArgumentError, "Unsupported asset: #{asset_id}"
+ big_amount
end
end
+
+ # Normalizes the asset ID to use during requests.
+ # @param asset_id [Symbol] The asset ID to normalize
+ # @return [Symbol] The normalized asset ID
+ def normalize_asset_id(asset_id)
+ if %i[wei gwei].include?(asset_id)
+ :eth
+ else
+ asset_id
+ end
+ end
+
+ def addresses_api
+ @addresses_api ||= Coinbase::Client::AddressesApi.new(Coinbase.configuration.api_client)
+ end
+
+ def transfers_api
+ @transfers_api ||= Coinbase::Client::TransfersApi.new(Coinbase.configuration.api_client)
+ end
end
end
diff --git a/lib/coinbase/asset.rb b/lib/coinbase/asset.rb
index 595e1b6d..d310338c 100644
--- a/lib/coinbase/asset.rb
+++ b/lib/coinbase/asset.rb
@@ -5,7 +5,8 @@ module Coinbase
class Asset
attr_reader :network_id, :asset_id, :display_name, :address_id
- # Returns a new Asset object.
+ # Returns a new Asset object. Do not use this method. Instead, use the Asset constants defined in
+ # the Coinbase module.
# @param network_id [Symbol] The ID of the Network to which the Asset belongs
# @param asset_id [Symbol] The Asset ID
# @param display_name [String] The Asset's display name
diff --git a/lib/coinbase/authenticator.rb b/lib/coinbase/authenticator.rb
new file mode 100644
index 00000000..1eb90a6a
--- /dev/null
+++ b/lib/coinbase/authenticator.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'faraday'
+require 'jwt'
+require 'openssl'
+require 'securerandom'
+
+module Coinbase
+ # A class that builds JWTs for authenticating with the Coinbase Platform APIs.
+ class Authenticator < Faraday::Middleware
+ # Initializes the Authenticator.
+ # @param app [Faraday::Connection] The Faraday connection
+ def initialize(app)
+ super(app)
+ @app = app
+ end
+
+ # Processes the request by adding the JWT to the Authorization header.
+ # @param env [Faraday::Env] The Faraday request environment
+ def call(env)
+ method = env.method.downcase.to_sym
+ uri = env.url.to_s
+ uri_without_protocol = URI(uri).host
+ token = build_jwt("#{method.upcase} #{uri_without_protocol}#{env.url.path}")
+ env.request_headers['Authorization'] = "Bearer #{token}"
+ @app.call(env)
+ end
+
+ # Builds the JWT for the given API endpoint URI. The JWT is signed with the API key's private key.
+ # @param uri [String] The API endpoint URI
+ # @return [String] The JWT
+ def build_jwt(uri)
+ header = {
+ typ: 'JWT',
+ kid: Coinbase.configuration.api_key_name,
+ nonce: SecureRandom.hex(16)
+ }
+
+ claims = {
+ sub: Coinbase.configuration.api_key_name,
+ iss: 'coinbase-cloud',
+ aud: ['cdp_service'],
+ nbf: Time.now.to_i,
+ exp: Time.now.to_i + 60, # Expiration time: 1 minute from now.
+ uris: [uri]
+ }
+
+ private_key = OpenSSL::PKey.read(Coinbase.configuration.api_key_private_key)
+ JWT.encode(claims, private_key, 'ES256', header)
+ end
+ end
+end
diff --git a/lib/coinbase/balance_map.rb b/lib/coinbase/balance_map.rb
index 7ce3b9bd..0ece340b 100644
--- a/lib/coinbase/balance_map.rb
+++ b/lib/coinbase/balance_map.rb
@@ -3,7 +3,7 @@
require 'bigdecimal'
module Coinbase
- # A convenience class for printing out crypto asset balances in a human-readable format.
+ # A convenience class for printing out Asset balances in a human-readable format.
class BalanceMap < Hash
# Returns a new BalanceMap object.
# @param hash [Map] The hash to initialize with
diff --git a/lib/coinbase/client.rb b/lib/coinbase/client.rb
new file mode 100644
index 00000000..f5d56974
--- /dev/null
+++ b/lib/coinbase/client.rb
@@ -0,0 +1,57 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+# Common files
+require 'coinbase/client/api_client'
+require 'coinbase/client/api_error'
+require 'coinbase/client/version'
+require 'coinbase/client/configuration'
+
+# Models
+Coinbase::Client.autoload :Address, 'coinbase/client/models/address'
+Coinbase::Client.autoload :AddressBalanceList, 'coinbase/client/models/address_balance_list'
+Coinbase::Client.autoload :AddressList, 'coinbase/client/models/address_list'
+Coinbase::Client.autoload :Asset, 'coinbase/client/models/asset'
+Coinbase::Client.autoload :Balance, 'coinbase/client/models/balance'
+Coinbase::Client.autoload :CreateAddressRequest, 'coinbase/client/models/create_address_request'
+Coinbase::Client.autoload :CreateTransferRequest, 'coinbase/client/models/create_transfer_request'
+Coinbase::Client.autoload :CreateWalletRequest, 'coinbase/client/models/create_wallet_request'
+Coinbase::Client.autoload :Error, 'coinbase/client/models/error'
+Coinbase::Client.autoload :Transfer, 'coinbase/client/models/transfer'
+Coinbase::Client.autoload :TransferList, 'coinbase/client/models/transfer_list'
+Coinbase::Client.autoload :User, 'coinbase/client/models/user'
+Coinbase::Client.autoload :Wallet, 'coinbase/client/models/wallet'
+Coinbase::Client.autoload :WalletList, 'coinbase/client/models/wallet_list'
+
+# APIs
+Coinbase::Client.autoload :AddressesApi, 'coinbase/client/api/addresses_api'
+Coinbase::Client.autoload :TransfersApi, 'coinbase/client/api/transfers_api'
+Coinbase::Client.autoload :UsersApi, 'coinbase/client/api/users_api'
+Coinbase::Client.autoload :WalletsApi, 'coinbase/client/api/wallets_api'
+
+module Coinbase::Client
+ class << self
+ # Customize default settings for the SDK using block.
+ # Coinbase::Client.configure do |config|
+ # config.username = "xxx"
+ # config.password = "xxx"
+ # end
+ # If no block given, return the default Configuration object.
+ def configure
+ if block_given?
+ yield(Configuration.default)
+ else
+ Configuration.default
+ end
+ end
+ end
+end
diff --git a/lib/coinbase/client/api/addresses_api.rb b/lib/coinbase/client/api/addresses_api.rb
new file mode 100644
index 00000000..26c59da1
--- /dev/null
+++ b/lib/coinbase/client/api/addresses_api.rb
@@ -0,0 +1,385 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'cgi'
+
+module Coinbase::Client
+ class AddressesApi
+ attr_accessor :api_client
+
+ def initialize(api_client = ApiClient.default)
+ @api_client = api_client
+ end
+ # Create a new address
+ # Create a new address scoped to the wallet.
+ # @param wallet_id [String] The ID of the wallet to create the address in.
+ # @param [Hash] opts the optional parameters
+ # @option opts [CreateAddressRequest] :create_address_request
+ # @return [Address]
+ def create_address(wallet_id, opts = {})
+ data, _status_code, _headers = create_address_with_http_info(wallet_id, opts)
+ data
+ end
+
+ # Create a new address
+ # Create a new address scoped to the wallet.
+ # @param wallet_id [String] The ID of the wallet to create the address in.
+ # @param [Hash] opts the optional parameters
+ # @option opts [CreateAddressRequest] :create_address_request
+ # @return [Array<(Address, Integer, Hash)>] Address data, response status code and response headers
+ def create_address_with_http_info(wallet_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: AddressesApi.create_address ...'
+ end
+ # verify the required parameter 'wallet_id' is set
+ if @api_client.config.client_side_validation && wallet_id.nil?
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling AddressesApi.create_address"
+ end
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/addresses'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s))
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+ # HTTP header 'Content-Type'
+ content_type = @api_client.select_header_content_type(['application/json'])
+ if !content_type.nil?
+ header_params['Content-Type'] = content_type
+ end
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'create_address_request'])
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'Address'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"AddressesApi.create_address",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: AddressesApi#create_address\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # Get address by onchain address
+ # Get address
+ # @param wallet_id [String] The ID of the wallet the address belongs to.
+ # @param address_id [String] The onchain address of the address that is being fetched.
+ # @param [Hash] opts the optional parameters
+ # @return [Address]
+ def get_address(wallet_id, address_id, opts = {})
+ data, _status_code, _headers = get_address_with_http_info(wallet_id, address_id, opts)
+ data
+ end
+
+ # Get address by onchain address
+ # Get address
+ # @param wallet_id [String] The ID of the wallet the address belongs to.
+ # @param address_id [String] The onchain address of the address that is being fetched.
+ # @param [Hash] opts the optional parameters
+ # @return [Array<(Address, Integer, Hash)>] Address data, response status code and response headers
+ def get_address_with_http_info(wallet_id, address_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: AddressesApi.get_address ...'
+ end
+ # verify the required parameter 'wallet_id' is set
+ if @api_client.config.client_side_validation && wallet_id.nil?
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling AddressesApi.get_address"
+ end
+ # verify the required parameter 'address_id' is set
+ if @api_client.config.client_side_validation && address_id.nil?
+ fail ArgumentError, "Missing the required parameter 'address_id' when calling AddressesApi.get_address"
+ end
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s))
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body]
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'Address'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"AddressesApi.get_address",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: AddressesApi#get_address\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # Get address balance for asset
+ # Get address balance
+ # @param wallet_id [String] The ID of the wallet to fetch the balance for
+ # @param address_id [String] The onchain address of the address that is being fetched.
+ # @param asset_id [String] The symbol of the asset to fetch the balance for
+ # @param [Hash] opts the optional parameters
+ # @return [Balance]
+ def get_address_balance(wallet_id, address_id, asset_id, opts = {})
+ data, _status_code, _headers = get_address_balance_with_http_info(wallet_id, address_id, asset_id, opts)
+ data
+ end
+
+ # Get address balance for asset
+ # Get address balance
+ # @param wallet_id [String] The ID of the wallet to fetch the balance for
+ # @param address_id [String] The onchain address of the address that is being fetched.
+ # @param asset_id [String] The symbol of the asset to fetch the balance for
+ # @param [Hash] opts the optional parameters
+ # @return [Array<(Balance, Integer, Hash)>] Balance data, response status code and response headers
+ def get_address_balance_with_http_info(wallet_id, address_id, asset_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: AddressesApi.get_address_balance ...'
+ end
+ # verify the required parameter 'wallet_id' is set
+ if @api_client.config.client_side_validation && wallet_id.nil?
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling AddressesApi.get_address_balance"
+ end
+ # verify the required parameter 'address_id' is set
+ if @api_client.config.client_side_validation && address_id.nil?
+ fail ArgumentError, "Missing the required parameter 'address_id' when calling AddressesApi.get_address_balance"
+ end
+ # verify the required parameter 'asset_id' is set
+ if @api_client.config.client_side_validation && asset_id.nil?
+ fail ArgumentError, "Missing the required parameter 'asset_id' when calling AddressesApi.get_address_balance"
+ end
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/balances/{asset_id}'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s)).sub('{' + 'asset_id' + '}', CGI.escape(asset_id.to_s))
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body]
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'Balance'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"AddressesApi.get_address_balance",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: AddressesApi#get_address_balance\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # Get all balances for address
+ # Get address balances
+ # @param wallet_id [String] The ID of the wallet to fetch the balances for
+ # @param address_id [String] The onchain address of the address that is being fetched.
+ # @param [Hash] opts the optional parameters
+ # @option opts [String] :page A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
+ # @return [AddressBalanceList]
+ def list_address_balances(wallet_id, address_id, opts = {})
+ data, _status_code, _headers = list_address_balances_with_http_info(wallet_id, address_id, opts)
+ data
+ end
+
+ # Get all balances for address
+ # Get address balances
+ # @param wallet_id [String] The ID of the wallet to fetch the balances for
+ # @param address_id [String] The onchain address of the address that is being fetched.
+ # @param [Hash] opts the optional parameters
+ # @option opts [String] :page A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
+ # @return [Array<(AddressBalanceList, Integer, Hash)>] AddressBalanceList data, response status code and response headers
+ def list_address_balances_with_http_info(wallet_id, address_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: AddressesApi.list_address_balances ...'
+ end
+ # verify the required parameter 'wallet_id' is set
+ if @api_client.config.client_side_validation && wallet_id.nil?
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling AddressesApi.list_address_balances"
+ end
+ # verify the required parameter 'address_id' is set
+ if @api_client.config.client_side_validation && address_id.nil?
+ fail ArgumentError, "Missing the required parameter 'address_id' when calling AddressesApi.list_address_balances"
+ end
+ if @api_client.config.client_side_validation && !opts[:'page'].nil? && opts[:'page'].to_s.length > 5000
+ fail ArgumentError, 'invalid value for "opts[:"page"]" when calling AddressesApi.list_address_balances, the character length must be smaller than or equal to 5000.'
+ end
+
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/balances'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s))
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+ query_params[:'page'] = opts[:'page'] if !opts[:'page'].nil?
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body]
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'AddressBalanceList'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"AddressesApi.list_address_balances",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: AddressesApi#list_address_balances\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # List addresses in a wallet.
+ # List addresses in the wallet.
+ # @param wallet_id [String] The ID of the wallet whose addresses to fetch
+ # @param [Hash] opts the optional parameters
+ # @option opts [Integer] :limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
+ # @option opts [String] :page A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
+ # @return [AddressList]
+ def list_addresses(wallet_id, opts = {})
+ data, _status_code, _headers = list_addresses_with_http_info(wallet_id, opts)
+ data
+ end
+
+ # List addresses in a wallet.
+ # List addresses in the wallet.
+ # @param wallet_id [String] The ID of the wallet whose addresses to fetch
+ # @param [Hash] opts the optional parameters
+ # @option opts [Integer] :limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
+ # @option opts [String] :page A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
+ # @return [Array<(AddressList, Integer, Hash)>] AddressList data, response status code and response headers
+ def list_addresses_with_http_info(wallet_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: AddressesApi.list_addresses ...'
+ end
+ # verify the required parameter 'wallet_id' is set
+ if @api_client.config.client_side_validation && wallet_id.nil?
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling AddressesApi.list_addresses"
+ end
+ if @api_client.config.client_side_validation && !opts[:'page'].nil? && opts[:'page'].to_s.length > 5000
+ fail ArgumentError, 'invalid value for "opts[:"page"]" when calling AddressesApi.list_addresses, the character length must be smaller than or equal to 5000.'
+ end
+
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/addresses'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s))
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+ query_params[:'limit'] = opts[:'limit'] if !opts[:'limit'].nil?
+ query_params[:'page'] = opts[:'page'] if !opts[:'page'].nil?
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body]
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'AddressList'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"AddressesApi.list_addresses",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: AddressesApi#list_addresses\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+ end
+end
diff --git a/lib/coinbase/client/api/transfers_api.rb b/lib/coinbase/client/api/transfers_api.rb
new file mode 100644
index 00000000..04031cfd
--- /dev/null
+++ b/lib/coinbase/client/api/transfers_api.rb
@@ -0,0 +1,256 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'cgi'
+
+module Coinbase::Client
+ class TransfersApi
+ attr_accessor :api_client
+
+ def initialize(api_client = ApiClient.default)
+ @api_client = api_client
+ end
+ # Create a new transfer for an address
+ # Create a new transfer
+ # @param wallet_id [String] The ID of the wallet the source address belongs to
+ # @param address_id [String] The ID of the address to transfer from
+ # @param create_transfer_request [CreateTransferRequest]
+ # @param [Hash] opts the optional parameters
+ # @return [Transfer]
+ def create_transfer(wallet_id, address_id, create_transfer_request, opts = {})
+ data, _status_code, _headers = create_transfer_with_http_info(wallet_id, address_id, create_transfer_request, opts)
+ data
+ end
+
+ # Create a new transfer for an address
+ # Create a new transfer
+ # @param wallet_id [String] The ID of the wallet the source address belongs to
+ # @param address_id [String] The ID of the address to transfer from
+ # @param create_transfer_request [CreateTransferRequest]
+ # @param [Hash] opts the optional parameters
+ # @return [Array<(Transfer, Integer, Hash)>] Transfer data, response status code and response headers
+ def create_transfer_with_http_info(wallet_id, address_id, create_transfer_request, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: TransfersApi.create_transfer ...'
+ end
+ # verify the required parameter 'wallet_id' is set
+ if @api_client.config.client_side_validation && wallet_id.nil?
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling TransfersApi.create_transfer"
+ end
+ # verify the required parameter 'address_id' is set
+ if @api_client.config.client_side_validation && address_id.nil?
+ fail ArgumentError, "Missing the required parameter 'address_id' when calling TransfersApi.create_transfer"
+ end
+ # verify the required parameter 'create_transfer_request' is set
+ if @api_client.config.client_side_validation && create_transfer_request.nil?
+ fail ArgumentError, "Missing the required parameter 'create_transfer_request' when calling TransfersApi.create_transfer"
+ end
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/transfers'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s))
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+ # HTTP header 'Content-Type'
+ content_type = @api_client.select_header_content_type(['application/json'])
+ if !content_type.nil?
+ header_params['Content-Type'] = content_type
+ end
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(create_transfer_request)
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'Transfer'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"TransfersApi.create_transfer",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: TransfersApi#create_transfer\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # Get a transfer by ID
+ # Get a transfer by ID
+ # @param wallet_id [String] The ID of the wallet the address belongs to
+ # @param address_id [String] The ID of the address the transfer belongs to
+ # @param transfer_id [String] The ID of the transfer to fetch
+ # @param [Hash] opts the optional parameters
+ # @return [Transfer]
+ def get_transfer(wallet_id, address_id, transfer_id, opts = {})
+ data, _status_code, _headers = get_transfer_with_http_info(wallet_id, address_id, transfer_id, opts)
+ data
+ end
+
+ # Get a transfer by ID
+ # Get a transfer by ID
+ # @param wallet_id [String] The ID of the wallet the address belongs to
+ # @param address_id [String] The ID of the address the transfer belongs to
+ # @param transfer_id [String] The ID of the transfer to fetch
+ # @param [Hash] opts the optional parameters
+ # @return [Array<(Transfer, Integer, Hash)>] Transfer data, response status code and response headers
+ def get_transfer_with_http_info(wallet_id, address_id, transfer_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: TransfersApi.get_transfer ...'
+ end
+ # verify the required parameter 'wallet_id' is set
+ if @api_client.config.client_side_validation && wallet_id.nil?
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling TransfersApi.get_transfer"
+ end
+ # verify the required parameter 'address_id' is set
+ if @api_client.config.client_side_validation && address_id.nil?
+ fail ArgumentError, "Missing the required parameter 'address_id' when calling TransfersApi.get_transfer"
+ end
+ # verify the required parameter 'transfer_id' is set
+ if @api_client.config.client_side_validation && transfer_id.nil?
+ fail ArgumentError, "Missing the required parameter 'transfer_id' when calling TransfersApi.get_transfer"
+ end
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/transfers/{transfer_id}'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s)).sub('{' + 'transfer_id' + '}', CGI.escape(transfer_id.to_s))
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body]
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'Transfer'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"TransfersApi.get_transfer",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: TransfersApi#get_transfer\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # List transfers for an address.
+ # List transfers for an address.
+ # @param wallet_id [String] The ID of the wallet the address belongs to
+ # @param address_id [String] The ID of the address to list transfers for
+ # @param [Hash] opts the optional parameters
+ # @option opts [Integer] :limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
+ # @option opts [String] :page A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
+ # @return [TransferList]
+ def list_transfers(wallet_id, address_id, opts = {})
+ data, _status_code, _headers = list_transfers_with_http_info(wallet_id, address_id, opts)
+ data
+ end
+
+ # List transfers for an address.
+ # List transfers for an address.
+ # @param wallet_id [String] The ID of the wallet the address belongs to
+ # @param address_id [String] The ID of the address to list transfers for
+ # @param [Hash] opts the optional parameters
+ # @option opts [Integer] :limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
+ # @option opts [String] :page A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
+ # @return [Array<(TransferList, Integer, Hash)>] TransferList data, response status code and response headers
+ def list_transfers_with_http_info(wallet_id, address_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: TransfersApi.list_transfers ...'
+ end
+ # verify the required parameter 'wallet_id' is set
+ if @api_client.config.client_side_validation && wallet_id.nil?
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling TransfersApi.list_transfers"
+ end
+ # verify the required parameter 'address_id' is set
+ if @api_client.config.client_side_validation && address_id.nil?
+ fail ArgumentError, "Missing the required parameter 'address_id' when calling TransfersApi.list_transfers"
+ end
+ if @api_client.config.client_side_validation && !opts[:'page'].nil? && opts[:'page'].to_s.length > 5000
+ fail ArgumentError, 'invalid value for "opts[:"page"]" when calling TransfersApi.list_transfers, the character length must be smaller than or equal to 5000.'
+ end
+
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/transfers'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s))
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+ query_params[:'limit'] = opts[:'limit'] if !opts[:'limit'].nil?
+ query_params[:'page'] = opts[:'page'] if !opts[:'page'].nil?
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body]
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'TransferList'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"TransfersApi.list_transfers",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: TransfersApi#list_transfers\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+ end
+end
diff --git a/lib/coinbase/client/api/users_api.rb b/lib/coinbase/client/api/users_api.rb
new file mode 100644
index 00000000..73080e3a
--- /dev/null
+++ b/lib/coinbase/client/api/users_api.rb
@@ -0,0 +1,79 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'cgi'
+
+module Coinbase::Client
+ class UsersApi
+ attr_accessor :api_client
+
+ def initialize(api_client = ApiClient.default)
+ @api_client = api_client
+ end
+ # Get current user
+ # Get current user
+ # @param [Hash] opts the optional parameters
+ # @return [User]
+ def get_current_user(opts = {})
+ data, _status_code, _headers = get_current_user_with_http_info(opts)
+ data
+ end
+
+ # Get current user
+ # Get current user
+ # @param [Hash] opts the optional parameters
+ # @return [Array<(User, Integer, Hash)>] User data, response status code and response headers
+ def get_current_user_with_http_info(opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: UsersApi.get_current_user ...'
+ end
+ # resource path
+ local_var_path = '/v1/users/me'
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body]
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'User'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"UsersApi.get_current_user",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: UsersApi#get_current_user\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+ end
+end
diff --git a/lib/coinbase/client/api/wallets_api.rb b/lib/coinbase/client/api/wallets_api.rb
new file mode 100644
index 00000000..21c7e8bc
--- /dev/null
+++ b/lib/coinbase/client/api/wallets_api.rb
@@ -0,0 +1,348 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'cgi'
+
+module Coinbase::Client
+ class WalletsApi
+ attr_accessor :api_client
+
+ def initialize(api_client = ApiClient.default)
+ @api_client = api_client
+ end
+ # Create a new wallet
+ # Create a new wallet scoped to the user.
+ # @param [Hash] opts the optional parameters
+ # @option opts [CreateWalletRequest] :create_wallet_request
+ # @return [Wallet]
+ def create_wallet(opts = {})
+ data, _status_code, _headers = create_wallet_with_http_info(opts)
+ data
+ end
+
+ # Create a new wallet
+ # Create a new wallet scoped to the user.
+ # @param [Hash] opts the optional parameters
+ # @option opts [CreateWalletRequest] :create_wallet_request
+ # @return [Array<(Wallet, Integer, Hash)>] Wallet data, response status code and response headers
+ def create_wallet_with_http_info(opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: WalletsApi.create_wallet ...'
+ end
+ # resource path
+ local_var_path = '/v1/wallets'
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+ # HTTP header 'Content-Type'
+ content_type = @api_client.select_header_content_type(['application/json'])
+ if !content_type.nil?
+ header_params['Content-Type'] = content_type
+ end
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'create_wallet_request'])
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'Wallet'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"WalletsApi.create_wallet",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: WalletsApi#create_wallet\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # Get wallet by ID
+ # Get wallet
+ # @param wallet_id [String] The ID of the wallet to fetch
+ # @param [Hash] opts the optional parameters
+ # @return [Wallet]
+ def get_wallet(wallet_id, opts = {})
+ data, _status_code, _headers = get_wallet_with_http_info(wallet_id, opts)
+ data
+ end
+
+ # Get wallet by ID
+ # Get wallet
+ # @param wallet_id [String] The ID of the wallet to fetch
+ # @param [Hash] opts the optional parameters
+ # @return [Array<(Wallet, Integer, Hash)>] Wallet data, response status code and response headers
+ def get_wallet_with_http_info(wallet_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: WalletsApi.get_wallet ...'
+ end
+ # verify the required parameter 'wallet_id' is set
+ if @api_client.config.client_side_validation && wallet_id.nil?
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling WalletsApi.get_wallet"
+ end
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s))
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body]
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'Wallet'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"WalletsApi.get_wallet",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: WalletsApi#get_wallet\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # Get the balance of an asset in the wallet
+ # Get the aggregated balance of an asset across all of the addresses in the wallet.
+ # @param wallet_id [String] The ID of the wallet to fetch the balance for
+ # @param asset_id [String] The symbol of the asset to fetch the balance for
+ # @param [Hash] opts the optional parameters
+ # @return [Balance]
+ def get_wallet_balance(wallet_id, asset_id, opts = {})
+ data, _status_code, _headers = get_wallet_balance_with_http_info(wallet_id, asset_id, opts)
+ data
+ end
+
+ # Get the balance of an asset in the wallet
+ # Get the aggregated balance of an asset across all of the addresses in the wallet.
+ # @param wallet_id [String] The ID of the wallet to fetch the balance for
+ # @param asset_id [String] The symbol of the asset to fetch the balance for
+ # @param [Hash] opts the optional parameters
+ # @return [Array<(Balance, Integer, Hash)>] Balance data, response status code and response headers
+ def get_wallet_balance_with_http_info(wallet_id, asset_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: WalletsApi.get_wallet_balance ...'
+ end
+ # verify the required parameter 'wallet_id' is set
+ if @api_client.config.client_side_validation && wallet_id.nil?
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling WalletsApi.get_wallet_balance"
+ end
+ # verify the required parameter 'asset_id' is set
+ if @api_client.config.client_side_validation && asset_id.nil?
+ fail ArgumentError, "Missing the required parameter 'asset_id' when calling WalletsApi.get_wallet_balance"
+ end
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/balances/{asset_id}'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'asset_id' + '}', CGI.escape(asset_id.to_s))
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body]
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'Balance'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"WalletsApi.get_wallet_balance",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: WalletsApi#get_wallet_balance\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # List wallet balances
+ # List the balances of all of the addresses in the wallet aggregated by asset.
+ # @param wallet_id [String] The ID of the wallet to fetch the balances for
+ # @param [Hash] opts the optional parameters
+ # @return [AddressBalanceList]
+ def list_wallet_balances(wallet_id, opts = {})
+ data, _status_code, _headers = list_wallet_balances_with_http_info(wallet_id, opts)
+ data
+ end
+
+ # List wallet balances
+ # List the balances of all of the addresses in the wallet aggregated by asset.
+ # @param wallet_id [String] The ID of the wallet to fetch the balances for
+ # @param [Hash] opts the optional parameters
+ # @return [Array<(AddressBalanceList, Integer, Hash)>] AddressBalanceList data, response status code and response headers
+ def list_wallet_balances_with_http_info(wallet_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: WalletsApi.list_wallet_balances ...'
+ end
+ # verify the required parameter 'wallet_id' is set
+ if @api_client.config.client_side_validation && wallet_id.nil?
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling WalletsApi.list_wallet_balances"
+ end
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/balances'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s))
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body]
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'AddressBalanceList'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"WalletsApi.list_wallet_balances",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: WalletsApi#list_wallet_balances\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # List wallets
+ # List wallets belonging to the user.
+ # @param [Hash] opts the optional parameters
+ # @option opts [Integer] :limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
+ # @option opts [String] :page A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
+ # @return [WalletList]
+ def list_wallets(opts = {})
+ data, _status_code, _headers = list_wallets_with_http_info(opts)
+ data
+ end
+
+ # List wallets
+ # List wallets belonging to the user.
+ # @param [Hash] opts the optional parameters
+ # @option opts [Integer] :limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
+ # @option opts [String] :page A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
+ # @return [Array<(WalletList, Integer, Hash)>] WalletList data, response status code and response headers
+ def list_wallets_with_http_info(opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: WalletsApi.list_wallets ...'
+ end
+ if @api_client.config.client_side_validation && !opts[:'page'].nil? && opts[:'page'].to_s.length > 5000
+ fail ArgumentError, 'invalid value for "opts[:"page"]" when calling WalletsApi.list_wallets, the character length must be smaller than or equal to 5000.'
+ end
+
+ # resource path
+ local_var_path = '/v1/wallets'
+
+ # query parameters
+ query_params = opts[:query_params] || {}
+ query_params[:'limit'] = opts[:'limit'] if !opts[:'limit'].nil?
+ query_params[:'page'] = opts[:'page'] if !opts[:'page'].nil?
+
+ # header parameters
+ header_params = opts[:header_params] || {}
+ # HTTP header 'Accept' (if needed)
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
+
+ # form parameters
+ form_params = opts[:form_params] || {}
+
+ # http body (model)
+ post_body = opts[:debug_body]
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'WalletList'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"WalletsApi.list_wallets",
+ :header_params => header_params,
+ :query_params => query_params,
+ :form_params => form_params,
+ :body => post_body,
+ :auth_names => auth_names,
+ :return_type => return_type
+ )
+
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
+ if @api_client.config.debugging
+ @api_client.config.logger.debug "API called: WalletsApi#list_wallets\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+ end
+end
diff --git a/lib/coinbase/client/api_client.rb b/lib/coinbase/client/api_client.rb
new file mode 100644
index 00000000..c1aafb61
--- /dev/null
+++ b/lib/coinbase/client/api_client.rb
@@ -0,0 +1,431 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'json'
+require 'logger'
+require 'tempfile'
+require 'time'
+require 'faraday'
+require 'faraday/multipart' if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0')
+require 'marcel'
+
+
+module Coinbase::Client
+ class ApiClient
+ # The Configuration object holding settings to be used in the API client.
+ attr_accessor :config
+
+ # Defines the headers to be used in HTTP requests of all API calls by default.
+ #
+ # @return [Hash]
+ attr_accessor :default_headers
+
+ # Initializes the ApiClient
+ # @option config [Configuration] Configuration for initializing the object, default to Configuration.default
+ def initialize(config = Configuration.default)
+ @config = config
+ @user_agent = "OpenAPI-Generator/#{VERSION}/ruby"
+ @default_headers = {
+ 'Content-Type' => 'application/json',
+ 'User-Agent' => @user_agent
+ }
+ end
+
+ def self.default
+ @@default ||= ApiClient.new
+ end
+
+ # Call an API with given options.
+ #
+ # @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
+ # the data deserialized from response body (could be nil), response status code and response headers.
+ def call_api(http_method, path, opts = {})
+ stream = nil
+ begin
+ response = connection(opts).public_send(http_method.to_sym.downcase) do |req|
+ request = build_request(http_method, path, req, opts)
+ stream = download_file(request) if opts[:return_type] == 'File' || opts[:return_type] == 'Binary'
+ end
+
+ if config.debugging
+ config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
+ end
+
+ unless response.success?
+ if response.status == 0 && response.respond_to?(:return_message)
+ # Errors from libcurl will be made visible here
+ fail ApiError.new(code: 0,
+ message: response.return_message)
+ else
+ fail ApiError.new(code: response.status,
+ response_headers: response.headers,
+ response_body: response.body),
+ response.reason_phrase
+ end
+ end
+ rescue Faraday::TimeoutError
+ fail ApiError.new('Connection timed out')
+ rescue Faraday::ConnectionFailed
+ fail ApiError.new('Connection failed')
+ end
+
+ if opts[:return_type] == 'File' || opts[:return_type] == 'Binary'
+ data = deserialize_file(response, stream)
+ elsif opts[:return_type]
+ data = deserialize(response, opts[:return_type])
+ else
+ data = nil
+ end
+ return data, response.status, response.headers
+ end
+
+ # Builds the HTTP request
+ #
+ # @param [String] http_method HTTP method/verb (e.g. POST)
+ # @param [String] path URL path (e.g. /account/new)
+ # @option opts [Hash] :header_params Header parameters
+ # @option opts [Hash] :query_params Query parameters
+ # @option opts [Hash] :form_params Query parameters
+ # @option opts [Object] :body HTTP body (JSON/XML)
+ # @return [Faraday::Request] A Faraday Request
+ def build_request(http_method, path, request, opts = {})
+ url = build_request_url(path, opts)
+ http_method = http_method.to_sym.downcase
+
+ header_params = @default_headers.merge(opts[:header_params] || {})
+ query_params = opts[:query_params] || {}
+ form_params = opts[:form_params] || {}
+
+ update_params_for_auth! header_params, query_params, opts[:auth_names]
+
+ if [:post, :patch, :put, :delete].include?(http_method)
+ req_body = build_request_body(header_params, form_params, opts[:body])
+ if config.debugging
+ config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
+ end
+ end
+ request.headers = header_params
+ request.body = req_body
+
+ # Overload default options only if provided
+ request.options.params_encoder = config.params_encoder if config.params_encoder
+ request.options.timeout = config.timeout if config.timeout
+
+ request.url url
+ request.params = query_params
+ request
+ end
+
+ # Builds the HTTP request body
+ #
+ # @param [Hash] header_params Header parameters
+ # @param [Hash] form_params Query parameters
+ # @param [Object] body HTTP body (JSON/XML)
+ # @return [String] HTTP body data in the form of string
+ def build_request_body(header_params, form_params, body)
+ # http form
+ if header_params['Content-Type'] == 'application/x-www-form-urlencoded'
+ data = URI.encode_www_form(form_params)
+ elsif header_params['Content-Type'] == 'multipart/form-data'
+ data = {}
+ form_params.each do |key, value|
+ case value
+ when ::File, ::Tempfile
+ data[key] = Faraday::FilePart.new(value.path, Marcel::MimeType.for(Pathname.new(value.path)))
+ when ::Array, nil
+ # let Faraday handle Array and nil parameters
+ data[key] = value
+ else
+ data[key] = value.to_s
+ end
+ end
+ elsif body
+ data = body.is_a?(String) ? body : body.to_json
+ else
+ data = nil
+ end
+ data
+ end
+
+ def download_file(request)
+ stream = []
+
+ # handle streaming Responses
+ request.options.on_data = Proc.new do |chunk, overall_received_bytes|
+ stream << chunk
+ end
+ stream
+ end
+
+ def deserialize_file(response, stream)
+ body = response.body
+ if @config.return_binary_data == true
+ # return byte stream
+ encoding = body.encoding
+ stream.join.force_encoding(encoding)
+ else
+ # return file instead of binary data
+ content_disposition = response.headers['Content-Disposition']
+ if content_disposition && content_disposition =~ /filename=/i
+ filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
+ prefix = sanitize_filename(filename)
+ else
+ prefix = 'download-'
+ end
+ prefix = prefix + '-' unless prefix.end_with?('-')
+ encoding = body.encoding
+ tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
+ tempfile.write(stream.join.force_encoding(encoding))
+ tempfile.close
+ config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\
+ "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\
+ "will be deleted automatically with GC. It's also recommended to delete the temp file "\
+ "explicitly with `tempfile.delete`"
+ tempfile
+ end
+ end
+
+ def connection(opts)
+ opts[:header_params]['Content-Type'] == 'multipart/form-data' ? connection_multipart : connection_regular
+ end
+
+ def connection_multipart
+ @connection_multipart ||= build_connection do |conn|
+ conn.request :multipart
+ conn.request :url_encoded
+ end
+ end
+
+ def connection_regular
+ @connection_regular ||= build_connection
+ end
+
+ def build_connection
+ Faraday.new(url: config.base_url, ssl: ssl_options, proxy: config.proxy) do |conn|
+ basic_auth(conn)
+ config.configure_middleware(conn)
+ yield(conn) if block_given?
+ conn.adapter(Faraday.default_adapter)
+ config.configure_connection(conn)
+ end
+ end
+
+ def ssl_options
+ {
+ ca_file: config.ssl_ca_file,
+ verify: config.ssl_verify,
+ verify_mode: config.ssl_verify_mode,
+ client_cert: config.ssl_client_cert,
+ client_key: config.ssl_client_key
+ }
+ end
+
+ def basic_auth(conn)
+ if config.username && config.password
+ if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0')
+ conn.request(:authorization, :basic, config.username, config.password)
+ else
+ conn.request(:basic_auth, config.username, config.password)
+ end
+ end
+ end
+
+ # Check if the given MIME is a JSON MIME.
+ # JSON MIME examples:
+ # application/json
+ # application/json; charset=UTF8
+ # APPLICATION/JSON
+ # */*
+ # @param [String] mime MIME
+ # @return [Boolean] True if the MIME is application/json
+ def json_mime?(mime)
+ (mime == '*/*') || !(mime =~ /Application\/.*json(?!p)(;.*)?/i).nil?
+ end
+
+ # Deserialize the response to the given return type.
+ #
+ # @param [Response] response HTTP response
+ # @param [String] return_type some examples: "User", "Array", "Hash"
+ def deserialize(response, return_type)
+ body = response.body
+ return nil if body.nil? || body.empty?
+
+ # return response body directly for String return type
+ return body.to_s if return_type == 'String'
+
+ # ensuring a default content type
+ content_type = response.headers['Content-Type'] || 'application/json'
+
+ fail "Content-Type is not supported: #{content_type}" unless json_mime?(content_type)
+
+ begin
+ data = JSON.parse("[#{body}]", :symbolize_names => true)[0]
+ rescue JSON::ParserError => e
+ if %w(String Date Time).include?(return_type)
+ data = body
+ else
+ raise e
+ end
+ end
+
+ convert_to_type data, return_type
+ end
+
+ # Convert data to the given return type.
+ # @param [Object] data Data to be converted
+ # @param [String] return_type Return type
+ # @return [Mixed] Data in a particular type
+ def convert_to_type(data, return_type)
+ return nil if data.nil?
+ case return_type
+ when 'String'
+ data.to_s
+ when 'Integer'
+ data.to_i
+ when 'Float'
+ data.to_f
+ when 'Boolean'
+ data == true
+ when 'Time'
+ # parse date time (expecting ISO 8601 format)
+ Time.parse data
+ when 'Date'
+ # parse date time (expecting ISO 8601 format)
+ Date.parse data
+ when 'Object'
+ # generic object (usually a Hash), return directly
+ data
+ when /\AArray<(.+)>\z/
+ # e.g. Array
+ sub_type = $1
+ data.map { |item| convert_to_type(item, sub_type) }
+ when /\AHash\\z/
+ # e.g. Hash
+ sub_type = $1
+ {}.tap do |hash|
+ data.each { |k, v| hash[k] = convert_to_type(v, sub_type) }
+ end
+ else
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(return_type)
+ klass.respond_to?(:openapi_one_of) ? klass.build(data) : klass.build_from_hash(data)
+ end
+ end
+
+ # Sanitize filename by removing path.
+ # e.g. ../../sun.gif becomes sun.gif
+ #
+ # @param [String] filename the filename to be sanitized
+ # @return [String] the sanitized filename
+ def sanitize_filename(filename)
+ filename.gsub(/.*[\/\\]/, '')
+ end
+
+ def build_request_url(path, opts = {})
+ # Add leading and trailing slashes to path
+ path = "/#{path}".gsub(/\/+/, '/')
+ @config.base_url(opts[:operation]) + path
+ end
+
+ # Update header and query params based on authentication settings.
+ #
+ # @param [Hash] header_params Header parameters
+ # @param [Hash] query_params Query parameters
+ # @param [String] auth_names Authentication scheme name
+ def update_params_for_auth!(header_params, query_params, auth_names)
+ Array(auth_names).each do |auth_name|
+ auth_setting = @config.auth_settings[auth_name]
+ next unless auth_setting
+ case auth_setting[:in]
+ when 'header' then header_params[auth_setting[:key]] = auth_setting[:value]
+ when 'query' then query_params[auth_setting[:key]] = auth_setting[:value]
+ else fail ArgumentError, 'Authentication token must be in `query` or `header`'
+ end
+ end
+ end
+
+ # Sets user agent in HTTP header
+ #
+ # @param [String] user_agent User agent (e.g. openapi-generator/ruby/1.0.0)
+ def user_agent=(user_agent)
+ @user_agent = user_agent
+ @default_headers['User-Agent'] = @user_agent
+ end
+
+ # Return Accept header based on an array of accepts provided.
+ # @param [Array] accepts array for Accept
+ # @return [String] the Accept header (e.g. application/json)
+ def select_header_accept(accepts)
+ return nil if accepts.nil? || accepts.empty?
+ # use JSON when present, otherwise use all of the provided
+ json_accept = accepts.find { |s| json_mime?(s) }
+ json_accept || accepts.join(',')
+ end
+
+ # Return Content-Type header based on an array of content types provided.
+ # @param [Array] content_types array for Content-Type
+ # @return [String] the Content-Type header (e.g. application/json)
+ def select_header_content_type(content_types)
+ # return nil by default
+ return if content_types.nil? || content_types.empty?
+ # use JSON when present, otherwise use the first one
+ json_content_type = content_types.find { |s| json_mime?(s) }
+ json_content_type || content_types.first
+ end
+
+ # Convert object (array, hash, object, etc) to JSON string.
+ # @param [Object] model object to be converted into JSON string
+ # @return [String] JSON string representation of the object
+ def object_to_http_body(model)
+ return model if model.nil? || model.is_a?(String)
+ local_body = nil
+ if model.is_a?(Array)
+ local_body = model.map { |m| object_to_hash(m) }
+ else
+ local_body = object_to_hash(model)
+ end
+ local_body.to_json
+ end
+
+ # Convert object(non-array) to hash.
+ # @param [Object] obj object to be converted into JSON string
+ # @return [String] JSON string representation of the object
+ def object_to_hash(obj)
+ if obj.respond_to?(:to_hash)
+ obj.to_hash
+ else
+ obj
+ end
+ end
+
+ # Build parameter value according to the given collection format.
+ # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi
+ def build_collection_param(param, collection_format)
+ case collection_format
+ when :csv
+ param.join(',')
+ when :ssv
+ param.join(' ')
+ when :tsv
+ param.join("\t")
+ when :pipes
+ param.join('|')
+ when :multi
+ # return the array directly as typhoeus will handle it as expected
+ param
+ else
+ fail "unknown collection format: #{collection_format.inspect}"
+ end
+ end
+ end
+end
diff --git a/lib/coinbase/client/api_error.rb b/lib/coinbase/client/api_error.rb
new file mode 100644
index 00000000..70c6b145
--- /dev/null
+++ b/lib/coinbase/client/api_error.rb
@@ -0,0 +1,58 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+module Coinbase::Client
+ class ApiError < StandardError
+ attr_reader :code, :response_headers, :response_body
+
+ # Usage examples:
+ # ApiError.new
+ # ApiError.new("message")
+ # ApiError.new(:code => 500, :response_headers => {}, :response_body => "")
+ # ApiError.new(:code => 404, :message => "Not Found")
+ def initialize(arg = nil)
+ if arg.is_a? Hash
+ if arg.key?(:message) || arg.key?('message')
+ super(arg[:message] || arg['message'])
+ else
+ super arg
+ end
+
+ arg.each do |k, v|
+ instance_variable_set "@#{k}", v
+ end
+ else
+ super arg
+ @message = arg
+ end
+ end
+
+ # Override to_s to display a friendly error message
+ def to_s
+ message
+ end
+
+ def message
+ if @message.nil?
+ msg = "Error message: the server returns an error"
+ else
+ msg = @message
+ end
+
+ msg += "\nHTTP status code: #{code}" if code
+ msg += "\nResponse headers: #{response_headers}" if response_headers
+ msg += "\nResponse body: #{response_body}" if response_body
+
+ msg
+ end
+ end
+end
diff --git a/lib/coinbase/client/configuration.rb b/lib/coinbase/client/configuration.rb
new file mode 100644
index 00000000..eeaa0719
--- /dev/null
+++ b/lib/coinbase/client/configuration.rb
@@ -0,0 +1,375 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+module Coinbase::Client
+ class Configuration
+ # Defines url scheme
+ attr_accessor :scheme
+
+ # Defines url host
+ attr_accessor :host
+
+ # Defines url base path
+ attr_accessor :base_path
+
+ # Define server configuration index
+ attr_accessor :server_index
+
+ # Define server operation configuration index
+ attr_accessor :server_operation_index
+
+ # Default server variables
+ attr_accessor :server_variables
+
+ # Default server operation variables
+ attr_accessor :server_operation_variables
+
+ # Defines API keys used with API Key authentications.
+ #
+ # @return [Hash] key: parameter name, value: parameter value (API key)
+ #
+ # @example parameter name is "api_key", API key is "xxx" (e.g. "api_key=xxx" in query string)
+ # config.api_key['api_key'] = 'xxx'
+ attr_accessor :api_key
+
+ # Defines API key prefixes used with API Key authentications.
+ #
+ # @return [Hash] key: parameter name, value: API key prefix
+ #
+ # @example parameter name is "Authorization", API key prefix is "Token" (e.g. "Authorization: Token xxx" in headers)
+ # config.api_key_prefix['api_key'] = 'Token'
+ attr_accessor :api_key_prefix
+
+ # Defines the username used with HTTP basic authentication.
+ #
+ # @return [String]
+ attr_accessor :username
+
+ # Defines the password used with HTTP basic authentication.
+ #
+ # @return [String]
+ attr_accessor :password
+
+ # Defines the access token (Bearer) used with OAuth2.
+ attr_accessor :access_token
+
+ # Defines a Proc used to fetch or refresh access tokens (Bearer) used with OAuth2.
+ # Overrides the access_token if set
+ # @return [Proc]
+ attr_accessor :access_token_getter
+
+ # Set this to return data as binary instead of downloading a temp file. When enabled (set to true)
+ # HTTP responses with return type `File` will be returned as a stream of binary data.
+ # Default to false.
+ attr_accessor :return_binary_data
+
+ # Set this to enable/disable debugging. When enabled (set to true), HTTP request/response
+ # details will be logged with `logger.debug` (see the `logger` attribute).
+ # Default to false.
+ #
+ # @return [true, false]
+ attr_accessor :debugging
+
+ # Defines the logger used for debugging.
+ # Default to `Rails.logger` (when in Rails) or logging to STDOUT.
+ #
+ # @return [#debug]
+ attr_accessor :logger
+
+ # Defines the temporary folder to store downloaded files
+ # (for API endpoints that have file response).
+ # Default to use `Tempfile`.
+ #
+ # @return [String]
+ attr_accessor :temp_folder_path
+
+ # The time limit for HTTP request in seconds.
+ # Default to 0 (never times out).
+ attr_accessor :timeout
+
+ # Set this to false to skip client side validation in the operation.
+ # Default to true.
+ # @return [true, false]
+ attr_accessor :client_side_validation
+
+ ### TLS/SSL setting
+ # Set this to false to skip verifying SSL certificate when calling API from https server.
+ # Default to true.
+ #
+ # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
+ #
+ # @return [true, false]
+ attr_accessor :ssl_verify
+
+ ### TLS/SSL setting
+ # Any `OpenSSL::SSL::` constant (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL.html)
+ #
+ # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
+ #
+ attr_accessor :ssl_verify_mode
+
+ ### TLS/SSL setting
+ # Set this to customize the certificate file to verify the peer.
+ #
+ # @return [String] the path to the certificate file
+ attr_accessor :ssl_ca_file
+
+ ### TLS/SSL setting
+ # Client certificate file (for client certificate)
+ attr_accessor :ssl_client_cert
+
+ ### TLS/SSL setting
+ # Client private key file (for client certificate)
+ attr_accessor :ssl_client_key
+
+ ### Proxy setting
+ # HTTP Proxy settings
+ attr_accessor :proxy
+
+ # Set this to customize parameters encoder of array parameter.
+ # Default to nil. Faraday uses NestedParamsEncoder when nil.
+ #
+ # @see The params_encoder option of Faraday. Related source code:
+ # https://github.com/lostisland/faraday/tree/main/lib/faraday/encoders
+ attr_accessor :params_encoder
+
+
+ attr_accessor :inject_format
+
+ attr_accessor :force_ending_format
+
+ def initialize
+ @scheme = 'https'
+ @host = 'api.cdp.coinbase.com'
+ @base_path = '/platform'
+ @server_index = nil
+ @server_operation_index = {}
+ @server_variables = {}
+ @server_operation_variables = {}
+ @api_key = {}
+ @api_key_prefix = {}
+ @client_side_validation = true
+ @ssl_verify = true
+ @ssl_verify_mode = nil
+ @ssl_ca_file = nil
+ @ssl_client_cert = nil
+ @ssl_client_key = nil
+ @middlewares = Hash.new { |h, k| h[k] = [] }
+ @configure_connection_blocks = []
+ @timeout = 60
+ # return data as binary instead of file
+ @return_binary_data = false
+ @params_encoder = nil
+ @debugging = false
+ @inject_format = false
+ @force_ending_format = false
+ @logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
+
+ yield(self) if block_given?
+ end
+
+ # The default Configuration object.
+ def self.default
+ @@default ||= Configuration.new
+ end
+
+ def configure
+ yield(self) if block_given?
+ end
+
+ def scheme=(scheme)
+ # remove :// from scheme
+ @scheme = scheme.sub(/:\/\//, '')
+ end
+
+ def host=(host)
+ # remove http(s):// and anything after a slash
+ @host = host.sub(/https?:\/\//, '').split('/').first
+ end
+
+ def base_path=(base_path)
+ # Add leading and trailing slashes to base_path
+ @base_path = "/#{base_path}".gsub(/\/+/, '/')
+ @base_path = '' if @base_path == '/'
+ end
+
+ # Returns base URL for specified operation based on server settings
+ def base_url(operation = nil)
+ if operation_server_settings.key?(operation) then
+ index = server_operation_index.fetch(operation, server_index)
+ server_url(index.nil? ? 0 : index, server_operation_variables.fetch(operation, server_variables), operation_server_settings[operation])
+ else
+ server_index.nil? ? "#{scheme}://#{[host, base_path].join('/').gsub(/\/+/, '/')}".sub(/\/+\z/, '') : server_url(server_index, server_variables, nil)
+ end
+ end
+
+ # Gets API key (with prefix if set).
+ # @param [String] param_name the parameter name of API key auth
+ def api_key_with_prefix(param_name, param_alias = nil)
+ key = @api_key[param_name]
+ key = @api_key.fetch(param_alias, key) unless param_alias.nil?
+ if @api_key_prefix[param_name]
+ "#{@api_key_prefix[param_name]} #{key}"
+ else
+ key
+ end
+ end
+
+ # Gets access_token using access_token_getter or uses the static access_token
+ def access_token_with_refresh
+ return access_token if access_token_getter.nil?
+ access_token_getter.call
+ end
+
+ # Gets Basic Auth token string
+ def basic_auth_token
+ 'Basic ' + ["#{username}:#{password}"].pack('m').delete("\r\n")
+ end
+
+ # Returns Auth Settings hash for api client.
+ def auth_settings
+ {
+ }
+ end
+
+ # Returns an array of Server setting
+ def server_settings
+ [
+ {
+ url: "https://api.cdp.coinbase.com/platform",
+ description: "No description provided",
+ }
+ ]
+ end
+
+ def operation_server_settings
+ {
+ }
+ end
+
+ # Returns URL based on server settings
+ #
+ # @param index array index of the server settings
+ # @param variables hash of variable and the corresponding value
+ def server_url(index, variables = {}, servers = nil)
+ servers = server_settings if servers == nil
+
+ # check array index out of bound
+ if (index.nil? || index < 0 || index >= servers.size)
+ fail ArgumentError, "Invalid index #{index} when selecting the server. Must not be nil and must be less than #{servers.size}"
+ end
+
+ server = servers[index]
+ url = server[:url]
+
+ return url unless server.key? :variables
+
+ # go through variable and assign a value
+ server[:variables].each do |name, variable|
+ if variables.key?(name)
+ if (!server[:variables][name].key?(:enum_values) || server[:variables][name][:enum_values].include?(variables[name]))
+ url.gsub! "{" + name.to_s + "}", variables[name]
+ else
+ fail ArgumentError, "The variable `#{name}` in the server URL has invalid value #{variables[name]}. Must be #{server[:variables][name][:enum_values]}."
+ end
+ else
+ # use default value
+ url.gsub! "{" + name.to_s + "}", server[:variables][name][:default_value]
+ end
+ end
+
+ url
+ end
+
+ # Configure Faraday connection directly.
+ #
+ # ```
+ # c.configure_faraday_connection do |conn|
+ # conn.use Faraday::HttpCache, shared_cache: false, logger: logger
+ # conn.response :logger, nil, headers: true, bodies: true, log_level: :debug do |logger|
+ # logger.filter(/(Authorization: )(.*)/, '\1[REDACTED]')
+ # end
+ # end
+ #
+ # c.configure_faraday_connection do |conn|
+ # conn.adapter :typhoeus
+ # end
+ # ```
+ #
+ # @param block [Proc] `#call`able object that takes one arg, the connection
+ def configure_faraday_connection(&block)
+ @configure_connection_blocks << block
+ end
+
+ def configure_connection(conn)
+ @configure_connection_blocks.each do |block|
+ block.call(conn)
+ end
+ end
+
+ # Adds middleware to the stack
+ def use(*middleware)
+ set_faraday_middleware(:use, *middleware)
+ end
+
+ # Adds request middleware to the stack
+ def request(*middleware)
+ set_faraday_middleware(:request, *middleware)
+ end
+
+ # Adds response middleware to the stack
+ def response(*middleware)
+ set_faraday_middleware(:response, *middleware)
+ end
+
+ # Adds Faraday middleware setting information to the stack
+ #
+ # @example Use the `set_faraday_middleware` method to set middleware information
+ # config.set_faraday_middleware(:request, :retry, max: 3, methods: [:get, :post], retry_statuses: [503])
+ # config.set_faraday_middleware(:response, :logger, nil, { bodies: true, log_level: :debug })
+ # config.set_faraday_middleware(:use, Faraday::HttpCache, store: Rails.cache, shared_cache: false)
+ # config.set_faraday_middleware(:insert, 0, FaradayMiddleware::FollowRedirects, { standards_compliant: true, limit: 1 })
+ # config.set_faraday_middleware(:swap, 0, Faraday::Response::Logger)
+ # config.set_faraday_middleware(:delete, Faraday::Multipart::Middleware)
+ #
+ # @see https://github.com/lostisland/faraday/blob/v2.3.0/lib/faraday/rack_builder.rb#L92-L143
+ def set_faraday_middleware(operation, key, *args, &block)
+ unless [:request, :response, :use, :insert, :insert_before, :insert_after, :swap, :delete].include?(operation)
+ fail ArgumentError, "Invalid faraday middleware operation #{operation}. Must be" \
+ " :request, :response, :use, :insert, :insert_before, :insert_after, :swap or :delete."
+ end
+
+ @middlewares[operation] << [key, args, block]
+ end
+ ruby2_keywords(:set_faraday_middleware) if respond_to?(:ruby2_keywords, true)
+
+ # Set up middleware on the connection
+ def configure_middleware(connection)
+ return if @middlewares.empty?
+
+ [:request, :response, :use, :insert, :insert_before, :insert_after, :swap].each do |operation|
+ next unless @middlewares.key?(operation)
+
+ @middlewares[operation].each do |key, args, block|
+ connection.builder.send(operation, key, *args, &block)
+ end
+ end
+
+ if @middlewares.key?(:delete)
+ @middlewares[:delete].each do |key, _args, _block|
+ connection.builder.delete(key)
+ end
+ end
+ end
+
+ end
+end
diff --git a/lib/coinbase/client/models/address.rb b/lib/coinbase/client/models/address.rb
new file mode 100644
index 00000000..a93c1c14
--- /dev/null
+++ b/lib/coinbase/client/models/address.rb
@@ -0,0 +1,273 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ class Address
+ # The ID of the wallet that owns the address
+ attr_accessor :wallet_id
+
+ # The ID of the blockchain network
+ attr_accessor :network_id
+
+ # The public key from which the address is derived.
+ attr_accessor :public_key
+
+ # The onchain address derived on the server-side.
+ attr_accessor :address_id
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'wallet_id' => :'wallet_id',
+ :'network_id' => :'network_id',
+ :'public_key' => :'public_key',
+ :'address_id' => :'address_id'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'wallet_id' => :'String',
+ :'network_id' => :'String',
+ :'public_key' => :'String',
+ :'address_id' => :'String'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::Address` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::Address`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'wallet_id')
+ self.wallet_id = attributes[:'wallet_id']
+ else
+ self.wallet_id = nil
+ end
+
+ if attributes.key?(:'network_id')
+ self.network_id = attributes[:'network_id']
+ else
+ self.network_id = nil
+ end
+
+ if attributes.key?(:'public_key')
+ self.public_key = attributes[:'public_key']
+ else
+ self.public_key = nil
+ end
+
+ if attributes.key?(:'address_id')
+ self.address_id = attributes[:'address_id']
+ else
+ self.address_id = nil
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @wallet_id.nil?
+ invalid_properties.push('invalid value for "wallet_id", wallet_id cannot be nil.')
+ end
+
+ if @network_id.nil?
+ invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')
+ end
+
+ if @public_key.nil?
+ invalid_properties.push('invalid value for "public_key", public_key cannot be nil.')
+ end
+
+ if @address_id.nil?
+ invalid_properties.push('invalid value for "address_id", address_id cannot be nil.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @wallet_id.nil?
+ return false if @network_id.nil?
+ return false if @public_key.nil?
+ return false if @address_id.nil?
+ true
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ wallet_id == o.wallet_id &&
+ network_id == o.network_id &&
+ public_key == o.public_key &&
+ address_id == o.address_id
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [wallet_id, network_id, public_key, address_id].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/models/address_balance_list.rb b/lib/coinbase/client/models/address_balance_list.rb
new file mode 100644
index 00000000..559b0f0c
--- /dev/null
+++ b/lib/coinbase/client/models/address_balance_list.rb
@@ -0,0 +1,275 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ #
+ class AddressBalanceList
+ attr_accessor :data
+
+ # True if this list has another page of items after this one that can be fetched.
+ attr_accessor :has_more
+
+ # The page token to be used to fetch the next page.
+ attr_accessor :next_page
+
+ # The total number of balances for the wallet.
+ attr_accessor :total_count
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'data' => :'data',
+ :'has_more' => :'has_more',
+ :'next_page' => :'next_page',
+ :'total_count' => :'total_count'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'data' => :'Array',
+ :'has_more' => :'Boolean',
+ :'next_page' => :'String',
+ :'total_count' => :'Integer'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::AddressBalanceList` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::AddressBalanceList`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'data')
+ if (value = attributes[:'data']).is_a?(Array)
+ self.data = value
+ end
+ else
+ self.data = nil
+ end
+
+ if attributes.key?(:'has_more')
+ self.has_more = attributes[:'has_more']
+ else
+ self.has_more = nil
+ end
+
+ if attributes.key?(:'next_page')
+ self.next_page = attributes[:'next_page']
+ else
+ self.next_page = nil
+ end
+
+ if attributes.key?(:'total_count')
+ self.total_count = attributes[:'total_count']
+ else
+ self.total_count = nil
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @data.nil?
+ invalid_properties.push('invalid value for "data", data cannot be nil.')
+ end
+
+ if @has_more.nil?
+ invalid_properties.push('invalid value for "has_more", has_more cannot be nil.')
+ end
+
+ if @next_page.nil?
+ invalid_properties.push('invalid value for "next_page", next_page cannot be nil.')
+ end
+
+ if @total_count.nil?
+ invalid_properties.push('invalid value for "total_count", total_count cannot be nil.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @data.nil?
+ return false if @has_more.nil?
+ return false if @next_page.nil?
+ return false if @total_count.nil?
+ true
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ data == o.data &&
+ has_more == o.has_more &&
+ next_page == o.next_page &&
+ total_count == o.total_count
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [data, has_more, next_page, total_count].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/models/address_list.rb b/lib/coinbase/client/models/address_list.rb
new file mode 100644
index 00000000..e88f0be3
--- /dev/null
+++ b/lib/coinbase/client/models/address_list.rb
@@ -0,0 +1,275 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ #
+ class AddressList
+ attr_accessor :data
+
+ # True if this list has another page of items after this one that can be fetched.
+ attr_accessor :has_more
+
+ # The page token to be used to fetch the next page.
+ attr_accessor :next_page
+
+ # The total number of addresses for the wallet.
+ attr_accessor :total_count
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'data' => :'data',
+ :'has_more' => :'has_more',
+ :'next_page' => :'next_page',
+ :'total_count' => :'total_count'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'data' => :'Array',
+ :'has_more' => :'Boolean',
+ :'next_page' => :'String',
+ :'total_count' => :'Integer'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::AddressList` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::AddressList`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'data')
+ if (value = attributes[:'data']).is_a?(Array)
+ self.data = value
+ end
+ else
+ self.data = nil
+ end
+
+ if attributes.key?(:'has_more')
+ self.has_more = attributes[:'has_more']
+ else
+ self.has_more = nil
+ end
+
+ if attributes.key?(:'next_page')
+ self.next_page = attributes[:'next_page']
+ else
+ self.next_page = nil
+ end
+
+ if attributes.key?(:'total_count')
+ self.total_count = attributes[:'total_count']
+ else
+ self.total_count = nil
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @data.nil?
+ invalid_properties.push('invalid value for "data", data cannot be nil.')
+ end
+
+ if @has_more.nil?
+ invalid_properties.push('invalid value for "has_more", has_more cannot be nil.')
+ end
+
+ if @next_page.nil?
+ invalid_properties.push('invalid value for "next_page", next_page cannot be nil.')
+ end
+
+ if @total_count.nil?
+ invalid_properties.push('invalid value for "total_count", total_count cannot be nil.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @data.nil?
+ return false if @has_more.nil?
+ return false if @next_page.nil?
+ return false if @total_count.nil?
+ true
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ data == o.data &&
+ has_more == o.has_more &&
+ next_page == o.next_page &&
+ total_count == o.total_count
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [data, has_more, next_page, total_count].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/models/asset.rb b/lib/coinbase/client/models/asset.rb
new file mode 100644
index 00000000..de3397c4
--- /dev/null
+++ b/lib/coinbase/client/models/asset.rb
@@ -0,0 +1,260 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ # An asset onchain scoped to a particular network, e.g. ETH on base-sepolia, or the USDC ERC20 Token on ethereum-mainnet.
+ class Asset
+ # The ID of the blockchain network
+ attr_accessor :network_id
+
+ # The ID for the asset on the network
+ attr_accessor :asset_id
+
+ # The number of decimals the asset supports. This is used to convert from atomic units to base units.
+ attr_accessor :decimals
+
+ # The optional contract address for the asset. This will be specified for smart contract-based assets, for example ERC20s.
+ attr_accessor :contract_address
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'network_id' => :'network_id',
+ :'asset_id' => :'asset_id',
+ :'decimals' => :'decimals',
+ :'contract_address' => :'contract_address'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'network_id' => :'String',
+ :'asset_id' => :'String',
+ :'decimals' => :'Integer',
+ :'contract_address' => :'String'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::Asset` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::Asset`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'network_id')
+ self.network_id = attributes[:'network_id']
+ else
+ self.network_id = nil
+ end
+
+ if attributes.key?(:'asset_id')
+ self.asset_id = attributes[:'asset_id']
+ else
+ self.asset_id = nil
+ end
+
+ if attributes.key?(:'decimals')
+ self.decimals = attributes[:'decimals']
+ end
+
+ if attributes.key?(:'contract_address')
+ self.contract_address = attributes[:'contract_address']
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @network_id.nil?
+ invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')
+ end
+
+ if @asset_id.nil?
+ invalid_properties.push('invalid value for "asset_id", asset_id cannot be nil.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @network_id.nil?
+ return false if @asset_id.nil?
+ true
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ network_id == o.network_id &&
+ asset_id == o.asset_id &&
+ decimals == o.decimals &&
+ contract_address == o.contract_address
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [network_id, asset_id, decimals, contract_address].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/models/balance.rb b/lib/coinbase/client/models/balance.rb
new file mode 100644
index 00000000..77caf04d
--- /dev/null
+++ b/lib/coinbase/client/models/balance.rb
@@ -0,0 +1,239 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ # The balance of an asset onchain
+ class Balance
+ # The amount in the atomic units of the asset
+ attr_accessor :amount
+
+ attr_accessor :asset
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'amount' => :'amount',
+ :'asset' => :'asset'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'amount' => :'String',
+ :'asset' => :'Asset'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::Balance` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::Balance`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'amount')
+ self.amount = attributes[:'amount']
+ else
+ self.amount = nil
+ end
+
+ if attributes.key?(:'asset')
+ self.asset = attributes[:'asset']
+ else
+ self.asset = nil
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @amount.nil?
+ invalid_properties.push('invalid value for "amount", amount cannot be nil.')
+ end
+
+ if @asset.nil?
+ invalid_properties.push('invalid value for "asset", asset cannot be nil.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @amount.nil?
+ return false if @asset.nil?
+ true
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ amount == o.amount &&
+ asset == o.asset
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [amount, asset].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/models/create_address_request.rb b/lib/coinbase/client/models/create_address_request.rb
new file mode 100644
index 00000000..97f67a83
--- /dev/null
+++ b/lib/coinbase/client/models/create_address_request.rb
@@ -0,0 +1,239 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ class CreateAddressRequest
+ # The public key from which the address will be derived.
+ attr_accessor :public_key
+
+ # An attestation signed by the private key that is associated with the wallet. The attestation will be a hex-encoded signature of a json payload with fields `wallet_id` and `public_key`, signed by the private key associated with the public_key set in the request.
+ attr_accessor :attestation
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'public_key' => :'public_key',
+ :'attestation' => :'attestation'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'public_key' => :'String',
+ :'attestation' => :'String'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::CreateAddressRequest` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::CreateAddressRequest`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'public_key')
+ self.public_key = attributes[:'public_key']
+ else
+ self.public_key = nil
+ end
+
+ if attributes.key?(:'attestation')
+ self.attestation = attributes[:'attestation']
+ else
+ self.attestation = nil
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @public_key.nil?
+ invalid_properties.push('invalid value for "public_key", public_key cannot be nil.')
+ end
+
+ if @attestation.nil?
+ invalid_properties.push('invalid value for "attestation", attestation cannot be nil.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @public_key.nil?
+ return false if @attestation.nil?
+ true
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ public_key == o.public_key &&
+ attestation == o.attestation
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [public_key, attestation].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/models/create_transfer_request.rb b/lib/coinbase/client/models/create_transfer_request.rb
new file mode 100644
index 00000000..40abf7a5
--- /dev/null
+++ b/lib/coinbase/client/models/create_transfer_request.rb
@@ -0,0 +1,273 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ class CreateTransferRequest
+ # The amount to transfer
+ attr_accessor :amount
+
+ # The ID of the blockchain network
+ attr_accessor :network_id
+
+ # The ID of the asset to transfer
+ attr_accessor :asset_id
+
+ # The destination address
+ attr_accessor :destination
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'amount' => :'amount',
+ :'network_id' => :'network_id',
+ :'asset_id' => :'asset_id',
+ :'destination' => :'destination'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'amount' => :'String',
+ :'network_id' => :'String',
+ :'asset_id' => :'String',
+ :'destination' => :'String'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::CreateTransferRequest` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::CreateTransferRequest`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'amount')
+ self.amount = attributes[:'amount']
+ else
+ self.amount = nil
+ end
+
+ if attributes.key?(:'network_id')
+ self.network_id = attributes[:'network_id']
+ else
+ self.network_id = nil
+ end
+
+ if attributes.key?(:'asset_id')
+ self.asset_id = attributes[:'asset_id']
+ else
+ self.asset_id = nil
+ end
+
+ if attributes.key?(:'destination')
+ self.destination = attributes[:'destination']
+ else
+ self.destination = nil
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @amount.nil?
+ invalid_properties.push('invalid value for "amount", amount cannot be nil.')
+ end
+
+ if @network_id.nil?
+ invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')
+ end
+
+ if @asset_id.nil?
+ invalid_properties.push('invalid value for "asset_id", asset_id cannot be nil.')
+ end
+
+ if @destination.nil?
+ invalid_properties.push('invalid value for "destination", destination cannot be nil.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @amount.nil?
+ return false if @network_id.nil?
+ return false if @asset_id.nil?
+ return false if @destination.nil?
+ true
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ amount == o.amount &&
+ network_id == o.network_id &&
+ asset_id == o.asset_id &&
+ destination == o.destination
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [amount, network_id, asset_id, destination].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/models/create_wallet_request.rb b/lib/coinbase/client/models/create_wallet_request.rb
new file mode 100644
index 00000000..06c5f445
--- /dev/null
+++ b/lib/coinbase/client/models/create_wallet_request.rb
@@ -0,0 +1,221 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ class CreateWalletRequest
+ attr_accessor :wallet
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'wallet' => :'wallet'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'wallet' => :'Wallet'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::CreateWalletRequest` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::CreateWalletRequest`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'wallet')
+ self.wallet = attributes[:'wallet']
+ else
+ self.wallet = nil
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @wallet.nil?
+ invalid_properties.push('invalid value for "wallet", wallet cannot be nil.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @wallet.nil?
+ true
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ wallet == o.wallet
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [wallet].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/models/error.rb b/lib/coinbase/client/models/error.rb
new file mode 100644
index 00000000..d58f199e
--- /dev/null
+++ b/lib/coinbase/client/models/error.rb
@@ -0,0 +1,278 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ # An error response from the Coinbase Developer Platform API
+ class Error
+ # A short string representing the reported error. Can be use to handle errors programmatically.
+ attr_accessor :code
+
+ # A human-readable message providing more details about the error.
+ attr_accessor :message
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'code' => :'code',
+ :'message' => :'message'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'code' => :'String',
+ :'message' => :'String'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::Error` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::Error`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'code')
+ self.code = attributes[:'code']
+ else
+ self.code = nil
+ end
+
+ if attributes.key?(:'message')
+ self.message = attributes[:'message']
+ else
+ self.message = nil
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @code.nil?
+ invalid_properties.push('invalid value for "code", code cannot be nil.')
+ end
+
+ if @code.to_s.length > 5000
+ invalid_properties.push('invalid value for "code", the character length must be smaller than or equal to 5000.')
+ end
+
+ if @message.nil?
+ invalid_properties.push('invalid value for "message", message cannot be nil.')
+ end
+
+ if @message.to_s.length > 5000
+ invalid_properties.push('invalid value for "message", the character length must be smaller than or equal to 5000.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @code.nil?
+ return false if @code.to_s.length > 5000
+ return false if @message.nil?
+ return false if @message.to_s.length > 5000
+ true
+ end
+
+ # Custom attribute writer method with validation
+ # @param [Object] code Value to be assigned
+ def code=(code)
+ if code.nil?
+ fail ArgumentError, 'code cannot be nil'
+ end
+
+ if code.to_s.length > 5000
+ fail ArgumentError, 'invalid value for "code", the character length must be smaller than or equal to 5000.'
+ end
+
+ @code = code
+ end
+
+ # Custom attribute writer method with validation
+ # @param [Object] message Value to be assigned
+ def message=(message)
+ if message.nil?
+ fail ArgumentError, 'message cannot be nil'
+ end
+
+ if message.to_s.length > 5000
+ fail ArgumentError, 'invalid value for "message", the character length must be smaller than or equal to 5000.'
+ end
+
+ @message = message
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ code == o.code &&
+ message == o.message
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [code, message].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/models/transfer.rb b/lib/coinbase/client/models/transfer.rb
new file mode 100644
index 00000000..aee6306e
--- /dev/null
+++ b/lib/coinbase/client/models/transfer.rb
@@ -0,0 +1,393 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ # A transfer of an asset from one address to another
+ class Transfer
+ # The ID of the blockchain network
+ attr_accessor :network_id
+
+ # The ID of the wallet that owns the from address
+ attr_accessor :wallet_id
+
+ # The onchain address of the sender
+ attr_accessor :address_id
+
+ # The onchain address of the recipient
+ attr_accessor :destination
+
+ # The amount in the atomic units of the asset
+ attr_accessor :amount
+
+ # The ID of the asset being transferred
+ attr_accessor :asset_id
+
+ # The ID of the transfer
+ attr_accessor :transfer_id
+
+ # The unsigned payload of the transfer. This is the payload that needs to be signed by the sender.
+ attr_accessor :unsigned_payload
+
+ # The status of the transfer
+ attr_accessor :status
+
+ class EnumAttributeValidator
+ attr_reader :datatype
+ attr_reader :allowable_values
+
+ def initialize(datatype, allowable_values)
+ @allowable_values = allowable_values.map do |value|
+ case datatype.to_s
+ when /Integer/i
+ value.to_i
+ when /Float/i
+ value.to_f
+ else
+ value
+ end
+ end
+ end
+
+ def valid?(value)
+ !value || allowable_values.include?(value)
+ end
+ end
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'network_id' => :'network_id',
+ :'wallet_id' => :'wallet_id',
+ :'address_id' => :'address_id',
+ :'destination' => :'destination',
+ :'amount' => :'amount',
+ :'asset_id' => :'asset_id',
+ :'transfer_id' => :'transfer_id',
+ :'unsigned_payload' => :'unsigned_payload',
+ :'status' => :'status'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'network_id' => :'String',
+ :'wallet_id' => :'String',
+ :'address_id' => :'String',
+ :'destination' => :'String',
+ :'amount' => :'String',
+ :'asset_id' => :'String',
+ :'transfer_id' => :'String',
+ :'unsigned_payload' => :'String',
+ :'status' => :'String'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::Transfer` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::Transfer`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'network_id')
+ self.network_id = attributes[:'network_id']
+ else
+ self.network_id = nil
+ end
+
+ if attributes.key?(:'wallet_id')
+ self.wallet_id = attributes[:'wallet_id']
+ else
+ self.wallet_id = nil
+ end
+
+ if attributes.key?(:'address_id')
+ self.address_id = attributes[:'address_id']
+ else
+ self.address_id = nil
+ end
+
+ if attributes.key?(:'destination')
+ self.destination = attributes[:'destination']
+ else
+ self.destination = nil
+ end
+
+ if attributes.key?(:'amount')
+ self.amount = attributes[:'amount']
+ else
+ self.amount = nil
+ end
+
+ if attributes.key?(:'asset_id')
+ self.asset_id = attributes[:'asset_id']
+ else
+ self.asset_id = nil
+ end
+
+ if attributes.key?(:'transfer_id')
+ self.transfer_id = attributes[:'transfer_id']
+ else
+ self.transfer_id = nil
+ end
+
+ if attributes.key?(:'unsigned_payload')
+ self.unsigned_payload = attributes[:'unsigned_payload']
+ else
+ self.unsigned_payload = nil
+ end
+
+ if attributes.key?(:'status')
+ self.status = attributes[:'status']
+ else
+ self.status = nil
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @network_id.nil?
+ invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')
+ end
+
+ if @wallet_id.nil?
+ invalid_properties.push('invalid value for "wallet_id", wallet_id cannot be nil.')
+ end
+
+ if @address_id.nil?
+ invalid_properties.push('invalid value for "address_id", address_id cannot be nil.')
+ end
+
+ if @destination.nil?
+ invalid_properties.push('invalid value for "destination", destination cannot be nil.')
+ end
+
+ if @amount.nil?
+ invalid_properties.push('invalid value for "amount", amount cannot be nil.')
+ end
+
+ if @asset_id.nil?
+ invalid_properties.push('invalid value for "asset_id", asset_id cannot be nil.')
+ end
+
+ if @transfer_id.nil?
+ invalid_properties.push('invalid value for "transfer_id", transfer_id cannot be nil.')
+ end
+
+ if @unsigned_payload.nil?
+ invalid_properties.push('invalid value for "unsigned_payload", unsigned_payload cannot be nil.')
+ end
+
+ if @status.nil?
+ invalid_properties.push('invalid value for "status", status cannot be nil.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @network_id.nil?
+ return false if @wallet_id.nil?
+ return false if @address_id.nil?
+ return false if @destination.nil?
+ return false if @amount.nil?
+ return false if @asset_id.nil?
+ return false if @transfer_id.nil?
+ return false if @unsigned_payload.nil?
+ return false if @status.nil?
+ status_validator = EnumAttributeValidator.new('String', ["pending", "broadcast", "complete", "failed"])
+ return false unless status_validator.valid?(@status)
+ true
+ end
+
+ # Custom attribute writer method checking allowed values (enum).
+ # @param [Object] status Object to be assigned
+ def status=(status)
+ validator = EnumAttributeValidator.new('String', ["pending", "broadcast", "complete", "failed"])
+ unless validator.valid?(status)
+ fail ArgumentError, "invalid value for \"status\", must be one of #{validator.allowable_values}."
+ end
+ @status = status
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ network_id == o.network_id &&
+ wallet_id == o.wallet_id &&
+ address_id == o.address_id &&
+ destination == o.destination &&
+ amount == o.amount &&
+ asset_id == o.asset_id &&
+ transfer_id == o.transfer_id &&
+ unsigned_payload == o.unsigned_payload &&
+ status == o.status
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [network_id, wallet_id, address_id, destination, amount, asset_id, transfer_id, unsigned_payload, status].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/models/transfer_list.rb b/lib/coinbase/client/models/transfer_list.rb
new file mode 100644
index 00000000..2ee3c3cb
--- /dev/null
+++ b/lib/coinbase/client/models/transfer_list.rb
@@ -0,0 +1,275 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ #
+ class TransferList
+ attr_accessor :data
+
+ # True if this list has another page of items after this one that can be fetched.
+ attr_accessor :has_more
+
+ # The page token to be used to fetch the next page.
+ attr_accessor :next_page
+
+ # The total number of transfers for the address in the wallet.
+ attr_accessor :total_count
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'data' => :'data',
+ :'has_more' => :'has_more',
+ :'next_page' => :'next_page',
+ :'total_count' => :'total_count'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'data' => :'Array',
+ :'has_more' => :'Boolean',
+ :'next_page' => :'String',
+ :'total_count' => :'Integer'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::TransferList` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::TransferList`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'data')
+ if (value = attributes[:'data']).is_a?(Array)
+ self.data = value
+ end
+ else
+ self.data = nil
+ end
+
+ if attributes.key?(:'has_more')
+ self.has_more = attributes[:'has_more']
+ else
+ self.has_more = nil
+ end
+
+ if attributes.key?(:'next_page')
+ self.next_page = attributes[:'next_page']
+ else
+ self.next_page = nil
+ end
+
+ if attributes.key?(:'total_count')
+ self.total_count = attributes[:'total_count']
+ else
+ self.total_count = nil
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @data.nil?
+ invalid_properties.push('invalid value for "data", data cannot be nil.')
+ end
+
+ if @has_more.nil?
+ invalid_properties.push('invalid value for "has_more", has_more cannot be nil.')
+ end
+
+ if @next_page.nil?
+ invalid_properties.push('invalid value for "next_page", next_page cannot be nil.')
+ end
+
+ if @total_count.nil?
+ invalid_properties.push('invalid value for "total_count", total_count cannot be nil.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @data.nil?
+ return false if @has_more.nil?
+ return false if @next_page.nil?
+ return false if @total_count.nil?
+ true
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ data == o.data &&
+ has_more == o.has_more &&
+ next_page == o.next_page &&
+ total_count == o.total_count
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [data, has_more, next_page, total_count].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/models/user.rb b/lib/coinbase/client/models/user.rb
new file mode 100644
index 00000000..4bc95a57
--- /dev/null
+++ b/lib/coinbase/client/models/user.rb
@@ -0,0 +1,231 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ class User
+ # The ID of the user
+ attr_accessor :id
+
+ attr_accessor :display_name
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'id' => :'id',
+ :'display_name' => :'display_name'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'id' => :'String',
+ :'display_name' => :'String'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::User` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::User`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'id')
+ self.id = attributes[:'id']
+ else
+ self.id = nil
+ end
+
+ if attributes.key?(:'display_name')
+ self.display_name = attributes[:'display_name']
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @id.nil?
+ invalid_properties.push('invalid value for "id", id cannot be nil.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @id.nil?
+ true
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ id == o.id &&
+ display_name == o.display_name
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [id, display_name].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/models/wallet.rb b/lib/coinbase/client/models/wallet.rb
new file mode 100644
index 00000000..49221f07
--- /dev/null
+++ b/lib/coinbase/client/models/wallet.rb
@@ -0,0 +1,241 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ class Wallet
+ # The server-assigned ID for the wallet.
+ attr_accessor :id
+
+ # The ID of the blockchain network
+ attr_accessor :network_id
+
+ attr_accessor :default_address
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'id' => :'id',
+ :'network_id' => :'network_id',
+ :'default_address' => :'default_address'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'id' => :'String',
+ :'network_id' => :'String',
+ :'default_address' => :'Address'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::Wallet` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::Wallet`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'id')
+ self.id = attributes[:'id']
+ end
+
+ if attributes.key?(:'network_id')
+ self.network_id = attributes[:'network_id']
+ else
+ self.network_id = nil
+ end
+
+ if attributes.key?(:'default_address')
+ self.default_address = attributes[:'default_address']
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @network_id.nil?
+ invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @network_id.nil?
+ true
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ id == o.id &&
+ network_id == o.network_id &&
+ default_address == o.default_address
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [id, network_id, default_address].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/models/wallet_list.rb b/lib/coinbase/client/models/wallet_list.rb
new file mode 100644
index 00000000..71ad7259
--- /dev/null
+++ b/lib/coinbase/client/models/wallet_list.rb
@@ -0,0 +1,275 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+require 'date'
+require 'time'
+
+module Coinbase::Client
+ # Paginated list of wallets
+ class WalletList
+ attr_accessor :data
+
+ # True if this list has another page of items after this one that can be fetched.
+ attr_accessor :has_more
+
+ # The page token to be used to fetch the next page.
+ attr_accessor :next_page
+
+ # The total number of wallets
+ attr_accessor :total_count
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'data' => :'data',
+ :'has_more' => :'has_more',
+ :'next_page' => :'next_page',
+ :'total_count' => :'total_count'
+ }
+ end
+
+ # Returns all the JSON keys this model knows about
+ def self.acceptable_attributes
+ attribute_map.values
+ end
+
+ # Attribute type mapping.
+ def self.openapi_types
+ {
+ :'data' => :'Array',
+ :'has_more' => :'Boolean',
+ :'next_page' => :'String',
+ :'total_count' => :'Integer'
+ }
+ end
+
+ # List of attributes with nullable: true
+ def self.openapi_nullable
+ Set.new([
+ ])
+ end
+
+ # Initializes the object
+ # @param [Hash] attributes Model attributes in the form of hash
+ def initialize(attributes = {})
+ if (!attributes.is_a?(Hash))
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::WalletList` initialize method"
+ end
+
+ # check to see if the attribute exists and convert string to symbol for hash key
+ attributes = attributes.each_with_object({}) { |(k, v), h|
+ if (!self.class.attribute_map.key?(k.to_sym))
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::WalletList`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
+ end
+ h[k.to_sym] = v
+ }
+
+ if attributes.key?(:'data')
+ if (value = attributes[:'data']).is_a?(Array)
+ self.data = value
+ end
+ else
+ self.data = nil
+ end
+
+ if attributes.key?(:'has_more')
+ self.has_more = attributes[:'has_more']
+ else
+ self.has_more = nil
+ end
+
+ if attributes.key?(:'next_page')
+ self.next_page = attributes[:'next_page']
+ else
+ self.next_page = nil
+ end
+
+ if attributes.key?(:'total_count')
+ self.total_count = attributes[:'total_count']
+ else
+ self.total_count = nil
+ end
+ end
+
+ # Show invalid properties with the reasons. Usually used together with valid?
+ # @return Array for valid properties with the reasons
+ def list_invalid_properties
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties = Array.new
+ if @data.nil?
+ invalid_properties.push('invalid value for "data", data cannot be nil.')
+ end
+
+ if @has_more.nil?
+ invalid_properties.push('invalid value for "has_more", has_more cannot be nil.')
+ end
+
+ if @next_page.nil?
+ invalid_properties.push('invalid value for "next_page", next_page cannot be nil.')
+ end
+
+ if @total_count.nil?
+ invalid_properties.push('invalid value for "total_count", total_count cannot be nil.')
+ end
+
+ invalid_properties
+ end
+
+ # Check to see if the all the properties in the model are valid
+ # @return true if the model is valid
+ def valid?
+ warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @data.nil?
+ return false if @has_more.nil?
+ return false if @next_page.nil?
+ return false if @total_count.nil?
+ true
+ end
+
+ # Checks equality by comparing each attribute.
+ # @param [Object] Object to be compared
+ def ==(o)
+ return true if self.equal?(o)
+ self.class == o.class &&
+ data == o.data &&
+ has_more == o.has_more &&
+ next_page == o.next_page &&
+ total_count == o.total_count
+ end
+
+ # @see the `==` method
+ # @param [Object] Object to be compared
+ def eql?(o)
+ self == o
+ end
+
+ # Calculates hash code according to all attributes.
+ # @return [Integer] Hash code
+ def hash
+ [data, has_more, next_page, total_count].hash
+ end
+
+ # Builds the object from hash
+ # @param [Hash] attributes Model attributes in the form of hash
+ # @return [Object] Returns the model itself
+ def self.build_from_hash(attributes)
+ return nil unless attributes.is_a?(Hash)
+ attributes = attributes.transform_keys(&:to_sym)
+ transformed_hash = {}
+ openapi_types.each_pair do |key, type|
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = nil
+ elsif type =~ /\AArray<(.*)>/i
+ # check to ensure the input is an array given that the attribute
+ # is documented as an array but the input is not
+ if attributes[attribute_map[key]].is_a?(Array)
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
+ end
+ elsif !attributes[attribute_map[key]].nil?
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
+ end
+ end
+ new(transformed_hash)
+ end
+
+ # Deserializes the data based on type
+ # @param string type Data type
+ # @param string value Value to be deserialized
+ # @return [Object] Deserialized data
+ def self._deserialize(type, value)
+ case type.to_sym
+ when :Time
+ Time.parse(value)
+ when :Date
+ Date.parse(value)
+ when :String
+ value.to_s
+ when :Integer
+ value.to_i
+ when :Float
+ value.to_f
+ when :Boolean
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
+ true
+ else
+ false
+ end
+ when :Object
+ # generic object (usually a Hash), return directly
+ value
+ when /\AArray<(?.+)>\z/
+ inner_type = Regexp.last_match[:inner_type]
+ value.map { |v| _deserialize(inner_type, v) }
+ when /\AHash<(?.+?), (?.+)>\z/
+ k_type = Regexp.last_match[:k_type]
+ v_type = Regexp.last_match[:v_type]
+ {}.tap do |hash|
+ value.each do |k, v|
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
+ end
+ end
+ else # model
+ # models (e.g. Pet) or oneOf
+ klass = Coinbase::Client.const_get(type)
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
+ end
+ end
+
+ # Returns the string representation of the object
+ # @return [String] String presentation of the object
+ def to_s
+ to_hash.to_s
+ end
+
+ # to_body is an alias to to_hash (backward compatibility)
+ # @return [Hash] Returns the object in the form of hash
+ def to_body
+ to_hash
+ end
+
+ # Returns the object in the form of hash
+ # @return [Hash] Returns the object in the form of hash
+ def to_hash
+ hash = {}
+ self.class.attribute_map.each_pair do |attr, param|
+ value = self.send(attr)
+ if value.nil?
+ is_nullable = self.class.openapi_nullable.include?(attr)
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param] = _to_hash(value)
+ end
+ hash
+ end
+
+ # Outputs non-array value in the form of hash
+ # For object, use to_hash. Otherwise, just return the value
+ # @param [Object] value Any valid value
+ # @return [Hash] Returns the value in the form of hash
+ def _to_hash(value)
+ if value.is_a?(Array)
+ value.compact.map { |v| _to_hash(v) }
+ elsif value.is_a?(Hash)
+ {}.tap do |hash|
+ value.each { |k, v| hash[k] = _to_hash(v) }
+ end
+ elsif value.respond_to? :to_hash
+ value.to_hash
+ else
+ value
+ end
+ end
+
+ end
+
+end
diff --git a/lib/coinbase/client/version.rb b/lib/coinbase/client/version.rb
new file mode 100644
index 00000000..b9708b21
--- /dev/null
+++ b/lib/coinbase/client/version.rb
@@ -0,0 +1,15 @@
+=begin
+#Coinbase Platform API
+
+#This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
+
+The version of the OpenAPI document: 0.0.1-alpha
+Contact: yuga.cohler@coinbase.com
+Generated by: https://openapi-generator.tech
+Generator version: 7.5.0
+
+=end
+
+module Coinbase::Client
+ VERSION = '0.0.1-alpha'
+end
diff --git a/lib/coinbase/constants.rb b/lib/coinbase/constants.rb
index c38fc998..06195142 100644
--- a/lib/coinbase/constants.rb
+++ b/lib/coinbase/constants.rb
@@ -29,10 +29,14 @@ module Coinbase
# The amount of Gwei per Ether.
GWEI_PER_ETHER = 1_000_000_000
+ # The amount of atomic units of USDC per USDC.
+ ATOMIC_UNITS_PER_USDC = 1_000_000
+
# A map of supported Asset IDs.
SUPPORTED_ASSET_IDS = {
eth: true, # Ether, the native asset of most EVM networks.
gwei: true, # A medium denomination of Ether, typically used in gas prices.
- wei: true # The smallest denomination of Ether.
+ wei: true, # The smallest denomination of Ether.
+ usdc: true # USD Coin, a stablecoin pegged to the US Dollar.
}.freeze
end
diff --git a/lib/coinbase/middleware.rb b/lib/coinbase/middleware.rb
new file mode 100644
index 00000000..dd0d59c3
--- /dev/null
+++ b/lib/coinbase/middleware.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require_relative 'authenticator'
+require_relative 'client/configuration'
+require 'faraday'
+
+module Coinbase
+ # A module for middleware that can be used with Faraday.
+ module Middleware
+ Faraday::Request.register_middleware authenticator: -> { Coinbase::Authenticator }
+
+ # Returns the default middleware configuration for the Coinbase SDK.
+ def self.config
+ Coinbase::Client::Configuration.default.tap do |config|
+ config.debugging = true
+ config.host = Coinbase.configuration.api_url
+ config.request(:authenticator)
+ end
+ end
+ end
+end
diff --git a/lib/coinbase/network.rb b/lib/coinbase/network.rb
index 7175786c..4bc7cca6 100644
--- a/lib/coinbase/network.rb
+++ b/lib/coinbase/network.rb
@@ -5,8 +5,8 @@ module Coinbase
class Network
attr_reader :chain_id
- # Returns a new Network object.
- #
+ # Returns a new Network object. Do not use this method directly. Instead, use the Network constants defined in
+ # the Coinbase module.
# @param network_id [Symbol] The Network ID
# @param display_name [String] The Network's display name
# @param protocol_family [String] The protocol family to which the Network belongs
diff --git a/lib/coinbase/transfer.rb b/lib/coinbase/transfer.rb
index dfbe69d6..8930e000 100644
--- a/lib/coinbase/transfer.rb
+++ b/lib/coinbase/transfer.rb
@@ -3,15 +3,14 @@
require_relative 'constants'
require 'bigdecimal'
require 'eth'
+require 'json'
module Coinbase
# A representation of a Transfer, which moves an amount of an Asset from
# a user-controlled Wallet to another address. The fee is assumed to be paid
- # in the native Asset of the Network. Currently only ETH transfers are supported. Transfers
- # should be created through {link:Wallet#transfer} or {link:Address#transfer}.
+ # in the native Asset of the Network. Transfers should be created through Wallet#transfer or
+ # Address#transfer.
class Transfer
- attr_reader :network_id, :wallet_id, :from_address_id, :amount, :asset_id, :to_address_id
-
# A representation of a Transfer status.
module Status
# The Transfer is awaiting being broadcast to the Network. At this point, transaction
@@ -29,28 +28,59 @@ module Status
FAILED = :failed
end
- # Returns a new Transfer object.
- # @param network_id [Symbol] The ID of the Network on which the Transfer originated
- # @param wallet_id [String] The ID of the Wallet from which the Transfer originated
- # @param from_address_id [String] The ID of the address from which the Transfer originated
- # @param amount [Integer, Float, BigDecimal] The amount of the Asset to send. Integers are interpreted as
- # the smallest denomination of the Asset (e.g. Wei for Ether). Floats and BigDecimals are interpreted as the Asset
- # itself (e.g. Ether).
- # @param asset_id [Symbol] The ID of the Asset being transferred. Currently only ETH is supported.
- # @param to_address_id [String] The address to which the Transfer is being sent
- # @param client [Jimson::Client] (Optional) The JSON RPC client to use for interacting with the Network
- def initialize(network_id, wallet_id, from_address_id, amount, asset_id, to_address_id,
- client: Jimson::Client.new(Coinbase.base_sepolia_rpc_url))
-
- raise ArgumentError, "Unsupported asset: #{asset_id}" if asset_id != :eth
-
- @network_id = network_id
- @wallet_id = wallet_id
- @from_address_id = from_address_id
- @amount = normalize_eth_amount(amount)
- @asset_id = asset_id
- @to_address_id = to_address_id
- @client = client
+ # Returns a new Transfer object. Do not use this method directly. Instead, use Wallet#transfer or
+ # Address#transfer.
+ # @param model [Coinbase::Client::Transfer] The underlying Transfer object
+ def initialize(model)
+ @model = model
+ end
+
+ # Returns the Transfer ID.
+ # @return [String] The Transfer ID
+ def transfer_id
+ @model.transfer_id
+ end
+
+ # Returns the Network ID of the Transfer.
+ # @return [String] The Network ID
+ def network_id
+ @model.network_id
+ end
+
+ # Returns the Wallet ID of the Transfer.
+ # @return [String] The Wallet ID
+ def wallet_id
+ @model.wallet_id
+ end
+
+ # Returns the From Address ID of the Transfer.
+ # @return [String] The From Address ID
+ def from_address_id
+ @model.address_id
+ end
+
+ # Returns the Destination Address ID of the Transfer.
+ # @return [String] The Destination Address ID
+ def destination_address_id
+ @model.destination
+ end
+
+ # Returns the Asset ID of the Transfer.
+ # @return [Symbol] The Asset ID
+ def asset_id
+ @model.asset_id.to_sym
+ end
+
+ # Returns the amount of the asset for the Transfer.
+ # @return [BigDecimal] The amount in units of ETH
+ def amount
+ BigDecimal(@model.amount) / BigDecimal(Coinbase::WEI_PER_ETHER.to_s)
+ end
+
+ # Returns the Unsigned Payload of the Transfer.
+ # @return [String] The Unsigned Payload
+ def unsigned_payload
+ @model.unsigned_payload
end
# Returns the underlying Transfer transaction, creating it if it has not been yet.
@@ -58,18 +88,19 @@ def initialize(network_id, wallet_id, from_address_id, amount, asset_id, to_addr
def transaction
return @transaction unless @transaction.nil?
- nonce = @client.eth_getTransactionCount(@from_address_id.to_s, 'latest').to_i(16)
- gas_price = @client.eth_gasPrice.to_i(16)
+ raw_payload = [unsigned_payload].pack('H*')
+ parsed_payload = JSON.parse(raw_payload)
params = {
- chain_id: BASE_SEPOLIA.chain_id, # TODO: Don't hardcode Base Sepolia.
- nonce: nonce,
- priority_fee: gas_price, # TODO: Optimize this.
- max_gas_fee: gas_price,
- gas_limit: 21_000, # TODO: Handle multiple currencies.
- from: Eth::Address.new(@from_address_id),
- to: Eth::Address.new(@to_address_id),
- value: (@amount * Coinbase::WEI_PER_ETHER).to_i
+ chain_id: parsed_payload['chainId'].to_i(16),
+ nonce: parsed_payload['nonce'].to_i(16),
+ priority_fee: parsed_payload['maxPriorityFeePerGas'].to_i(16),
+ max_gas_fee: parsed_payload['maxFeePerGas'].to_i(16),
+ gas_limit: parsed_payload['gas'].to_i(16), # TODO: Handle multiple currencies.
+ from: Eth::Address.new(from_address_id),
+ to: Eth::Address.new(parsed_payload['to']),
+ value: parsed_payload['value'].to_i(16),
+ data: parsed_payload['input'] || ''
}
@transaction = Eth::Tx::Eip1559.new(Eth::Tx.validate_eip1559_params(params))
@@ -87,7 +118,7 @@ def status
return Status::PENDING
end
- onchain_transaction = @client.eth_getTransactionByHash(transaction_hash)
+ onchain_transaction = Coinbase.configuration.base_sepolia_client.eth_getTransactionByHash(transaction_hash)
if onchain_transaction.nil?
# If the transaction has not been broadcast, it is still pending.
@@ -97,7 +128,7 @@ def status
# broadcast.
Status::BROADCAST
else
- transaction_receipt = @client.eth_getTransactionReceipt(transaction_hash)
+ transaction_receipt = Coinbase.configuration.base_sepolia_client.eth_getTransactionReceipt(transaction_hash)
if transaction_receipt['status'].to_i(16) == 1
Status::COMPLETE
@@ -133,21 +164,5 @@ def transaction_hash
rescue Eth::Signature::SignatureError
nil
end
-
- private
-
- # Normalizes the given Ether amount into a BigDecimal.
- # @param amount [Integer, Float, BigDecimal] The amount to normalize
- # @return [BigDecimal] The normalized amount
- def normalize_eth_amount(amount)
- case amount
- when BigDecimal
- amount
- when Integer, Float
- BigDecimal(amount.to_s)
- else
- raise ArgumentError, "Invalid amount: #{amount}"
- end
- end
end
end
diff --git a/lib/coinbase/user.rb b/lib/coinbase/user.rb
new file mode 100644
index 00000000..b7148716
--- /dev/null
+++ b/lib/coinbase/user.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+require_relative 'client'
+require_relative 'wallet'
+
+module Coinbase
+ # A representation of a User. Users have Wallets, which can hold balances of Assets. Access the default User through
+ # Coinbase#default_user.
+ class User
+ # Returns a new User object. Do not use this method directly. Instead, use Coinbase#default_user.
+ # @param model [Coinbase::Client::User] the underlying User object
+ def initialize(model)
+ @model = model
+ end
+
+ # Returns the User ID.
+ # @return [String] the User ID
+ def user_id
+ @model.id
+ end
+
+ # Creates a new Wallet belonging to the User.
+ # @return [Coinbase::Wallet] the new Wallet
+ def create_wallet
+ create_wallet_request = {
+ wallet: {
+ # TODO: Don't hardcode this.
+ network_id: 'base-sepolia'
+ }
+ }
+ opts = { create_wallet_request: create_wallet_request }
+
+ model = wallets_api.create_wallet(opts)
+
+ Wallet.new(model)
+ end
+
+ # Imports a Wallet belonging to the User.
+ # @param data [Coinbase::Wallet::Data] the Wallet data to import
+ # @return [Coinbase::Wallet] the imported Wallet
+ def import_wallet(data)
+ model = wallets_api.get_wallet(data.wallet_id)
+ address_count = addresses_api.list_addresses(model.id).total_count
+ Wallet.new(model, seed: data.seed, address_count: address_count)
+ end
+
+ # Lists the IDs of the Wallets belonging to the User.
+ # @return [Array] the IDs of the Wallets belonging to the User
+ def list_wallet_ids
+ wallets = wallets_api.list_wallets
+ wallets.data.map(&:id)
+ end
+
+ private
+
+ def addresses_api
+ @addresses_api ||= Coinbase::Client::AddressesApi.new(Coinbase.configuration.api_client)
+ end
+
+ def wallets_api
+ @wallets_api ||= Coinbase::Client::WalletsApi.new(Coinbase.configuration.api_client)
+ end
+ end
+end
diff --git a/lib/coinbase/wallet.rb b/lib/coinbase/wallet.rb
index 1bea9be5..01e27a10 100644
--- a/lib/coinbase/wallet.rb
+++ b/lib/coinbase/wallet.rb
@@ -1,29 +1,31 @@
# frozen_string_literal: true
+require 'digest'
require 'jimson'
+require 'json'
require 'money-tree'
require 'securerandom'
module Coinbase
# A representation of a Wallet. Wallets come with a single default Address, but can expand to have a set of Addresses,
# each of which can hold a balance of one or more Assets. Wallets can create new Addresses, list their addresses,
- # list their balances, and transfer Assets to other Addresses.
+ # list their balances, and transfer Assets to other Addresses. Wallets should be created through User#create_wallet or
+ # User#import_wallet.
class Wallet
- attr_reader :wallet_id, :network_id
-
- # Returns a new Wallet object.
- # @param seed [Integer] (Optional) The seed to use for the Wallet. Expects a 32-byte hexadecimal. If not provided,
- # a new seed will be generated.
- # @param address_count [Integer] (Optional) The number of addresses to generate for the Wallet. If not provided,
- # a single address will be generated.
+ # Returns a new Wallet object. Do not use this method directly. Instead, use User#create_wallet or
+ # User#import_wallet.
+ # @param model [Coinbase::Client::Wallet] The underlying Wallet object
+ # @param seed [String] (Optional) The seed to use for the Wallet. Expects a 32-byte hexadecimal with no 0x prefix.
+ # If not provided, a new seed will be generated.
+ # @param address_count [Integer] (Optional) The number of addresses already registered for the Wallet.
# @param client [Jimson::Client] (Optional) The JSON RPC client to use for interacting with the Network
- def initialize(seed: nil, address_count: 1, client: Jimson::Client.new(Coinbase.base_sepolia_rpc_url))
+ def initialize(model, seed: nil, address_count: 0)
raise ArgumentError, 'Seed must be 32 bytes' if !seed.nil? && seed.length != 64
- raise ArgumentError, 'Address count must be positive' if address_count < 1
+
+ @model = model
@master = seed.nil? ? MoneyTree::Master.new : MoneyTree::Master.new(seed_hex: seed)
- @wallet_id = SecureRandom.uuid
# TODO: Make Network an argument to the constructor.
@network_id = :base_sepolia
@addresses = []
@@ -32,28 +34,49 @@ def initialize(seed: nil, address_count: 1, client: Jimson::Client.new(Coinbase.
@address_path_prefix = "m/44'/60'/0'/0"
@address_index = 0
- @client = client
+ if address_count.positive?
+ address_count.times { derive_address }
+ else
+ create_address
+ # Update the model to reflect the new default address.
+ update_model
+ end
+ end
- address_count.times { create_address }
+ # Returns the Wallet ID.
+ # @return [String] The Wallet ID
+ def wallet_id
+ @model.id
+ end
+
+ # Returns the Network ID of the Wallet.
+ # @return [Symbol] The Network ID
+ def network_id
+ Coinbase.to_sym(@model.network_id)
end
# Creates a new Address in the Wallet.
# @return [Address] The new Address
def create_address
- # TODO: Register with server.
- path = "#{@address_path_prefix}/#{@address_index}"
- private_key = @master.node_for_path(path).private_key.to_hex
- key = Eth::Key.new(priv: private_key)
- address = Address.new(@network_id, key.address.address, @wallet_id, key, client: @client)
- @addresses << address
- @address_index += 1
- address
+ key = derive_key
+ attestation = create_attestation(key)
+ public_key = key.public_key.compressed.unpack1('H*')
+
+ opts = {
+ create_address_request: {
+ public_key: public_key,
+ attestation: attestation
+ }
+ }
+ address_model = addresses_api.create_address(wallet_id, opts)
+
+ cache_address(address_model, key)
end
# Returns the default address of the Wallet.
# @return [Address] The default address
def default_address
- @addresses.first
+ @addresses.find { |address| address.address_id == @model.default_address.address_id }
end
# Returns the Address with the given ID.
@@ -66,25 +89,14 @@ def get_address(address_id)
# Returns the list of Addresses in the Wallet.
# @return [Array] The list of Addresses
def list_addresses
- # TODO: Register with server.
@addresses
end
# Returns the list of balances of this Wallet. Balances are aggregated across all Addresses in the Wallet.
# @return [BalanceMap] The list of balances. The key is the Asset ID, and the value is the balance.
def list_balances
- balance_map = BalanceMap.new
-
- @addresses.each do |address|
- address.list_balances.each do |asset_id, balance|
- balance_map[asset_id] ||= BigDecimal(0)
- current_balance = balance_map[asset_id]
- new_balance = balance + current_balance
- balance_map[asset_id] = new_balance
- end
- end
-
- balance_map
+ response = wallets_api.list_wallet_balances(wallet_id)
+ Coinbase.to_balance_map(response)
end
# Returns the balance of the provided Asset. Balances are aggregated across all Addresses in the Wallet.
@@ -97,17 +109,21 @@ def get_balance(asset_id)
asset_id
end
- eth_balance = list_balances[normalized_asset_id] || BigDecimal(0)
+ response = wallets_api.get_wallet_balance(wallet_id, normalized_asset_id.to_s)
+
+ return BigDecimal('0') if response.nil?
+
+ amount = BigDecimal(response.amount)
case asset_id
when :eth
- eth_balance
+ amount / BigDecimal(Coinbase::WEI_PER_ETHER.to_s)
when :gwei
- eth_balance * Coinbase::GWEI_PER_ETHER
- when :wei
- eth_balance * Coinbase::WEI_PER_ETHER
+ amount / BigDecimal(Coinbase::GWEI_PER_ETHER.to_s)
+ when :usdc
+ amount / BigDecimal(Coinbase::ATOMIC_UNITS_PER_USDC.to_s)
else
- BigDecimal(0)
+ amount
end
end
@@ -132,29 +148,105 @@ def transfer(amount, asset_id, destination)
default_address.transfer(amount, asset_id, destination)
end
- # Exports the Wallet's data to a WalletData object.
- # @return [WalletData] The Wallet data
+ # Exports the Wallet's data to a Data object.
+ # @return [Data] The Wallet data
def export
- WalletData.new(@master.seed_hex, @addresses.length)
+ Data.new(wallet_id: wallet_id, seed: @master.seed_hex)
end
# The data required to recreate a Wallet.
- class WalletData
- attr_reader :seed, :address_count
+ class Data
+ attr_reader :wallet_id, :seed
- # Returns a new WalletData object.
+ # Returns a new Data object.
+ # @param wallet_id [String] The ID of the Wallet
# @param seed [String] The seed of the Wallet
- # @param address_count [Integer] The number of addresses in the Wallet
- def initialize(seed, address_count)
+ def initialize(wallet_id:, seed:)
+ @wallet_id = wallet_id
@seed = seed
- @address_count = address_count
end
+
+ # Converts the Data object to a Hash.
+ # @return [Hash] The Hash representation of the Data object
+ def to_hash
+ { wallet_id: wallet_id, seed: seed }
+ end
+
+ # Creates a Data object from the given Hash.
+ # @param data [Hash] The Hash to create the Data object from
+ # @return [Data] The new Data object
+ def self.from_hash(data)
+ Data.new(wallet_id: data['wallet_id'], seed: data['seed'])
+ end
+ end
+
+ private
+
+ # Derives an already registered Address in the Wallet.
+ # @return [Address] The new Address
+ def derive_address
+ key = derive_key
+
+ address_id = key.address.to_s
+ address_model = addresses_api.get_address(wallet_id, address_id)
+
+ cache_address(address_model, key)
+ end
+
+ # Derives a key for an already registered Address in the Wallet.
+ # @return [Eth::Key] The new key
+ def derive_key
+ path = "#{@address_path_prefix}/#{@address_index}"
+ private_key = @master.node_for_path(path).private_key.to_hex
+ Eth::Key.new(priv: private_key)
+ end
+
+ # Caches an Address on the client-side and increments the address index.
+ # @param address_model [Coinbase::Client::Address] The Address model
+ # @param key [Eth::Key] The private key of the Address
+ # @return [Address] The new Address
+ def cache_address(address_model, key)
+ address = Address.new(address_model, key)
+ @addresses << address
+ @address_index += 1
+ address
+ end
+
+ # Creates an attestation for the Address currently being created.
+ # @param key [Eth::Key] The private key of the Address
+ # @return [String] The attestation
+ def create_attestation(key)
+ public_key = key.public_key.compressed.unpack1('H*')
+ payload = {
+ wallet_id: wallet_id,
+ public_key: public_key
+ }.to_json
+ hashed_payload = Digest::SHA256.digest(payload)
+ signature = key.sign(hashed_payload)
+
+ # The secp256k1 library serializes the signature as R, S, V.
+ # The server expects the signature as V, R, S in the format:
+ # <(byte of 27+public key solution)+4 if compressed >< padded bytes for signature R>
+ # Ruby gem does not add 4 to the recovery byte, so we need to add it here.
+ # Take the last byte (V) and add 4 to it to show signature is compressed.
+ signature_bytes = [signature].pack('H*').unpack('C*')
+ last_byte = signature_bytes.last
+ compressed_last_byte = last_byte + 4
+ new_signature_bytes = [compressed_last_byte] + signature_bytes[0..-2]
+ new_signature_bytes.pack('C*').unpack1('H*')
+ end
+
+ # Updates the Wallet model with the latest data.
+ def update_model
+ @model = wallets_api.get_wallet(wallet_id)
+ end
+
+ def addresses_api
+ @addresses_api ||= Coinbase::Client::AddressesApi.new(Coinbase.configuration.api_client)
end
- # Returns the data required to recreate the Wallet.
- # @return [WalletData] The Wallet data
- def to_data
- WalletData.new(@master.seed_hex, @addresses.length)
+ def wallets_api
+ @wallets_api ||= Coinbase::Client::WalletsApi.new(Coinbase.configuration.api_client)
end
end
end
diff --git a/spec/coinbase/address_spec.rb b/spec/coinbase/address_spec.rb
deleted file mode 100644
index b027e213..00000000
--- a/spec/coinbase/address_spec.rb
+++ /dev/null
@@ -1,141 +0,0 @@
-# frozen_string_literal: true
-
-describe Coinbase::Address do
- let(:key) { Eth::Key.new }
- let(:network_id) { :base_sepolia }
- let(:address_id) { key.address.to_s }
- let(:wallet_id) { SecureRandom.uuid }
- let(:client) { double('Jimson::Client') }
-
- subject(:address) do
- described_class.new(network_id, address_id, wallet_id, key, client: client)
- end
-
- describe '#initialize' do
- it 'initializes a new Address' do
- expect(address).to be_a(Coinbase::Address)
- end
- end
-
- describe '#network_id' do
- it 'returns the network ID' do
- expect(address.network_id).to eq(network_id)
- end
- end
-
- describe '#address_id' do
- it 'returns the address ID' do
- expect(address.address_id).to eq(address_id)
- end
- end
-
- describe '#wallet_id' do
- it 'returns the wallet ID' do
- expect(address.wallet_id).to eq(wallet_id)
- end
- end
-
- describe '#list_balances' do
- before do
- allow(client).to receive(:eth_getBalance).with(address_id, 'latest').and_return('0xde0b6b3a7640000')
- end
-
- it 'returns a hash with an ETH balance' do
- expect(address.list_balances).to eq(eth: BigDecimal('1'))
- end
- end
-
- describe '#get_balance' do
- before do
- allow(client).to receive(:eth_getBalance).with(address_id, 'latest').and_return('0xde0b6b3a7640000')
- end
-
- it 'returns the correct ETH balance' do
- expect(address.get_balance(:eth)).to eq BigDecimal('1')
- end
-
- it 'returns the correct Gwei balance' do
- expect(address.get_balance(:gwei)).to eq BigDecimal('1_000_000_000')
- end
-
- it 'returns the correct Wei balance' do
- expect(address.get_balance(:wei)).to eq BigDecimal('1_000_000_000_000_000_000')
- end
-
- it 'returns 0 for an unsupported asset' do
- expect(address.get_balance(:uni)).to eq BigDecimal('0')
- end
- end
-
- describe '#transfer' do
- let(:amount) { 500_000_000_000_000_000 }
- let(:asset_id) { :wei }
- let(:to_key) { Eth::Key.new }
- let(:to_address_id) { to_key.address.to_s }
- let(:transaction_hash) { '0xdeadbeef' }
- let(:raw_signed_transaction) { '0123456789abcdef' }
- let(:transaction) { double('Transaction', sign: transaction_hash, hex: raw_signed_transaction) }
- let(:transfer) do
- double('Transfer', transaction: transaction)
- end
-
- before do
- allow(client).to receive(:eth_getBalance).with(address_id, 'latest').and_return('0xde0b6b3a7640000')
- allow(Coinbase::Transfer).to receive(:new).and_return(transfer)
- allow(client).to receive(:eth_sendRawTransaction).with("0x#{raw_signed_transaction}").and_return(transaction_hash)
- end
-
- # TODO: Add test case for when the destination is a Wallet.
-
- context 'when the destination is a valid Address' do
- let(:destination) { described_class.new(network_id, to_address_id, wallet_id, to_key, client: client) }
-
- it 'creates a Transfer' do
- expect(address.transfer(amount, asset_id, destination)).to eq(transfer)
- end
- end
-
- context 'when the destination is a valid Address ID' do
- let(:destination) { to_address_id }
-
- it 'creates a Transfer' do
- expect(address.transfer(amount, asset_id, destination)).to eq(transfer)
- end
- end
-
- context 'when the asset is unsupported' do
- it 'raises an ArgumentError' do
- expect { address.transfer(amount, :uni, to_address_id) }.to raise_error(ArgumentError, 'Unsupported asset: uni')
- end
- end
-
- # TODO: Add test case for when the destination is a Wallet.
-
- context 'when the destination Address is on a different network' do
- it 'raises an ArgumentError' do
- expect do
- address.transfer(amount, asset_id, Coinbase::Address.new(:different_network, to_address_id, wallet_id,
- to_key, client: client))
- end.to raise_error(ArgumentError, 'Transfer must be on the same Network')
- end
- end
-
- context 'when the balance is insufficient' do
- before do
- allow(client).to receive(:eth_getBalance).with(address_id, 'latest').and_return('0x0')
- end
-
- it 'raises an ArgumentError' do
- expect do
- address.transfer(amount, asset_id, to_address_id)
- end.to raise_error(ArgumentError, "Insufficient funds: #{amount} requested, but only 0.0 available")
- end
- end
- end
-
- describe '#to_s' do
- it 'returns the address as a string' do
- expect(address.to_s).to eq(address_id)
- end
- end
-end
diff --git a/spec/coinbase/wallet_spec.rb b/spec/coinbase/wallet_spec.rb
deleted file mode 100644
index 54f61223..00000000
--- a/spec/coinbase/wallet_spec.rb
+++ /dev/null
@@ -1,164 +0,0 @@
-# frozen_string_literal: true
-
-describe Coinbase::Wallet do
- let(:client) { double('Jimson::Client') }
- subject(:wallet) { described_class.new(client: client) }
-
- describe '#initialize' do
- it 'initializes a new Wallet' do
- expect(wallet).to be_a(Coinbase::Wallet)
- end
-
- context 'when a seed is provided' do
- let(:seed) { '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f' }
- let(:seed_wallet) { described_class.new(seed: seed, client: client) }
-
- it 'initializes a new Wallet with the provided seed' do
- expect(seed_wallet).to be_a(Coinbase::Wallet)
- end
-
- it 'raises an error for an invalid seed' do
- expect do
- described_class.new(seed: 'invalid', client: client)
- end.to raise_error(ArgumentError, 'Seed must be 32 bytes')
- end
- end
-
- context 'when the address count is provided' do
- let(:address_count) { 5 }
- let(:address_wallet) { described_class.new(address_count: address_count, client: client) }
-
- it 'initializes a new Wallet with the provided address count' do
- expect(address_wallet.list_addresses.length).to eq(address_count)
- end
-
- it 'raises an error for a negative address count' do
- expect do
- described_class.new(address_count: -1, client: client)
- end.to raise_error(ArgumentError, 'Address count must be positive')
- end
- end
- end
-
- describe '#create_address' do
- it 'creates a new address' do
- address = wallet.create_address
- expect(address).to be_a(Coinbase::Address)
- expect(wallet.list_addresses.length).to eq(2)
- expect(address).not_to eq(wallet.default_address)
- end
- end
-
- describe '#default_address' do
- it 'returns the first address' do
- expect(wallet.default_address).to eq(wallet.list_addresses.first)
- end
- end
-
- describe '#get_address' do
- it 'returns the correct address' do
- default_address = wallet.default_address
- expect(wallet.get_address(default_address.address_id)).to eq(default_address)
- end
- end
-
- describe '#list_addresses' do
- it 'contains one address' do
- expect(wallet.list_addresses.length).to eq(1)
- end
- end
-
- describe '#list_balances' do
- before do
- expect(wallet.default_address).to receive(:list_balances).and_return({ eth: BigDecimal(1) })
- end
-
- it 'returns a hash with an ETH balance' do
- expect(wallet.list_balances).to eq({ eth: BigDecimal(1) })
- end
- end
-
- describe '#get_balance' do
- before do
- expect(wallet.default_address).to receive(:list_balances).and_return({ eth: BigDecimal(5) })
- end
-
- it 'returns the correct ETH balance' do
- expect(wallet.get_balance(:eth)).to eq(BigDecimal(5))
- end
-
- it 'returns the correct Gwei balance' do
- expect(wallet.get_balance(:gwei)).to eq(BigDecimal(5 * Coinbase::GWEI_PER_ETHER))
- end
-
- it 'returns the correct Wei balance' do
- expect(wallet.get_balance(:wei)).to eq(BigDecimal(5 * Coinbase::WEI_PER_ETHER))
- end
- end
-
- describe '#transfer' do
- let(:transfer) { double('Coinbase::Transfer') }
- let(:amount) { 5 }
- let(:asset_id) { :eth }
-
- context 'when the destination is a Wallet' do
- let(:destination) { described_class.new(client: client) }
- let(:to_address_id) { destination.default_address.address_id }
-
- before do
- expect(wallet.default_address).to receive(:transfer).with(amount, asset_id, to_address_id).and_return(transfer)
- end
-
- it 'creates a transfer to the default address ID' do
- expect(wallet.transfer(amount, asset_id, destination)).to eq(transfer)
- end
- end
-
- context 'when the desination is an Address' do
- let(:destination) { wallet.create_address }
- let(:to_address_id) { destination.address_id }
-
- before do
- expect(wallet.default_address).to receive(:transfer).with(amount, asset_id, to_address_id).and_return(transfer)
- end
-
- it 'creates a transfer to the address ID' do
- expect(wallet.transfer(amount, asset_id, destination)).to eq(transfer)
- end
- end
-
- context 'when the destination is a String' do
- let(:destination) { '0x1234567890' }
-
- before do
- expect(wallet.default_address).to receive(:transfer).with(amount, asset_id, destination).and_return(transfer)
- end
-
- it 'creates a transfer to the address ID' do
- expect(wallet.transfer(amount, asset_id, destination)).to eq(transfer)
- end
- end
- end
-
- describe '#export' do
- let(:seed) { '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f' }
- let(:address_count) { 5 }
- let(:seed_wallet) { described_class.new(seed: seed, address_count: address_count, client: client) }
-
- it 'exports the Wallet data' do
- wallet_data = seed_wallet.export
- expect(wallet_data).to be_a(Coinbase::Wallet::WalletData)
- expect(wallet_data.seed).to eq(seed)
- expect(wallet_data.address_count).to eq(address_count)
- end
-
- it 'allows for re-creation of a Wallet' do
- wallet_data = seed_wallet.export
- new_wallet = described_class.new(seed: wallet_data.seed, address_count: wallet_data.address_count, client: client)
- expect(new_wallet.list_addresses.length).to eq(address_count)
- new_wallet.list_addresses.each_with_index do |address, i|
- expect(address.address_id).to eq(seed_wallet.list_addresses[i].address_id)
- end
- end
- end
-end
diff --git a/spec/coinbase_spec.rb b/spec/coinbase_spec.rb
deleted file mode 100644
index 0e1d33ac..00000000
--- a/spec/coinbase_spec.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-describe Coinbase do
- describe '#base_sepolia_rpc_url' do
- it 'returns the Base Sepolia RPC URL' do
- expect(Coinbase.base_sepolia_rpc_url).to eq('https://sepolia.base.org')
- end
- end
-
- describe '#base_sepolia_rpc_url=' do
- it 'sets the Base Sepolia RPC URL' do
- Coinbase.base_sepolia_rpc_url = 'https://not-sepolia.base.org'
- expect(Coinbase.base_sepolia_rpc_url).to eq('https://not-sepolia.base.org')
- end
- end
-end
diff --git a/spec/e2e/production.rb b/spec/e2e/production.rb
new file mode 100644
index 00000000..0e7fee33
--- /dev/null
+++ b/spec/e2e/production.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'dotenv'
+Dotenv.load
+
+describe Coinbase do
+ describe 'v0.0.2 SDK' do
+ it 'behaves as expected' do
+ # GitHub secrets truncate newlines as whitespace, so we need to replace them.
+ # See https://github.com/github/docs/issues/14207
+ api_key_name = ENV['API_KEY_NAME'].gsub('\n', "\n")
+ api_key_private_key = ENV['API_KEY_PRIVATE_KEY'].gsub('\n', "\n")
+ Coinbase.configure do |config|
+ config.api_key_name = api_key_name
+ config.api_key_private_key = api_key_private_key
+ end
+
+ puts 'Fetching default user...'
+ u = Coinbase.default_user
+ expect(u).not_to be_nil
+ puts "Fetched default user with ID: #{u.user_id}"
+
+ puts 'Creating new wallet...'
+ w1 = u.create_wallet
+ expect(w1).not_to be_nil
+ puts "Created new wallet with ID: #{w1.wallet_id}, default address: #{w1.default_address}"
+
+ puts 'Importing wallet with balance...'
+ data_string = ENV['WALLET_DATA']
+ data_hash = JSON.parse(data_string)
+ data = Coinbase::Wallet::Data.from_hash(data_hash)
+ w2 = u.import_wallet(data)
+ expect(w2).not_to be_nil
+ puts "Imported wallet with ID: #{w2.wallet_id}, default address: #{w2.default_address}"
+
+ puts 'Listing addresses...'
+ addresses = w2.list_addresses
+ expect(addresses.length).to be > 1
+ puts "Listed addresses: #{addresses.map(&:to_s).join(', ')}"
+
+ puts 'Fetching balances...'
+ balances = w2.list_balances
+ expect(balances.length).to be >= 1
+ puts "Fetched balances: #{balances}"
+
+ puts 'Transfering 1 Gwei from default address to second address...'
+ a1 = addresses[0]
+ a2 = addresses[1]
+ t = a1.transfer(1, :gwei, a2).wait!
+ expect(t.status).to eq(:complete)
+ puts "Transferred 1 Gwei from #{a1} to #{a2}"
+
+ puts 'Fetching updated balances...'
+ first_balance = a1.list_balances
+ second_balance = a2.list_balances
+ expect(first_balance[:eth]).to be > BigDecimal('0')
+ expect(second_balance[:eth]).to be > BigDecimal('0')
+ puts "First address balances: #{first_balance}"
+ puts "Second address balances: #{second_balance}"
+ end
+ end
+end
diff --git a/spec/fixtures/cdp_api_key.json b/spec/fixtures/cdp_api_key.json
new file mode 100644
index 00000000..77787117
--- /dev/null
+++ b/spec/fixtures/cdp_api_key.json
@@ -0,0 +1,4 @@
+{
+ "name": "organizations/e0716da6-47ce-4c68-b3da-d551b5a8671b/apiKeys/3688b1ac-d453-42db-814e-c425746dc967",
+ "privateKey": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFxG95q+feSkhWSnAKze+rWB3eo7oDNYKXpkiX45h3QcoAoGCCqGSM49\nAwEHoUQDQgAEyVDroLdmHJEpDAzJX6YJYQjMiWGYzEdDzu2TNyVUAP6w4ayA8qGe\nuJROGr7n7QT7MGg/IaA+MkhqO7lhgWLw2A==\n-----END EC PRIVATE KEY-----\n"
+}
\ No newline at end of file
diff --git a/spec/unit/coinbase/address_spec.rb b/spec/unit/coinbase/address_spec.rb
new file mode 100644
index 00000000..14cd026e
--- /dev/null
+++ b/spec/unit/coinbase/address_spec.rb
@@ -0,0 +1,311 @@
+# frozen_string_literal: true
+
+describe Coinbase::Address do
+ let(:key) { Eth::Key.new }
+ let(:network_id) { :base_sepolia }
+ let(:address_id) { key.address.to_s }
+ let(:wallet_id) { SecureRandom.uuid }
+ let(:model) do
+ Coinbase::Client::Address.new({
+ 'network_id' => 'base-sepolia',
+ 'address_id' => address_id,
+ 'wallet_id' => wallet_id,
+ 'public_key' => key.public_key.compressed.unpack1('H*')
+ })
+ end
+ let(:addresses_api) { double('Coinbase::Client::AddressesApi') }
+ let(:transfers_api) { double('Coinbase::Client::TransfersApi') }
+ let(:client) { double('Jimson::Client') }
+
+ before(:each) do
+ allow(Coinbase.configuration).to receive(:base_sepolia_client).and_return(client)
+ allow(Coinbase::Client::AddressesApi).to receive(:new).and_return(addresses_api)
+ allow(Coinbase::Client::TransfersApi).to receive(:new).and_return(transfers_api)
+ end
+
+ subject(:address) do
+ described_class.new(model, key)
+ end
+
+ describe '#initialize' do
+ it 'initializes a new Address' do
+ expect(address).to be_a(Coinbase::Address)
+ end
+ end
+
+ describe '#network_id' do
+ it 'returns the network ID' do
+ expect(address.network_id).to eq(network_id)
+ end
+ end
+
+ describe '#address_id' do
+ it 'returns the address ID' do
+ expect(address.address_id).to eq(address_id)
+ end
+ end
+
+ describe '#wallet_id' do
+ it 'returns the wallet ID' do
+ expect(address.wallet_id).to eq(wallet_id)
+ end
+ end
+
+ describe '#list_balances' do
+ let(:response) do
+ Coinbase::Client::AddressBalanceList.new(
+ 'data' => [
+ Coinbase::Client::Balance.new(
+ {
+ 'amount' => '1000000000000000000',
+ 'asset' => Coinbase::Client::Asset.new({
+ 'network_id': 'base-sepolia',
+ 'asset_id': 'eth',
+ 'decimals': 18
+ })
+ }
+ ),
+ Coinbase::Client::Balance.new(
+ {
+ 'amount' => '5000000000',
+ 'asset' => Coinbase::Client::Asset.new({
+ 'network_id': 'base-sepolia',
+ 'asset_id': 'usdc',
+ 'decimals': 6
+ })
+ }
+ )
+ ]
+ )
+ end
+
+ it 'returns a hash with balances' do
+ expect(addresses_api)
+ .to receive(:list_address_balances)
+ .with(wallet_id, address_id)
+ .and_return(response)
+ expect(address.list_balances).to eq(eth: BigDecimal('1'), usdc: BigDecimal('5000'))
+ end
+ end
+
+ describe '#get_balance' do
+ let(:response) do
+ Coinbase::Client::Balance.new(
+ {
+ 'amount' => '1000000000000000000',
+ 'asset' => Coinbase::Client::Asset.new({
+ 'network_id': 'base-sepolia',
+ 'asset_id': 'eth',
+ 'decimals': 18
+ })
+ }
+ )
+ end
+
+ it 'returns the correct ETH balance' do
+ expect(addresses_api)
+ .to receive(:get_address_balance)
+ .with(wallet_id, address_id, 'eth')
+ .and_return(response)
+ expect(address.get_balance(:eth)).to eq BigDecimal('1')
+ end
+
+ it 'returns the correct Gwei balance' do
+ expect(addresses_api)
+ .to receive(:get_address_balance)
+ .with(wallet_id, address_id, 'eth')
+ .and_return(response)
+ expect(address.get_balance(:gwei)).to eq BigDecimal('1_000_000_000')
+ end
+
+ it 'returns the correct Wei balance' do
+ expect(addresses_api)
+ .to receive(:get_address_balance)
+ .with(wallet_id, address_id, 'eth')
+ .and_return(response)
+ expect(address.get_balance(:wei)).to eq BigDecimal('1_000_000_000_000_000_000')
+ end
+
+ it 'returns 0 for an unsupported asset' do
+ expect(addresses_api)
+ .to receive(:get_address_balance)
+ .with(wallet_id, address_id, 'uni')
+ .and_return(nil)
+ expect(address.get_balance(:uni)).to eq BigDecimal('0')
+ end
+ end
+
+ describe '#transfer' do
+ let(:eth_balance_response) do
+ Coinbase::Client::Balance.new(
+ {
+ 'amount' => '1000000000000000000',
+ 'asset' => Coinbase::Client::Asset.new({
+ 'network_id': 'base-sepolia',
+ 'asset_id': 'eth',
+ 'decimals': 18
+ })
+ }
+ )
+ end
+ let(:usdc_balance_response) do
+ Coinbase::Client::Balance.new(
+ {
+ 'amount' => '10000000000',
+ 'asset' => Coinbase::Client::Asset.new({
+ 'network_id': 'base-sepolia',
+ 'asset_id': 'usdc',
+ 'decimals': 6
+ })
+ }
+ )
+ end
+ let(:to_key) { Eth::Key.new }
+ let(:to_address_id) { to_key.address.to_s }
+ let(:transaction_hash) { '0xdeadbeef' }
+ let(:raw_signed_transaction) { '0123456789abcdef' }
+ let(:transaction) { double('Transaction', sign: transaction_hash, hex: raw_signed_transaction) }
+ let(:transfer) do
+ double('Transfer', transaction: transaction)
+ end
+
+ before do
+ allow(Coinbase::Transfer).to receive(:new).and_return(transfer)
+ allow(client).to receive(:eth_sendRawTransaction).with("0x#{raw_signed_transaction}").and_return(transaction_hash)
+ end
+
+ # TODO: Add test case for when the destination is a Wallet.
+
+ context 'when the destination is a valid Address' do
+ let(:asset_id) { :wei }
+ let(:amount) { 500_000_000_000_000_000 }
+ let(:destination) { described_class.new(model, to_key) }
+ let(:create_transfer_request) do
+ { amount: amount.to_s, network_id: network_id, asset_id: 'eth', destination: destination.address_id }
+ end
+
+ it 'creates a Transfer' do
+ expect(addresses_api)
+ .to receive(:get_address_balance)
+ .with(wallet_id, address_id, 'eth')
+ .and_return(eth_balance_response)
+ expect(transfers_api)
+ .to receive(:create_transfer)
+ .with(wallet_id, address_id, create_transfer_request)
+ expect(address.transfer(amount, asset_id, destination)).to eq(transfer)
+ end
+ end
+
+ context 'when the destination is a valid Address and asset is USDC' do
+ let(:asset_id) { :usdc }
+ let(:usdc_amount) { 5 }
+ let(:usdc_atomic_amount) { 5_000_000 }
+ let(:destination) { described_class.new(model, to_key) }
+ let(:create_transfer_request) do
+ { amount: usdc_atomic_amount.to_s, network_id: network_id, asset_id: 'usdc',
+ destination: destination.address_id }
+ end
+
+ it 'creates a Transfer' do
+ expect(addresses_api)
+ .to receive(:get_address_balance)
+ .with(wallet_id, address_id, 'usdc')
+ .and_return(usdc_balance_response)
+ expect(transfers_api)
+ .to receive(:create_transfer)
+ .with(wallet_id, address_id, create_transfer_request)
+ expect(address.transfer(usdc_amount, asset_id, destination)).to eq(transfer)
+ end
+ end
+
+ context 'when the destination is a valid Address ID' do
+ let(:asset_id) { :wei }
+ let(:amount) { 500_000_000_000_000_000 }
+ let(:destination) { to_address_id }
+ let(:create_transfer_request) do
+ { amount: amount.to_s, network_id: network_id, asset_id: 'eth', destination: to_address_id }
+ end
+ it 'creates a Transfer' do
+ expect(addresses_api)
+ .to receive(:get_address_balance)
+ .with(wallet_id, address_id, 'eth')
+ .and_return(eth_balance_response)
+ expect(transfers_api)
+ .to receive(:create_transfer)
+ .with(wallet_id, address_id, create_transfer_request)
+ expect(address.transfer(amount, asset_id, destination)).to eq(transfer)
+ end
+ end
+
+ context 'when the destination is a valid Address ID and asset is Gwei' do
+ let(:asset_id) { :gwei }
+ let(:amount) { 500_000_000 }
+ let(:wei_amount) { 500_000_000_000_000_000 }
+ let(:destination) { to_address_id }
+ let(:create_transfer_request) do
+ { amount: wei_amount.to_s, network_id: network_id, asset_id: 'eth', destination: to_address_id }
+ end
+ it 'creates a Transfer' do
+ expect(addresses_api)
+ .to receive(:get_address_balance)
+ .with(wallet_id, address_id, 'eth')
+ .and_return(eth_balance_response)
+ expect(transfers_api)
+ .to receive(:create_transfer)
+ .with(wallet_id, address_id, create_transfer_request)
+ expect(address.transfer(amount, asset_id, destination)).to eq(transfer)
+ end
+ end
+
+ context 'when the asset is unsupported' do
+ let(:amount) { 500_000_000_000_000_000 }
+ it 'raises an ArgumentError' do
+ expect { address.transfer(amount, :uni, to_address_id) }.to raise_error(ArgumentError, 'Unsupported asset: uni')
+ end
+ end
+
+ # TODO: Add test case for when the destination is a Wallet.
+
+ context 'when the destination Address is on a different network' do
+ let(:asset_id) { :wei }
+ let(:amount) { 500_000_000_000_000_000 }
+ let(:new_model) do
+ Coinbase::Client::Address.new({
+ 'network_id' => 'base-mainnet',
+ 'address_id' => address_id,
+ 'wallet_id' => wallet_id,
+ 'public_key' => key.public_key.compressed.unpack1('H*')
+ })
+ end
+
+ it 'raises an ArgumentError' do
+ expect do
+ address.transfer(amount, asset_id, Coinbase::Address.new(new_model, to_key))
+ end.to raise_error(ArgumentError, 'Transfer must be on the same Network')
+ end
+ end
+
+ context 'when the balance is insufficient' do
+ let(:asset_id) { :wei }
+ let(:excessive_amount) { 9_000_000_000_000_000_000_000 }
+ before do
+ expect(addresses_api)
+ .to receive(:get_address_balance)
+ .with(wallet_id, address_id, 'eth')
+ .and_return(eth_balance_response)
+ end
+
+ it 'raises an ArgumentError' do
+ expect do
+ address.transfer(excessive_amount, asset_id, to_address_id)
+ end.to raise_error(ArgumentError)
+ end
+ end
+ end
+
+ describe '#to_s' do
+ it 'returns the address as a string' do
+ expect(address.to_s).to eq(address_id)
+ end
+ end
+end
diff --git a/spec/unit/coinbase/authenticator_spec.rb b/spec/unit/coinbase/authenticator_spec.rb
new file mode 100644
index 00000000..f6e119ad
--- /dev/null
+++ b/spec/unit/coinbase/authenticator_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+describe Coinbase::Authenticator do
+ let(:app) { double('Faraday::Connection') }
+ let(:authenticator) { described_class.new(app) }
+ let(:data) { JSON.parse(File.read('spec/fixtures/cdp_api_key.json')) }
+ let(:api_key_name) { data['name'] }
+ let(:api_key_private_key) { data['privateKey'] }
+
+ before do
+ allow(Coinbase.configuration).to receive(:api_key_name).and_return(api_key_name)
+ allow(Coinbase.configuration).to receive(:api_key_private_key).and_return(api_key_private_key)
+ end
+
+ describe '#call' do
+ let(:env) { double('Faraday::Env') }
+
+ it 'adds the JWT to the Authorization header' do
+ allow(env).to receive(:method).and_return('GET')
+ allow(env).to receive(:url).and_return(URI('https://cdp.api.coinbase.com/v1/users/me'))
+ allow(env).to receive(:request_headers).and_return({})
+ expect(app).to receive(:call) do |env|
+ expect(env.request_headers['Authorization']).to start_with('Bearer ')
+ end
+
+ authenticator.call(env)
+ end
+ end
+
+ describe '#build_jwt' do
+ let(:uri) { 'https://cdp.api.coinbase.com/v1/users/me' }
+
+ it 'builds a JWT for the given endpoint URI' do
+ jwt = authenticator.build_jwt(uri)
+
+ expect(jwt).to be_a(String)
+ end
+ end
+end
diff --git a/spec/coinbase/network_spec.rb b/spec/unit/coinbase/network_spec.rb
similarity index 100%
rename from spec/coinbase/network_spec.rb
rename to spec/unit/coinbase/network_spec.rb
diff --git a/spec/coinbase/transfer_spec.rb b/spec/unit/coinbase/transfer_spec.rb
similarity index 60%
rename from spec/coinbase/transfer_spec.rb
rename to spec/unit/coinbase/transfer_spec.rb
index 33ddc9e5..e4c6673f 100644
--- a/spec/coinbase/transfer_spec.rb
+++ b/spec/unit/coinbase/transfer_spec.rb
@@ -6,23 +6,63 @@
let(:network_id) { :base_sepolia }
let(:wallet_id) { SecureRandom.uuid }
let(:from_address_id) { from_key.address.to_s }
- let(:amount) { 5 }
+ let(:amount) { BigDecimal(100) }
+ let(:eth_amount) { amount / BigDecimal(Coinbase::WEI_PER_ETHER.to_s) }
let(:to_address_id) { to_key.address.to_s }
+ let(:transfer_id) { SecureRandom.uuid }
+ let(:unsigned_payload) do \
+ '7b2274797065223a22307832222c22636861696e4964223a2230783134613334222c226e6f6e63' \
+'65223a22307830222c22746f223a22307834643965346633663464316138623566346637623166' \
+'356235633762386436623262336231623062222c22676173223a22307835323038222c22676173' \
+'5072696365223a6e756c6c2c226d61785072696f72697479466565506572476173223a223078' \
+'3539363832663030222c226d6178466565506572476173223a2230783539363832663030222c22' \
+'76616c7565223a2230783536626337356532643633313030303030222c22696e707574223a22' \
+'3078222c226163636573734c697374223a5b5d2c2276223a22307830222c2272223a2230783022' \
+'2c2273223a22307830222c2279506172697479223a22307830222c2268617368223a2230783664' \
+'633334306534643663323633653363396561396135656438646561346332383966613861363966' \
+'3031653635393462333732386230386138323335333433227d'
+ end
+ let(:model) do
+ Coinbase::Client::Transfer.new({
+ 'network_id' => network_id,
+ 'wallet_id' => wallet_id,
+ 'address_id' => from_address_id,
+ 'destination' => to_address_id,
+ 'asset_id' => 'eth',
+ 'amount' => amount.to_s,
+ 'transfer_id' => transfer_id,
+ 'status' => 'pending',
+ 'unsigned_payload' => unsigned_payload
+ })
+ end
+ let(:transfers_api) { double('Coinbase::Client::TransfersApi') }
let(:client) { double('Jimson::Client') }
+ before(:each) do
+ configuration = double(Coinbase::Configuration)
+ allow(Coinbase).to receive(:configuration).and_return(configuration)
+ allow(configuration).to receive(:base_sepolia_client).and_return(client)
+ end
+
subject(:transfer) do
- described_class.new(network_id, wallet_id, from_address_id, amount, :eth, to_address_id, client: client)
+ described_class.new(model)
end
describe '#initialize' do
it 'initializes a new Transfer' do
expect(transfer).to be_a(Coinbase::Transfer)
end
+ end
+
+ describe '#transfer_id' do
+ it 'returns the transfer ID' do
+ expect(transfer.transfer_id).to eq(transfer_id)
+ end
+ end
- it 'does not initialize a new transfer for an invalid asset' do
- expect do
- Coinbase::Transfer.new(network_id, wallet_id, from_address_id, amount, :uni, to_address_id, client: client)
- end.to raise_error(ArgumentError, 'Unsupported asset: uni')
+ describe '#unsigned_payload' do
+ it 'returns the unsigned payload' do
+ expect(transfer.unsigned_payload).to eq(unsigned_payload)
end
end
@@ -46,41 +86,7 @@
describe '#amount' do
it 'returns the amount' do
- expect(transfer.amount).to eq(amount)
- end
-
- context 'when the amount is a Float' do
- let(:float_amount) { 0.5 }
- let(:float_transfer) do
- described_class.new(network_id, wallet_id, from_address_id, float_amount, :eth, to_address_id, client: client)
- end
-
- it 'normalizes the amount' do
- expect(float_transfer.amount).to eq(BigDecimal('0.5'))
- end
- end
-
- context 'when the amount is an Integer' do
- let(:integer_amount) { 5 }
- let(:integer_transfer) do
- described_class.new(network_id, wallet_id, from_address_id, integer_amount, :eth, to_address_id, client: client)
- end
-
- it 'normalizes the amount' do
- expect(integer_transfer.amount).to eq(BigDecimal('5'))
- end
- end
-
- context 'when the amount is a BigDecimal' do
- let(:big_decimal_amount) { BigDecimal('0.5') }
- let(:big_decimal_transfer) do
- described_class.new(network_id, wallet_id, from_address_id, big_decimal_amount, :eth, to_address_id,
- client: client)
- end
-
- it 'normalizes the amount' do
- expect(big_decimal_transfer.amount).to eq(big_decimal_amount)
- end
+ expect(transfer.amount).to eq(eth_amount)
end
end
@@ -90,30 +96,54 @@
end
end
- describe '#to_address_id' do
+ describe '#destination_address_id' do
it 'returns the destination address ID' do
- expect(transfer.to_address_id).to eq(to_address_id)
+ expect(transfer.destination_address_id).to eq(to_address_id)
end
end
describe '#transaction' do
- before do
- allow(client).to receive(:eth_getTransactionCount).with(from_address_id, 'latest').and_return('0x7')
- allow(client).to receive(:eth_gasPrice).and_return('0x7b')
- end
-
it 'returns the Transfer transaction' do
expect(transfer.transaction).to be_a(Eth::Tx::Eip1559)
expect(transfer.transaction.amount).to eq(amount * Coinbase::WEI_PER_ETHER)
end
- end
- describe '#transaction_hash' do
- before do
- allow(client).to receive(:eth_getTransactionCount).with(from_address_id, 'latest').and_return('0x7')
- allow(client).to receive(:eth_gasPrice).and_return('0x7b')
+ context 'when the transaction is for an ERC-20' do
+ let(:usdc_unsigned_payload) do
+ '7b2274797065223a22307832222c22636861696e4964223a2230783134613334222c226e6f6e6365223a22307830222c22746f223a22' \
+ '307830333663626435333834326335343236363334653739323935343165633233313866336463663765222c22676173223a22307831' \
+ '38366130222c226761735072696365223a6e756c6c2c226d61785072696f72697479466565506572476173223a223078353936383266' \
+ '3030222c226d6178466565506572476173223a2230783539363832663030222c2276616c7565223a22307830222c22696e707574223a' \
+ '223078613930353963626230303030303030303030303030303030303030303030303034643965346633663464316138623566346637' \
+ '623166356235633762386436623262336231623062303030303030303030303030303030303030303030303030303030303030303030' \
+ '30303030303030303030303030303030303030303030303030303030303031222c226163636573734c697374223a5b5d2c2276223a22' \
+ '307830222c2272223a22307830222c2273223a22307830222c2279506172697479223a22307830222c2268617368223a223078316365' \
+ '386164393935306539323437316461666665616664653562353836373938323430663630303138336136363365393661643738383039' \
+ '66643965303666227d'
+ end
+
+ let(:usdc_model) do
+ Coinbase::Client::Transfer.new({
+ 'address_id' => from_address_id,
+ 'destination' => to_address_id,
+ 'unsigned_payload' => usdc_unsigned_payload
+ })
+ end
+ let(:usdc_transfer) do
+ described_class.new(usdc_model)
+ end
+
+ it 'returns the Transfer transaction' do
+ expect(usdc_transfer.transaction).to be_a(Eth::Tx::Eip1559)
+ expect(usdc_transfer.transaction.amount).to eq(BigDecimal('0'))
+ expect(usdc_transfer.transaction.chain_id).to eq(84_532)
+ expect(usdc_transfer.transaction.max_fee_per_gas).to eq(1_500_000_000)
+ expect(usdc_transfer.transaction.max_priority_fee_per_gas).to eq(1_500_000_000)
+ end
end
+ end
+ describe '#transaction_hash' do
context 'when the transaction has been signed' do
it 'returns the transaction hash' do
transfer.transaction.sign(from_key)
@@ -136,11 +166,6 @@
end
describe '#status' do
- before do
- allow(client).to receive(:eth_getTransactionCount).with(from_address_id, 'latest').and_return('0x7')
- allow(client).to receive(:eth_gasPrice).and_return('0x7b')
- end
-
context 'when the transaction has not been created' do
it 'returns PENDING' do
expect(transfer.status).to eq(Coinbase::Transfer::Status::PENDING)
@@ -226,8 +251,6 @@
describe '#wait!' do
before do
- allow(client).to receive(:eth_getTransactionCount).with(from_address_id, 'latest').and_return('0x7')
- allow(client).to receive(:eth_gasPrice).and_return('0x7b')
# TODO: This isn't working for some reason.
allow(transfer).to receive(:sleep)
end
diff --git a/spec/unit/coinbase/user_spec.rb b/spec/unit/coinbase/user_spec.rb
new file mode 100644
index 00000000..54d3f52d
--- /dev/null
+++ b/spec/unit/coinbase/user_spec.rb
@@ -0,0 +1,130 @@
+# frozen_string_literal: true
+
+describe Coinbase::User do
+ let(:user_id) { SecureRandom.uuid }
+ let(:model) { Coinbase::Client::User.new({ 'id': user_id }) }
+ let(:wallets_api) { instance_double(Coinbase::Client::WalletsApi) }
+ let(:addresses_api) { instance_double(Coinbase::Client::AddressesApi) }
+ let(:user) { described_class.new(model) }
+ let(:transfers_api) { instance_double(Coinbase::Client::TransfersApi) }
+
+ describe '#user_id' do
+ it 'returns the user ID' do
+ expect(user.user_id).to eq(user_id)
+ end
+ end
+
+ describe '#create_wallet' do
+ let(:wallet_id) { SecureRandom.uuid }
+ let(:network_id) { 'base-sepolia' }
+ let(:create_wallet_request) { { wallet: { network_id: network_id } } }
+ let(:opts) { { create_wallet_request: create_wallet_request } }
+ let(:wallet_model) { Coinbase::Client::Wallet.new({ 'id': wallet_id, 'network_id': network_id }) }
+ let(:wallet_model_with_default_address) do
+ Coinbase::Client::Wallet.new(
+ {
+ 'id': wallet_id,
+ 'network_id': 'base-sepolia',
+ 'default_address': Coinbase::Client::Address.new({
+ 'address_id': '0xdeadbeef',
+ 'wallet_id': wallet_id,
+ 'public_key': '0x1234567890',
+ 'network_id': 'base-sepolia'
+ })
+ }
+ )
+ end
+
+ before do
+ allow(Coinbase::Client::AddressesApi).to receive(:new).and_return(addresses_api)
+ allow(Coinbase::Client::WalletsApi).to receive(:new).and_return(wallets_api)
+ expect(wallets_api).to receive(:create_wallet).with(opts).and_return(wallet_model)
+ expect(addresses_api)
+ .to receive(:create_address)
+ .with(wallet_id, satisfy do |opts|
+ public_key_present = opts[:create_address_request][:public_key].is_a?(String)
+ attestation_present = opts[:create_address_request][:attestation].is_a?(String)
+ public_key_present && attestation_present
+ end)
+ expect(wallets_api).to receive(:get_wallet).with(wallet_id).and_return(wallet_model_with_default_address)
+ end
+
+ it 'creates a new wallet' do
+ wallet = user.create_wallet
+ expect(wallet).to be_a(Coinbase::Wallet)
+ expect(wallet.wallet_id).to eq(wallet_id)
+ expect(wallet.network_id).to eq(:base_sepolia)
+ end
+ end
+
+ describe '#import_wallet' do
+ let(:client) { double('Jimson::Client') }
+ let(:wallet_id) { SecureRandom.uuid }
+ let(:wallet_model) { Coinbase::Client::Wallet.new({ 'id': wallet_id, 'network_id': 'base-sepolia' }) }
+ let(:wallets_api) { double('Coinbase::Client::WalletsApi') }
+ let(:network_id) { 'base-sepolia' }
+ let(:create_wallet_request) { { wallet: { network_id: network_id } } }
+ let(:opts) { { create_wallet_request: create_wallet_request } }
+ let(:addresses_api) { double('Coinbase::Client::AddressesApi') }
+ let(:address_model) do
+ Coinbase::Client::Address.new({
+ 'address_id': '0xdeadbeef',
+ 'wallet_id': wallet_id,
+ 'public_key': '0x1234567890',
+ 'network_id': 'base-sepolia'
+ })
+ end
+ let(:wallet_model_with_default_address) do
+ Coinbase::Client::Wallet.new(
+ {
+ 'id': wallet_id,
+ 'network_id': 'base-sepolia',
+ 'default_address': address_model
+ }
+ )
+ end
+ let(:address_list_model) do
+ Coinbase::Client::AddressList.new({ 'data' => [address_model], 'total_count' => 1 })
+ end
+ let(:wallet_export_data) do
+ Coinbase::Wallet::Data.new(
+ wallet_id: wallet_id,
+ seed: MoneyTree::Master.new.seed_hex
+ )
+ end
+ subject(:imported_wallet) { user.import_wallet(wallet_export_data) }
+
+ before do
+ allow(Coinbase::Client::AddressesApi).to receive(:new).and_return(addresses_api)
+ allow(Coinbase::Client::WalletsApi).to receive(:new).and_return(wallets_api)
+ expect(wallets_api).to receive(:get_wallet).with(wallet_id).and_return(wallet_model_with_default_address)
+ expect(addresses_api).to receive(:list_addresses).with(wallet_id).and_return(address_list_model)
+ expect(addresses_api).to receive(:get_address).and_return(address_model)
+ end
+
+ it 'imports an exported wallet' do
+ expect(imported_wallet.wallet_id).to eq(wallet_id)
+ end
+
+ it 'loads the wallet addresses' do
+ expect(imported_wallet.list_addresses.length).to eq(address_list_model.total_count)
+ end
+
+ it 'contains the same seed when re-exported' do
+ expect(imported_wallet.export.seed).to eq(wallet_export_data.seed)
+ end
+ end
+
+ describe '#list_wallet_ids' do
+ let(:wallet_ids) { [SecureRandom.uuid, SecureRandom.uuid] }
+ let(:data) do
+ wallet_ids.map { |id| Coinbase::Client::Wallet.new({ 'id': id, 'network_id': 'base-sepolia' }) }
+ end
+ let(:wallet_list) { Coinbase::Client::WalletList.new({ 'data' => data }) }
+ it 'lists the wallet IDs' do
+ allow(Coinbase::Client::WalletsApi).to receive(:new).and_return(wallets_api)
+ expect(wallets_api).to receive(:list_wallets).and_return(wallet_list)
+ expect(user.list_wallet_ids).to eq(wallet_ids)
+ end
+ end
+end
diff --git a/spec/unit/coinbase/wallet_spec.rb b/spec/unit/coinbase/wallet_spec.rb
new file mode 100644
index 00000000..047874ce
--- /dev/null
+++ b/spec/unit/coinbase/wallet_spec.rb
@@ -0,0 +1,275 @@
+# frozen_string_literal: true
+
+describe Coinbase::Wallet do
+ let(:client) { double('Jimson::Client') }
+ let(:wallet_id) { SecureRandom.uuid }
+ let(:model) { Coinbase::Client::Wallet.new({ 'id': wallet_id, 'network_id': 'base-sepolia' }) }
+ let(:address_model) do
+ Coinbase::Client::Address.new({
+ 'address_id': '0xdeadbeef',
+ 'wallet_id': wallet_id,
+ 'public_key': '0x1234567890',
+ 'network_id': 'base-sepolia'
+ })
+ end
+ let(:model_with_default_address) do
+ Coinbase::Client::Wallet.new(
+ {
+ 'id': wallet_id,
+ 'network_id': 'base-sepolia',
+ 'default_address': address_model
+ }
+ )
+ end
+ let(:wallets_api) { double('Coinbase::Client::WalletsApi') }
+ let(:addresses_api) { double('Coinbase::Client::AddressesApi') }
+ let(:transfers_api) { double('Coinbase::Client::TransfersApi') }
+
+ before do
+ allow(Coinbase::Client::AddressesApi).to receive(:new).and_return(addresses_api)
+ allow(Coinbase::Client::WalletsApi).to receive(:new).and_return(wallets_api)
+ allow(addresses_api).to receive(:create_address).and_return(address_model)
+ allow(addresses_api).to receive(:get_address).and_return(address_model)
+ allow(wallets_api).to receive(:get_wallet).with(wallet_id).and_return(model_with_default_address)
+ @wallet = described_class.new(model)
+ end
+
+ describe '#initialize' do
+ context 'when no seed or address count is provided' do
+ it 'initializes a new Wallet' do
+ expect(addresses_api)
+ .to receive(:create_address)
+ .with(wallet_id, satisfy do |opts|
+ public_key_present = opts[:create_address_request][:public_key].is_a?(String)
+ attestation_present = opts[:create_address_request][:attestation].is_a?(String)
+ public_key_present && attestation_present
+ end)
+ @wallet = described_class.new(model)
+ expect(@wallet).to be_a(Coinbase::Wallet)
+ end
+ end
+
+ context 'when a seed is provided' do
+ let(:seed) { '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f' }
+ let(:seed_wallet) { described_class.new(model, seed: seed) }
+
+ it 'initializes a new Wallet with the provided seed' do
+ expect(addresses_api)
+ .to receive(:create_address)
+ .with(wallet_id, satisfy do |opts|
+ public_key_present = opts[:create_address_request][:public_key].is_a?(String)
+ attestation_present = opts[:create_address_request][:attestation].is_a?(String)
+ public_key_present && attestation_present
+ end)
+ .and_return(address_model)
+ expect(seed_wallet).to be_a(Coinbase::Wallet)
+ end
+
+ it 'raises an error for an invalid seed' do
+ expect do
+ described_class.new(model, seed: 'invalid')
+ end.to raise_error(ArgumentError, 'Seed must be 32 bytes')
+ end
+ end
+
+ context 'when the address count is provided' do
+ let(:address_count) { 5 }
+ let(:address_wallet) do
+ described_class.new(model, address_count: address_count)
+ end
+
+ it 'initializes a new Wallet with the provided address count' do
+ expect(addresses_api).to receive(:get_address).exactly(address_count).times
+ expect(address_wallet.list_addresses.length).to eq(address_count)
+ end
+ end
+ end
+
+ describe '#wallet_id' do
+ it 'returns the Wallet ID' do
+ expect(@wallet.wallet_id).to eq(wallet_id)
+ end
+ end
+
+ describe '#network_id' do
+ it 'returns the Network ID' do
+ expect(@wallet.network_id).to eq(:base_sepolia)
+ end
+ end
+
+ describe '#create_address' do
+ it 'creates a new address' do
+ expect(addresses_api)
+ .to receive(:create_address)
+ .with(wallet_id, satisfy do |opts|
+ public_key_present = opts[:create_address_request][:public_key].is_a?(String)
+ attestation_present = opts[:create_address_request][:attestation].is_a?(String)
+ public_key_present && attestation_present
+ end)
+ .and_return(address_model)
+ .exactly(1).times
+ address = @wallet.create_address
+ expect(address).to be_a(Coinbase::Address)
+ expect(@wallet.list_addresses.length).to eq(2)
+ expect(address).not_to eq(@wallet.default_address)
+ end
+ end
+
+ describe '#default_address' do
+ it 'returns the first address' do
+ expect(@wallet.default_address).to eq(@wallet.list_addresses.first)
+ end
+ end
+
+ describe '#get_address' do
+ before do
+ allow(addresses_api).to receive(:create_address).and_return(address_model)
+ end
+
+ it 'returns the correct address' do
+ default_address = @wallet.default_address
+ expect(@wallet.get_address(default_address.address_id)).to eq(default_address)
+ end
+ end
+
+ describe '#list_addresses' do
+ it 'contains one address' do
+ expect(@wallet.list_addresses.length).to eq(1)
+ end
+ end
+
+ describe '#list_balances' do
+ let(:response) do
+ Coinbase::Client::AddressBalanceList.new(
+ 'data' => [
+ Coinbase::Client::Balance.new(
+ {
+ 'amount' => '1000000000000000000',
+ 'asset' => Coinbase::Client::Asset.new({
+ 'network_id': 'base-sepolia',
+ 'asset_id': 'eth',
+ 'decimals': 18
+ })
+ }
+ ),
+ Coinbase::Client::Balance.new(
+ {
+ 'amount' => '5000000',
+ 'asset' => Coinbase::Client::Asset.new({
+ 'network_id': 'base-sepolia',
+ 'asset_id': 'usdc',
+ 'decimals': 6
+ })
+ }
+ )
+ ]
+ )
+ end
+ before do
+ expect(wallets_api).to receive(:list_wallet_balances).and_return(response)
+ end
+
+ it 'returns a hash with an ETH and USDC balance' do
+ expect(@wallet.list_balances).to eq({ eth: BigDecimal(1), usdc: BigDecimal(5) })
+ end
+ end
+
+ describe '#get_balance' do
+ let(:response) do
+ Coinbase::Client::Balance.new(
+ {
+ 'amount' => '5000000000000000000',
+ 'asset' => Coinbase::Client::Asset.new({
+ 'network_id': 'base-sepolia',
+ 'asset_id': 'eth',
+ 'decimals': 18
+ })
+ }
+ )
+ end
+
+ before do
+ expect(wallets_api).to receive(:get_wallet_balance).with(wallet_id, 'eth').and_return(response)
+ end
+
+ it 'returns the correct ETH balance' do
+ expect(@wallet.get_balance(:eth)).to eq(BigDecimal(5))
+ end
+
+ it 'returns the correct Gwei balance' do
+ expect(@wallet.get_balance(:gwei)).to eq(BigDecimal(5 * Coinbase::GWEI_PER_ETHER))
+ end
+
+ it 'returns the correct Wei balance' do
+ expect(@wallet.get_balance(:wei)).to eq(BigDecimal(5 * Coinbase::WEI_PER_ETHER))
+ end
+ end
+
+ describe '#transfer' do
+ let(:transfer) { double('Coinbase::Transfer') }
+ let(:amount) { 5 }
+ let(:asset_id) { :eth }
+
+ context 'when the destination is a Wallet' do
+ let(:destination) { described_class.new(model) }
+ let(:to_address_id) { destination.default_address.address_id }
+
+ before do
+ expect(@wallet.default_address).to receive(:transfer).with(amount, asset_id, to_address_id).and_return(transfer)
+ end
+
+ it 'creates a transfer to the default address ID' do
+ expect(@wallet.transfer(amount, asset_id, destination)).to eq(transfer)
+ end
+ end
+
+ context 'when the desination is an Address' do
+ let(:destination) { @wallet.create_address }
+ let(:to_address_id) { destination.address_id }
+
+ before do
+ expect(@wallet.default_address).to receive(:transfer).with(amount, asset_id, to_address_id).and_return(transfer)
+ end
+
+ it 'creates a transfer to the address ID' do
+ expect(@wallet.transfer(amount, asset_id, destination)).to eq(transfer)
+ end
+ end
+
+ context 'when the destination is a String' do
+ let(:destination) { '0x1234567890' }
+
+ before do
+ expect(@wallet.default_address).to receive(:transfer).with(amount, asset_id, destination).and_return(transfer)
+ end
+
+ it 'creates a transfer to the address ID' do
+ expect(@wallet.transfer(amount, asset_id, destination)).to eq(transfer)
+ end
+ end
+ end
+
+ describe '#export' do
+ let(:seed) { '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f' }
+ let(:address_count) { 5 }
+ let(:seed_wallet) do
+ described_class.new(model, seed: seed, address_count: address_count)
+ end
+
+ it 'exports the Wallet data' do
+ wallet_data = seed_wallet.export
+ expect(wallet_data).to be_a(Coinbase::Wallet::Data)
+ expect(wallet_data.wallet_id).to eq(seed_wallet.wallet_id)
+ expect(wallet_data.seed).to eq(seed)
+ end
+
+ it 'allows for re-creation of a Wallet' do
+ wallet_data = seed_wallet.export
+ new_wallet = described_class.new(model, seed: wallet_data.seed, address_count: address_count)
+ expect(new_wallet.list_addresses.length).to eq(address_count)
+ new_wallet.list_addresses.each_with_index do |address, i|
+ expect(address.address_id).to eq(seed_wallet.list_addresses[i].address_id)
+ end
+ end
+ end
+end
diff --git a/spec/unit/coinbase_spec.rb b/spec/unit/coinbase_spec.rb
new file mode 100644
index 00000000..ca78c9b1
--- /dev/null
+++ b/spec/unit/coinbase_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+describe Coinbase do
+ describe '#configure' do
+ let(:api_key_private_key) { 'some-key' }
+ let(:api_key_name) { 'some-key-name' }
+
+ subject do
+ Coinbase.configure do |config|
+ config.api_key_private_key = api_key_private_key
+ config.api_key_name = api_key_name
+ end
+ end
+
+ context 'when api_key_private_key is nil' do
+ let(:api_key_private_key) { nil }
+ it 'raises an exception' do
+ expect { subject }.to raise_error(Coinbase::InvalidConfiguration, /API key private key/)
+ end
+ end
+
+ context 'when api_key_name is nil' do
+ let(:api_key_name) { nil }
+ it 'raises an exception' do
+ expect { subject }.to raise_error(Coinbase::InvalidConfiguration, /API key name/)
+ end
+ end
+ end
+
+ describe '#default_user' do
+ let(:users_api) { double Coinbase::Client::UsersApi }
+ let(:user_model) { double 'User Model' }
+
+ before(:each) do
+ allow(Coinbase::Client::UsersApi).to receive(:new).and_return(users_api)
+ allow(users_api).to receive(:get_current_user).and_return(user_model)
+ allow(Coinbase::User).to receive(:new)
+ end
+
+ it 'creates a new users api client' do
+ Coinbase.default_user
+ expect(Coinbase::Client::UsersApi).to have_received(:new).with(Coinbase.configuration.api_client)
+ end
+
+ it 'gets the current user from the api' do
+ Coinbase.default_user
+ expect(users_api).to have_received(:get_current_user)
+ end
+
+ it 'creates a new user object from the response' do
+ Coinbase.default_user
+ expect(Coinbase::User).to have_received(:new).with(user_model)
+ end
+ end
+
+ describe Coinbase::Configuration do
+ describe '#api_url' do
+ it 'returns the default api url' do
+ expect(Coinbase.configuration.api_url).to eq 'https://api.cdp.coinbase.com'
+ end
+ end
+
+ describe '#base_sepolia_rpc_url' do
+ it 'returns the default base sepolia rpc url' do
+ expect(Coinbase.configuration.base_sepolia_rpc_url).to eq 'https://sepolia.base.org'
+ end
+ end
+ end
+end