diff --git a/.gitignore b/.gitignore
index a4095614..bae78fe5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@ Gemfile.lock
lib/**/.DS_Store
.idea
.DS_Store
-seeds.json
\ No newline at end of file
+seeds.json
+coverage
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d3acc6ad..db2ef031 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,12 +9,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Trade
+## [0.0.6] - 2024-06-03
+
+### Added
+
+- Server-Signer feature: ability to create wallets backed by server signers and create transfers with them.
+
+### Changed
+
+- Changed save_wallet to save_seed
+- Changed load_wallets to load_seed and moved at wallet level
+
## [0.0.5] - 2024-05-20
### Added
- `wallets` method on the User class
- Ability to hydrate wallets (i.e. set the seed on it)
+- Ability to create wallets backed by server signers.
+ - Note: External developers cannot use this until we enable them to create and run them.
## [0.0.4] - 2024-05-13
diff --git a/Makefile b/Makefile
index c44a976d..33cbd22c 100644
--- a/Makefile
+++ b/Makefile
@@ -10,6 +10,10 @@ lint:
test:
bundle exec rake test
+.PHONY: test-coverage
+test-coverage:
+ open coverage/index.html
+
.PHONY: repl
repl:
bundle exec bin/repl
diff --git a/README.md b/README.md
index 16ea6c19..0fb0eaa1 100644
--- a/README.md
+++ b/README.md
@@ -162,6 +162,11 @@ This will allow you to [authenticate](./authentication.md) with the Platform API
u = Coinbase.default_user
```
+If you are using a CDP Server-Signer to manage your private keys, enable it with
+
+```ruby
+Coinbase.configuration.use_server_signer=true
+```
Now, create a wallet from the User. Wallets are created with a single default address.
```ruby
@@ -227,14 +232,17 @@ store(data.to_hash)
For more information on wallet persistence, see [the documentation on wallets](./wallets.md#persisting-a-wallet).
-Alternatively, you can use the `save_wallet_locally!` function to persist wallets on your local file system. This is a
+Alternatively, you can use the `save_seed!` function to persist a wallet's seed to a local file. This is a
convenience function purely for testing purposes, and should not be considered a secure method of persisting wallets.
```ruby
-# Set encrypt: true to encrypt the wallet export data with your CDP API key.
-u.save_wallet_locally!(w1, encrypt: true)
+# Pick a file to which to save your wallet seed.
+file_path = 'my_seed.json'
-puts "Wallet #{w1.id} successfully saved to local file storage."
+# Set encrypt: true to encrypt the wallet seed with your CDP API key.
+w1.save_seed!(file_path, encrypt: true)
+
+puts "Seed for wallet #{w1.id} successfully saved to #{file_path}."
```
## Re-instantiating a Wallet
@@ -250,17 +258,16 @@ fetched_data = fetch(w1.id)
w3 = u.import_wallet(fetched_data)
```
-If you used the `save_wallet_locally!` function to persist wallets on your local file system, then you can use the
-`load_wallets_from_local` function re-instantiate the wallets.
+If you used the `save_seed!` function to persist a wallet's seed to a local file, then you can first fetch
+the unhydrated wallet from the server, and then use the `load_seed` method to re-instantiate the wallet.
```ruby
-# wallets will contain a Hash from wallet ID to wallet.
-wallets = u.load_wallets_from_local
-
-puts "Wallets successfully loaded from local file storage."
+# Get the unhydrated wallet from the server.
+w4 = u.wallet(w1.id)
-# w4 will be equivalent to w1 and w3.
-w4 = wallets[w1.id]
+# You can now load the seed into the wallet from the local file.
+# w4 will be equivalent to w1.
+w4.load_seed(file_path)
```
## Development
diff --git a/coinbase.gemspec b/coinbase.gemspec
index dd5894e5..b809de75 100644
--- a/coinbase.gemspec
+++ b/coinbase.gemspec
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'rspec'
# Pin to a specific version of RuboCop to ensure consistent linting.
spec.add_development_dependency 'rubocop', '1.63.1'
+ spec.add_development_dependency 'simplecov'
# Pin to a specific version of YARD to ensure consistent documentation generation.
spec.add_development_dependency 'yard', '0.9.36'
spec.add_development_dependency 'yard-markdown'
diff --git a/docs/Coinbase.html b/docs/Coinbase.html
index 36a527bc..ec1faf8d 100644
--- a/docs/Coinbase.html
+++ b/docs/Coinbase.html
@@ -323,7 +323,7 @@
# File 'lib/coinbase.rb', line 31defself.configureyield(configuration)raiseInvalidConfiguration,'API key private key is not set'unlessconfiguration.api_key_private_keyraiseInvalidConfiguration,'API key name is not set'unlessconfiguration.api_key_name
+
+ 'Successfully configured Coinbase SDK'end
(String)
- (defaults to: 'coinbase_cloud_api_key.json')
+ (defaults to: 'cdp_api_key.json')
—
@@ -671,6 +717,24 @@
+
Returns:
+
+
+
+
+
+ (String)
+
+
+
+ —
+
+
A string indicating successful configuration
+
+
+
+
+
Raises:
@@ -691,21 +755,25 @@
-40
-41
-42
-43
44
-45
+45
+46
+47
+48
+49
+50
+51
-
# File 'lib/coinbase.rb', line 40
+
# File 'lib/coinbase.rb', line 44
-defself.configure_from_json(file_path='coinbase_cloud_api_key.json')
+defself.configure_from_json(file_path='cdp_api_key.json')configuration.from_json(file_path)raiseInvalidConfiguration,'API key private key is not set'unlessconfiguration.api_key_private_keyraiseInvalidConfiguration,'API key name is not set'unlessconfiguration.api_key_name
+
+ 'Successfully configured Coinbase SDK'end
@@ -756,12 +824,12 @@
-92
-93
-94
+98
+99
+100
-
# File 'lib/coinbase.rb', line 92
+
# File 'lib/coinbase.rb', line 98defself.default_user@default_user||=load_default_user
@@ -815,14 +883,14 @@
-105
-106
-107
-108
-109
+111
+112
+113
+114
+115
-
# File 'lib/coinbase.rb', line 105
+
# File 'lib/coinbase.rb', line 111defself.load_default_userusers_api=Coinbase::Client::UsersApi.new(configuration.api_client)
@@ -898,12 +966,12 @@
-99
-100
-101
+105
+106
+107
-
# File 'lib/coinbase.rb', line 99
+
# File 'lib/coinbase.rb', line 105defself.to_sym(value)value.to_s.gsub('-','_').to_sym
@@ -911,6 +979,65 @@
+
+
+
+
+
+ .use_server_signer? ⇒ bool
+
+
+
+
+
+
+
+
+
Returns whether to use a server signer to manage private keys.
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (bool)
+
+
+
+ —
+
+
whether to use a server signer to manage private keys.
# File 'lib/coinbase/address.rb', line 81deftransfer(amount,asset_id,destination)
- raise'Cannot transfer from address without private key loaded'if@key.nil?
-
- raiseArgumentError,"Unsupported asset: #{asset_id}"unlessCoinbase::Asset.supported?(asset_id)
-
- ifdestination.is_a?(Wallet)
- raiseArgumentError,'Transfer must be on the same Network'ifdestination.network_id!=network_id
-
- destination=destination.default_address.id
- elsifdestination.is_a?(Address)
- raiseArgumentError,'Transfer must be on the same Network'ifdestination.network_id!=network_id
-
- destination=destination.id
- end
+ destination_address,destination_network=destination_address_and_network(destination)
- current_balance=balance(asset_id)
- ifcurrent_balance<amount
- raiseArgumentError,"Insufficient funds: #{amount} requested, but only #{current_balance} available"
- end
-
- create_transfer_request={
- amount:Coinbase::Asset.to_atomic_amount(amount,asset_id).to_i.to_s,
- network_id:network_id,
- asset_id:Coinbase::Asset.primary_denomination(asset_id).to_s,
- destination:destination
- }
-
- transfer_model=Coinbase.call_apido
- transfers_api.create_transfer(wallet_id,id,create_transfer_request)
- end
+ validate_can_transfer!(amount,asset_id,destination_network)
- transfer=Coinbase::Transfer.new(transfer_model)
+ transfer=create_transfer(amount,asset_id,destination_address)
- transaction=transfer.transaction
- transaction.sign(@key)
+ # If a server signer is managing keys, it will sign and broadcast the underlying transfer transaction out of band.
+returntransferifCoinbase.use_server_signer?
- signed_payload=transaction.hex
-
- broadcast_transfer_request={
- signed_payload:signed_payload
- }
-
- transfer_model=Coinbase.call_apido
- transfers_api.broadcast_transfer(wallet_id,id,transfer.id,broadcast_transfer_request)
- end
+ signed_payload=sign_transfer(transfer)
- Coinbase::Transfer.new(transfer_model)
+ broadcast_transfer(transfer,signed_payload)end
# File 'lib/coinbase/client/models/broadcast_trade_request.rb', line 48
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::BroadcastTradeRequest` 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::BroadcastTradeRequest`. 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?(:'signed_payload')
+ self.signed_payload=attributes[:'signed_payload']
+ else
+ self.signed_payload=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #signed_payload ⇒ Object
+
+
+
+
+
+
+
+
+
The hex-encoded signed payload of the trade
+
+
+
+
+
+
+
+
+
+
+
+
+
+19
+20
+21
+
+
+
# File 'lib/coinbase/client/models/broadcast_trade_request.rb', line 19
+
+defsigned_payload
+ @signed_payload
+end
# File 'lib/coinbase/client/models/broadcast_trade_request.rb', line 111
+
+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/broadcast_trade_request.rb', line 206
+
+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
+
+
+
+
+
+
+
+
+
+98
+99
+100
+
+
+
# File 'lib/coinbase/client/models/broadcast_trade_request.rb', line 98
+
+defeql?(o)
+ self==o
+end
+
+
+
+
+
+
+
+
+ #hash ⇒ Integer
+
+
+
+
+
+
+
+
+
Calculates hash code according to all attributes.
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Integer)
+
+
+
+ —
+
+
Hash code
+
+
+
+
+
+
+
+
+
+
+
+
+104
+105
+106
+
+
+
# File 'lib/coinbase/client/models/broadcast_trade_request.rb', line 104
+
+defhash
+ [signed_payload].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
+
+
+
+
+
+
+
+
+
+
+
+
+70
+71
+72
+73
+74
+75
+76
+77
+78
+
+
+
# File 'lib/coinbase/client/models/broadcast_trade_request.rb', line 70
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@signed_payload.nil?
+ invalid_properties.push('invalid value for "signed_payload", signed_payload 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
+
+
+
+
+
+
+
+
+
+
+
+
+182
+183
+184
+
+
+
# File 'lib/coinbase/client/models/broadcast_trade_request.rb', line 182
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/broadcast_trade_request.rb', line 188
+
+defto_hash
+ hash={}
+ self.class.attribute_map.each_pairdo|attr,param|
+ value=self.send(attr)
+ ifvalue.nil?
+ is_nullable=self.class.openapi_nullable.include?(attr)
+ nextif!is_nullable||(is_nullable&&!instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param]=_to_hash(value)
+ end
+ hash
+end
+
+
+
+
+
+
+
+
+ #to_s ⇒ String
+
+
+
+
+
+
+
+
+
Returns the string representation of the object
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (String)
+
+
+
+ —
+
+
String presentation of the object
+
+
+
+
+
+
+
+
+
+
+
+
+176
+177
+178
+
+
+
# File 'lib/coinbase/client/models/broadcast_trade_request.rb', line 176
+
+defto_s
+ to_hash.to_s
+end
+
+
+
+
+
+
+
+
+ #valid? ⇒ Boolean
+
+
+
+
+
+
+
+
+
Check to see if the all the properties in the model are valid
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Boolean)
+
+
+
+ —
+
+
true if the model is valid
+
+
+
+
+
+
+
+
+
+
+
+
+82
+83
+84
+85
+86
+
+
+
# File 'lib/coinbase/client/models/broadcast_trade_request.rb', line 82
+
+defvalid?
+ warn'[DEPRECATED] the `valid?` method is obsolete'
+ returnfalseif@signed_payload.nil?
+ true
+end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/Coinbase/Client/CreateAddressRequest.html b/docs/Coinbase/Client/CreateAddressRequest.html
index 2a3342ab..54a9cca2 100644
--- a/docs/Coinbase/Client/CreateAddressRequest.html
+++ b/docs/Coinbase/Client/CreateAddressRequest.html
@@ -640,11 +640,7 @@
70
71
72
-73
-74
-75
-76
-77
+73
# File 'lib/coinbase/client/models/create_address_request.rb', line 53
@@ -664,14 +660,10 @@
# File 'lib/coinbase/client/models/create_address_request.rb', line 81
+
# File 'lib/coinbase/client/models/create_address_request.rb', line 77deflist_invalid_propertieswarn'[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_propertiesend
@@ -1664,12 +1640,12 @@
-199
-200
-201
+185
+186
+187
-
# File 'lib/coinbase/client/models/create_address_request.rb', line 199
+
# File 'lib/coinbase/client/models/create_address_request.rb', line 185defto_bodyto_hash
@@ -1723,22 +1699,22 @@
# File 'lib/coinbase/client/models/create_address_request.rb', line 205
+
# File 'lib/coinbase/client/models/create_address_request.rb', line 191defto_hashhash={}
@@ -1802,12 +1778,12 @@
-193
-194
-195
+179
+180
+181
-
# File 'lib/coinbase/client/models/create_address_request.rb', line 193
+
# File 'lib/coinbase/client/models/create_address_request.rb', line 179defto_sto_hash.to_s
@@ -1861,20 +1837,16 @@
-97
-98
-99
-100
-101
-102
+85
+86
+87
+88
-
# File 'lib/coinbase/client/models/create_address_request.rb', line 97
+
# File 'lib/coinbase/client/models/create_address_request.rb', line 85defvalid?warn'[DEPRECATED] the `valid?` method is obsolete'
- returnfalseif@public_key.nil?
- returnfalseif@attestation.nil?trueend
# File 'lib/coinbase/client/models/create_server_signer_request.rb', line 53
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::CreateServerSignerRequest` 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::CreateServerSignerRequest`. 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?(:'server_signer_id')
+ self.server_signer_id=attributes[:'server_signer_id']
+ else
+ self.server_signer_id=nil
+ end
+
+ ifattributes.key?(:'enrollment_data')
+ self.enrollment_data=attributes[:'enrollment_data']
+ else
+ self.enrollment_data=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #enrollment_data ⇒ Object
+
+
+
+
+
+
+
+
+
The enrollment data of the server signer. This will be the base64 encoded server-signer-id.
+
+
+
+
+
+
+
+
+
+
+
+
+
+22
+23
+24
+
+
+
# File 'lib/coinbase/client/models/create_server_signer_request.rb', line 22
+
+defenrollment_data
+ @enrollment_data
+end
+
+
+
+
+
+
+
+
+
+
+ #server_signer_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the server signer
+
+
+
+
+
+
+
+
+
+
+
+
+
+19
+20
+21
+
+
+
# File 'lib/coinbase/client/models/create_server_signer_request.rb', line 19
+
+defserver_signer_id
+ @server_signer_id
+end
# File 'lib/coinbase/client/models/create_server_signer_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_server_signer_request.rb', line 81
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@server_signer_id.nil?
+ invalid_properties.push('invalid value for "server_signer_id", server_signer_id cannot be nil.')
+ end
+
+ if@enrollment_data.nil?
+ invalid_properties.push('invalid value for "enrollment_data", enrollment_data 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_server_signer_request.rb', line 199
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/create_trade_request.rb', line 58
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::CreateTradeRequest` 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::CreateTradeRequest`. 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?(:'from_asset_id')
+ self.from_asset_id=attributes[:'from_asset_id']
+ else
+ self.from_asset_id=nil
+ end
+
+ ifattributes.key?(:'to_asset_id')
+ self.to_asset_id=attributes[:'to_asset_id']
+ else
+ self.to_asset_id=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #amount ⇒ Object
+
+
+
+
+
+
+
+
+
The amount to trade
+
+
+
+
+
+
+
+
+
+
+
+
+
+19
+20
+21
+
+
+
# File 'lib/coinbase/client/models/create_trade_request.rb', line 19
+
+defamount
+ @amount
+end
+
+
+
+
+
+
+
+
+
+
+ #from_asset_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the asset to trade
+
+
+
+
+
+
+
+
+
+
+
+
+
+22
+23
+24
+
+
+
# File 'lib/coinbase/client/models/create_trade_request.rb', line 22
+
+deffrom_asset_id
+ @from_asset_id
+end
+
+
+
+
+
+
+
+
+
+
+ #to_asset_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the asset to receive from the trade
+
+
+
+
+
+
+
+
+
+
+
+
+
+25
+26
+27
+
+
+
# File 'lib/coinbase/client/models/create_trade_request.rb', line 25
+
+defto_asset_id
+ @to_asset_id
+end
# File 'lib/coinbase/client/models/create_trade_request.rb', line 145
+
+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_trade_request.rb', line 92
+
+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@from_asset_id.nil?
+ invalid_properties.push('invalid value for "from_asset_id", from_asset_id cannot be nil.')
+ end
+
+ if@to_asset_id.nil?
+ invalid_properties.push('invalid value for "to_asset_id", to_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
+
+
+
+
+
+
+
+
+
+
+
+
+216
+217
+218
+
+
+
# File 'lib/coinbase/client/models/create_trade_request.rb', line 216
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/create_trade_request.rb', line 222
+
+defto_hash
+ hash={}
+ self.class.attribute_map.each_pairdo|attr,param|
+ value=self.send(attr)
+ ifvalue.nil?
+ is_nullable=self.class.openapi_nullable.include?(attr)
+ nextif!is_nullable||(is_nullable&&!instance_variable_defined?(:"@#{attr}"))
+ end
+
+ hash[param]=_to_hash(value)
+ end
+ hash
+end
+
+
+
+
+
+
+
+
+ #to_s ⇒ String
+
+
+
+
+
+
+
+
+
Returns the string representation of the object
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (String)
+
+
+
+ —
+
+
String presentation of the object
+
+
+
+
+
+
+
+
+
+
+
+
+210
+211
+212
+
+
+
# File 'lib/coinbase/client/models/create_trade_request.rb', line 210
+
+defto_s
+ to_hash.to_s
+end
+
+
+
+
+
+
+
+
+ #valid? ⇒ Boolean
+
+
+
+
+
+
+
+
+
Check to see if the all the properties in the model are valid
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Boolean)
+
+
+
+ —
+
+
true if the model is valid
+
+
+
+
+
+
+
+
+
+
+
+
+112
+113
+114
+115
+116
+117
+118
+
+
+
# File 'lib/coinbase/client/models/create_trade_request.rb', line 112
+
+defvalid?
+ warn'[DEPRECATED] the `valid?` method is obsolete'
+ returnfalseif@amount.nil?
+ returnfalseif@from_asset_id.nil?
+ returnfalseif@to_asset_id.nil?
+ true
+end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/Coinbase/Client/CreateWalletRequest.html b/docs/Coinbase/Client/CreateWalletRequest.html
index 7a0d1eee..c56de844 100644
--- a/docs/Coinbase/Client/CreateWalletRequest.html
+++ b/docs/Coinbase/Client/CreateWalletRequest.html
@@ -1137,7 +1137,7 @@
# File 'lib/coinbase/client/models/create_wallet_request_wallet.rb', line 54
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::CreateWalletRequestWallet` 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::CreateWalletRequestWallet`. 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?(:'use_server_signer')
+ self.use_server_signer=attributes[:'use_server_signer']
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #network_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the blockchain network
+
+
+
+
+
+
+
+
+
+
+
+
+
+20
+21
+22
+
+
+
# File 'lib/coinbase/client/models/create_wallet_request_wallet.rb', line 20
+
+defnetwork_id
+ @network_id
+end
+
+
+
+
+
+
+
+
+
+
+ #use_server_signer ⇒ Object
+
+
+
+
+
+
+
+
+
Whether the wallet should use the project's server signer or if the addresses in the wallets will belong to a private key the developer manages. Defaults to false.
+
+
+
+
+
+
+
+
+
+
+
+
+
+23
+24
+25
+
+
+
# File 'lib/coinbase/client/models/create_wallet_request_wallet.rb', line 23
+
+defuse_server_signer
+ @use_server_signer
+end
# File 'lib/coinbase/client/models/create_wallet_request_wallet.rb', line 122
+
+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_wallet.rb', line 217
+
+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
+
+
+
+
+
+
+
+
+
+109
+110
+111
+
+
+
# File 'lib/coinbase/client/models/create_wallet_request_wallet.rb', line 109
+
+defeql?(o)
+ self==o
+end
+
+
+
+
+
+
+
+
+ #hash ⇒ Integer
+
+
+
+
+
+
+
+
+
Calculates hash code according to all attributes.
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Integer)
+
+
+
+ —
+
+
Hash code
+
+
+
+
+
+
+
+
+
+
+
+
+115
+116
+117
+
+
+
# File 'lib/coinbase/client/models/create_wallet_request_wallet.rb', line 115
+
+defhash
+ [network_id,use_server_signer].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
+
+
+
+
+
+
+
+
+
+
+
+
+80
+81
+82
+83
+84
+85
+86
+87
+88
+
+
+
# File 'lib/coinbase/client/models/create_wallet_request_wallet.rb', line 80
+
+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
+
+
+
+
+
+
+
+
+
+
+
+
+193
+194
+195
+
+
+
# File 'lib/coinbase/client/models/create_wallet_request_wallet.rb', line 193
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/seed_creation_event.rb', line 54
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::SeedCreationEvent` 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::SeedCreationEvent`. 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?(:'wallet_user_id')
+ self.wallet_user_id=attributes[:'wallet_user_id']
+ else
+ self.wallet_user_id=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #wallet_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the wallet that the server-signer should create the seed for
+
+
+
+
+
+
+
+
+
+
+
+
+
+20
+21
+22
+
+
+
# File 'lib/coinbase/client/models/seed_creation_event.rb', line 20
+
+defwallet_id
+ @wallet_id
+end
+
+
+
+
+
+
+
+
+
+
+ #wallet_user_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the user that the wallet belongs to
+
+
+
+
+
+
+
+
+
+
+
+
+
+23
+24
+25
+
+
+
# File 'lib/coinbase/client/models/seed_creation_event.rb', line 23
+
+defwallet_user_id
+ @wallet_user_id
+end
# File 'lib/coinbase/client/models/seed_creation_event.rb', line 129
+
+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/seed_creation_event.rb', line 82
+
+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@wallet_user_id.nil?
+ invalid_properties.push('invalid value for "wallet_user_id", wallet_user_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
+
+
+
+
+
+
+
+
+
+
+
+
+200
+201
+202
+
+
+
# File 'lib/coinbase/client/models/seed_creation_event.rb', line 200
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/seed_creation_event_result.rb', line 64
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::SeedCreationEventResult` 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::SeedCreationEventResult`. 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?(:'wallet_user_id')
+ self.wallet_user_id=attributes[:'wallet_user_id']
+ else
+ self.wallet_user_id=nil
+ end
+
+ ifattributes.key?(:'extended_public_key')
+ self.extended_public_key=attributes[:'extended_public_key']
+ else
+ self.extended_public_key=nil
+ end
+
+ ifattributes.key?(:'seed_id')
+ self.seed_id=attributes[:'seed_id']
+ else
+ self.seed_id=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #extended_public_key ⇒ Object
+
+
+
+
+
+
+
+
+
The extended public key for the first master key derived from seed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+26
+27
+28
+
+
+
# File 'lib/coinbase/client/models/seed_creation_event_result.rb', line 26
+
+defextended_public_key
+ @extended_public_key
+end
+
+
+
+
+
+
+
+
+
+
+ #seed_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the seed in Server-Signer used to generate the extended public key.
+
+
+
+
+
+
+
+
+
+
+
+
+
+29
+30
+31
+
+
+
# File 'lib/coinbase/client/models/seed_creation_event_result.rb', line 29
+
+defseed_id
+ @seed_id
+end
+
+
+
+
+
+
+
+
+
+
+ #wallet_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the wallet that the seed was created for
+
+
+
+
+
+
+
+
+
+
+
+
+
+20
+21
+22
+
+
+
# File 'lib/coinbase/client/models/seed_creation_event_result.rb', line 20
+
+defwallet_id
+ @wallet_id
+end
+
+
+
+
+
+
+
+
+
+
+ #wallet_user_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the user that the wallet belongs to
+
+
+
+
+
+
+
+
+
+
+
+
+
+23
+24
+25
+
+
+
# File 'lib/coinbase/client/models/seed_creation_event_result.rb', line 23
+
+defwallet_user_id
+ @wallet_user_id
+end
# File 'lib/coinbase/client/models/seed_creation_event_result.rb', line 163
+
+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/seed_creation_event_result.rb', line 104
+
+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@wallet_user_id.nil?
+ invalid_properties.push('invalid value for "wallet_user_id", wallet_user_id cannot be nil.')
+ end
+
+ if@extended_public_key.nil?
+ invalid_properties.push('invalid value for "extended_public_key", extended_public_key cannot be nil.')
+ end
+
+ if@seed_id.nil?
+ invalid_properties.push('invalid value for "seed_id", seed_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
+
+
+
+
+
+
+
+
+
+
+
+
+234
+235
+236
+
+
+
# File 'lib/coinbase/client/models/seed_creation_event_result.rb', line 234
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/server_signer.rb', line 54
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::ServerSigner` 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::ServerSigner`. 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?(:'server_signer_id')
+ self.server_signer_id=attributes[:'server_signer_id']
+ else
+ self.server_signer_id=nil
+ end
+
+ ifattributes.key?(:'wallets')
+ if(value=attributes[:'wallets']).is_a?(Array)
+ self.wallets=value
+ end
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #server_signer_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the server-signer
+
+
+
+
+
+
+
+
+
+
+
+
+
+20
+21
+22
+
+
+
# File 'lib/coinbase/client/models/server_signer.rb', line 20
+
+defserver_signer_id
+ @server_signer_id
+end
+
+
+
+
+
+
+
+
+
+
+ #wallets ⇒ Object
+
+
+
+
+
+
+
+
+
The IDs of the wallets that the server-signer can sign for
+
+
+
+
+
+
+
+
+
+
+
+
+
+23
+24
+25
+
+
+
# File 'lib/coinbase/client/models/server_signer.rb', line 23
+
+defwallets
+ @wallets
+end
# File 'lib/coinbase/client/models/server_signer.rb', line 124
+
+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/server_signer.rb', line 219
+
+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
+
+
+
+
+
+
+
+
+
+111
+112
+113
+
+
+
# File 'lib/coinbase/client/models/server_signer.rb', line 111
+
+defeql?(o)
+ self==o
+end
+
+
+
+
+
+
+
+
+ #hash ⇒ Integer
+
+
+
+
+
+
+
+
+
Calculates hash code according to all attributes.
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Integer)
+
+
+
+ —
+
+
Hash code
+
+
+
+
+
+
+
+
+
+
+
+
+117
+118
+119
+
+
+
# File 'lib/coinbase/client/models/server_signer.rb', line 117
+
+defhash
+ [server_signer_id,wallets].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
+
+
+
+
+
+
+
+
+
+
+
+
+82
+83
+84
+85
+86
+87
+88
+89
+90
+
+
+
# File 'lib/coinbase/client/models/server_signer.rb', line 82
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@server_signer_id.nil?
+ invalid_properties.push('invalid value for "server_signer_id", server_signer_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
+
+
+
+
+
+
+
+
+
+
+
+
+195
+196
+197
+
+
+
# File 'lib/coinbase/client/models/server_signer.rb', line 195
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/server_signer_event.rb', line 53
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::ServerSignerEvent` 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::ServerSignerEvent`. 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?(:'server_signer_id')
+ self.server_signer_id=attributes[:'server_signer_id']
+ else
+ self.server_signer_id=nil
+ end
+
+ ifattributes.key?(:'event')
+ self.event=attributes[:'event']
+ else
+ self.event=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #event ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the value of attribute event.
+
+
+
+
+
+
+
+
+
+
+
+
+
+22
+23
+24
+
+
+
# File 'lib/coinbase/client/models/server_signer_event.rb', line 22
+
+defevent
+ @event
+end
+
+
+
+
+
+
+
+
+
+
+ #server_signer_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the server-signer that the event is for
+
+
+
+
+
+
+
+
+
+
+
+
+
+20
+21
+22
+
+
+
# File 'lib/coinbase/client/models/server_signer_event.rb', line 20
+
+defserver_signer_id
+ @server_signer_id
+end
# File 'lib/coinbase/client/models/server_signer_event.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/server_signer_event.rb', line 81
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@server_signer_id.nil?
+ invalid_properties.push('invalid value for "server_signer_id", server_signer_id cannot be nil.')
+ end
+
+ if@event.nil?
+ invalid_properties.push('invalid value for "event", event 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/server_signer_event.rb', line 199
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/server_signer_event_event.rb', line 30
+
+defbuild(data)
+ # Go through the list of oneOf items and attempt to identify the appropriate one.
+# Note:
+# - We do not attempt to check whether exactly one item matches.
+# - No advanced validation of types in some cases (e.g. "x: { type: string }" will happily match { x: 123 })
+# due to the way the deserialization is made in the base_object template (it just casts without verifying).
+# - TODO: scalar values are de facto behaving as if they were nullable.
+# - TODO: logging when debugging is set.
+openapi_one_of.eachdo|klass|
+ begin
+ nextifklass==:AnyType# "nullable: true"
+typed_data=find_and_cast_into_type(klass,data)
+ returntyped_dataiftyped_data
+ rescue# rescue all errors so we keep iterating even if the current item lookup raises
+end
+ end
+
+ openapi_one_of.include?(:AnyType)?data:nil
+end
# File 'lib/coinbase/client/models/server_signer_event_list.rb', line 63
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::ServerSignerEventList` 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::ServerSignerEventList`. 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/server_signer_event_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/server_signer_event_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/server_signer_event_list.rb', line 25
+
+defnext_page
+ @next_page
+end
+
+
+
+
+
+
+
+
+
+
+ #total_count ⇒ Object
+
+
+
+
+
+
+
+
+
The total number of events for the server signer.
+
+
+
+
+
+
+
+
+
+
+
+
+
+28
+29
+30
+
+
+
# File 'lib/coinbase/client/models/server_signer_event_list.rb', line 28
+
+deftotal_count
+ @total_count
+end
# File 'lib/coinbase/client/models/server_signer_event_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/server_signer_event_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/server_signer_event_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/signature_creation_event.rb', line 105
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::SignatureCreationEvent` 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::SignatureCreationEvent`. 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?(:'seed_id')
+ self.seed_id=attributes[:'seed_id']
+ else
+ self.seed_id=nil
+ end
+
+ ifattributes.key?(:'wallet_id')
+ self.wallet_id=attributes[:'wallet_id']
+ else
+ self.wallet_id=nil
+ end
+
+ ifattributes.key?(:'wallet_user_id')
+ self.wallet_user_id=attributes[:'wallet_user_id']
+ else
+ self.wallet_user_id=nil
+ end
+
+ ifattributes.key?(:'address_id')
+ self.address_id=attributes[:'address_id']
+ else
+ self.address_id=nil
+ end
+
+ ifattributes.key?(:'address_index')
+ self.address_index=attributes[:'address_index']
+ else
+ self.address_index=nil
+ end
+
+ ifattributes.key?(:'signing_payload')
+ self.signing_payload=attributes[:'signing_payload']
+ else
+ self.signing_payload=nil
+ end
+
+ ifattributes.key?(:'transaction_type')
+ self.transaction_type=attributes[:'transaction_type']
+ else
+ self.transaction_type=nil
+ end
+
+ ifattributes.key?(:'transaction_id')
+ self.transaction_id=attributes[:'transaction_id']
+ else
+ self.transaction_id=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #address_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the address the transfer belongs to
+
+
+
+
+
+
+
+
+
+
+
+
+
+29
+30
+31
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event.rb', line 29
+
+defaddress_id
+ @address_id
+end
+
+
+
+
+
+
+
+
+
+
+ #address_index ⇒ Object
+
+
+
+
+
+
+
+
+
The index of the address that the server-signer should sign with
+
+
+
+
+
+
+
+
+
+
+
+
+
+32
+33
+34
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event.rb', line 32
+
+defaddress_index
+ @address_index
+end
+
+
+
+
+
+
+
+
+
+
+ #seed_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the seed that the server-signer should create the signature for
+
+
+
+
+
+
+
+
+
+
+
+
+
+20
+21
+22
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event.rb', line 20
+
+defseed_id
+ @seed_id
+end
+
+
+
+
+
+
+
+
+
+
+ #signing_payload ⇒ Object
+
+
+
+
+
+
+
+
+
The payload that the server-signer should sign
+
+
+
+
+
+
+
+
+
+
+
+
+
+35
+36
+37
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event.rb', line 35
+
+defsigning_payload
+ @signing_payload
+end
+
+
+
+
+
+
+
+
+
+
+ #transaction_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the transaction that the server-signer should sign
+
+
+
+
+
+
+
+
+
+
+
+
+
+40
+41
+42
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event.rb', line 40
+
+deftransaction_id
+ @transaction_id
+end
+
+
+
+
+
+
+
+
+
+
+ #transaction_type ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the value of attribute transaction_type.
+
+
+
+
+
+
+
+
+
+
+
+
+
+37
+38
+39
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event.rb', line 37
+
+deftransaction_type
+ @transaction_type
+end
+
+
+
+
+
+
+
+
+
+
+ #wallet_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the wallet the signature is for
+
+
+
+
+
+
+
+
+
+
+
+
+
+23
+24
+25
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event.rb', line 23
+
+defwallet_id
+ @wallet_id
+end
+
+
+
+
+
+
+
+
+
+
+ #wallet_user_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the user that the wallet belongs to
+
+
+
+
+
+
+
+
+
+
+
+
+
+26
+27
+28
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event.rb', line 26
+
+defwallet_user_id
+ @wallet_user_id
+end
# File 'lib/coinbase/client/models/signature_creation_event.rb', line 252
+
+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/signature_creation_event.rb', line 169
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ if@seed_id.nil?
+ invalid_properties.push('invalid value for "seed_id", seed_id cannot be nil.')
+ end
+
+ if@wallet_id.nil?
+ invalid_properties.push('invalid value for "wallet_id", wallet_id cannot be nil.')
+ end
+
+ if@wallet_user_id.nil?
+ invalid_properties.push('invalid value for "wallet_user_id", wallet_user_id cannot be nil.')
+ end
+
+ if@address_id.nil?
+ invalid_properties.push('invalid value for "address_id", address_id cannot be nil.')
+ end
+
+ if@address_index.nil?
+ invalid_properties.push('invalid value for "address_index", address_index cannot be nil.')
+ end
+
+ if@signing_payload.nil?
+ invalid_properties.push('invalid value for "signing_payload", signing_payload cannot be nil.')
+ end
+
+ if@transaction_type.nil?
+ invalid_properties.push('invalid value for "transaction_type", transaction_type cannot be nil.')
+ end
+
+ if@transaction_id.nil?
+ invalid_properties.push('invalid value for "transaction_id", transaction_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
+
+
+
+
+
+
+
+
+
+
+
+
+323
+324
+325
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event.rb', line 323
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/signature_creation_event_result.rb', line 95
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::SignatureCreationEventResult` 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::SignatureCreationEventResult`. 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?(:'wallet_user_id')
+ self.wallet_user_id=attributes[:'wallet_user_id']
+ else
+ self.wallet_user_id=nil
+ end
+
+ ifattributes.key?(:'address_id')
+ self.address_id=attributes[:'address_id']
+ else
+ self.address_id=nil
+ end
+
+ ifattributes.key?(:'transaction_type')
+ self.transaction_type=attributes[:'transaction_type']
+ else
+ self.transaction_type=nil
+ end
+
+ ifattributes.key?(:'transaction_id')
+ self.transaction_id=attributes[:'transaction_id']
+ else
+ self.transaction_id=nil
+ end
+
+ ifattributes.key?(:'signature')
+ self.signature=attributes[:'signature']
+ else
+ self.signature=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #address_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the address the transfer belongs to
+
+
+
+
+
+
+
+
+
+
+
+
+
+26
+27
+28
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event_result.rb', line 26
+
+defaddress_id
+ @address_id
+end
+
+
+
+
+
+
+
+
+
+
+ #signature ⇒ Object
+
+
+
+
+
+
+
+
+
The signature created by the server-signer.
+
+
+
+
+
+
+
+
+
+
+
+
+
+34
+35
+36
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event_result.rb', line 34
+
+defsignature
+ @signature
+end
+
+
+
+
+
+
+
+
+
+
+ #transaction_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the transaction that the Server-Signer has signed for
+
+
+
+
+
+
+
+
+
+
+
+
+
+31
+32
+33
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event_result.rb', line 31
+
+deftransaction_id
+ @transaction_id
+end
+
+
+
+
+
+
+
+
+
+
+ #transaction_type ⇒ Object
+
+
+
+
+
+
+
+
+
Returns the value of attribute transaction_type.
+
+
+
+
+
+
+
+
+
+
+
+
+
+28
+29
+30
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event_result.rb', line 28
+
+deftransaction_type
+ @transaction_type
+end
+
+
+
+
+
+
+
+
+
+
+ #wallet_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the wallet that the event was created for.
+
+
+
+
+
+
+
+
+
+
+
+
+
+20
+21
+22
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event_result.rb', line 20
+
+defwallet_id
+ @wallet_id
+end
+
+
+
+
+
+
+
+
+
+
+ #wallet_user_id ⇒ Object
+
+
+
+
+
+
+
+
+
The ID of the user that the wallet belongs to
+
+
+
+
+
+
+
+
+
+
+
+
+
+23
+24
+25
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event_result.rb', line 23
+
+defwallet_user_id
+ @wallet_user_id
+end
# File 'lib/coinbase/client/models/signature_creation_event_result.rb', line 218
+
+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/signature_creation_event_result.rb', line 147
+
+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@wallet_user_id.nil?
+ invalid_properties.push('invalid value for "wallet_user_id", wallet_user_id cannot be nil.')
+ end
+
+ if@address_id.nil?
+ invalid_properties.push('invalid value for "address_id", address_id cannot be nil.')
+ end
+
+ if@transaction_type.nil?
+ invalid_properties.push('invalid value for "transaction_type", transaction_type cannot be nil.')
+ end
+
+ if@transaction_id.nil?
+ invalid_properties.push('invalid value for "transaction_id", transaction_id cannot be nil.')
+ end
+
+ if@signature.nil?
+ invalid_properties.push('invalid value for "signature", signature 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
+
+
+
+
+
+
+
+
+
+
+
+
+289
+290
+291
+
+
+
# File 'lib/coinbase/client/models/signature_creation_event_result.rb', line 289
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/trade.rb', line 245
+
+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/trade.rb', line 156
+
+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@trade_id.nil?
+ invalid_properties.push('invalid value for "trade_id", trade_id cannot be nil.')
+ end
+
+ if@from_amount.nil?
+ invalid_properties.push('invalid value for "from_amount", from_amount cannot be nil.')
+ end
+
+ if@from_asset.nil?
+ invalid_properties.push('invalid value for "from_asset", from_asset cannot be nil.')
+ end
+
+ if@to_amount.nil?
+ invalid_properties.push('invalid value for "to_amount", to_amount cannot be nil.')
+ end
+
+ if@to_asset.nil?
+ invalid_properties.push('invalid value for "to_asset", to_asset cannot be nil.')
+ end
+
+ if@transaction.nil?
+ invalid_properties.push('invalid value for "transaction", transaction 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
+
+
+
+
+
+
+
+
+
+
+
+
+316
+317
+318
+
+
+
# File 'lib/coinbase/client/models/trade.rb', line 316
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/trade_list.rb', line 63
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::TradeList` 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::TradeList`. 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/trade_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/trade_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/trade_list.rb', line 25
+
+defnext_page
+ @next_page
+end
+
+
+
+
+
+
+
+
+
+
+ #total_count ⇒ Object
+
+
+
+
+
+
+
+
+
The total number of trades for the address in the wallet.
+
+
+
+
+
+
+
+
+
+
+
+
+
+28
+29
+30
+
+
+
# File 'lib/coinbase/client/models/trade_list.rb', line 28
+
+deftotal_count
+ @total_count
+end
# File 'lib/coinbase/client/models/trade_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/trade_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/trade_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/transaction.rb', line 86
+
+definitialize(attributes={})
+ if(!attributes.is_a?(Hash))
+ failArgumentError,"The input argument (attributes) must be a hash in `Coinbase::Client::Transaction` 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::Transaction`. 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?(:'unsigned_payload')
+ self.unsigned_payload=attributes[:'unsigned_payload']
+ else
+ self.unsigned_payload=nil
+ end
+
+ ifattributes.key?(:'signed_payload')
+ self.signed_payload=attributes[:'signed_payload']
+ end
+
+ ifattributes.key?(:'transaction_hash')
+ self.transaction_hash=attributes[:'transaction_hash']
+ end
+
+ ifattributes.key?(:'status')
+ self.status=attributes[:'status']
+ else
+ self.status=nil
+ end
+end
+
+
+
+
+
+
+
+
+
Instance Attribute Details
+
+
+
+
+
+
+ #signed_payload ⇒ Object
+
+
+
+
+
+
+
+
+
The signed payload of the transaction. This is the payload that has been signed by the sender.
+
+
+
+
+
+
+
+
+
+
+
+
+
+23
+24
+25
+
+
+
# File 'lib/coinbase/client/models/transaction.rb', line 23
+
+defsigned_payload
+ @signed_payload
+end
+
+
+
+
+
+
+
+
+
+
+ #status ⇒ Object
+
+
+
+
+
+
+
+
+
The status of the transaction
+
+
+
+
+
+
+
+
+
+
+
+
+
+29
+30
+31
+
+
+
# File 'lib/coinbase/client/models/transaction.rb', line 29
+
+defstatus
+ @status
+end
+
+
+
+
+
+
+
+
+
+
+ #transaction_hash ⇒ Object
+
+
+
+
+
+
+
+
+
The hash of the transaction
+
+
+
+
+
+
+
+
+
+
+
+
+
+26
+27
+28
+
+
+
# File 'lib/coinbase/client/models/transaction.rb', line 26
+
+deftransaction_hash
+ @transaction_hash
+end
+
+
+
+
+
+
+
+
+
+
+ #unsigned_payload ⇒ Object
+
+
+
+
+
+
+
+
+
The unsigned payload of the transaction. This is the payload that needs to be signed by the sender.
+
+
+
+
+
+
+
+
+
+
+
+
+
+20
+21
+22
+
+
+
# File 'lib/coinbase/client/models/transaction.rb', line 20
+
+defunsigned_payload
+ @unsigned_payload
+end
# File 'lib/coinbase/client/models/transaction.rb', line 183
+
+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/transaction.rb', line 122
+
+deflist_invalid_properties
+ warn'[DEPRECATED] the `list_invalid_properties` method is obsolete'
+ invalid_properties=Array.new
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
+254
+255
+256
+
+
+
# File 'lib/coinbase/client/models/transaction.rb', line 254
+
+defto_body
+ to_hash
+end
# File 'lib/coinbase/client/models/transaction_type.rb', line 20
+
+defself.all_vars
+ @all_vars||=[TRANSFER].freeze
+end
+
+
+
+
+
+
+
+
+ .build_from_hash(value) ⇒ String
+
+
+
+
+
+
+
+
+
Builds the enum from string
+
+
+
+
+
+
Parameters:
+
+
+
+
+ The
+
+
+ (String)
+
+
+
+ —
+
+
enum value in the form of the string
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (String)
+
+
+
+ —
+
+
The enum value
+
+
+
+
+
+
+
+
+
+
+
+
+27
+28
+29
+
+
+
# File 'lib/coinbase/client/models/transaction_type.rb', line 27
+
+defself.build_from_hash(value)
+ new.build_from_hash(value)
+end
+
+
+
+
+
+
+
+
+
Instance Method Details
+
+
+
+
+
+ #build_from_hash(value) ⇒ String
+
+
+
+
+
+
+
+
+
Builds the enum from string
+
+
+
+
+
+
Parameters:
+
+
+
+
+ The
+
+
+ (String)
+
+
+
+ —
+
+
enum value in the form of the string
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (String)
+
+
+
+ —
+
+
The enum value
+
+
+
+
+
+
+
+
+
+
+
+
+34
+35
+36
+37
+
+
+
# File 'lib/coinbase/client/models/transaction_type.rb', line 34
+
+defbuild_from_hash(value)
+ returnvalueifTransactionType.all_vars.include?(value)
+ raise"Invalid ENUM value #{value} for class #TransactionType"
+end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/Coinbase/Client/Wallet.html b/docs/Coinbase/Client/Wallet.html
index 31d22d19..78b39725 100644
--- a/docs/Coinbase/Client/Wallet.html
+++ b/docs/Coinbase/Client/Wallet.html
@@ -99,6 +99,16 @@
+
# File 'lib/coinbase/client/models/wallet.rb', line 87
+
# File 'lib/coinbase/client/models/wallet.rb', line 120deflist_invalid_propertieswarn'[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
+
if@network_id.nil?invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')end
@@ -1736,12 +1842,12 @@
-201
-202
-203
+252
+253
+254
-
# File 'lib/coinbase/client/models/wallet.rb', line 201
+
# File 'lib/coinbase/client/models/wallet.rb', line 252defto_bodyto_hash
@@ -1795,22 +1901,22 @@
# File 'lib/coinbase/client/models/wallet.rb', line 31
+
+defallowable_values
+ @allowable_values
+end
+
+
+
+
+
+
+
+
+
+
+ #datatype ⇒ Object(readonly)
+
+
+
+
+
+
+
+
+
Returns the value of attribute datatype.
+
+
+
+
+
+
+
+
+
+
+
+
+
+30
+31
+32
+
+
+
# File 'lib/coinbase/client/models/wallet.rb', line 30
+
+defdatatype
+ @datatype
+end
+
+
+
+
+
+
+
+
+
+
Instance Method Details
+
+
+
+
+
+ #valid?(value) ⇒ Boolean
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Returns:
+
+
+
+
+
+ (Boolean)
+
+
+
+
+
+
+
+
+
+
+
+
+
+46
+47
+48
+
+
+
# File 'lib/coinbase/client/models/wallet.rb', line 46
+
+defvalid?(value)
+ !value||allowable_values.include?(value)
+end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/Coinbase/Configuration.html b/docs/Coinbase/Configuration.html
index 504a0ace..8af2a619 100644
--- a/docs/Coinbase/Configuration.html
+++ b/docs/Coinbase/Configuration.html
@@ -201,7 +201,7 @@
# File 'lib/coinbase/transfer.rb', line 136defstatus
- # Check if the transfer has been signed yet.
-returnStatus::PENDINGiftransaction_hash.nil?
-
- 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)
+ @model.status
+end
# File 'lib/coinbase/user.rb', line 25
- model=Coinbase.call_apido
- wallets_api.create_wallet(opts)
- end
+defcreate_wallet(create_wallet_options={})
+ # For ruby 2.7 compatibility we cannot pass in keyword args when the create wallet
+# options is empty
+returnWallet.createifcreate_wallet_options.empty?
- Wallet.new(model)
+ Wallet.create(**create_wallet_options)end
@@ -623,12 +603,12 @@
-43
-44
-45
+36
+37
+38
-
# File 'lib/coinbase/user.rb', line 43
+
# File 'lib/coinbase/user.rb', line 36defimport_wallet(data)Wallet.import(data)
@@ -682,12 +662,12 @@
-162
-163
-164
+97
+98
+99
-
# File 'lib/coinbase/user.rb', line 162
+
# File 'lib/coinbase/user.rb', line 97definspectto_s
@@ -698,9 +678,9 @@
Saves a wallet to local file system. Wallet saved this way can be re-instantiated with load_wallets_from_local function, provided the backup_file is available. This is an insecure method of storing wallet seeds and should only be used for development purposes. If you call save_wallet_locally! twice with wallets containing the same wallet_id, the backup will be overwritten during the second attempt. The default backup_file is `seeds.json` in the root folder. It can be configured by changing Coinbase.configuration.backup_file_path.
Creates a new Wallet on the specified Network and generate a default address for it. have an active seed, if using a ServerSigner, in seconds create a seed for the Wallet, in seconds
# File 'lib/coinbase/wallet.rb', line 56
+
+defcreate(network_id:'base-sepolia',interval_seconds:0.2,timeout_seconds:20)
+ model=Coinbase.call_apido
+ wallets_api.create_wallet(
+ create_wallet_request:{
+ wallet:{
+ network_id:network_id,
+ use_server_signer:Coinbase.use_server_signer?
+ }
+ }
+ )
+ end
+
+ wallet=new(model)
+
+ # When used with a ServerSigner, the Signer must first register
+# with the Wallet before addresses can be created.
+wait_for_signer(wallet.id,interval_seconds,timeout_seconds)ifCoinbase.use_server_signer?
+
+ wallet.create_address
+ wallet
+end
# File 'lib/coinbase/wallet.rb', line 35defimport(data)raiseArgumentError,'data must be a Coinbase::Wallet::Data object'unlessdata.is_a?(Data)
@@ -1073,12 +1284,12 @@
-149
-150
-151
+207
+208
+209
-
# File 'lib/coinbase/wallet.rb', line 149
+
# File 'lib/coinbase/wallet.rb', line 207defaddress(address_id)@addresses.find{|address|address.id==address_id}
@@ -1152,18 +1363,18 @@
-166
-167
-168
-169
-170
-171
-172
-173
-174
+224
+225
+226
+227
+228
+229
+230
+231
+232
-
# File 'lib/coinbase/wallet.rb', line 166
+
# File 'lib/coinbase/wallet.rb', line 224defbalance(asset_id)response=Coinbase.call_apido
@@ -1223,16 +1434,16 @@
-155
-156
-157
-158
-159
-160
-161
+213
+214
+215
+216
+217
+218
+219
-
# File 'lib/coinbase/wallet.rb', line 155
+
# File 'lib/coinbase/wallet.rb', line 213defbalancesresponse=Coinbase.call_apido
@@ -1290,12 +1501,12 @@
-218
-219
-220
+266
+267
+268
-
# File 'lib/coinbase/wallet.rb', line 218
+
# File 'lib/coinbase/wallet.rb', line 266defcan_sign?!@master.nil?
@@ -1349,42 +1560,54 @@
Saves the seed of the Wallet to the given file. Wallets whose seeds are saved this way can be rehydrated using load_seed. A single file can be used for multiple Wallet seeds. This is an insecure method of storing Wallet seeds and should only be used for development purposes.
Transfers the given amount of the given Asset to the given address. Only same-Network Transfers are supported. Currently only the default_address is used to source the Transfer.
+
Transfers the given amount of the given Asset to the specified address or wallet. Only same-network Transfers are supported. Currently only the default_address is used to source the Transfer.
# File 'lib/coinbase/wallet.rb', line 241deftransfer(amount,asset_id,destination)
- ifdestination.is_a?(Wallet)
- raiseArgumentError,'Transfer must be on the same Network'ifdestination.network_id!=@network_id
-
- destination=destination.default_address.id
- elsifdestination.is_a?(Address)
- raiseArgumentError,'Transfer must be on the same Network'ifdestination.network_id!=@network_id
-
- destination=destination.id
- end
-
default_address.transfer(amount,asset_id,destination)end
The Wallet is awaiting seed creation by the ServerSigner. At this point, the Wallet cannot create addresses or sign transactions.
+
+
+
+
+
+
+
+
+
+
'pending_seed_creation'
+
+
ACTIVE =
+
+
+
+
The Wallet has an associated seed created by the ServerSigner. It is ready to create addresses and sign transactions.
+
+
+
+
+
+
+
+
+
+
'active_seed'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/_index.html b/docs/_index.html
index 6610c6d7..b441038b 100644
--- a/docs/_index.html
+++ b/docs/_index.html
@@ -88,16 +88,16 @@
Alternatively, you can use the save_wallet_locally! function to persist wallets on your local file system. This is a convenience function purely for testing purposes, and should not be considered a secure method of persisting wallets.
+
Alternatively, you can use the save_seed! function to persist a wallet's seed to a local file. This is a convenience function purely for testing purposes, and should not be considered a secure method of persisting wallets.
-
# Set encrypt: true to encrypt the wallet export data with your CDP API key.
-u.save_wallet_locally!(w1,encrypt:true)
+
# Pick a file to which to save your wallet seed.
+file_path='my_seed.json'
-puts"Wallet #{w1.id} successfully saved to local file storage."
+# Set encrypt: true to encrypt the wallet seed with your CDP API key.
+w1.save_seed!(file_path,encrypt:true)
+
+puts"Seed for wallet #{w1.id} successfully saved to #{file_path}."
Re-instantiating a Wallet
@@ -276,15 +284,14 @@
Re-instantiating a Wallet
w3=u.import_wallet(fetched_data)
-
If you used the save_wallet_locally! function to persist wallets on your local file system, then you can use the load_wallets_from_local function re-instantiate the wallets.
-
-
# wallets will contain a Hash from wallet ID to wallet.
-wallets=u.load_wallets_from_local
+
If you used the save_seed! function to persist a wallet's seed to a local file, then you can first fetch the unhydrated wallet from the server, and then use the load_seed method to re-instantiate the wallet.
-puts"Wallets successfully loaded from local file storage."
+
# Get the unhydrated wallet from the server.
+w4=u.wallet(w1.id)
-# w4 will be equivalent to w1 and w3.
-w4=wallets[w1.id]
+# You can now load the seed into the wallet from the local file.
+# w4 will be equivalent to w1.
+w4.load_seed(file_path)
Alternatively, you can use the save_wallet_locally! function to persist wallets on your local file system. This is a convenience function purely for testing purposes, and should not be considered a secure method of persisting wallets.
+
Alternatively, you can use the save_seed! function to persist a wallet's seed to a local file. This is a convenience function purely for testing purposes, and should not be considered a secure method of persisting wallets.
-
# Set encrypt: true to encrypt the wallet export data with your CDP API key.
-u.save_wallet_locally!(w1,encrypt:true)
+
# Pick a file to which to save your wallet seed.
+file_path='my_seed.json'
-puts"Wallet #{w1.id} successfully saved to local file storage."
+# Set encrypt: true to encrypt the wallet seed with your CDP API key.
+w1.save_seed!(file_path,encrypt:true)
+
+puts"Seed for wallet #{w1.id} successfully saved to #{file_path}."
Re-instantiating a Wallet
@@ -276,15 +284,14 @@
Re-instantiating a Wallet
w3=u.import_wallet(fetched_data)
-
If you used the save_wallet_locally! function to persist wallets on your local file system, then you can use the load_wallets_from_local function re-instantiate the wallets.
-
-
# wallets will contain a Hash from wallet ID to wallet.
-wallets=u.load_wallets_from_local
+
If you used the save_seed! function to persist a wallet's seed to a local file, then you can first fetch the unhydrated wallet from the server, and then use the load_seed method to re-instantiate the wallet.
-puts"Wallets successfully loaded from local file storage."
+
# Get the unhydrated wallet from the server.
+w4=u.wallet(w1.id)
-# w4 will be equivalent to w1 and w3.
-w4=wallets[w1.id]
+# You can now load the seed into the wallet from the local file.
+# w4 will be equivalent to w1.
+w4.load_seed(file_path)
diff --git a/lib/coinbase.rb b/lib/coinbase.rb
index 5031bd40..9db31c64 100644
--- a/lib/coinbase.rb
+++ b/lib/coinbase.rb
@@ -27,27 +27,33 @@ def self.configuration
end
# Configures the Coinbase SDK.
+ # @return [String] A string indicating successful configuration
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
+
+ 'Successfully configured Coinbase SDK'
end
# Configures the Coinbase SDK from the given CDP API Key JSON file.
# @param file_path [String] (Optional) the path to the CDP API Key JSON file
# file in the root directory by default.
- def self.configure_from_json(file_path = 'coinbase_cloud_api_key.json')
+ # @return [String] A string indicating successful configuration
+ def self.configure_from_json(file_path = 'cdp_api_key.json')
configuration.from_json(file_path)
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
+
+ 'Successfully configured Coinbase SDK'
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, :debug_api, :backup_file_path
+ attr_accessor :api_url, :api_key_name, :api_key_private_key, :debug_api, :use_server_signer
# Initializes the configuration object.
def initialize
@@ -55,13 +61,13 @@ def initialize
@base_sepolia_client = Jimson::Client.new(@base_sepolia_rpc_url)
@api_url = 'https://api.cdp.coinbase.com'
@debug_api = false
- @backup_file_path = 'seeds.json'
+ @use_server_signer = false
end
# Sets configuration values based on the provided CDP API Key JSON file.
# @param file_path [String] (Optional) the path to the CDP API Key JSON file
# file in the root directory by default.
- def from_json(file_path = 'coinbase_cloud_api_key.json')
+ def from_json(file_path = 'cdp_api_key.json')
# Expand paths to respect shortcuts like ~.
file_path = File.expand_path(file_path)
@@ -117,4 +123,10 @@ def self.call_api
rescue StandardError => e
raise e
end
+
+ # Returns whether to use a server signer to manage private keys.
+ # @return [bool] whether to use a server signer to manage private keys.
+ def self.use_server_signer?
+ Coinbase.configuration.use_server_signer
+ end
end
diff --git a/lib/coinbase/address.rb b/lib/coinbase/address.rb
index 86c718aa..1bcd2f35 100644
--- a/lib/coinbase/address.rb
+++ b/lib/coinbase/address.rb
@@ -71,59 +71,26 @@ def balance(asset_id)
Coinbase::Balance.from_model_and_asset_id(response, asset_id).amount
end
- # Transfers the given amount of the given Asset to the given address. Only same-Network Transfers are supported.
+ # Transfers the given amount of the given Asset to the specified address or wallet.
+ # Only same-network Transfers are supported.
# @param amount [Integer, Float, BigDecimal] The amount of the Asset to send.
# @param asset_id [Symbol] The ID of the Asset to send. For Ether, :eth, :gwei, and :wei are supported.
# @param destination [Wallet | Address | String] The destination of the transfer. If a Wallet, sends to the Wallet's
# 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)
- raise 'Cannot transfer from address without private key loaded' if @key.nil?
+ destination_address, destination_network = destination_address_and_network(destination)
- raise ArgumentError, "Unsupported asset: #{asset_id}" unless Coinbase::Asset.supported?(asset_id)
-
- if destination.is_a?(Wallet)
- raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != network_id
+ validate_can_transfer!(amount, asset_id, destination_network)
- destination = destination.default_address.id
- elsif destination.is_a?(Address)
- raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != network_id
+ transfer = create_transfer(amount, asset_id, destination_address)
- destination = destination.id
- end
-
- current_balance = balance(asset_id)
- if current_balance < amount
- raise ArgumentError, "Insufficient funds: #{amount} requested, but only #{current_balance} available"
- end
-
- create_transfer_request = {
- amount: Coinbase::Asset.to_atomic_amount(amount, asset_id).to_i.to_s,
- network_id: network_id,
- asset_id: Coinbase::Asset.primary_denomination(asset_id).to_s,
- destination: destination
- }
-
- transfer_model = Coinbase.call_api do
- transfers_api.create_transfer(wallet_id, id, create_transfer_request)
- end
+ # If a server signer is managing keys, it will sign and broadcast the underlying transfer transaction out of band.
+ return transfer if Coinbase.use_server_signer?
- transfer = Coinbase::Transfer.new(transfer_model)
+ signed_payload = sign_transfer(transfer)
- transaction = transfer.transaction
- transaction.sign(@key)
-
- signed_payload = transaction.hex
-
- broadcast_transfer_request = {
- signed_payload: signed_payload
- }
-
- transfer_model = Coinbase.call_api do
- transfers_api.broadcast_transfer(wallet_id, id, transfer.id, broadcast_transfer_request)
- end
-
- Coinbase::Transfer.new(transfer_model)
+ broadcast_transfer(transfer, signed_payload)
end
# Returns whether the Address has a private key backing it to sign transactions.
@@ -170,12 +137,13 @@ def transfers
page = nil
loop do
- puts "fetch transfers page: #{page}"
response = Coinbase.call_api do
transfers_api.list_transfers(wallet_id, id, { limit: 100, page: page })
end
- transfers.concat(response.data.map { |transfer| Coinbase::Transfer.new(transfer) }) if response.data
+ break if response.data.empty?
+
+ transfers.concat(response.data.map { |transfer| Coinbase::Transfer.new(transfer) })
break unless response.has_more
@@ -194,5 +162,56 @@ def addresses_api
def transfers_api
@transfers_api ||= Coinbase::Client::TransfersApi.new(Coinbase.configuration.api_client)
end
+
+ def destination_address_and_network(destination)
+ return [destination.default_address.id, destination.network_id] if destination.is_a?(Wallet)
+ return [destination.id, destination.network_id] if destination.is_a?(Address)
+
+ [destination, network_id]
+ end
+
+ def validate_can_transfer!(amount, asset_id, destination_network_id)
+ raise 'Cannot transfer from address without private key loaded' unless can_sign? || Coinbase.use_server_signer?
+
+ raise ArgumentError, "Unsupported asset: #{asset_id}" unless Coinbase::Asset.supported?(asset_id)
+
+ raise ArgumentError, 'Transfer must be on the same Network' unless destination_network_id == network_id
+
+ current_balance = balance(asset_id)
+
+ return unless current_balance < amount
+
+ raise ArgumentError, "Insufficient funds: #{amount} requested, but only #{current_balance} available"
+ end
+
+ def create_transfer(amount, asset_id, destination)
+ create_transfer_request = {
+ amount: Coinbase::Asset.to_atomic_amount(amount, asset_id).to_i.to_s,
+ network_id: network_id,
+ asset_id: Coinbase::Asset.primary_denomination(asset_id).to_s,
+ destination: destination
+ }
+
+ transfer_model = Coinbase.call_api do
+ transfers_api.create_transfer(wallet_id, id, create_transfer_request)
+ end
+
+ Coinbase::Transfer.new(transfer_model)
+ end
+
+ def sign_transfer(transfer)
+ transaction = transfer.transaction
+ transaction.sign(@key)
+
+ transaction.hex
+ end
+
+ def broadcast_transfer(transfer, signed_payload)
+ transfer_model = Coinbase.call_api do
+ transfers_api.broadcast_transfer(wallet_id, id, transfer.id, { signed_payload: signed_payload })
+ end
+
+ Coinbase::Transfer.new(transfer_model)
+ end
end
end
diff --git a/lib/coinbase/authenticator.rb b/lib/coinbase/authenticator.rb
index 1eb90a6a..d4221686 100644
--- a/lib/coinbase/authenticator.rb
+++ b/lib/coinbase/authenticator.rb
@@ -38,7 +38,7 @@ def build_jwt(uri)
claims = {
sub: Coinbase.configuration.api_key_name,
- iss: 'coinbase-cloud',
+ iss: 'cdp',
aud: ['cdp_service'],
nbf: Time.now.to_i,
exp: Time.now.to_i + 60, # Expiration time: 1 minute from now.
diff --git a/lib/coinbase/client.rb b/lib/coinbase/client.rb
index 77db6167..a674082c 100644
--- a/lib/coinbase/client.rb
+++ b/lib/coinbase/client.rb
@@ -22,12 +22,28 @@
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 :BroadcastTradeRequest, 'coinbase/client/models/broadcast_trade_request'
Coinbase::Client.autoload :BroadcastTransferRequest, 'coinbase/client/models/broadcast_transfer_request'
Coinbase::Client.autoload :CreateAddressRequest, 'coinbase/client/models/create_address_request'
+Coinbase::Client.autoload :CreateServerSignerRequest, 'coinbase/client/models/create_server_signer_request'
+Coinbase::Client.autoload :CreateTradeRequest, 'coinbase/client/models/create_trade_request'
Coinbase::Client.autoload :CreateTransferRequest, 'coinbase/client/models/create_transfer_request'
Coinbase::Client.autoload :CreateWalletRequest, 'coinbase/client/models/create_wallet_request'
+Coinbase::Client.autoload :CreateWalletRequestWallet, 'coinbase/client/models/create_wallet_request_wallet'
Coinbase::Client.autoload :Error, 'coinbase/client/models/error'
Coinbase::Client.autoload :FaucetTransaction, 'coinbase/client/models/faucet_transaction'
+Coinbase::Client.autoload :SeedCreationEvent, 'coinbase/client/models/seed_creation_event'
+Coinbase::Client.autoload :SeedCreationEventResult, 'coinbase/client/models/seed_creation_event_result'
+Coinbase::Client.autoload :ServerSigner, 'coinbase/client/models/server_signer'
+Coinbase::Client.autoload :ServerSignerEvent, 'coinbase/client/models/server_signer_event'
+Coinbase::Client.autoload :ServerSignerEventEvent, 'coinbase/client/models/server_signer_event_event'
+Coinbase::Client.autoload :ServerSignerEventList, 'coinbase/client/models/server_signer_event_list'
+Coinbase::Client.autoload :SignatureCreationEvent, 'coinbase/client/models/signature_creation_event'
+Coinbase::Client.autoload :SignatureCreationEventResult, 'coinbase/client/models/signature_creation_event_result'
+Coinbase::Client.autoload :Trade, 'coinbase/client/models/trade'
+Coinbase::Client.autoload :TradeList, 'coinbase/client/models/trade_list'
+Coinbase::Client.autoload :Transaction, 'coinbase/client/models/transaction'
+Coinbase::Client.autoload :TransactionType, 'coinbase/client/models/transaction_type'
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'
@@ -36,6 +52,8 @@
# APIs
Coinbase::Client.autoload :AddressesApi, 'coinbase/client/api/addresses_api'
+Coinbase::Client.autoload :ServerSignersApi, 'coinbase/client/api/server_signers_api'
+Coinbase::Client.autoload :TradesApi, 'coinbase/client/api/trades_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'
diff --git a/lib/coinbase/client/api/server_signers_api.rb b/lib/coinbase/client/api/server_signers_api.rb
new file mode 100644
index 00000000..46c8fd7b
--- /dev/null
+++ b/lib/coinbase/client/api/server_signers_api.rb
@@ -0,0 +1,419 @@
+=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 ServerSignersApi
+ attr_accessor :api_client
+
+ def initialize(api_client = ApiClient.default)
+ @api_client = api_client
+ end
+ # Create a new Server-Signer
+ # Create a new Server-Signer
+ # @param [Hash] opts the optional parameters
+ # @option opts [CreateServerSignerRequest] :create_server_signer_request
+ # @return [ServerSigner]
+ def create_server_signer(opts = {})
+ data, _status_code, _headers = create_server_signer_with_http_info(opts)
+ data
+ end
+
+ # Create a new Server-Signer
+ # Create a new Server-Signer
+ # @param [Hash] opts the optional parameters
+ # @option opts [CreateServerSignerRequest] :create_server_signer_request
+ # @return [Array<(ServerSigner, Integer, Hash)>] ServerSigner data, response status code and response headers
+ def create_server_signer_with_http_info(opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: ServerSignersApi.create_server_signer ...'
+ end
+ # resource path
+ local_var_path = '/v1/server_signers'
+
+ # 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_server_signer_request'])
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'ServerSigner'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"ServerSignersApi.create_server_signer",
+ :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: ServerSignersApi#create_server_signer\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # Get a server signer by ID
+ # Get a server signer by ID
+ # @param server_signer_id [String] The ID of the server signer to fetch
+ # @param [Hash] opts the optional parameters
+ # @return [ServerSigner]
+ def get_server_signer(server_signer_id, opts = {})
+ data, _status_code, _headers = get_server_signer_with_http_info(server_signer_id, opts)
+ data
+ end
+
+ # Get a server signer by ID
+ # Get a server signer by ID
+ # @param server_signer_id [String] The ID of the server signer to fetch
+ # @param [Hash] opts the optional parameters
+ # @return [Array<(ServerSigner, Integer, Hash)>] ServerSigner data, response status code and response headers
+ def get_server_signer_with_http_info(server_signer_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: ServerSignersApi.get_server_signer ...'
+ end
+ # verify the required parameter 'server_signer_id' is set
+ if @api_client.config.client_side_validation && server_signer_id.nil?
+ fail ArgumentError, "Missing the required parameter 'server_signer_id' when calling ServerSignersApi.get_server_signer"
+ end
+ # resource path
+ local_var_path = '/v1/server_signers/{server_signer_id}'.sub('{' + 'server_signer_id' + '}', CGI.escape(server_signer_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] || 'ServerSigner'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"ServerSignersApi.get_server_signer",
+ :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: ServerSignersApi#get_server_signer\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # List events for a server signer
+ # List events for a server signer
+ # @param server_signer_id [String] The ID of the server signer to fetch events 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 [ServerSignerEventList]
+ def list_server_signer_events(server_signer_id, opts = {})
+ data, _status_code, _headers = list_server_signer_events_with_http_info(server_signer_id, opts)
+ data
+ end
+
+ # List events for a server signer
+ # List events for a server signer
+ # @param server_signer_id [String] The ID of the server signer to fetch events 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<(ServerSignerEventList, Integer, Hash)>] ServerSignerEventList data, response status code and response headers
+ def list_server_signer_events_with_http_info(server_signer_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: ServerSignersApi.list_server_signer_events ...'
+ end
+ # verify the required parameter 'server_signer_id' is set
+ if @api_client.config.client_side_validation && server_signer_id.nil?
+ fail ArgumentError, "Missing the required parameter 'server_signer_id' when calling ServerSignersApi.list_server_signer_events"
+ 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 ServerSignersApi.list_server_signer_events, the character length must be smaller than or equal to 5000.'
+ end
+
+ # resource path
+ local_var_path = '/v1/server_signers/{server_signer_id}/events'.sub('{' + 'server_signer_id' + '}', CGI.escape(server_signer_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] || 'ServerSignerEventList'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"ServerSignersApi.list_server_signer_events",
+ :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: ServerSignersApi#list_server_signer_events\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # List server signers for the current project
+ # List server signers for the current project
+ # @param [Hash] opts the optional parameters
+ # @return [ServerSigner]
+ def list_server_signers(opts = {})
+ data, _status_code, _headers = list_server_signers_with_http_info(opts)
+ data
+ end
+
+ # List server signers for the current project
+ # List server signers for the current project
+ # @param [Hash] opts the optional parameters
+ # @return [Array<(ServerSigner, Integer, Hash)>] ServerSigner data, response status code and response headers
+ def list_server_signers_with_http_info(opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: ServerSignersApi.list_server_signers ...'
+ end
+ # resource path
+ local_var_path = '/v1/server_signers'
+
+ # 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] || 'ServerSigner'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"ServerSignersApi.list_server_signers",
+ :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: ServerSignersApi#list_server_signers\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # Submit the result of a server signer event
+ # Submit the result of a server signer event
+ # @param server_signer_id [String] The ID of the server signer to submit the event result for
+ # @param [Hash] opts the optional parameters
+ # @option opts [SeedCreationEventResult] :seed_creation_event_result
+ # @return [SeedCreationEventResult]
+ def submit_server_signer_seed_event_result(server_signer_id, opts = {})
+ data, _status_code, _headers = submit_server_signer_seed_event_result_with_http_info(server_signer_id, opts)
+ data
+ end
+
+ # Submit the result of a server signer event
+ # Submit the result of a server signer event
+ # @param server_signer_id [String] The ID of the server signer to submit the event result for
+ # @param [Hash] opts the optional parameters
+ # @option opts [SeedCreationEventResult] :seed_creation_event_result
+ # @return [Array<(SeedCreationEventResult, Integer, Hash)>] SeedCreationEventResult data, response status code and response headers
+ def submit_server_signer_seed_event_result_with_http_info(server_signer_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: ServerSignersApi.submit_server_signer_seed_event_result ...'
+ end
+ # verify the required parameter 'server_signer_id' is set
+ if @api_client.config.client_side_validation && server_signer_id.nil?
+ fail ArgumentError, "Missing the required parameter 'server_signer_id' when calling ServerSignersApi.submit_server_signer_seed_event_result"
+ end
+ # resource path
+ local_var_path = '/v1/server_signers/{server_signer_id}/seed_event_result'.sub('{' + 'server_signer_id' + '}', CGI.escape(server_signer_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[:'seed_creation_event_result'])
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'SeedCreationEventResult'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"ServerSignersApi.submit_server_signer_seed_event_result",
+ :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: ServerSignersApi#submit_server_signer_seed_event_result\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # Submit the result of a server signer event
+ # Submit the result of a server signer event
+ # @param server_signer_id [String] The ID of the server signer to submit the event result for
+ # @param [Hash] opts the optional parameters
+ # @option opts [SignatureCreationEventResult] :signature_creation_event_result
+ # @return [SignatureCreationEventResult]
+ def submit_server_signer_signature_event_result(server_signer_id, opts = {})
+ data, _status_code, _headers = submit_server_signer_signature_event_result_with_http_info(server_signer_id, opts)
+ data
+ end
+
+ # Submit the result of a server signer event
+ # Submit the result of a server signer event
+ # @param server_signer_id [String] The ID of the server signer to submit the event result for
+ # @param [Hash] opts the optional parameters
+ # @option opts [SignatureCreationEventResult] :signature_creation_event_result
+ # @return [Array<(SignatureCreationEventResult, Integer, Hash)>] SignatureCreationEventResult data, response status code and response headers
+ def submit_server_signer_signature_event_result_with_http_info(server_signer_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: ServerSignersApi.submit_server_signer_signature_event_result ...'
+ end
+ # verify the required parameter 'server_signer_id' is set
+ if @api_client.config.client_side_validation && server_signer_id.nil?
+ fail ArgumentError, "Missing the required parameter 'server_signer_id' when calling ServerSignersApi.submit_server_signer_signature_event_result"
+ end
+ # resource path
+ local_var_path = '/v1/server_signers/{server_signer_id}/signature_event_result'.sub('{' + 'server_signer_id' + '}', CGI.escape(server_signer_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[:'signature_creation_event_result'])
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'SignatureCreationEventResult'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"ServerSignersApi.submit_server_signer_signature_event_result",
+ :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: ServerSignersApi#submit_server_signer_signature_event_result\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/trades_api.rb b/lib/coinbase/client/api/trades_api.rb
new file mode 100644
index 00000000..58e8fdfc
--- /dev/null
+++ b/lib/coinbase/client/api/trades_api.rb
@@ -0,0 +1,342 @@
+=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 TradesApi
+ attr_accessor :api_client
+
+ def initialize(api_client = ApiClient.default)
+ @api_client = api_client
+ end
+ # Broadcast a trade
+ # Broadcast a trade
+ # @param wallet_id [String] The ID of the wallet the address belongs to
+ # @param address_id [String] The ID of the address the trade belongs to
+ # @param trade_id [String] The ID of the trade to broadcast
+ # @param broadcast_trade_request [BroadcastTradeRequest]
+ # @param [Hash] opts the optional parameters
+ # @return [Trade]
+ def broadcast_trade(wallet_id, address_id, trade_id, broadcast_trade_request, opts = {})
+ data, _status_code, _headers = broadcast_trade_with_http_info(wallet_id, address_id, trade_id, broadcast_trade_request, opts)
+ data
+ end
+
+ # Broadcast a trade
+ # Broadcast a trade
+ # @param wallet_id [String] The ID of the wallet the address belongs to
+ # @param address_id [String] The ID of the address the trade belongs to
+ # @param trade_id [String] The ID of the trade to broadcast
+ # @param broadcast_trade_request [BroadcastTradeRequest]
+ # @param [Hash] opts the optional parameters
+ # @return [Array<(Trade, Integer, Hash)>] Trade data, response status code and response headers
+ def broadcast_trade_with_http_info(wallet_id, address_id, trade_id, broadcast_trade_request, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: TradesApi.broadcast_trade ...'
+ 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 TradesApi.broadcast_trade"
+ 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 TradesApi.broadcast_trade"
+ end
+ # verify the required parameter 'trade_id' is set
+ if @api_client.config.client_side_validation && trade_id.nil?
+ fail ArgumentError, "Missing the required parameter 'trade_id' when calling TradesApi.broadcast_trade"
+ end
+ # verify the required parameter 'broadcast_trade_request' is set
+ if @api_client.config.client_side_validation && broadcast_trade_request.nil?
+ fail ArgumentError, "Missing the required parameter 'broadcast_trade_request' when calling TradesApi.broadcast_trade"
+ end
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/trades/{trade_id}/broadcast'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s)).sub('{' + 'trade_id' + '}', CGI.escape(trade_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(broadcast_trade_request)
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'Trade'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"TradesApi.broadcast_trade",
+ :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: TradesApi#broadcast_trade\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # Create a new trade for an address
+ # Create a new trade
+ # @param wallet_id [String] The ID of the wallet the source address belongs to
+ # @param address_id [String] The ID of the address to conduct the trade from
+ # @param create_trade_request [CreateTradeRequest]
+ # @param [Hash] opts the optional parameters
+ # @return [Trade]
+ def create_trade(wallet_id, address_id, create_trade_request, opts = {})
+ data, _status_code, _headers = create_trade_with_http_info(wallet_id, address_id, create_trade_request, opts)
+ data
+ end
+
+ # Create a new trade for an address
+ # Create a new trade
+ # @param wallet_id [String] The ID of the wallet the source address belongs to
+ # @param address_id [String] The ID of the address to conduct the trade from
+ # @param create_trade_request [CreateTradeRequest]
+ # @param [Hash] opts the optional parameters
+ # @return [Array<(Trade, Integer, Hash)>] Trade data, response status code and response headers
+ def create_trade_with_http_info(wallet_id, address_id, create_trade_request, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: TradesApi.create_trade ...'
+ 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 TradesApi.create_trade"
+ 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 TradesApi.create_trade"
+ end
+ # verify the required parameter 'create_trade_request' is set
+ if @api_client.config.client_side_validation && create_trade_request.nil?
+ fail ArgumentError, "Missing the required parameter 'create_trade_request' when calling TradesApi.create_trade"
+ end
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/trades'.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_trade_request)
+
+ # return_type
+ return_type = opts[:debug_return_type] || 'Trade'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"TradesApi.create_trade",
+ :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: TradesApi#create_trade\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # Get a trade by ID
+ # Get a trade 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 trade belongs to
+ # @param trade_id [String] The ID of the trade to fetch
+ # @param [Hash] opts the optional parameters
+ # @return [Trade]
+ def get_trade(wallet_id, address_id, trade_id, opts = {})
+ data, _status_code, _headers = get_trade_with_http_info(wallet_id, address_id, trade_id, opts)
+ data
+ end
+
+ # Get a trade by ID
+ # Get a trade 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 trade belongs to
+ # @param trade_id [String] The ID of the trade to fetch
+ # @param [Hash] opts the optional parameters
+ # @return [Array<(Trade, Integer, Hash)>] Trade data, response status code and response headers
+ def get_trade_with_http_info(wallet_id, address_id, trade_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: TradesApi.get_trade ...'
+ 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 TradesApi.get_trade"
+ 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 TradesApi.get_trade"
+ end
+ # verify the required parameter 'trade_id' is set
+ if @api_client.config.client_side_validation && trade_id.nil?
+ fail ArgumentError, "Missing the required parameter 'trade_id' when calling TradesApi.get_trade"
+ end
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/trades/{trade_id}'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s)).sub('{' + 'trade_id' + '}', CGI.escape(trade_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] || 'Trade'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"TradesApi.get_trade",
+ :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: TradesApi#get_trade\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+
+ # List trades for an address.
+ # List trades 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 trades 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 [TradeList]
+ def list_trades(wallet_id, address_id, opts = {})
+ data, _status_code, _headers = list_trades_with_http_info(wallet_id, address_id, opts)
+ data
+ end
+
+ # List trades for an address.
+ # List trades 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 trades 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<(TradeList, Integer, Hash)>] TradeList data, response status code and response headers
+ def list_trades_with_http_info(wallet_id, address_id, opts = {})
+ if @api_client.config.debugging
+ @api_client.config.logger.debug 'Calling API: TradesApi.list_trades ...'
+ 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 TradesApi.list_trades"
+ 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 TradesApi.list_trades"
+ 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 TradesApi.list_trades, the character length must be smaller than or equal to 5000.'
+ end
+
+ # resource path
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/trades'.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] || 'TradeList'
+
+ # auth_names
+ auth_names = opts[:debug_auth_names] || []
+
+ new_options = opts.merge(
+ :operation => :"TradesApi.list_trades",
+ :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: TradesApi#list_trades\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
+ end
+ return data, status_code, headers
+ end
+ end
+end
diff --git a/lib/coinbase/client/models/broadcast_trade_request.rb b/lib/coinbase/client/models/broadcast_trade_request.rb
new file mode 100644
index 00000000..f6cd7e7f
--- /dev/null
+++ b/lib/coinbase/client/models/broadcast_trade_request.rb
@@ -0,0 +1,222 @@
+=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 BroadcastTradeRequest
+ # The hex-encoded signed payload of the trade
+ attr_accessor :signed_payload
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'signed_payload' => :'signed_payload'
+ }
+ 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
+ {
+ :'signed_payload' => :'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::BroadcastTradeRequest` 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::BroadcastTradeRequest`. 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?(:'signed_payload')
+ self.signed_payload = attributes[:'signed_payload']
+ else
+ self.signed_payload = 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 @signed_payload.nil?
+ invalid_properties.push('invalid value for "signed_payload", signed_payload 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 @signed_payload.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 &&
+ signed_payload == o.signed_payload
+ 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
+ [signed_payload].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
index 97f67a83..003cde45 100644
--- a/lib/coinbase/client/models/create_address_request.rb
+++ b/lib/coinbase/client/models/create_address_request.rb
@@ -65,14 +65,10 @@ def initialize(attributes = {})
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
@@ -81,14 +77,6 @@ def initialize(attributes = {})
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
@@ -96,8 +84,6 @@ def list_invalid_properties
# @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
diff --git a/lib/coinbase/client/models/create_server_signer_request.rb b/lib/coinbase/client/models/create_server_signer_request.rb
new file mode 100644
index 00000000..36c8f73c
--- /dev/null
+++ b/lib/coinbase/client/models/create_server_signer_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 CreateServerSignerRequest
+ # The ID of the server signer
+ attr_accessor :server_signer_id
+
+ # The enrollment data of the server signer. This will be the base64 encoded server-signer-id.
+ attr_accessor :enrollment_data
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'server_signer_id' => :'server_signer_id',
+ :'enrollment_data' => :'enrollment_data'
+ }
+ 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
+ {
+ :'server_signer_id' => :'String',
+ :'enrollment_data' => :'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::CreateServerSignerRequest` 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::CreateServerSignerRequest`. 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?(:'server_signer_id')
+ self.server_signer_id = attributes[:'server_signer_id']
+ else
+ self.server_signer_id = nil
+ end
+
+ if attributes.key?(:'enrollment_data')
+ self.enrollment_data = attributes[:'enrollment_data']
+ else
+ self.enrollment_data = 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 @server_signer_id.nil?
+ invalid_properties.push('invalid value for "server_signer_id", server_signer_id cannot be nil.')
+ end
+
+ if @enrollment_data.nil?
+ invalid_properties.push('invalid value for "enrollment_data", enrollment_data 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 @server_signer_id.nil?
+ return false if @enrollment_data.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 &&
+ server_signer_id == o.server_signer_id &&
+ enrollment_data == o.enrollment_data
+ 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
+ [server_signer_id, enrollment_data].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_trade_request.rb b/lib/coinbase/client/models/create_trade_request.rb
new file mode 100644
index 00000000..71e20dee
--- /dev/null
+++ b/lib/coinbase/client/models/create_trade_request.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 'date'
+require 'time'
+
+module Coinbase::Client
+ class CreateTradeRequest
+ # The amount to trade
+ attr_accessor :amount
+
+ # The ID of the asset to trade
+ attr_accessor :from_asset_id
+
+ # The ID of the asset to receive from the trade
+ attr_accessor :to_asset_id
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'amount' => :'amount',
+ :'from_asset_id' => :'from_asset_id',
+ :'to_asset_id' => :'to_asset_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
+ {
+ :'amount' => :'String',
+ :'from_asset_id' => :'String',
+ :'to_asset_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::CreateTradeRequest` 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::CreateTradeRequest`. 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?(:'from_asset_id')
+ self.from_asset_id = attributes[:'from_asset_id']
+ else
+ self.from_asset_id = nil
+ end
+
+ if attributes.key?(:'to_asset_id')
+ self.to_asset_id = attributes[:'to_asset_id']
+ else
+ self.to_asset_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 @amount.nil?
+ invalid_properties.push('invalid value for "amount", amount cannot be nil.')
+ end
+
+ if @from_asset_id.nil?
+ invalid_properties.push('invalid value for "from_asset_id", from_asset_id cannot be nil.')
+ end
+
+ if @to_asset_id.nil?
+ invalid_properties.push('invalid value for "to_asset_id", to_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 @amount.nil?
+ return false if @from_asset_id.nil?
+ return false if @to_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 &&
+ amount == o.amount &&
+ from_asset_id == o.from_asset_id &&
+ to_asset_id == o.to_asset_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
+ [amount, from_asset_id, to_asset_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/create_wallet_request.rb b/lib/coinbase/client/models/create_wallet_request.rb
index 06c5f445..69f18f79 100644
--- a/lib/coinbase/client/models/create_wallet_request.rb
+++ b/lib/coinbase/client/models/create_wallet_request.rb
@@ -32,7 +32,7 @@ def self.acceptable_attributes
# Attribute type mapping.
def self.openapi_types
{
- :'wallet' => :'Wallet'
+ :'wallet' => :'CreateWalletRequestWallet'
}
end
diff --git a/lib/coinbase/client/models/create_wallet_request_wallet.rb b/lib/coinbase/client/models/create_wallet_request_wallet.rb
new file mode 100644
index 00000000..ba108937
--- /dev/null
+++ b/lib/coinbase/client/models/create_wallet_request_wallet.rb
@@ -0,0 +1,233 @@
+=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
+ # Parameters for configuring a wallet
+ class CreateWalletRequestWallet
+ # The ID of the blockchain network
+ attr_accessor :network_id
+
+ # Whether the wallet should use the project's server signer or if the addresses in the wallets will belong to a private key the developer manages. Defaults to false.
+ attr_accessor :use_server_signer
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'network_id' => :'network_id',
+ :'use_server_signer' => :'use_server_signer'
+ }
+ 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',
+ :'use_server_signer' => :'Boolean'
+ }
+ 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::CreateWalletRequestWallet` 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::CreateWalletRequestWallet`. 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?(:'use_server_signer')
+ self.use_server_signer = attributes[:'use_server_signer']
+ 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 &&
+ network_id == o.network_id &&
+ use_server_signer == o.use_server_signer
+ 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, use_server_signer].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/seed_creation_event.rb b/lib/coinbase/client/models/seed_creation_event.rb
new file mode 100644
index 00000000..5256ad53
--- /dev/null
+++ b/lib/coinbase/client/models/seed_creation_event.rb
@@ -0,0 +1,240 @@
+=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 event representing a seed creation.
+ class SeedCreationEvent
+ # The ID of the wallet that the server-signer should create the seed for
+ attr_accessor :wallet_id
+
+ # The ID of the user that the wallet belongs to
+ attr_accessor :wallet_user_id
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'wallet_id' => :'wallet_id',
+ :'wallet_user_id' => :'wallet_user_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',
+ :'wallet_user_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::SeedCreationEvent` 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::SeedCreationEvent`. 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?(:'wallet_user_id')
+ self.wallet_user_id = attributes[:'wallet_user_id']
+ else
+ self.wallet_user_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 @wallet_user_id.nil?
+ invalid_properties.push('invalid value for "wallet_user_id", wallet_user_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 @wallet_user_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 &&
+ wallet_user_id == o.wallet_user_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, wallet_user_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/seed_creation_event_result.rb b/lib/coinbase/client/models/seed_creation_event_result.rb
new file mode 100644
index 00000000..bd1bf136
--- /dev/null
+++ b/lib/coinbase/client/models/seed_creation_event_result.rb
@@ -0,0 +1,274 @@
+=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 result to a SeedCreationEvent.
+ class SeedCreationEventResult
+ # The ID of the wallet that the seed was created for
+ attr_accessor :wallet_id
+
+ # The ID of the user that the wallet belongs to
+ attr_accessor :wallet_user_id
+
+ # The extended public key for the first master key derived from seed.
+ attr_accessor :extended_public_key
+
+ # The ID of the seed in Server-Signer used to generate the extended public key.
+ attr_accessor :seed_id
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'wallet_id' => :'wallet_id',
+ :'wallet_user_id' => :'wallet_user_id',
+ :'extended_public_key' => :'extended_public_key',
+ :'seed_id' => :'seed_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',
+ :'wallet_user_id' => :'String',
+ :'extended_public_key' => :'String',
+ :'seed_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::SeedCreationEventResult` 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::SeedCreationEventResult`. 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?(:'wallet_user_id')
+ self.wallet_user_id = attributes[:'wallet_user_id']
+ else
+ self.wallet_user_id = nil
+ end
+
+ if attributes.key?(:'extended_public_key')
+ self.extended_public_key = attributes[:'extended_public_key']
+ else
+ self.extended_public_key = nil
+ end
+
+ if attributes.key?(:'seed_id')
+ self.seed_id = attributes[:'seed_id']
+ else
+ self.seed_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 @wallet_user_id.nil?
+ invalid_properties.push('invalid value for "wallet_user_id", wallet_user_id cannot be nil.')
+ end
+
+ if @extended_public_key.nil?
+ invalid_properties.push('invalid value for "extended_public_key", extended_public_key cannot be nil.')
+ end
+
+ if @seed_id.nil?
+ invalid_properties.push('invalid value for "seed_id", seed_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 @wallet_user_id.nil?
+ return false if @extended_public_key.nil?
+ return false if @seed_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 &&
+ wallet_user_id == o.wallet_user_id &&
+ extended_public_key == o.extended_public_key &&
+ seed_id == o.seed_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, wallet_user_id, extended_public_key, seed_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/server_signer.rb b/lib/coinbase/client/models/server_signer.rb
new file mode 100644
index 00000000..3ebcff38
--- /dev/null
+++ b/lib/coinbase/client/models/server_signer.rb
@@ -0,0 +1,235 @@
+=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 Server-Signer assigned to sign transactions in a wallet.
+ class ServerSigner
+ # The ID of the server-signer
+ attr_accessor :server_signer_id
+
+ # The IDs of the wallets that the server-signer can sign for
+ attr_accessor :wallets
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'server_signer_id' => :'server_signer_id',
+ :'wallets' => :'wallets'
+ }
+ 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
+ {
+ :'server_signer_id' => :'String',
+ :'wallets' => :'Array'
+ }
+ 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::ServerSigner` 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::ServerSigner`. 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?(:'server_signer_id')
+ self.server_signer_id = attributes[:'server_signer_id']
+ else
+ self.server_signer_id = nil
+ end
+
+ if attributes.key?(:'wallets')
+ if (value = attributes[:'wallets']).is_a?(Array)
+ self.wallets = value
+ end
+ 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 @server_signer_id.nil?
+ invalid_properties.push('invalid value for "server_signer_id", server_signer_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 @server_signer_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 &&
+ server_signer_id == o.server_signer_id &&
+ wallets == o.wallets
+ 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
+ [server_signer_id, wallets].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/server_signer_event.rb b/lib/coinbase/client/models/server_signer_event.rb
new file mode 100644
index 00000000..bd6a5306
--- /dev/null
+++ b/lib/coinbase/client/models/server_signer_event.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
+ # An event that is waiting to be processed by a Server-Signer.
+ class ServerSignerEvent
+ # The ID of the server-signer that the event is for
+ attr_accessor :server_signer_id
+
+ attr_accessor :event
+
+ # Attribute mapping from ruby-style variable name to JSON key.
+ def self.attribute_map
+ {
+ :'server_signer_id' => :'server_signer_id',
+ :'event' => :'event'
+ }
+ 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
+ {
+ :'server_signer_id' => :'String',
+ :'event' => :'ServerSignerEventEvent'
+ }
+ 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::ServerSignerEvent` 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::ServerSignerEvent`. 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?(:'server_signer_id')
+ self.server_signer_id = attributes[:'server_signer_id']
+ else
+ self.server_signer_id = nil
+ end
+
+ if attributes.key?(:'event')
+ self.event = attributes[:'event']
+ else
+ self.event = 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 @server_signer_id.nil?
+ invalid_properties.push('invalid value for "server_signer_id", server_signer_id cannot be nil.')
+ end
+
+ if @event.nil?
+ invalid_properties.push('invalid value for "event", event 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 @server_signer_id.nil?
+ return false if @event.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 &&
+ server_signer_id == o.server_signer_id &&
+ event == o.event
+ 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
+ [server_signer_id, event].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/server_signer_event_event.rb b/lib/coinbase/client/models/server_signer_event_event.rb
new file mode 100644
index 00000000..e9b194e7
--- /dev/null
+++ b/lib/coinbase/client/models/server_signer_event_event.rb
@@ -0,0 +1,105 @@
+=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
+ module ServerSignerEventEvent
+ class << self
+ # List of class defined in oneOf (OpenAPI v3)
+ def openapi_one_of
+ [
+ :'SeedCreationEvent',
+ :'SignatureCreationEvent'
+ ]
+ end
+
+ # Builds the object
+ # @param [Mixed] Data to be matched against the list of oneOf items
+ # @return [Object] Returns the model or the data itself
+ def build(data)
+ # Go through the list of oneOf items and attempt to identify the appropriate one.
+ # Note:
+ # - We do not attempt to check whether exactly one item matches.
+ # - No advanced validation of types in some cases (e.g. "x: { type: string }" will happily match { x: 123 })
+ # due to the way the deserialization is made in the base_object template (it just casts without verifying).
+ # - TODO: scalar values are de facto behaving as if they were nullable.
+ # - TODO: logging when debugging is set.
+ openapi_one_of.each do |klass|
+ begin
+ next if klass == :AnyType # "nullable: true"
+ typed_data = find_and_cast_into_type(klass, data)
+ return typed_data if typed_data
+ rescue # rescue all errors so we keep iterating even if the current item lookup raises
+ end
+ end
+
+ openapi_one_of.include?(:AnyType) ? data : nil
+ end
+
+ private
+
+ SchemaMismatchError = Class.new(StandardError)
+
+ # Note: 'File' is missing here because in the regular case we get the data _after_ a call to JSON.parse.
+ def find_and_cast_into_type(klass, data)
+ return if data.nil?
+
+ case klass.to_s
+ when 'Boolean'
+ return data if data.instance_of?(TrueClass) || data.instance_of?(FalseClass)
+ when 'Float'
+ return data if data.instance_of?(Float)
+ when 'Integer'
+ return data if data.instance_of?(Integer)
+ when 'Time'
+ return Time.parse(data)
+ when 'Date'
+ return Date.parse(data)
+ when 'String'
+ return data if data.instance_of?(String)
+ when 'Object' # "type: object"
+ return data if data.instance_of?(Hash)
+ when /\AArray<(?.+)>\z/ # "type: array"
+ if data.instance_of?(Array)
+ sub_type = Regexp.last_match[:sub_type]
+ return data.map { |item| find_and_cast_into_type(sub_type, item) }
+ end
+ when /\AHash.+)>\z/ # "type: object" with "additionalProperties: { ... }"
+ if data.instance_of?(Hash) && data.keys.all? { |k| k.instance_of?(Symbol) || k.instance_of?(String) }
+ sub_type = Regexp.last_match[:sub_type]
+ return data.each_with_object({}) { |(k, v), hsh| hsh[k] = find_and_cast_into_type(sub_type, v) }
+ end
+ else # model
+ const = Coinbase::Client.const_get(klass)
+ if const
+ if const.respond_to?(:openapi_one_of) # nested oneOf model
+ model = const.build(data)
+ return model if model
+ else
+ # raise if data contains keys that are not known to the model
+ raise if const.respond_to?(:acceptable_attributes) && !(data.keys - const.acceptable_attributes).empty?
+ model = const.build_from_hash(data)
+ return model if model
+ end
+ end
+ end
+
+ raise # if no match by now, raise
+ rescue
+ raise SchemaMismatchError, "#{data} doesn't match the #{klass} type"
+ end
+ end
+ end
+
+end
diff --git a/lib/coinbase/client/models/server_signer_event_list.rb b/lib/coinbase/client/models/server_signer_event_list.rb
new file mode 100644
index 00000000..1dfe11bf
--- /dev/null
+++ b/lib/coinbase/client/models/server_signer_event_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 ServerSignerEventList
+ 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 events for the server signer.
+ 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::ServerSignerEventList` 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::ServerSignerEventList`. 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/signature_creation_event.rb b/lib/coinbase/client/models/signature_creation_event.rb
new file mode 100644
index 00000000..0efd71fd
--- /dev/null
+++ b/lib/coinbase/client/models/signature_creation_event.rb
@@ -0,0 +1,363 @@
+=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 event representing a signature creation.
+ class SignatureCreationEvent
+ # The ID of the seed that the server-signer should create the signature for
+ attr_accessor :seed_id
+
+ # The ID of the wallet the signature is for
+ attr_accessor :wallet_id
+
+ # The ID of the user that the wallet belongs to
+ attr_accessor :wallet_user_id
+
+ # The ID of the address the transfer belongs to
+ attr_accessor :address_id
+
+ # The index of the address that the server-signer should sign with
+ attr_accessor :address_index
+
+ # The payload that the server-signer should sign
+ attr_accessor :signing_payload
+
+ attr_accessor :transaction_type
+
+ # The ID of the transaction that the server-signer should sign
+ attr_accessor :transaction_id
+
+ 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
+ {
+ :'seed_id' => :'seed_id',
+ :'wallet_id' => :'wallet_id',
+ :'wallet_user_id' => :'wallet_user_id',
+ :'address_id' => :'address_id',
+ :'address_index' => :'address_index',
+ :'signing_payload' => :'signing_payload',
+ :'transaction_type' => :'transaction_type',
+ :'transaction_id' => :'transaction_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
+ {
+ :'seed_id' => :'String',
+ :'wallet_id' => :'String',
+ :'wallet_user_id' => :'String',
+ :'address_id' => :'String',
+ :'address_index' => :'Integer',
+ :'signing_payload' => :'String',
+ :'transaction_type' => :'TransactionType',
+ :'transaction_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::SignatureCreationEvent` 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::SignatureCreationEvent`. 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?(:'seed_id')
+ self.seed_id = attributes[:'seed_id']
+ else
+ self.seed_id = nil
+ end
+
+ if attributes.key?(:'wallet_id')
+ self.wallet_id = attributes[:'wallet_id']
+ else
+ self.wallet_id = nil
+ end
+
+ if attributes.key?(:'wallet_user_id')
+ self.wallet_user_id = attributes[:'wallet_user_id']
+ else
+ self.wallet_user_id = nil
+ end
+
+ if attributes.key?(:'address_id')
+ self.address_id = attributes[:'address_id']
+ else
+ self.address_id = nil
+ end
+
+ if attributes.key?(:'address_index')
+ self.address_index = attributes[:'address_index']
+ else
+ self.address_index = nil
+ end
+
+ if attributes.key?(:'signing_payload')
+ self.signing_payload = attributes[:'signing_payload']
+ else
+ self.signing_payload = nil
+ end
+
+ if attributes.key?(:'transaction_type')
+ self.transaction_type = attributes[:'transaction_type']
+ else
+ self.transaction_type = nil
+ end
+
+ if attributes.key?(:'transaction_id')
+ self.transaction_id = attributes[:'transaction_id']
+ else
+ self.transaction_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 @seed_id.nil?
+ invalid_properties.push('invalid value for "seed_id", seed_id cannot be nil.')
+ end
+
+ if @wallet_id.nil?
+ invalid_properties.push('invalid value for "wallet_id", wallet_id cannot be nil.')
+ end
+
+ if @wallet_user_id.nil?
+ invalid_properties.push('invalid value for "wallet_user_id", wallet_user_id cannot be nil.')
+ end
+
+ if @address_id.nil?
+ invalid_properties.push('invalid value for "address_id", address_id cannot be nil.')
+ end
+
+ if @address_index.nil?
+ invalid_properties.push('invalid value for "address_index", address_index cannot be nil.')
+ end
+
+ if @signing_payload.nil?
+ invalid_properties.push('invalid value for "signing_payload", signing_payload cannot be nil.')
+ end
+
+ if @transaction_type.nil?
+ invalid_properties.push('invalid value for "transaction_type", transaction_type cannot be nil.')
+ end
+
+ if @transaction_id.nil?
+ invalid_properties.push('invalid value for "transaction_id", transaction_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 @seed_id.nil?
+ return false if @wallet_id.nil?
+ return false if @wallet_user_id.nil?
+ return false if @address_id.nil?
+ return false if @address_index.nil?
+ return false if @signing_payload.nil?
+ return false if @transaction_type.nil?
+ return false if @transaction_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 &&
+ seed_id == o.seed_id &&
+ wallet_id == o.wallet_id &&
+ wallet_user_id == o.wallet_user_id &&
+ address_id == o.address_id &&
+ address_index == o.address_index &&
+ signing_payload == o.signing_payload &&
+ transaction_type == o.transaction_type &&
+ transaction_id == o.transaction_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
+ [seed_id, wallet_id, wallet_user_id, address_id, address_index, signing_payload, transaction_type, transaction_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/signature_creation_event_result.rb b/lib/coinbase/client/models/signature_creation_event_result.rb
new file mode 100644
index 00000000..fb7bf63b
--- /dev/null
+++ b/lib/coinbase/client/models/signature_creation_event_result.rb
@@ -0,0 +1,329 @@
+=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 result to a SignatureCreationEvent.
+ class SignatureCreationEventResult
+ # The ID of the wallet that the event was created for.
+ attr_accessor :wallet_id
+
+ # The ID of the user that the wallet belongs to
+ attr_accessor :wallet_user_id
+
+ # The ID of the address the transfer belongs to
+ attr_accessor :address_id
+
+ attr_accessor :transaction_type
+
+ # The ID of the transaction that the Server-Signer has signed for
+ attr_accessor :transaction_id
+
+ # The signature created by the server-signer.
+ attr_accessor :signature
+
+ 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
+ {
+ :'wallet_id' => :'wallet_id',
+ :'wallet_user_id' => :'wallet_user_id',
+ :'address_id' => :'address_id',
+ :'transaction_type' => :'transaction_type',
+ :'transaction_id' => :'transaction_id',
+ :'signature' => :'signature'
+ }
+ 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',
+ :'wallet_user_id' => :'String',
+ :'address_id' => :'String',
+ :'transaction_type' => :'TransactionType',
+ :'transaction_id' => :'String',
+ :'signature' => :'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::SignatureCreationEventResult` 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::SignatureCreationEventResult`. 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?(:'wallet_user_id')
+ self.wallet_user_id = attributes[:'wallet_user_id']
+ else
+ self.wallet_user_id = nil
+ end
+
+ if attributes.key?(:'address_id')
+ self.address_id = attributes[:'address_id']
+ else
+ self.address_id = nil
+ end
+
+ if attributes.key?(:'transaction_type')
+ self.transaction_type = attributes[:'transaction_type']
+ else
+ self.transaction_type = nil
+ end
+
+ if attributes.key?(:'transaction_id')
+ self.transaction_id = attributes[:'transaction_id']
+ else
+ self.transaction_id = nil
+ end
+
+ if attributes.key?(:'signature')
+ self.signature = attributes[:'signature']
+ else
+ self.signature = 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 @wallet_user_id.nil?
+ invalid_properties.push('invalid value for "wallet_user_id", wallet_user_id cannot be nil.')
+ end
+
+ if @address_id.nil?
+ invalid_properties.push('invalid value for "address_id", address_id cannot be nil.')
+ end
+
+ if @transaction_type.nil?
+ invalid_properties.push('invalid value for "transaction_type", transaction_type cannot be nil.')
+ end
+
+ if @transaction_id.nil?
+ invalid_properties.push('invalid value for "transaction_id", transaction_id cannot be nil.')
+ end
+
+ if @signature.nil?
+ invalid_properties.push('invalid value for "signature", signature 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 @wallet_user_id.nil?
+ return false if @address_id.nil?
+ return false if @transaction_type.nil?
+ return false if @transaction_id.nil?
+ return false if @signature.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 &&
+ wallet_user_id == o.wallet_user_id &&
+ address_id == o.address_id &&
+ transaction_type == o.transaction_type &&
+ transaction_id == o.transaction_id &&
+ signature == o.signature
+ 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, wallet_user_id, address_id, transaction_type, transaction_id, signature].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/trade.rb b/lib/coinbase/client/models/trade.rb
new file mode 100644
index 00000000..1e11f89f
--- /dev/null
+++ b/lib/coinbase/client/models/trade.rb
@@ -0,0 +1,356 @@
+=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 trade of an asset to another asset
+ class Trade
+ # 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 ID of the trade
+ attr_accessor :trade_id
+
+ # The amount of the from asset to be traded (in atomic units of the from asset)
+ attr_accessor :from_amount
+
+ attr_accessor :from_asset
+
+ # The amount of the to asset that will be received (in atomic units of the to asset)
+ attr_accessor :to_amount
+
+ attr_accessor :to_asset
+
+ attr_accessor :transaction
+
+ # 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',
+ :'trade_id' => :'trade_id',
+ :'from_amount' => :'from_amount',
+ :'from_asset' => :'from_asset',
+ :'to_amount' => :'to_amount',
+ :'to_asset' => :'to_asset',
+ :'transaction' => :'transaction'
+ }
+ 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',
+ :'trade_id' => :'String',
+ :'from_amount' => :'String',
+ :'from_asset' => :'Asset',
+ :'to_amount' => :'String',
+ :'to_asset' => :'Asset',
+ :'transaction' => :'Transaction'
+ }
+ 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::Trade` 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::Trade`. 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?(:'trade_id')
+ self.trade_id = attributes[:'trade_id']
+ else
+ self.trade_id = nil
+ end
+
+ if attributes.key?(:'from_amount')
+ self.from_amount = attributes[:'from_amount']
+ else
+ self.from_amount = nil
+ end
+
+ if attributes.key?(:'from_asset')
+ self.from_asset = attributes[:'from_asset']
+ else
+ self.from_asset = nil
+ end
+
+ if attributes.key?(:'to_amount')
+ self.to_amount = attributes[:'to_amount']
+ else
+ self.to_amount = nil
+ end
+
+ if attributes.key?(:'to_asset')
+ self.to_asset = attributes[:'to_asset']
+ else
+ self.to_asset = nil
+ end
+
+ if attributes.key?(:'transaction')
+ self.transaction = attributes[:'transaction']
+ else
+ self.transaction = 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 @trade_id.nil?
+ invalid_properties.push('invalid value for "trade_id", trade_id cannot be nil.')
+ end
+
+ if @from_amount.nil?
+ invalid_properties.push('invalid value for "from_amount", from_amount cannot be nil.')
+ end
+
+ if @from_asset.nil?
+ invalid_properties.push('invalid value for "from_asset", from_asset cannot be nil.')
+ end
+
+ if @to_amount.nil?
+ invalid_properties.push('invalid value for "to_amount", to_amount cannot be nil.')
+ end
+
+ if @to_asset.nil?
+ invalid_properties.push('invalid value for "to_asset", to_asset cannot be nil.')
+ end
+
+ if @transaction.nil?
+ invalid_properties.push('invalid value for "transaction", transaction 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 @trade_id.nil?
+ return false if @from_amount.nil?
+ return false if @from_asset.nil?
+ return false if @to_amount.nil?
+ return false if @to_asset.nil?
+ return false if @transaction.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 &&
+ wallet_id == o.wallet_id &&
+ address_id == o.address_id &&
+ trade_id == o.trade_id &&
+ from_amount == o.from_amount &&
+ from_asset == o.from_asset &&
+ to_amount == o.to_amount &&
+ to_asset == o.to_asset &&
+ transaction == o.transaction
+ 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, trade_id, from_amount, from_asset, to_amount, to_asset, transaction].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/trade_list.rb b/lib/coinbase/client/models/trade_list.rb
new file mode 100644
index 00000000..0c4d2cd2
--- /dev/null
+++ b/lib/coinbase/client/models/trade_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 TradeList
+ 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 trades 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::TradeList` 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::TradeList`. 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/transaction.rb b/lib/coinbase/client/models/transaction.rb
new file mode 100644
index 00000000..89929af1
--- /dev/null
+++ b/lib/coinbase/client/models/transaction.rb
@@ -0,0 +1,294 @@
+=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 onchain transaction.
+ class Transaction
+ # The unsigned payload of the transaction. This is the payload that needs to be signed by the sender.
+ attr_accessor :unsigned_payload
+
+ # The signed payload of the transaction. This is the payload that has been signed by the sender.
+ attr_accessor :signed_payload
+
+ # The hash of the transaction
+ attr_accessor :transaction_hash
+
+ # The status of the transaction
+ 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
+ {
+ :'unsigned_payload' => :'unsigned_payload',
+ :'signed_payload' => :'signed_payload',
+ :'transaction_hash' => :'transaction_hash',
+ :'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
+ {
+ :'unsigned_payload' => :'String',
+ :'signed_payload' => :'String',
+ :'transaction_hash' => :'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::Transaction` 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::Transaction`. 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?(:'unsigned_payload')
+ self.unsigned_payload = attributes[:'unsigned_payload']
+ else
+ self.unsigned_payload = nil
+ end
+
+ if attributes.key?(:'signed_payload')
+ self.signed_payload = attributes[:'signed_payload']
+ end
+
+ if attributes.key?(:'transaction_hash')
+ self.transaction_hash = attributes[:'transaction_hash']
+ 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 @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 @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 &&
+ unsigned_payload == o.unsigned_payload &&
+ signed_payload == o.signed_payload &&
+ transaction_hash == o.transaction_hash &&
+ 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
+ [unsigned_payload, signed_payload, transaction_hash, 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/transaction_type.rb b/lib/coinbase/client/models/transaction_type.rb
new file mode 100644
index 00000000..3a9321f5
--- /dev/null
+++ b/lib/coinbase/client/models/transaction_type.rb
@@ -0,0 +1,39 @@
+=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 TransactionType
+ TRANSFER = "transfer".freeze
+
+ def self.all_vars
+ @all_vars ||= [TRANSFER].freeze
+ end
+
+ # Builds the enum from string
+ # @param [String] The enum value in the form of the string
+ # @return [String] The enum value
+ def self.build_from_hash(value)
+ new.build_from_hash(value)
+ end
+
+ # Builds the enum from string
+ # @param [String] The enum value in the form of the string
+ # @return [String] The enum value
+ def build_from_hash(value)
+ return value if TransactionType.all_vars.include?(value)
+ raise "Invalid ENUM value #{value} for class #TransactionType"
+ end
+ end
+end
diff --git a/lib/coinbase/client/models/wallet.rb b/lib/coinbase/client/models/wallet.rb
index 49221f07..89b9163d 100644
--- a/lib/coinbase/client/models/wallet.rb
+++ b/lib/coinbase/client/models/wallet.rb
@@ -23,12 +23,38 @@ class Wallet
attr_accessor :default_address
+ # The status of the Server-Signer for the wallet if present.
+ attr_accessor :server_signer_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
{
:'id' => :'id',
:'network_id' => :'network_id',
- :'default_address' => :'default_address'
+ :'default_address' => :'default_address',
+ :'server_signer_status' => :'server_signer_status'
}
end
@@ -42,7 +68,8 @@ def self.openapi_types
{
:'id' => :'String',
:'network_id' => :'String',
- :'default_address' => :'Address'
+ :'default_address' => :'Address',
+ :'server_signer_status' => :'String'
}
end
@@ -69,6 +96,8 @@ def initialize(attributes = {})
if attributes.key?(:'id')
self.id = attributes[:'id']
+ else
+ self.id = nil
end
if attributes.key?(:'network_id')
@@ -80,6 +109,10 @@ def initialize(attributes = {})
if attributes.key?(:'default_address')
self.default_address = attributes[:'default_address']
end
+
+ if attributes.key?(:'server_signer_status')
+ self.server_signer_status = attributes[:'server_signer_status']
+ end
end
# Show invalid properties with the reasons. Usually used together with valid?
@@ -87,6 +120,10 @@ def initialize(attributes = {})
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
+
if @network_id.nil?
invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')
end
@@ -98,10 +135,23 @@ def list_invalid_properties
# @return true if the model is valid
def valid?
warn '[DEPRECATED] the `valid?` method is obsolete'
+ return false if @id.nil?
return false if @network_id.nil?
+ server_signer_status_validator = EnumAttributeValidator.new('String', ["pending_seed_creation", "active_seed"])
+ return false unless server_signer_status_validator.valid?(@server_signer_status)
true
end
+ # Custom attribute writer method checking allowed values (enum).
+ # @param [Object] server_signer_status Object to be assigned
+ def server_signer_status=(server_signer_status)
+ validator = EnumAttributeValidator.new('String', ["pending_seed_creation", "active_seed"])
+ unless validator.valid?(server_signer_status)
+ fail ArgumentError, "invalid value for \"server_signer_status\", must be one of #{validator.allowable_values}."
+ end
+ @server_signer_status = server_signer_status
+ end
+
# Checks equality by comparing each attribute.
# @param [Object] Object to be compared
def ==(o)
@@ -109,7 +159,8 @@ def ==(o)
self.class == o.class &&
id == o.id &&
network_id == o.network_id &&
- default_address == o.default_address
+ default_address == o.default_address &&
+ server_signer_status == o.server_signer_status
end
# @see the `==` method
@@ -121,7 +172,7 @@ def eql?(o)
# Calculates hash code according to all attributes.
# @return [Integer] Hash code
def hash
- [id, network_id, default_address].hash
+ [id, network_id, default_address, server_signer_status].hash
end
# Builds the object from hash
diff --git a/lib/coinbase/transfer.rb b/lib/coinbase/transfer.rb
index cdfef0c0..7765e0e4 100644
--- a/lib/coinbase/transfer.rb
+++ b/lib/coinbase/transfer.rb
@@ -134,27 +134,17 @@ def transaction
# Returns the status of the Transfer.
# @return [Symbol] The status
def status
- # Check if the transfer has been signed yet.
- return Status::PENDING if transaction_hash.nil?
-
- 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.
- Status::PENDING
- elsif onchain_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)
+ @model.status
+ end
- if transaction_receipt['status'].to_i(16) == 1
- Status::COMPLETE
- else
- Status::FAILED
- end
+ # Reload reloads the Transfer model with the latest version from the server side.
+ # @return [Transfer] The most recent version of Transfer from the server.
+ def reload
+ @model = Coinbase.call_api do
+ transfers_api.get_transfer(wallet_id, from_address_id, id)
end
+
+ self
end
# Waits until the Transfer is completed or failed by polling the Network at the given interval. Raises a
@@ -162,11 +152,13 @@ def status
# @param interval_seconds [Integer] The interval at which to poll the Network, in seconds
# @param timeout_seconds [Integer] The maximum amount of time to wait for the Transfer to complete, in seconds
# @return [Transfer] The completed Transfer object
- def wait!(interval_seconds = 0.2, timeout_seconds = 10)
+ def wait!(interval_seconds = 0.2, timeout_seconds = 20)
start_time = Time.now
loop do
- return self if status == Status::COMPLETE || status == Status::FAILED
+ reload
+
+ return self if terminal_state?
raise Timeout::Error, 'Transfer timed out' if Time.now - start_time > timeout_seconds
@@ -190,5 +182,13 @@ def to_s
def inspect
to_s
end
+
+ def transfers_api
+ @transfers_api ||= Coinbase::Client::TransfersApi.new(Coinbase.configuration.api_client)
+ end
+
+ def terminal_state?
+ status == Status::COMPLETE.to_s || status == Status::FAILED.to_s
+ end
end
end
diff --git a/lib/coinbase/user.rb b/lib/coinbase/user.rb
index 64317af3..40f99248 100644
--- a/lib/coinbase/user.rb
+++ b/lib/coinbase/user.rb
@@ -40,7 +40,8 @@ def import_wallet(data)
# Lists the Wallets belonging to the User.
# @param page_size [Integer] (Optional) the number of Wallets to return per page. Defaults to 10
# @param next_page_token [String] (Optional) the token for the next page of Wallets
- # @return [Coinbase::Wallet] the Wallets belonging to the User
+ # @return [Array] the Wallets belonging to the User and the pagination token, if
+ # any.
def wallets(page_size: 10, next_page_token: nil)
opts = {
limit: page_size
@@ -63,85 +64,26 @@ def wallets(page_size: 10, next_page_token: nil)
address_model_map[wallet_model.id] = addresses_list.data
end
- wallet_list.data.map do |wallet_model|
+ wallets = wallet_list.data.map do |wallet_model|
Wallet.new(wallet_model, seed: '', address_models: address_model_map[wallet_model.id])
end
+
+ [wallets, wallet_list.next_page]
end
- # Saves a wallet to local file system. Wallet saved this way can be re-instantiated with load_wallets_from_local
- # function, provided the backup_file is available. This is an insecure method of storing wallet seeds and should
- # only be used for development purposes. If you call save_wallet_locally! twice with wallets containing the same
- # wallet_id, the backup will be overwritten during the second attempt.
- # The default backup_file is `seeds.json` in the root folder. It can be configured by changing
- # Coinbase.configuration.backup_file_path.
- #
- # @param wallet [Coinbase::Wallet] The wallet model to save.
- # @param encrypt [bool] (Optional) Boolean representing whether the backup persisted to local file system should be
- # encrypted or not. Data is unencrypted by default.
- # @return [Coinbase::Wallet] the saved wallet.
- def save_wallet_locally!(wallet, encrypt: false)
- existing_seeds_in_store = existing_seeds
- data = wallet.export
- seed_to_store = data.seed
- auth_tag = ''
- iv = ''
- if encrypt
- shared_secret = store_encryption_key
- cipher = OpenSSL::Cipher.new('aes-256-gcm').encrypt
- cipher.key = OpenSSL::Digest.digest('SHA256', shared_secret)
- iv = cipher.random_iv
- cipher.iv = iv
- cipher.auth_data = ''
- encrypted_data = cipher.update(data.seed) + cipher.final
- auth_tag = cipher.auth_tag.unpack1('H*')
- iv = iv.unpack1('H*')
- seed_to_store = encrypted_data.unpack1('H*')
+ # Returns the Wallet with the given ID.
+ # @param wallet_id [String] the ID of the Wallet
+ # @return [Coinbase::Wallet] the unhydrated Wallet
+ def wallet(wallet_id)
+ wallet_model = Coinbase.call_api do
+ wallets_api.get_wallet(wallet_id)
end
- existing_seeds_in_store[data.wallet_id] = {
- seed: seed_to_store,
- encrypted: encrypt,
- auth_tag: auth_tag,
- iv: iv
- }
-
- File.open(Coinbase.configuration.backup_file_path, 'w') do |file|
- file.write(JSON.pretty_generate(existing_seeds_in_store))
+ addresses_list = Coinbase.call_api do
+ addresses_api.list_addresses(wallet_model.id, { limit: Coinbase::Wallet::MAX_ADDRESSES })
end
- wallet
- end
- # Loads all wallets belonging to the User with backup persisted to the local file system.
- # @return [MapCoinbase::Wallet] the map of wallet_ids to the wallets.
- def load_wallets_from_local
- existing_seeds_in_store = existing_seeds
- raise ArgumentError, 'Backup file not found' if existing_seeds_in_store == {}
-
- wallets = {}
- existing_seeds_in_store.each do |wallet_id, seed_data|
- seed = seed_data['seed']
- raise ArgumentError, 'Malformed backup data' if seed.nil? || seed == ''
-
- if seed_data['encrypted']
- shared_secret = store_encryption_key
- raise ArgumentError, 'Malformed encrypted seed data' if seed_data['iv'] == '' ||
- seed_data['auth_tag'] == ''
-
- cipher = OpenSSL::Cipher.new('aes-256-gcm').decrypt
- cipher.key = OpenSSL::Digest.digest('SHA256', shared_secret)
- iv = [seed_data['iv']].pack('H*')
- cipher.iv = iv
- auth_tag = [seed_data['auth_tag']].pack('H*')
- cipher.auth_tag = auth_tag
- cipher.auth_data = ''
- hex_decoded_data = [seed_data['seed']].pack('H*')
- seed = cipher.update(hex_decoded_data) + cipher.final
- end
-
- data = Coinbase::Wallet::Data.new(wallet_id: wallet_id, seed: seed)
- wallets[wallet_id] = import_wallet(data)
- end
- wallets
+ Wallet.new(wallet_model, seed: '', address_models: addresses_list.data)
end
# Returns a string representation of the User.
@@ -165,22 +107,5 @@ def addresses_api
def wallets_api
@wallets_api ||= Coinbase::Client::WalletsApi.new(Coinbase.configuration.api_client)
end
-
- def existing_seeds
- existing_seed_data = '{}'
- file_path = Coinbase.configuration.backup_file_path
- existing_seed_data = File.read(file_path) if File.exist?(file_path)
- output = JSON.parse(existing_seed_data)
-
- raise ArgumentError, 'Malformed backup data' unless output.is_a?(Hash)
-
- output
- end
-
- def store_encryption_key
- pk = OpenSSL::PKey.read(Coinbase.configuration.api_key_private_key)
- public_key = pk.public_key # use own public key to generate the shared secret.
- pk.dh_compute_key(public_key)
- end
end
end
diff --git a/lib/coinbase/wallet.rb b/lib/coinbase/wallet.rb
index bbab7627..0fabdda6 100644
--- a/lib/coinbase/wallet.rb
+++ b/lib/coinbase/wallet.rb
@@ -17,6 +17,17 @@ class Wallet
# The maximum number of addresses in a Wallet.
MAX_ADDRESSES = 20
+ # A representation of ServerSigner status in a Wallet.
+ module ServerSignerStatus
+ # The Wallet is awaiting seed creation by the ServerSigner. At this point,
+ # the Wallet cannot create addresses or sign transactions.
+ PENDING = 'pending_seed_creation'
+
+ # The Wallet has an associated seed created by the ServerSigner. It is ready
+ # to create addresses and sign transactions.
+ ACTIVE = 'active_seed'
+ end
+
class << self
# Imports a Wallet from previously exported wallet data.
# @param data [Coinbase::Wallet::Data] the Wallet data to import
@@ -37,13 +48,18 @@ def import(data)
# Creates a new Wallet on the specified Network and generate a default address for it.
# @param network_id [String] (Optional) the ID of the blockchain network. Defaults to 'base-sepolia'.
+ # @param interval_seconds [Integer] The interval at which to poll the CDPService for the Wallet to
+ # have an active seed, if using a ServerSigner, in seconds
+ # @param timeout_seconds [Integer] The maximum amount of time to wait for the ServerSigner to
+ # create a seed for the Wallet, in seconds
# @return [Coinbase::Wallet] the new Wallet
- def create(network_id: 'base-sepolia')
+ def create(network_id: 'base-sepolia', interval_seconds: 0.2, timeout_seconds: 20)
model = Coinbase.call_api do
wallets_api.create_wallet(
create_wallet_request: {
wallet: {
- network_id: network_id
+ network_id: network_id,
+ use_server_signer: Coinbase.use_server_signer?
}
}
)
@@ -51,13 +67,42 @@ def create(network_id: 'base-sepolia')
wallet = new(model)
- wallet.create_address
+ # When used with a ServerSigner, the Signer must first register
+ # with the Wallet before addresses can be created.
+ wait_for_signer(wallet.id, interval_seconds, timeout_seconds) if Coinbase.use_server_signer?
+ wallet.create_address
wallet
end
private
+ # Wait_for_signer waits until the ServerSigner has created a seed for the Wallet.
+ # Timeout::Error if the ServerSigner takes longer than the given timeout to create the seed.
+ # @param wallet_id [string] The ID of the Wallet that is awaiting seed creation.
+ # @param interval_seconds [Integer] The interval at which to poll the CDPService, in seconds
+ # @param timeout_seconds [Integer] The maximum amount of time to wait for the Signer to create a seed, in seconds
+ # @return [Wallet] The completed Wallet object that is ready to create addresses.
+ def wait_for_signer(wallet_id, interval_seconds, timeout_seconds)
+ start_time = Time.now
+
+ loop do
+ model = Coinbase.call_api do
+ wallets_api.get_wallet(wallet_id)
+ end
+
+ return self if model.server_signer_status == ServerSignerStatus::ACTIVE
+
+ if Time.now - start_time > timeout_seconds
+ raise Timeout::Error, 'Wallet creation timed out. Check status of your Server-Signer'
+ end
+
+ self.sleep interval_seconds
+ end
+
+ self
+ end
+
# TODO: Memoize these objects in a thread-safe way at the top-level.
def addresses_api
Coinbase::Client::AddressesApi.new(Coinbase.configuration.api_client)
@@ -78,12 +123,15 @@ def wallets_api
# with the Wallet. If not provided, the Wallet will derive the first default address.
# @param client [Jimson::Client] (Optional) The JSON RPC client to use for interacting with the Network
def initialize(model, seed: nil, address_models: [])
- validate_seed_and_address_models(seed, address_models)
+ validate_seed_and_address_models(seed, address_models) unless Coinbase.use_server_signer?
@model = model
- @master = master_node(seed)
@addresses = []
- @private_key_index = 0
+
+ unless Coinbase.use_server_signer?
+ @master = master_node(seed)
+ @private_key_index = 0
+ end
derive_addresses(address_models)
end
@@ -100,6 +148,12 @@ def network_id
Coinbase.to_sym(@model.network_id)
end
+ # Returns the ServerSigner Status of the Wallet.
+ # @return [Symbol] The ServerSigner Status
+ def server_signer_status
+ Coinbase.to_sym(@model.server_signer_status)
+ end
+
# Sets the seed of the Wallet. This seed is used to derive keys and sign transactions.
# @param seed [String] The seed to set. Expects a 32-byte hexadecimal with no 0x prefix.
def seed=(seed)
@@ -121,16 +175,19 @@ def seed=(seed)
# Creates a new Address in the Wallet.
# @return [Address] The new Address
def create_address
- key = derive_key
- attestation = create_attestation(key)
- public_key = key.public_key.compressed.unpack1('H*')
+ opts = { create_address_request: {} }
- opts = {
- create_address_request: {
- public_key: public_key,
- attestation: attestation
+ unless Coinbase.use_server_signer?
+ key = derive_key
+
+ opts = {
+ create_address_request: {
+ public_key: key.public_key.compressed.unpack1('H*'),
+ attestation: create_attestation(key)
+ }
}
- }
+ end
+
address_model = Coinbase.call_api do
addresses_api.create_address(id, opts)
end
@@ -177,30 +234,23 @@ def balance(asset_id)
Coinbase::Balance.from_model_and_asset_id(response, asset_id).amount
end
- # Transfers the given amount of the given Asset to the given address. Only same-Network Transfers are supported.
- # Currently only the default_address is used to source the Transfer.
+ # Transfers the given amount of the given Asset to the specified address or wallet.
+ # Only same-network Transfers are supported. Currently only the default_address is used to source the Transfer.
# @param amount [Integer, Float, BigDecimal] The amount of the Asset to send
# @param asset_id [Symbol] The ID of the Asset to send
# @param destination [Wallet | Address | String] The destination of the transfer. If a Wallet, sends to the Wallet's
# default address. If a String, interprets it as the address ID.
# @return [Transfer] The hash of the Transfer transaction.
def transfer(amount, asset_id, destination)
- if destination.is_a?(Wallet)
- raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != network_id
-
- destination = destination.default_address.id
- elsif destination.is_a?(Address)
- raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != network_id
-
- destination = destination.id
- end
-
default_address.transfer(amount, asset_id, destination)
end
# Exports the Wallet's data to a Data object.
# @return [Data] The Wallet data
def export
+ # TODO: Improve this check by relying on the backend data to decide whether a wallet is server-signer backed.
+ raise 'Cannot export data for Server-Signer backed Wallet' if Coinbase.use_server_signer?
+
raise 'Cannot export Wallet without loaded seed' if @master.nil?
Data.new(wallet_id: id, seed: @master.seed_hex)
@@ -223,6 +273,87 @@ def can_sign?
!@master.nil?
end
+ # Saves the seed of the Wallet to the given file. Wallets whose seeds are saved this way can be
+ # rehydrated using load_seed. A single file can be used for multiple Wallet seeds.
+ # This is an insecure method of storing Wallet seeds and should only be used for development purposes.
+ #
+ # @param file_path [String] The path of the file to save the seed to
+ # @param encrypt [bool] (Optional) Whether the seed information persisted to the local file system should be
+ # encrypted or not. Data is unencrypted by default.
+ # @return [String] A string indicating the success of the operation
+ def save_seed!(file_path, encrypt: false)
+ raise 'Wallet does not have seed loaded' if @master.nil?
+
+ existing_seeds_in_store = existing_seeds(file_path)
+
+ seed_to_store = @master.seed_hex
+ auth_tag = ''
+ iv = ''
+ if encrypt
+ cipher = OpenSSL::Cipher.new('aes-256-gcm').encrypt
+ cipher.key = OpenSSL::Digest.digest('SHA256', encryption_key)
+ iv = cipher.random_iv
+ cipher.iv = iv
+ cipher.auth_data = ''
+ encrypted_data = cipher.update(@master.seed_hex) + cipher.final
+ auth_tag = cipher.auth_tag.unpack1('H*')
+ iv = iv.unpack1('H*')
+ seed_to_store = encrypted_data.unpack1('H*')
+ end
+
+ existing_seeds_in_store[id] = {
+ seed: seed_to_store,
+ encrypted: encrypt,
+ auth_tag: auth_tag,
+ iv: iv
+ }
+
+ File.open(file_path, 'w') do |file|
+ file.write(JSON.pretty_generate(existing_seeds_in_store))
+ end
+
+ "Successfully saved seed for wallet #{id} to #{file_path}."
+ end
+
+ # Loads the seed of the Wallet from the given file.
+ # @param file_path [String] The path of the file to load the seed from
+ # @return [String] A string indicating the success of the operation
+ def load_seed(file_path)
+ raise 'Wallet already has seed loaded' unless @master.nil?
+
+ existing_seeds_in_store = existing_seeds(file_path)
+
+ raise ArgumentError, "File #{file_path} does not contain seed data" if existing_seeds_in_store == {}
+
+ if existing_seeds_in_store[id].nil?
+ raise ArgumentError, "File #{file_path} does not contain seed data for wallet #{id}"
+ end
+
+ seed_data = existing_seeds_in_store[id]
+ local_seed = seed_data['seed']
+
+ raise ArgumentError, 'Seed data is malformed' if local_seed.nil? || local_seed == ''
+
+ if seed_data['encrypted']
+ raise ArgumentError, 'Encrypted seed data is malformed' if seed_data['iv'] == '' ||
+ seed_data['auth_tag'] == ''
+
+ cipher = OpenSSL::Cipher.new('aes-256-gcm').decrypt
+ cipher.key = OpenSSL::Digest.digest('SHA256', encryption_key)
+ iv = [seed_data['iv']].pack('H*')
+ cipher.iv = iv
+ auth_tag = [seed_data['auth_tag']].pack('H*')
+ cipher.auth_tag = auth_tag
+ cipher.auth_data = ''
+ hex_decoded_data = [seed_data['seed']].pack('H*')
+ local_seed = cipher.update(hex_decoded_data) + cipher.final
+ end
+
+ self.seed = local_seed
+
+ "Successfully loaded seed for wallet #{id} from #{file_path}."
+ end
+
# Returns a String representation of the Wallet.
# @return [String] a String representation of the Wallet
def to_s
@@ -390,6 +521,25 @@ def validate_seed_and_address_models(seed, address_models)
raise ArgumentError, 'Seed must be empty if address_models are not provided'
end
+ # Loads the Hash of Wallet seeds from the given file.
+ # @param file_path [String] The path of the file to load the seed from
+ # @return [Hash] The Hash of from Wallet IDs to seed data
+ def existing_seeds(file_path)
+ existing_seed_data = '{}'
+ existing_seed_data = File.read(file_path) if File.exist?(file_path)
+ existing_seeds = JSON.parse(existing_seed_data)
+ raise ArgumentError, "#{file_path} is malformed, must be a valid JSON object" unless existing_seeds.is_a?(Hash)
+
+ existing_seeds
+ end
+
+ # Returns the shared secret to use for encrypting the seed.
+ def encryption_key
+ pk = OpenSSL::PKey.read(Coinbase.configuration.api_key_private_key)
+ public_key = pk.public_key # use own public key to generate the shared secret.
+ pk.dh_compute_key(public_key)
+ end
+
def addresses_api
@addresses_api ||= Coinbase::Client::AddressesApi.new(Coinbase.configuration.api_client)
end
diff --git a/spec/e2e/end_to_end.rb b/spec/e2e/end_to_end.rb
index 99ffdc55..1093d9c8 100644
--- a/spec/e2e/end_to_end.rb
+++ b/spec/e2e/end_to_end.rb
@@ -52,7 +52,7 @@
a1 = addresses[0]
a2 = addresses[1]
t = a1.transfer(1, :gwei, a2).wait!
- expect(t.status).to eq(:complete)
+ expect(t.status).to eq('complete')
puts "Transferred 1 Gwei from #{a1} to #{a2}"
puts 'Fetching updated balances...'
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 9b773f11..a57f4cbd 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,3 +1,12 @@
# frozen_string_literal: true
+require 'simplecov'
+
+SimpleCov.start do
+ enable_coverage :branch
+ primary_coverage :branch
+ add_filter '/spec/'
+ add_filter '/lib/coinbase/client/'
+end
+
require_relative '../lib/coinbase'
diff --git a/spec/unit/coinbase/address_spec.rb b/spec/unit/coinbase/address_spec.rb
index 80e5ab39..7ebf3de4 100644
--- a/spec/unit/coinbase/address_spec.rb
+++ b/spec/unit/coinbase/address_spec.rb
@@ -7,12 +7,21 @@
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*')
- })
+ 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(:eth_asset) do
+ Coinbase::Client::Asset.new(network_id: 'base-sepolia', asset_id: 'eth', decimals: 18)
+ end
+ let(:usdc_asset) do
+ Coinbase::Client::Asset.new(network_id: 'base-sepolia', asset_id: 'usdc', decimals: 6)
+ end
+ let(:weth_asset) do
+ Coinbase::Client::Asset.new(network_id: 'base-sepolia', asset_id: 'weth', decimals: 18)
end
let(:addresses_api) { double('Coinbase::Client::AddressesApi') }
let(:transfers_api) { double('Coinbase::Client::TransfersApi') }
@@ -55,37 +64,10 @@
describe '#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
- })
- }
- ),
- Coinbase::Client::Balance.new(
- {
- 'amount' => '3000000000000000000',
- 'asset' => Coinbase::Client::Asset.new({
- 'network_id': 'base-sepolia',
- 'asset_id': 'weth',
- 'decimals': 6
- })
- }
- )
+ data: [
+ Coinbase::Client::Balance.new(amount: '1000000000000000000', asset: eth_asset),
+ Coinbase::Client::Balance.new(amount: '5000000000', asset: usdc_asset),
+ Coinbase::Client::Balance.new(amount: '3000000000000000000', asset: weth_asset)
]
)
end
@@ -118,16 +100,7 @@
describe '#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
- })
- }
- )
+ Coinbase::Client::Balance.new(amount: '1000000000000000000', asset: eth_asset)
end
it 'returns the correct ETH balance' do
@@ -165,28 +138,10 @@
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
- })
- }
- )
+ Coinbase::Client::Balance.new(amount: '1000000000000000000', asset: eth_asset)
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
- })
- }
- )
+ Coinbase::Client::Balance.new(amount: '10000000000', asset: usdc_asset)
end
let(:transfer_id) { SecureRandom.uuid }
let(:to_key) { Eth::Key.new }
@@ -198,145 +153,219 @@
{ signed_payload: raw_signed_transaction }
end
let(:transaction) { double('Transaction', sign: transaction_hash, hex: raw_signed_transaction) }
- let(:transfer) do
- double('Transfer', transaction: transaction, id: transfer_id)
- end
+ let(:created_transfer) { double('Transfer', transaction: transaction, id: transfer_id) }
+ let(:transfer_model) { instance_double('Coinbase::Client::Transfer', status: 'pending') }
+ let(:broadcasted_transfer_model) { instance_double('Coinbase::Client::Transfer', status: 'broadcast') }
+ let(:broadcasted_transfer) { double('Transfer', transaction: transaction, id: transfer_id) }
+ let(:transfer_asset_id) { 'eth' }
+ let(:balance_response) { eth_balance_response }
+ let(:destination) { to_address_id }
- before do
- allow(Coinbase::Transfer).to receive(:new).and_return(transfer)
- end
+ subject(:transfer) { address.transfer(amount, asset_id, destination) }
- # TODO: Add test case for when the destination is a Wallet.
-
- context 'when the destination is a valid Address' do
+ context 'when the transfer is successful' do
let(:asset_id) { :wei }
let(:amount) { 500_000_000_000_000_000 }
- let(:destination) { described_class.new(model, to_key) }
+ let(:transfer_amount) { 500_000_000_000_000_000 }
let(:create_transfer_request) do
- { amount: amount.to_s, network_id: network_id, asset_id: 'eth', destination: destination.id }
+ { amount: transfer_amount.to_s, network_id: network_id, asset_id: transfer_asset_id,
+ destination: to_address_id }
end
- it 'creates a Transfer' do
- expect(addresses_api)
+ before do
+ allow(addresses_api)
.to receive(:get_address_balance)
- .with(wallet_id, address_id, 'eth')
- .and_return(eth_balance_response)
- expect(transfers_api)
+ .with(wallet_id, address_id, transfer_asset_id)
+ .and_return(balance_response)
+
+ allow(transfers_api)
.to receive(:create_transfer)
.with(wallet_id, address_id, create_transfer_request)
- expect(transfers_api)
+ .and_return(transfer_model)
+
+ allow(Coinbase::Transfer).to receive(:new).with(transfer_model).and_return(created_transfer)
+
+ allow(transfers_api)
.to receive(:broadcast_transfer)
.with(wallet_id, address_id, transfer_id, broadcast_transfer_request)
- expect(address.transfer(amount, asset_id, destination)).to eq(transfer)
- end
- end
+ .and_return(broadcasted_transfer_model)
- 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.id
- }
+ allow(Coinbase::Transfer).to receive(:new).with(broadcasted_transfer_model).and_return(broadcasted_transfer)
+
+ transfer
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)
+ it 'creates the transfer' do
expect(transfers_api)
- .to receive(:create_transfer)
+ .to have_received(:create_transfer)
.with(wallet_id, address_id, create_transfer_request)
- expect(transfers_api)
- .to receive(:broadcast_transfer)
- .with(wallet_id, address_id, transfer_id, broadcast_transfer_request)
+ end
- expect(address.transfer(usdc_amount, asset_id, destination)).to eq(transfer)
+ it 'returns the broadcasted transfer' do
+ expect(transfer).to eq(broadcasted_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 }
+ it 'signs the transaction with the key' do
+ expect(transaction).to have_received(:sign).with(key)
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(transfers_api)
- .to receive(:broadcast_transfer)
- .with(wallet_id, address_id, transfer_id, broadcast_transfer_request)
- expect(address.transfer(amount, asset_id, destination)).to eq(transfer)
+
+ context 'when the asset is Gwei' do
+ let(:asset_id) { :gwei }
+ let(:amount) { 500_000_000 }
+
+ it 'returns the broadcast transfer' do
+ expect(transfer).to eq(broadcasted_transfer)
+ end
+
+ it 'signs the transaction with the address key' do
+ expect(transaction).to have_received(:sign).with(key)
+ end
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 }
+ context 'when the asset is ETH' do
+ let(:asset_id) { :eth }
+ let(:amount) { 0.5 }
+ let(:transfer_amount) { 500_000_000_000_000_000 }
+
+ it 'returns the broadcast transfer' do
+ expect(transfer).to eq(broadcasted_transfer)
+ end
+
+ it 'signs the transaction with the address key' do
+ expect(transaction).to have_received(:sign).with(key)
+ end
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(transfers_api)
- .to receive(:broadcast_transfer)
- .with(wallet_id, address_id, transfer_id, broadcast_transfer_request)
- expect(address.transfer(amount, asset_id, destination)).to eq(transfer)
+
+ context 'when the asset is USDC' do
+ let(:asset_id) { :usdc }
+ let(:transfer_asset_id) { 'usdc' }
+ let(:amount) { 5 }
+ let(:transfer_amount) { 5_000_000 }
+ let(:balance_response) { usdc_balance_response }
+
+ it 'creates a Transfer' do
+ expect(transfer).to eq(broadcasted_transfer)
+ end
+ end
+
+ context 'when the destination is a Wallet' do
+ let(:default_address_model) do
+ Coinbase::Client::Address.new(
+ network_id: 'base-sepolia',
+ address_id: to_address_id,
+ wallet_id: wallet_id,
+ public_key: to_key.public_key.compressed.unpack1('H*')
+ )
+ end
+ let(:destination) do
+ Coinbase::Wallet.new(
+ Coinbase::Client::Wallet.new(id: wallet_id, network_id: 'base-sepolia',
+ default_address: default_address_model),
+ seed: '',
+ address_models: [default_address_model]
+ )
+ end
+
+ it 'returns the broadcasted transfer' do
+ expect(transfer).to eq(broadcasted_transfer)
+ end
+
+ it 'signs the transaction with the address key' do
+ expect(transaction).to have_received(:sign).with(key)
+ end
+ end
+
+ context 'when the destination is a Address' do
+ let(:asset_id) { :wei }
+ let(:amount) { 500_000_000_000_000_000 }
+ let(:transfer_amount) { amount }
+ let(:balance_response) { eth_balance_response }
+ let(:to_model) do
+ Coinbase::Client::Address.new(
+ network_id: 'base-sepolia',
+ address_id: to_address_id,
+ wallet_id: wallet_id,
+ public_key: to_key.public_key.compressed.unpack1('H*')
+ )
+ end
+ let(:destination) { described_class.new(to_model, to_key) }
+ let(:destination_address) { destination.id }
+
+ it 'returns the broadcasted transfer' do
+ expect(transfer).to eq(broadcasted_transfer)
+ end
+
+ it 'signs the transaction with the address key' do
+ expect(transaction).to have_received(:sign).with(key)
+ end
end
end
- context 'when the asset is unsupported' do
+ context 'when the destination Address is on a different network' do
+ let(:to_model) do
+ Coinbase::Client::Address.new(
+ network_id: 'ethereum-sepolia',
+ address_id: to_address_id,
+ wallet_id: wallet_id,
+ public_key: to_key.public_key.compressed.unpack1('H*')
+ )
+ end
let(:amount) { 500_000_000_000_000_000 }
+ let(:asset_id) { :wei }
+ let(:destination) { described_class.new(to_model, to_key) }
+
it 'raises an ArgumentError' do
- expect { address.transfer(amount, :uni, to_address_id) }.to raise_error(ArgumentError, 'Unsupported asset: uni')
+ expect do
+ address.transfer(amount, asset_id, destination)
+ end.to raise_error(ArgumentError, 'Transfer must be on the same Network')
end
end
- # TODO: Add test case for when the destination is a Wallet.
+ context 'when the destination Wallet is on a different network' do
+ let(:default_address_model) do
+ Coinbase::Client::Address.new(
+ network_id: 'base-sepolia',
+ address_id: to_address_id,
+ wallet_id: wallet_id,
+ public_key: to_key.public_key.compressed.unpack1('H*')
+ )
+ end
+ let(:destination) do
+ Coinbase::Wallet.new(
+ Coinbase::Client::Wallet.new(id: wallet_id, network_id: 'base-mainnet',
+ default_address: default_address_model),
+ seed: '',
+ address_models: [default_address_model]
+ )
+ end
- 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
+ let(:asset_id) { :wei }
it 'raises an ArgumentError' do
expect do
- address.transfer(amount, asset_id, Coinbase::Address.new(new_model, to_key))
+ address.transfer(amount, asset_id, destination)
end.to raise_error(ArgumentError, 'Transfer must be on the same Network')
end
end
+ context 'when the asset is unsupported' do
+ let(:amount) { 500_000_000_000_000_000 }
+ let(:transfer_amount) { amount }
+ let(:asset_id) { :uni }
+
+ it 'raises an ArgumentError' do
+ expect do
+ address.transfer(amount, asset_id, destination)
+ end.to raise_error(ArgumentError, 'Unsupported asset: uni')
+ end
+ end
+
context 'when the balance is insufficient' do
let(:asset_id) { :wei }
let(:excessive_amount) { 9_000_000_000_000_000_000_000 }
+ let(:excessive_amount) { 9_000_000_000_000_000_000_000 }
+
before do
expect(addresses_api)
.to receive(:get_address_balance)
@@ -360,6 +389,41 @@
end.to raise_error('Cannot transfer from address without private key loaded')
end
end
+
+ context 'when using server signer' do
+ let(:configuration) { double('Coinbase::Configuration', use_server_signer: true, api_client: nil) }
+ 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.id }
+ end
+
+ before do
+ allow(Coinbase).to receive(:configuration).and_return(configuration)
+ allow(addresses_api)
+ .to receive(:get_address_balance)
+ .with(wallet_id, address_id, transfer_asset_id)
+ .and_return(balance_response)
+
+ allow(transfers_api)
+ .to receive(:create_transfer)
+ .with(wallet_id, address_id, create_transfer_request)
+ .and_return(transfer_model)
+ allow(Coinbase::Transfer).to receive(:new).with(transfer_model).and_return(created_transfer)
+ end
+
+ it 'creates a transfer without broadcast' 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
end
describe '#can_sign?' do
@@ -460,9 +524,9 @@
Array.new(page_size) { SecureRandom.uuid }
end
let(:data) do
- transfer_ids.map { |id| Coinbase::Client::Transfer.new({ 'transfer_id': id, 'network_id': 'base-sepolia' }) }
+ transfer_ids.map { |id| Coinbase::Client::Transfer.new(transfer_id: id, network_id: 'base-sepolia') }
end
- let(:transfers_list) { Coinbase::Client::TransferList.new({ 'data' => data }) }
+ let(:transfers_list) { Coinbase::Client::TransferList.new(data: data) }
let(:expected_transfers) do
data.map { |transfer_model| Coinbase::Transfer.new(transfer_model) }
end
@@ -482,14 +546,27 @@
expect(address.transfers).to eq(expected_transfers)
end
+ context 'with no transfers' do
+ let(:data) { [] }
+
+ it 'returns an empty list' do
+ expect(transfers_api)
+ .to receive(:list_transfers)
+ .with(wallet_id, address_id, { limit: 100, page: nil })
+ .and_return(transfers_list)
+
+ expect(address.transfers).to be_empty
+ end
+ end
+
context 'with multiple pages' do
let(:page_size) { 150 }
let(:next_page) { 'page_token_2' }
let(:transfers_list_page1) do
- Coinbase::Client::TransferList.new({ 'data' => data.take(100), 'has_more' => true, 'next_page' => next_page })
+ Coinbase::Client::TransferList.new(data: data.take(100), has_more: true, next_page: next_page)
end
let(:transfers_list_page2) do
- Coinbase::Client::TransferList.new({ 'data' => data.drop(100), 'has_more' => false, 'next_page' => nil })
+ Coinbase::Client::TransferList.new(data: data.drop(100), has_more: false, next_page: nil)
end
it 'lists all of the transfers' do
diff --git a/spec/unit/coinbase/transfer_spec.rb b/spec/unit/coinbase/transfer_spec.rb
index 01e9f52a..12e570f5 100644
--- a/spec/unit/coinbase/transfer_spec.rb
+++ b/spec/unit/coinbase/transfer_spec.rb
@@ -55,19 +55,47 @@
})
end
let(:broadcast_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,
- 'signed_payload' => signed_payload,
- 'transaction_hash' => transaction_hash
- })
+ 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,
+ 'signed_payload': signed_payload,
+ 'transaction_hash': transaction_hash
+ )
+ end
+ let(:complete_broadcast_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': 'complete',
+ 'unsigned_payload': unsigned_payload,
+ 'signed_payload': signed_payload,
+ 'transaction_hash': transaction_hash
+ )
+ end
+ let(:failed_broadcast_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': 'failed',
+ 'unsigned_payload': unsigned_payload
+ )
end
let(:transfers_api) { double('Coinbase::Client::TransfersApi') }
let(:client) { double('Jimson::Client') }
@@ -223,101 +251,63 @@
end
end
- describe '#status' do
+ describe '#reload' do
context 'when the transaction has not been created' do
- it 'returns PENDING' do
- expect(transfer.status).to eq(Coinbase::Transfer::Status::PENDING)
- end
- end
-
- context 'when the transaction has been created but not signed' do
- it 'returns PENDING' do
- transfer.transaction
- expect(transfer.status).to eq(Coinbase::Transfer::Status::PENDING)
- end
- end
-
- context 'when the transaction has been signed but not broadcast' do
before do
- transfer.transaction.sign(from_key)
+ allow(transfers_api)
+ .to receive(:get_transfer)
+ .with(transfer.wallet_id, transfer.from_address_id, transfer.id)
+ .and_return(broadcast_model)
end
it 'returns PENDING' do
- expect(transfer.status).to eq(Coinbase::Transfer::Status::PENDING)
+ expect(transfer).to be_a(Coinbase::Transfer)
+ expect(transfer.reload.status).to eq(Coinbase::Transfer::Status::PENDING.to_s)
end
end
- context 'when the transaction has been broadcast but not included in a block' do
+ context 'when the transaction is complete' do
let(:onchain_transaction) { { 'blockHash' => nil } }
subject(:transfer) do
- described_class.new(broadcast_model)
+ described_class.new(complete_broadcast_model)
end
before do
transfer.transaction.sign(from_key)
- allow(client)
- .to receive(:eth_getTransactionByHash)
- .with(transfer.transaction_hash)
- .and_return(onchain_transaction)
- end
-
- it 'returns BROADCAST' do
- expect(transfer.status).to eq(Coinbase::Transfer::Status::BROADCAST)
- end
- end
-
- context 'when the transaction has confirmed' do
- let(:onchain_transaction) { { 'blockHash' => '0xdeadbeef' } }
- let(:transaction_receipt) { { 'status' => '0x1' } }
- subject(:transfer) do
- described_class.new(broadcast_model)
- end
-
- before do
- transfer.transaction.sign(from_key)
- allow(client)
- .to receive(:eth_getTransactionByHash)
- .with(transfer.transaction_hash)
- .and_return(onchain_transaction)
- allow(client)
- .to receive(:eth_getTransactionReceipt)
- .with(transfer.transaction_hash)
- .and_return(transaction_receipt)
+ allow(transfers_api)
+ .to receive(:get_transfer)
+ .with(transfer.wallet_id, transfer.from_address_id, transfer.id)
+ .and_return(complete_broadcast_model)
end
it 'returns COMPLETE' do
- expect(transfer.status).to eq(Coinbase::Transfer::Status::COMPLETE)
+ expect(transfer).to be_a(Coinbase::Transfer)
+ expect(transfer.reload.status).to eq(Coinbase::Transfer::Status::COMPLETE.to_s)
end
end
context 'when the transaction has failed' do
- let(:onchain_transaction) { { 'blockHash' => '0xdeadbeef' } }
- let(:transaction_receipt) { { 'status' => '0x0' } }
subject(:transfer) do
described_class.new(broadcast_model)
end
before do
- transfer.transaction.sign(from_key)
- allow(client)
- .to receive(:eth_getTransactionByHash)
- .with(transfer.transaction_hash)
- .and_return(onchain_transaction)
- allow(client)
- .to receive(:eth_getTransactionReceipt)
- .with(transfer.transaction_hash)
- .and_return(transaction_receipt)
+ allow(transfers_api)
+ .to receive(:get_transfer)
+ .with(transfer.wallet_id, transfer.from_address_id, transfer.id)
+ .and_return(failed_broadcast_model)
end
it 'returns FAILED' do
- expect(transfer.status).to eq(Coinbase::Transfer::Status::FAILED)
+ expect(transfer).to be_a(Coinbase::Transfer)
+ expect(transfer.reload.status).to eq(Coinbase::Transfer::Status::FAILED.to_s)
end
end
end
describe '#wait!' do
subject(:transfer) do
- described_class.new(broadcast_model)
+ described_class.new(complete_broadcast_model)
end
before do
@@ -331,41 +321,29 @@
before do
transfer.transaction.sign(from_key)
- allow(client)
- .to receive(:eth_getTransactionByHash)
- .with(transfer.transaction_hash)
- .and_return(onchain_transaction)
- allow(client)
- .to receive(:eth_getTransactionReceipt)
- .with(transfer.transaction_hash)
- .and_return(transaction_receipt)
+ allow(transfers_api)
+ .to receive(:get_transfer)
+ .with(transfer.wallet_id, transfer.from_address_id, transfer.id)
+ .and_return(broadcast_model, complete_broadcast_model)
end
it 'returns the completed Transfer' do
- expect(transfer.wait!).to eq(transfer)
- expect(transfer.status).to eq(Coinbase::Transfer::Status::COMPLETE)
+ expect(transfer.wait!(0.001, 0.1)).to eq(transfer)
+ expect(transfer.status).to eq(Coinbase::Transfer::Status::COMPLETE.to_s)
end
end
context 'when the transfer is failed' do
- let(:onchain_transaction) { { 'blockHash' => '0xdeadbeef' } }
- let(:transaction_receipt) { { 'status' => '0x0' } }
-
before do
- transfer.transaction.sign(from_key)
- allow(client)
- .to receive(:eth_getTransactionByHash)
- .with(transfer.transaction_hash)
- .and_return(onchain_transaction)
- allow(client)
- .to receive(:eth_getTransactionReceipt)
- .with(transfer.transaction_hash)
- .and_return(transaction_receipt)
+ allow(transfers_api)
+ .to receive(:get_transfer)
+ .with(transfer.wallet_id, transfer.from_address_id, transfer.id)
+ .and_return(failed_broadcast_model)
end
it 'returns the failed Transfer' do
expect(transfer.wait!).to eq(transfer)
- expect(transfer.status).to eq(Coinbase::Transfer::Status::FAILED)
+ expect(transfer.status).to eq(Coinbase::Transfer::Status::FAILED.to_s)
end
end
@@ -374,14 +352,14 @@
before do
transfer.transaction.sign(from_key)
- allow(client)
- .to receive(:eth_getTransactionByHash)
- .with(transfer.transaction_hash)
- .and_return(onchain_transaction)
+ allow(transfers_api)
+ .to receive(:get_transfer)
+ .with(transfer.wallet_id, transfer.from_address_id, transfer.id)
+ .and_return(broadcast_model)
end
it 'raises a Timeout::Error' do
- expect { transfer.wait!(0.2, 0.00001) }.to raise_error(Timeout::Error, 'Transfer timed out')
+ expect { transfer.wait!(0.0001, 0.0005) }.to raise_error(Timeout::Error, 'Transfer timed out')
end
end
end
diff --git a/spec/unit/coinbase/user_spec.rb b/spec/unit/coinbase/user_spec.rb
index 494c178f..3cd7516c 100644
--- a/spec/unit/coinbase/user_spec.rb
+++ b/spec/unit/coinbase/user_spec.rb
@@ -100,7 +100,13 @@
expect(wallets_api)
.to receive(:list_wallets)
.and_return(
- Coinbase::Client::WalletList.new({ 'data' => [wallet_model1, wallet_model2], 'total_count' => 2 })
+ Coinbase::Client::WalletList.new(
+ {
+ 'data' => [wallet_model1, wallet_model2],
+ 'next_page' => 'next_page_token',
+ 'total_count' => 2
+ }
+ )
)
expect(addresses_api)
.to receive(:list_addresses)
@@ -117,262 +123,11 @@
end
it 'returns all wallets' do
- wallets = user.wallets
+ wallets, next_page_token = user.wallets
expect(wallets.size).to eq(2)
expect(wallets[0].id).to eq(wallet_model1.id)
expect(wallets[1].id).to eq(wallet_model2.id)
- end
- end
-
- describe '#save_wallet_locally!' do
- let(:seed) { '86fc9fba421dcc6ad42747f14132c3cd975bd9fb1454df84ce5ea554f2542fbe' }
- let(:address_model) do
- Coinbase::Client::Address.new({
- 'address_id': '0xfbd9D61057eC1debCeEE12C62812Fb3E1d025201',
- 'wallet_id': wallet_id,
- 'public_key': '0x1234567890',
- 'network_id': 'base-sepolia'
- })
- end
- let(:wallet_id) { SecureRandom.uuid }
- let(:network_id) { 'base-sepolia' }
- let(:wallet_model) { Coinbase::Client::Wallet.new({ 'id': wallet_id, 'network_id': network_id }) }
- let(:seed_wallet) do
- Coinbase::Wallet.new(wallet_model, seed: seed, address_models: [address_model])
- end
- let(:user) { described_class.new(model) }
- let(:addresses_api) { double('Coinbase::Client::AddressesApi') }
-
- let(:initial_seed_data) { JSON.pretty_generate({}) }
- let(:expected_seed_data) do
- {
- seed_wallet.id => {
- seed: seed,
- encrypted: false
- }
- }
- end
-
- before do
- @backup_file_path = Coinbase.configuration.backup_file_path
- @api_key_private_key = Coinbase.configuration.api_key_private_key
- Coinbase.configuration.backup_file_path = "#{SecureRandom.uuid}.json"
- Coinbase.configuration.api_key_private_key = OpenSSL::PKey::EC.generate('prime256v1').to_pem
- allow(Coinbase::Client::AddressesApi).to receive(:new).and_return(addresses_api)
- File.open(Coinbase.configuration.backup_file_path, 'w') do |file|
- file.write(initial_seed_data)
- end
- end
-
- after do
- File.delete(Coinbase.configuration.backup_file_path)
- Coinbase.configuration.backup_file_path = @backup_file_path
- Coinbase.configuration.api_key_private_key = @api_key_private_key
- end
-
- it 'saves the Wallet data when encryption is false' do
- saved_wallet = user.save_wallet_locally!(seed_wallet)
- # Verify that the file has new wallet.
- stored_seed_data = File.read(Coinbase.configuration.backup_file_path)
- wallets = JSON.parse(stored_seed_data)
- data = wallets[seed_wallet.id]
- expect(data).not_to be_empty
- expect(data['encrypted']).to eq(false)
- expect(data['iv']).to eq('')
- expect(data['auth_tag']).to eq('')
- expect(data['seed']).to eq(seed)
- expect(saved_wallet).to eq(seed_wallet)
- end
-
- it 'saves the Wallet data when encryption is true' do
- saved_wallet = user.save_wallet_locally!(seed_wallet, encrypt: true)
- # Verify that the file has new wallet.
- stored_seed_data = File.read(Coinbase.configuration.backup_file_path)
- wallets = JSON.parse(stored_seed_data)
- data = wallets[seed_wallet.id]
- expect(data).not_to be_empty
- expect(data['encrypted']).to eq(true)
- expect(data['iv']).not_to be_empty
- expect(data['auth_tag']).not_to be_empty
- expect(data['seed']).not_to eq(seed)
- expect(saved_wallet).to eq(seed_wallet)
- end
-
- it 'it creates a new file and saves the wallet when the file does not exist' do
- File.delete(Coinbase.configuration.backup_file_path)
- saved_wallet = user.save_wallet_locally!(seed_wallet)
- stored_seed_data = File.read(Coinbase.configuration.backup_file_path)
- wallets = JSON.parse(stored_seed_data)
- data = wallets[seed_wallet.id]
- expect(data).not_to be_empty
- expect(data['encrypted']).to eq(false)
- expect(saved_wallet).to eq(seed_wallet)
- end
-
- it 'it throws an error when the existing file is malformed' do
- File.open(Coinbase.configuration.backup_file_path, 'w') do |file|
- file.write(JSON.pretty_generate({
- malformed: 'test'
- }.to_json))
- end
- expect do
- user.save_wallet_locally!(seed_wallet)
- end.to raise_error(ArgumentError, 'Malformed backup data')
- end
- end
-
- describe '#load_wallets_from_local' do
- let(:seed) { '86fc9fba421dcc6ad42747f14132c3cd975bd9fb1454df84ce5ea554f2542fbe' }
- let(:address_count) { 1 }
- let(:wallet_id) { SecureRandom.uuid }
- let(:address_model) do
- Coinbase::Client::Address.new({
- 'address_id': '0xfbd9D61057eC1debCeEE12C62812Fb3E1d025201',
- 'wallet_id': wallet_id,
- 'public_key': '0x1234567890',
- 'network_id': 'base-sepolia'
- })
- end
- let(:seed_wallet) do
- Coinbase::Wallet.new(model, seed: seed, address_models: [address_model])
- end
- let(:user) { described_class.new(model) }
- let(:addresses_api) { double('Coinbase::Client::AddressesApi') }
- 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(:initial_seed_data) do
- {
- wallet_id => {
- seed: seed,
- encrypted: false
- }
- }
- end
- let(:malformed_seed_data) do
- {
- wallet_id => 'test'
- }
- end
- let(:seed_data_without_seed) do
- {
- wallet_id => {
- seed: '',
- encrypted: false
- }
- }
- end
- let(:seed_data_without_iv) do
- {
- wallet_id => {
- seed: seed,
- encrypted: true,
- iv: '',
- auth_tag: '0x111'
- }
- }
- end
- let(:seed_data_without_auth_tag) do
- {
- wallet_id => {
- seed: seed,
- encrypted: true,
- iv: '0x111',
- auth_tag: ''
- }
- }
- end
-
- before do
- @backup_file_path = Coinbase.configuration.backup_file_path
- @api_key_private_key = Coinbase.configuration.api_key_private_key
- Coinbase.configuration.backup_file_path = "#{SecureRandom.uuid}.json"
- Coinbase.configuration.api_key_private_key = OpenSSL::PKey::EC.generate('prime256v1').to_pem
- File.open(Coinbase.configuration.backup_file_path, 'w') do |file|
- file.write(JSON.pretty_generate(initial_seed_data))
- end
- end
- after do
- File.delete(Coinbase.configuration.backup_file_path) if File.exist?(Coinbase.configuration.backup_file_path)
- Coinbase.configuration.backup_file_path = @backup_file_path
- Coinbase.configuration.api_key_private_key = @api_key_private_key
- end
-
- it 'loads the Wallet from backup' 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, { limit: Coinbase::Wallet::MAX_ADDRESSES })
- .and_return(address_list_model)
-
- wallets = user.load_wallets_from_local
- wallet = wallets[wallet_id]
- expect(wallet).not_to be_nil
- expect(wallet.id).to eq(wallet_id)
- expect(wallet.default_address.id).to eq(address_model.address_id)
- end
-
- it 'throws an error when the backup file is absent' do
- File.delete(Coinbase.configuration.backup_file_path)
- expect do
- user.load_wallets_from_local
- end.to raise_error(ArgumentError, 'Backup file not found')
- end
-
- it 'throws an error when the backup file is corrupted' do
- File.open(Coinbase.configuration.backup_file_path, 'w') do |file|
- file.write(JSON.pretty_generate(malformed_seed_data))
- end
- expect do
- user.load_wallets_from_local
- end.to raise_error(ArgumentError, 'Malformed backup data')
- end
-
- it 'throws an error when backup does not contain seed' do
- # Delete the existing file and write a new malformed file.
- File.delete(Coinbase.configuration.backup_file_path) if File.exist?(Coinbase.configuration.backup_file_path)
-
- File.open(Coinbase.configuration.backup_file_path, 'w') do |file|
- file.write(JSON.pretty_generate(seed_data_without_seed))
- end
- expect do
- user.load_wallets_from_local
- end.to raise_error(ArgumentError, 'Malformed backup data')
- end
-
- it 'throws an error when backup does not contain iv' do
- # Delete the existing file and write a new malformed file.
- File.delete(Coinbase.configuration.backup_file_path) if File.exist?(Coinbase.configuration.backup_file_path)
-
- File.open(Coinbase.configuration.backup_file_path, 'w') do |file|
- file.write(JSON.pretty_generate(seed_data_without_iv))
- end
- expect do
- user.load_wallets_from_local
- end.to raise_error(ArgumentError, 'Malformed encrypted seed data')
- end
-
- it 'throws an error when backup does not contain auth_tag' do
- # Delete the existing file and write a new malformed file.
- File.delete(Coinbase.configuration.backup_file_path) if File.exist?(Coinbase.configuration.backup_file_path)
-
- File.open(Coinbase.configuration.backup_file_path, 'w') do |file|
- file.write(JSON.pretty_generate(seed_data_without_auth_tag))
- end
- expect do
- user.load_wallets_from_local
- end.to raise_error(ArgumentError, 'Malformed encrypted seed data')
+ expect(next_page_token).to eq('next_page_token')
end
end
diff --git a/spec/unit/coinbase/wallet_spec.rb b/spec/unit/coinbase/wallet_spec.rb
index 97197dff..586f6122 100644
--- a/spec/unit/coinbase/wallet_spec.rb
+++ b/spec/unit/coinbase/wallet_spec.rb
@@ -7,31 +7,41 @@
let(:model) { Coinbase::Client::Wallet.new({ 'id': wallet_id, 'network_id': network_id }) }
let(:address_model1) do
Coinbase::Client::Address.new(
- {
- 'address_id': '0x919538116b4F25f1CE01429fd9Ed7964556bf565',
- 'wallet_id': wallet_id,
- 'public_key': '0292df2f2c31a5c4b0d4946e922cc3bd25ad7196ffeb049905b0952b9ac48ef25f',
- 'network_id': network_id
- }
+ 'address_id': '0x919538116b4F25f1CE01429fd9Ed7964556bf565',
+ 'wallet_id': wallet_id,
+ 'public_key': '0292df2f2c31a5c4b0d4946e922cc3bd25ad7196ffeb049905b0952b9ac48ef25f',
+ 'network_id': network_id
)
end
let(:address_model2) do
Coinbase::Client::Address.new(
- {
- 'address_id': '0xf23692a9DE556Ee1711b172Bf744C5f33B13DC89',
- 'wallet_id': wallet_id,
- 'public_key': '034ecbfc86f7447c8bfd1a5f71b13600d767ccb58d290c7b146632090f3a05c66c',
- 'network_id': network_id
- }
+ 'address_id': '0xf23692a9DE556Ee1711b172Bf744C5f33B13DC89',
+ 'wallet_id': wallet_id,
+ 'public_key': '034ecbfc86f7447c8bfd1a5f71b13600d767ccb58d290c7b146632090f3a05c66c',
+ 'network_id': network_id
)
end
let(:model_with_default_address) do
Coinbase::Client::Wallet.new(
- {
- 'id': wallet_id,
- 'network_id': network_id,
- 'default_address': address_model1
- }
+ 'id': wallet_id,
+ 'network_id': network_id,
+ 'default_address': address_model1
+ )
+ end
+
+ let(:model_with_seed_pending) do
+ Coinbase::Client::Wallet.new(
+ 'id': wallet_id,
+ 'network_id': network_id,
+ 'server_signer_status': 'pending_seed_creation'
+ )
+ end
+ let(:model_with_seed_active) do
+ Coinbase::Client::Wallet.new(
+ 'id': wallet_id,
+ 'network_id': network_id,
+ 'default_address': address_model1,
+ 'server_signer_status': 'active_seed'
)
end
let(:seed) { '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f' }
@@ -64,6 +74,7 @@
seed: seed
)
end
+ let(:configuration) { double('Coinbase::Configuration', use_server_signer: use_server_signer, api_client: nil) }
subject(:imported_wallet) { Coinbase::Wallet.import(exported_data) }
before do
@@ -72,33 +83,56 @@
.to receive(:list_addresses)
.with(wallet_id, { limit: 20 })
.and_return(address_list_model)
+ allow(Coinbase).to receive(:configuration).and_return(configuration)
end
- it 'imports an exported wallet' do
- expect(imported_wallet.id).to eq(wallet_id)
- end
+ context 'when not using server signer' do
+ let(:use_server_signer) { false }
+ it 'imports an exported wallet' do
+ expect(imported_wallet.id).to eq(wallet_id)
+ end
- it 'loads the wallet addresses' do
- expect(imported_wallet.addresses.length).to eq(address_list_model.total_count)
- end
+ it 'loads the wallet addresses' do
+ expect(imported_wallet.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(exported_data.seed)
+ it 'contains the same seed when re-exported' do
+ expect(imported_wallet.export.seed).to eq(exported_data.seed)
+ end
end
context 'when there are no addresses' do
+ let(:use_server_signer) { false }
let(:address_list_model) { Coinbase::Client::AddressList.new({ 'data' => [], 'total_count' => 0 }) }
it 'loads the wallet addresses' do
expect(imported_wallet.addresses.length).to eq(0)
end
end
+
+ context 'when using a server signer' do
+ let(:use_server_signer) { true }
+
+ it 'imports a wallet with id' do
+ expect(imported_wallet.id).to eq(wallet_id)
+ end
+
+ it 'loads the wallet addresses' do
+ expect(imported_wallet.addresses.length).to eq(address_list_model.total_count)
+ end
+
+ it 'cannot export the wallet' do
+ expect do
+ imported_wallet.export
+ end.to raise_error 'Cannot export data for Server-Signer backed Wallet'
+ end
+ end
end
describe '.create' do
let(:wallet_id) { SecureRandom.uuid }
let(:create_wallet_request) do
- { wallet: { network_id: network_id } }
+ { wallet: { network_id: network_id, use_server_signer: use_server_signer } }
end
let(:request) { { create_wallet_request: create_wallet_request } }
let(:wallet_model) { Coinbase::Client::Wallet.new({ 'id': wallet_id, 'network_id': network_id }) }
@@ -112,40 +146,67 @@
}
)
end
+ let(:configuration) { double('Coinbase::Configuration', use_server_signer: use_server_signer, api_client: nil) }
subject(:created_wallet) { described_class.create }
before do
+ allow(Coinbase).to receive(:configuration).and_return(configuration)
allow(wallets_api).to receive(:create_wallet).with(request).and_return(wallet_model)
+ end
- allow(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_model1)
+ context 'when not using a server signer' do
+ let(:use_server_signer) { false }
+ before do
+ allow(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_model1)
- allow(wallets_api)
- .to receive(:get_wallet)
- .with(wallet_id)
- .and_return(model_with_default_address)
- end
+ allow(wallets_api)
+ .to receive(:get_wallet)
+ .with(wallet_id)
+ .and_return(model_with_default_address)
+ end
- it 'creates a new wallet' do
- expect(created_wallet).to be_a(Coinbase::Wallet)
- end
+ it 'creates a new wallet' do
+ expect(created_wallet).to be_a(Coinbase::Wallet)
+ end
- it 'creates a default address' do
- expect(created_wallet.default_address).to be_a(Coinbase::Address)
- expect(created_wallet.addresses.length).to eq(1)
+ it 'creates a default address' do
+ expect(created_wallet.default_address).to be_a(Coinbase::Address)
+ expect(created_wallet.addresses.length).to eq(1)
+ end
end
context 'when setting the network ID explicitly' do
let(:network_id) { 'base-mainnet' }
+ let(:use_server_signer) { false }
+
+ before do
+ allow(addresses_api)
+ .to receive(:create_address)
+ .with(
+ wallet_id,
+ satisfy do |req|
+ public_key = req[:create_address_request][:public_key]
+ attestation = req[:create_address_request][:attestation]
+
+ public_key.is_a?(String) && attestation.is_a?(String)
+ end
+ ).and_return(address_model1)
+
+ allow(wallets_api)
+ .to receive(:get_wallet)
+ .with(wallet_id)
+ .and_return(model_with_default_address)
+ end
subject(:created_wallet) do
described_class.create(network_id: network_id)
@@ -159,6 +220,58 @@
expect(created_wallet.network_id).to eq(:base_mainnet)
end
end
+
+ context 'when using a server signer' do
+ let(:use_server_signer) { true }
+ before do
+ allow(addresses_api)
+ .to receive(:create_address)
+ .with(wallet_id, { create_address_request: {} })
+ .and_return(address_model1)
+
+ allow(wallets_api)
+ .to receive(:get_wallet)
+ .with(wallet_id)
+ .and_return(model_with_seed_active)
+ end
+
+ subject(:created_wallet) do
+ described_class.create(interval_seconds: 0.2, timeout_seconds: 0.00001)
+ end
+
+ it 'creates a new wallet' do
+ expect(created_wallet).to be_a(Coinbase::Wallet)
+ end
+
+ it 'creates a default address' do
+ expect(created_wallet.default_address).to be_a(Coinbase::Address)
+ expect(created_wallet.addresses.length).to eq(1)
+ end
+
+ it 'sets the default network ID' do
+ expect(created_wallet.network_id).to eq(:base_sepolia)
+ end
+ end
+
+ context 'when using a server signer is not active' do
+ let(:use_server_signer) { true }
+ before do
+ allow(wallets_api)
+ .to receive(:get_wallet)
+ .with(wallet_id)
+ .and_return(model_with_seed_pending)
+ end
+
+ subject(:created_wallet) do
+ described_class.create(interval_seconds: 0.2, timeout_seconds: 0.00001)
+ end
+
+ it 'raises a Timeout::Error' do
+ expect do
+ created_wallet
+ end.to raise_error(Timeout::Error, 'Wallet creation timed out. Check status of your Server-Signer')
+ end
+ end
end
describe '#initialize' do
@@ -272,6 +385,8 @@
described_class.new(model, seed: seed)
end
+ let(:configuration) { double('Coinbase::Configuration', use_server_signer: use_server_signer, api_client: nil) }
+
subject(:created_address) { wallet.create_address }
before do
@@ -328,6 +443,27 @@
expect(created_address).not_to eq(wallet.default_address)
end
end
+
+ context 'when using a server signer' do
+ let(:configuration) { double('Coinbase::Configuration', use_server_signer: true, api_client: nil) }
+ let(:created_address_model) { address_model1 }
+
+ subject(:created_address) { wallet.create_address }
+
+ before do
+ allow(addresses_api)
+ .to receive(:create_address)
+ .with(wallet_id).and_return(created_address_model)
+ allow(wallets_api)
+ .to receive(:get_wallet)
+ .with(wallet_id)
+ .and_return(model_with_default_address)
+ end
+
+ it 'creates a new address' do
+ expect(created_address).to be_a(Coinbase::Address)
+ end
+ end
end
describe '#default_address' do
@@ -454,32 +590,30 @@
context 'when the destination is a Wallet' do
let(:destination) { other_wallet }
- let(:to_address_id) { destination.default_address.id }
before do
allow(wallet.default_address)
.to receive(:transfer)
- .with(amount, asset_id, to_address_id)
+ .with(amount, asset_id, destination)
.and_return(transfer)
end
- it 'creates a transfer to the default address ID' do
+ it 'creates a transfer from the default address to the wallet' do
expect(wallet.transfer(amount, asset_id, destination)).to eq(transfer)
end
end
- context 'when the desination is an Address' do
+ context 'when the destination is an Address' do
let(:destination) { other_wallet.default_address }
- let(:to_address_id) { destination.id }
before do
allow(wallet.default_address)
.to receive(:transfer)
- .with(amount, asset_id, to_address_id)
+ .with(amount, asset_id, destination)
.and_return(transfer)
end
- it 'creates a transfer to the address ID' do
+ it 'creates a transfer from the default address to the address' do
expect(wallet.transfer(amount, asset_id, destination)).to eq(transfer)
end
end
@@ -494,31 +628,52 @@
.and_return(transfer)
end
- it 'creates a transfer to the address ID' do
+ it 'creates a transfer from the default address to the address ID' do
expect(wallet.transfer(amount, asset_id, destination)).to eq(transfer)
end
end
end
describe '#export' do
- let(:seed_wallet) do
- described_class.new(model, seed: seed, address_models: [address_model1, address_model2])
+ let(:configuration) { double('Coinbase::Configuration', use_server_signer: use_server_signer, api_client: nil) }
+ before do
+ allow(Coinbase).to receive(:configuration).and_return(configuration)
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.id)
- expect(wallet_data.seed).to eq(seed)
+ context 'when not using a server signer' do
+ let(:use_server_signer) { false }
+ let(:seed_wallet) do
+ described_class.new(model, seed: seed, address_models: [address_model1, address_model2])
+ 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.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_models: [address_model1, address_model2])
+ expect(new_wallet.addresses.length).to eq(2)
+ new_wallet.addresses.each_with_index do |address, i|
+ expect(address.id).to eq(seed_wallet.addresses[i].id)
+ end
+ end
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_models: [address_model1, address_model2])
- expect(new_wallet.addresses.length).to eq(2)
- new_wallet.addresses.each_with_index do |address, i|
- expect(address.id).to eq(seed_wallet.addresses[i].id)
+ context 'when using a server signer' do
+ let(:use_server_signer) { true }
+ let(:wallet_without_seed) do
+ described_class.new(model, seed: nil, address_models: [address_model1, address_model2])
+ end
+
+ it 'does not export seed data' do
+ expect do
+ wallet_without_seed.export
+ end.to raise_error 'Cannot export data for Server-Signer backed Wallet'
end
end
end
@@ -562,6 +717,180 @@
end
end
+ describe '#save_seed!' do
+ let(:file_path) { "#{SecureRandom.uuid}.json" }
+ let(:initial_seed_data) { JSON.pretty_generate({}) }
+ let(:seed_wallet) do
+ described_class.new(model_with_default_address, seed: seed, address_models: [address_model1])
+ end
+
+ before do
+ @api_key_private_key = Coinbase.configuration.api_key_private_key
+ Coinbase.configuration.api_key_private_key = OpenSSL::PKey::EC.generate('prime256v1').to_pem
+ File.open(file_path, 'w') do |file|
+ file.write(initial_seed_data)
+ end
+ end
+
+ after do
+ File.delete(file_path)
+ Coinbase.configuration.api_key_private_key = @api_key_private_key
+ end
+
+ it 'saves the seed when encrypt is false' do
+ seed_wallet.save_seed!(file_path, encrypt: false)
+
+ # Verify that the file has new wallet.
+ stored_seed_data = File.read(file_path)
+ wallets = JSON.parse(stored_seed_data)
+ data = wallets[seed_wallet.id]
+ expect(data).not_to be_empty
+ expect(data['encrypted']).to eq(false)
+ expect(data['iv']).to eq('')
+ expect(data['auth_tag']).to eq('')
+ expect(data['seed']).to eq(seed)
+ end
+
+ it 'saves the seed when encryption is true' do
+ seed_wallet.save_seed!(file_path, encrypt: true)
+
+ # Verify that the file has new wallet.
+ stored_seed_data = File.read(file_path)
+ wallets = JSON.parse(stored_seed_data)
+ data = wallets[seed_wallet.id]
+ expect(data).not_to be_empty
+ expect(data['encrypted']).to eq(true)
+ expect(data['iv']).not_to be_empty
+ expect(data['auth_tag']).not_to be_empty
+ expect(data['seed']).not_to eq(seed)
+ end
+
+ it 'throws an error when the wallet is seedless' do
+ seedless_wallet = described_class.new(model_with_default_address, seed: '', address_models: [address_model1])
+ expect do
+ seedless_wallet.save_seed!(file_path)
+ end.to raise_error 'Wallet does not have seed loaded'
+ end
+
+ it 'throws an error when the file is malformed' do
+ File.open(file_path, 'w') do |file|
+ file.write(JSON.pretty_generate({
+ malformed: 'test'
+ }.to_json))
+ end
+ expect do
+ seed_wallet.save_seed!(file_path)
+ end.to raise_error(ArgumentError)
+ end
+ end
+
+ describe '#load_seed' do
+ let(:file_path) { "#{SecureRandom.uuid}.json" }
+ let(:initial_seed_data) { JSON.pretty_generate({}) }
+ let(:address_list_model) do
+ Coinbase::Client::AddressList.new(
+ {
+ 'data' => [address_model1],
+ 'total_count' => 1
+ }
+ )
+ end
+ let(:seed_wallet) do
+ described_class.new(model_with_default_address, seed: seed, address_models: [address_model1])
+ end
+ let(:seedless_wallet) do
+ described_class.new(model_with_default_address, seed: '', address_models: [address_model1])
+ end
+ let(:initial_seed_data) do
+ {
+ wallet_id => {
+ seed: seed,
+ encrypted: false
+ }
+ }
+ end
+ let(:other_seed_data) do
+ {
+ SecureRandom.uuid => {
+ seed: 'other-seed',
+ encrypted: false
+ }
+ }
+ end
+ let(:malformed_seed_data) do
+ {
+ wallet_id => 'test'
+ }
+ end
+
+ before do
+ @api_key_private_key = Coinbase.configuration.api_key_private_key
+ Coinbase.configuration.api_key_private_key = OpenSSL::PKey::EC.generate('prime256v1').to_pem
+ File.open(file_path, 'w') do |file|
+ file.write(JSON.pretty_generate(initial_seed_data))
+ end
+ end
+
+ after do
+ File.delete(file_path) if File.exist?(file_path)
+ Coinbase.configuration.api_key_private_key = @api_key_private_key
+ end
+
+ it 'loads the seed from the file' do
+ seedless_wallet.load_seed(file_path)
+ expect(seedless_wallet.can_sign?).to be true
+ end
+
+ it 'loads the encrypted seed from the file' do
+ seed_wallet.save_seed!(file_path, encrypt: true)
+ seedless_wallet.load_seed(file_path)
+ expect(seedless_wallet.can_sign?).to be true
+ end
+
+ it 'loads the encrypted seed from file with multiple seeds' do
+ seed_wallet.save_seed!(file_path, encrypt: true)
+
+ other_model = Coinbase::Client::Wallet.new({ 'id': SecureRandom.uuid, 'network_id': network_id })
+ other_wallet = described_class.new(other_model)
+ other_wallet.save_seed!(file_path, encrypt: true)
+
+ seedless_wallet.load_seed(file_path)
+ expect(seedless_wallet.can_sign?).to be true
+ end
+
+ it 'throws an error when the wallet is already hydrated' do
+ expect do
+ seed_wallet.load_seed(file_path)
+ end.to raise_error('Wallet already has seed loaded')
+ end
+
+ it 'throws an error when file contains different wallet data' do
+ File.open(file_path, 'w') do |file|
+ file.write(JSON.pretty_generate(other_seed_data))
+ end
+
+ expect do
+ seedless_wallet.load_seed(file_path)
+ end.to raise_error(ArgumentError, /does not contain seed data for wallet/)
+ end
+
+ it 'throws an error when the file is absent' do
+ File.delete(file_path)
+ expect do
+ seedless_wallet.load_seed(file_path)
+ end.to raise_error(ArgumentError, /does not contain seed data/)
+ end
+
+ it 'throws an error when the backup file is corrupted' do
+ File.open(file_path, 'w') do |file|
+ file.write(JSON.pretty_generate(malformed_seed_data))
+ end
+ expect do
+ seedless_wallet.load_seed(file_path)
+ end.to raise_error(ArgumentError, 'Seed data is malformed')
+ end
+ end
+
describe '#inspect' do
it 'includes wallet details' do
expect(wallet.inspect).to include(wallet_id, Coinbase.to_sym(network_id).to_s)