diff --git a/README.md b/README.md index ad023fa6..6b889e99 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,9 @@ testnet ETH. You are allowed one faucet claim per 24-hour window. # Fund the wallet with a faucet transaction. faucet_tx = wallet1.faucet +# Wait for the faucet transaction to complete. +faucet_tx.wait! + puts "Faucet transaction successfully completed: #{faucet_tx}" ``` diff --git a/lib/coinbase/address.rb b/lib/coinbase/address.rb index 4e0d5a2a..d5837abd 100644 --- a/lib/coinbase/address.rb +++ b/lib/coinbase/address.rb @@ -91,11 +91,16 @@ def transactions # @raise [Coinbase::FaucetLimitReachedError] If the faucet limit has been reached for the address or user. # @raise [Coinbase::Client::ApiError] If an unexpected error occurs while requesting faucet funds. def faucet(asset_id: nil) - opts = { asset_id: asset_id }.compact - Coinbase.call_api do Coinbase::FaucetTransaction.new( - addresses_api.request_external_faucet_funds(network.normalized_id, id, opts) + addresses_api.request_external_faucet_funds( + network.normalized_id, + id, + { + asset_id: asset_id, + skip_wait: true + }.compact + ) ) end end diff --git a/lib/coinbase/client.rb b/lib/coinbase/client.rb index b73dd20c..b40ebda5 100644 --- a/lib/coinbase/client.rb +++ b/lib/coinbase/client.rb @@ -35,6 +35,8 @@ Coinbase::Client.autoload :ContractInvocationList, 'coinbase/client/models/contract_invocation_list' Coinbase::Client.autoload :CreateAddressRequest, 'coinbase/client/models/create_address_request' Coinbase::Client.autoload :CreateContractInvocationRequest, 'coinbase/client/models/create_contract_invocation_request' +Coinbase::Client.autoload :CreateFundOperationRequest, 'coinbase/client/models/create_fund_operation_request' +Coinbase::Client.autoload :CreateFundQuoteRequest, 'coinbase/client/models/create_fund_quote_request' Coinbase::Client.autoload :CreatePayloadSignatureRequest, 'coinbase/client/models/create_payload_signature_request' Coinbase::Client.autoload :CreateServerSignerRequest, 'coinbase/client/models/create_server_signer_request' Coinbase::Client.autoload :CreateSmartContractRequest, 'coinbase/client/models/create_smart_contract_request' @@ -45,6 +47,7 @@ Coinbase::Client.autoload :CreateWalletRequestWallet, 'coinbase/client/models/create_wallet_request_wallet' Coinbase::Client.autoload :CreateWalletWebhookRequest, 'coinbase/client/models/create_wallet_webhook_request' Coinbase::Client.autoload :CreateWebhookRequest, 'coinbase/client/models/create_webhook_request' +Coinbase::Client.autoload :CryptoAmount, 'coinbase/client/models/crypto_amount' Coinbase::Client.autoload :DeploySmartContractRequest, 'coinbase/client/models/deploy_smart_contract_request' Coinbase::Client.autoload :ERC20TransferEvent, 'coinbase/client/models/erc20_transfer_event' Coinbase::Client.autoload :ERC721TransferEvent, 'coinbase/client/models/erc721_transfer_event' @@ -60,6 +63,11 @@ Coinbase::Client.autoload :FetchHistoricalStakingBalances200Response, 'coinbase/client/models/fetch_historical_staking_balances200_response' Coinbase::Client.autoload :FetchStakingRewards200Response, 'coinbase/client/models/fetch_staking_rewards200_response' Coinbase::Client.autoload :FetchStakingRewardsRequest, 'coinbase/client/models/fetch_staking_rewards_request' +Coinbase::Client.autoload :FiatAmount, 'coinbase/client/models/fiat_amount' +Coinbase::Client.autoload :FundOperation, 'coinbase/client/models/fund_operation' +Coinbase::Client.autoload :FundOperationFees, 'coinbase/client/models/fund_operation_fees' +Coinbase::Client.autoload :FundOperationList, 'coinbase/client/models/fund_operation_list' +Coinbase::Client.autoload :FundQuote, 'coinbase/client/models/fund_quote' Coinbase::Client.autoload :GetStakingContextRequest, 'coinbase/client/models/get_staking_context_request' Coinbase::Client.autoload :HistoricalBalance, 'coinbase/client/models/historical_balance' Coinbase::Client.autoload :MultiTokenContractOptions, 'coinbase/client/models/multi_token_contract_options' @@ -68,7 +76,6 @@ Coinbase::Client.autoload :NetworkIdentifier, 'coinbase/client/models/network_identifier' Coinbase::Client.autoload :OnchainName, 'coinbase/client/models/onchain_name' Coinbase::Client.autoload :OnchainNameList, 'coinbase/client/models/onchain_name_list' -Coinbase::Client.autoload :OnchainNameTextRecordsInner, 'coinbase/client/models/onchain_name_text_records_inner' Coinbase::Client.autoload :PayloadSignature, 'coinbase/client/models/payload_signature' Coinbase::Client.autoload :PayloadSignatureList, 'coinbase/client/models/payload_signature_list' Coinbase::Client.autoload :ReadContractRequest, 'coinbase/client/models/read_contract_request' @@ -127,6 +134,7 @@ Coinbase::Client.autoload :ContractEventsApi, 'coinbase/client/api/contract_events_api' Coinbase::Client.autoload :ContractInvocationsApi, 'coinbase/client/api/contract_invocations_api' Coinbase::Client.autoload :ExternalAddressesApi, 'coinbase/client/api/external_addresses_api' +Coinbase::Client.autoload :FundApi, 'coinbase/client/api/fund_api' Coinbase::Client.autoload :NetworksApi, 'coinbase/client/api/networks_api' Coinbase::Client.autoload :OnchainIdentityApi, 'coinbase/client/api/onchain_identity_api' Coinbase::Client.autoload :ServerSignersApi, 'coinbase/client/api/server_signers_api' diff --git a/lib/coinbase/client/api/external_addresses_api.rb b/lib/coinbase/client/api/external_addresses_api.rb index 888c5104..5e26ec39 100644 --- a/lib/coinbase/client/api/external_addresses_api.rb +++ b/lib/coinbase/client/api/external_addresses_api.rb @@ -94,6 +94,81 @@ def get_external_address_balance_with_http_info(network_id, address_id, asset_id return data, status_code, headers end + # Get the status of a faucet transaction + # Get the status of a faucet transaction + # @param network_id [String] The ID of the blockchain network + # @param address_id [String] The ID of the address to fetch the faucet transaction for + # @param tx_hash [String] The hash of the faucet transaction + # @param [Hash] opts the optional parameters + # @return [FaucetTransaction] + def get_faucet_transaction(network_id, address_id, tx_hash, opts = {}) + data, _status_code, _headers = get_faucet_transaction_with_http_info(network_id, address_id, tx_hash, opts) + data + end + + # Get the status of a faucet transaction + # Get the status of a faucet transaction + # @param network_id [String] The ID of the blockchain network + # @param address_id [String] The ID of the address to fetch the faucet transaction for + # @param tx_hash [String] The hash of the faucet transaction + # @param [Hash] opts the optional parameters + # @return [Array<(FaucetTransaction, Integer, Hash)>] FaucetTransaction data, response status code and response headers + def get_faucet_transaction_with_http_info(network_id, address_id, tx_hash, opts = {}) + if @api_client.config.debugging + @api_client.config.logger.debug 'Calling API: ExternalAddressesApi.get_faucet_transaction ...' + end + # verify the required parameter 'network_id' is set + if @api_client.config.client_side_validation && network_id.nil? + fail ArgumentError, "Missing the required parameter 'network_id' when calling ExternalAddressesApi.get_faucet_transaction" + 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 ExternalAddressesApi.get_faucet_transaction" + end + # verify the required parameter 'tx_hash' is set + if @api_client.config.client_side_validation && tx_hash.nil? + fail ArgumentError, "Missing the required parameter 'tx_hash' when calling ExternalAddressesApi.get_faucet_transaction" + end + # resource path + local_var_path = '/v1/networks/{network_id}/addresses/{address_id}/faucet/{tx_hash}'.sub('{' + 'network_id' + '}', CGI.escape(network_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s)).sub('{' + 'tx_hash' + '}', CGI.escape(tx_hash.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']) unless header_params['Accept'] + + # form parameters + form_params = opts[:form_params] || {} + + # http body (model) + post_body = opts[:debug_body] + + # return_type + return_type = opts[:debug_return_type] || 'FaucetTransaction' + + # auth_names + auth_names = opts[:debug_auth_names] || [] + + new_options = opts.merge( + :operation => :"ExternalAddressesApi.get_faucet_transaction", + :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: ExternalAddressesApi#get_faucet_transaction\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}" + end + return data, status_code, headers + end + # Get the balances of an external address # List all of the balances of an external address # @param network_id [String] The ID of the blockchain network @@ -176,6 +251,7 @@ def list_external_address_balances_with_http_info(network_id, address_id, opts = # @param address_id [String] The onchain address of the address that is being fetched. # @param [Hash] opts the optional parameters # @option opts [String] :asset_id The ID of the asset to transfer from the faucet. + # @option opts [Boolean] :skip_wait Whether to skip waiting for the transaction to be mined. This will become the default behavior in the future. # @return [FaucetTransaction] def request_external_faucet_funds(network_id, address_id, opts = {}) data, _status_code, _headers = request_external_faucet_funds_with_http_info(network_id, address_id, opts) @@ -188,6 +264,7 @@ def request_external_faucet_funds(network_id, address_id, opts = {}) # @param address_id [String] The onchain address of the address that is being fetched. # @param [Hash] opts the optional parameters # @option opts [String] :asset_id The ID of the asset to transfer from the faucet. + # @option opts [Boolean] :skip_wait Whether to skip waiting for the transaction to be mined. This will become the default behavior in the future. # @return [Array<(FaucetTransaction, Integer, Hash)>] FaucetTransaction data, response status code and response headers def request_external_faucet_funds_with_http_info(network_id, address_id, opts = {}) if @api_client.config.debugging @@ -207,6 +284,7 @@ def request_external_faucet_funds_with_http_info(network_id, address_id, opts = # query parameters query_params = opts[:query_params] || {} query_params[:'asset_id'] = opts[:'asset_id'] if !opts[:'asset_id'].nil? + query_params[:'skip_wait'] = opts[:'skip_wait'] if !opts[:'skip_wait'].nil? # header parameters header_params = opts[:header_params] || {} diff --git a/lib/coinbase/client/api/fund_api.rb b/lib/coinbase/client/api/fund_api.rb new file mode 100644 index 00000000..6c97f4bb --- /dev/null +++ b/lib/coinbase/client/api/fund_api.rb @@ -0,0 +1,336 @@ +=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 + +Generated by: https://openapi-generator.tech +Generator version: 7.8.0 + +=end + +require 'cgi' + +module Coinbase::Client + class FundApi + attr_accessor :api_client + + def initialize(api_client = ApiClient.default) + @api_client = api_client + end + # Create a new fund operation. + # Create a new fund operation with an address. + # @param wallet_id [String] The ID of the wallet the address belongs to. + # @param address_id [String] The onchain address to be funded. + # @param create_fund_operation_request [CreateFundOperationRequest] + # @param [Hash] opts the optional parameters + # @return [FundOperation] + def create_fund_operation(wallet_id, address_id, create_fund_operation_request, opts = {}) + data, _status_code, _headers = create_fund_operation_with_http_info(wallet_id, address_id, create_fund_operation_request, opts) + data + end + + # Create a new fund operation. + # Create a new fund operation with an address. + # @param wallet_id [String] The ID of the wallet the address belongs to. + # @param address_id [String] The onchain address to be funded. + # @param create_fund_operation_request [CreateFundOperationRequest] + # @param [Hash] opts the optional parameters + # @return [Array<(FundOperation, Integer, Hash)>] FundOperation data, response status code and response headers + def create_fund_operation_with_http_info(wallet_id, address_id, create_fund_operation_request, opts = {}) + if @api_client.config.debugging + @api_client.config.logger.debug 'Calling API: FundApi.create_fund_operation ...' + 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 FundApi.create_fund_operation" + 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 FundApi.create_fund_operation" + end + # verify the required parameter 'create_fund_operation_request' is set + if @api_client.config.client_side_validation && create_fund_operation_request.nil? + fail ArgumentError, "Missing the required parameter 'create_fund_operation_request' when calling FundApi.create_fund_operation" + end + # resource path + local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/fund_operations'.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']) unless header_params['Accept'] + # 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_fund_operation_request) + + # return_type + return_type = opts[:debug_return_type] || 'FundOperation' + + # auth_names + auth_names = opts[:debug_auth_names] || [] + + new_options = opts.merge( + :operation => :"FundApi.create_fund_operation", + :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: FundApi#create_fund_operation\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}" + end + return data, status_code, headers + end + + # Create a Fund Operation quote. + # Create a new fund operation with an address. + # @param wallet_id [String] The ID of the wallet the address belongs to. + # @param address_id [String] The onchain address to be funded. + # @param create_fund_quote_request [CreateFundQuoteRequest] + # @param [Hash] opts the optional parameters + # @return [FundQuote] + def create_fund_quote(wallet_id, address_id, create_fund_quote_request, opts = {}) + data, _status_code, _headers = create_fund_quote_with_http_info(wallet_id, address_id, create_fund_quote_request, opts) + data + end + + # Create a Fund Operation quote. + # Create a new fund operation with an address. + # @param wallet_id [String] The ID of the wallet the address belongs to. + # @param address_id [String] The onchain address to be funded. + # @param create_fund_quote_request [CreateFundQuoteRequest] + # @param [Hash] opts the optional parameters + # @return [Array<(FundQuote, Integer, Hash)>] FundQuote data, response status code and response headers + def create_fund_quote_with_http_info(wallet_id, address_id, create_fund_quote_request, opts = {}) + if @api_client.config.debugging + @api_client.config.logger.debug 'Calling API: FundApi.create_fund_quote ...' + 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 FundApi.create_fund_quote" + 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 FundApi.create_fund_quote" + end + # verify the required parameter 'create_fund_quote_request' is set + if @api_client.config.client_side_validation && create_fund_quote_request.nil? + fail ArgumentError, "Missing the required parameter 'create_fund_quote_request' when calling FundApi.create_fund_quote" + end + # resource path + local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/fund_operations/quote'.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']) unless header_params['Accept'] + # 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_fund_quote_request) + + # return_type + return_type = opts[:debug_return_type] || 'FundQuote' + + # auth_names + auth_names = opts[:debug_auth_names] || [] + + new_options = opts.merge( + :operation => :"FundApi.create_fund_quote", + :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: FundApi#create_fund_quote\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}" + end + return data, status_code, headers + end + + # Get fund operation. + # Get fund operation. + # @param wallet_id [String] The ID of the wallet the address belongs to. + # @param address_id [String] The onchain address of the address that created the fund operation. + # @param fund_operation_id [String] The ID of the fund operation to fetch. + # @param [Hash] opts the optional parameters + # @return [FundOperation] + def get_fund_operation(wallet_id, address_id, fund_operation_id, opts = {}) + data, _status_code, _headers = get_fund_operation_with_http_info(wallet_id, address_id, fund_operation_id, opts) + data + end + + # Get fund operation. + # Get fund operation. + # @param wallet_id [String] The ID of the wallet the address belongs to. + # @param address_id [String] The onchain address of the address that created the fund operation. + # @param fund_operation_id [String] The ID of the fund operation to fetch. + # @param [Hash] opts the optional parameters + # @return [Array<(FundOperation, Integer, Hash)>] FundOperation data, response status code and response headers + def get_fund_operation_with_http_info(wallet_id, address_id, fund_operation_id, opts = {}) + if @api_client.config.debugging + @api_client.config.logger.debug 'Calling API: FundApi.get_fund_operation ...' + 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 FundApi.get_fund_operation" + 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 FundApi.get_fund_operation" + end + # verify the required parameter 'fund_operation_id' is set + if @api_client.config.client_side_validation && fund_operation_id.nil? + fail ArgumentError, "Missing the required parameter 'fund_operation_id' when calling FundApi.get_fund_operation" + end + # resource path + local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/fund_operations/{fund_operation_id}'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s)).sub('{' + 'fund_operation_id' + '}', CGI.escape(fund_operation_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']) unless header_params['Accept'] + + # form parameters + form_params = opts[:form_params] || {} + + # http body (model) + post_body = opts[:debug_body] + + # return_type + return_type = opts[:debug_return_type] || 'FundOperation' + + # auth_names + auth_names = opts[:debug_auth_names] || [] + + new_options = opts.merge( + :operation => :"FundApi.get_fund_operation", + :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: FundApi#get_fund_operation\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}" + end + return data, status_code, headers + end + + # List fund operations for an address. + # List fund operations for an address. + # @param wallet_id [String] The ID of the wallet the address belongs to. + # @param address_id [String] The onchain address of the address to list fund operations 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 [FundOperationList] + def list_fund_operations(wallet_id, address_id, opts = {}) + data, _status_code, _headers = list_fund_operations_with_http_info(wallet_id, address_id, opts) + data + end + + # List fund operations for an address. + # List fund operations for an address. + # @param wallet_id [String] The ID of the wallet the address belongs to. + # @param address_id [String] The onchain address of the address to list fund operations 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<(FundOperationList, Integer, Hash)>] FundOperationList data, response status code and response headers + def list_fund_operations_with_http_info(wallet_id, address_id, opts = {}) + if @api_client.config.debugging + @api_client.config.logger.debug 'Calling API: FundApi.list_fund_operations ...' + 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 FundApi.list_fund_operations" + 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 FundApi.list_fund_operations" + 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 FundApi.list_fund_operations, the character length must be smaller than or equal to 5000.' + end + + # resource path + local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/fund_operations'.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']) unless header_params['Accept'] + + # form parameters + form_params = opts[:form_params] || {} + + # http body (model) + post_body = opts[:debug_body] + + # return_type + return_type = opts[:debug_return_type] || 'FundOperationList' + + # auth_names + auth_names = opts[:debug_auth_names] || [] + + new_options = opts.merge( + :operation => :"FundApi.list_fund_operations", + :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: FundApi#list_fund_operations\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/onchain_identity_api.rb b/lib/coinbase/client/api/onchain_identity_api.rb index fe4edb60..294cb3c8 100644 --- a/lib/coinbase/client/api/onchain_identity_api.rb +++ b/lib/coinbase/client/api/onchain_identity_api.rb @@ -24,6 +24,7 @@ def initialize(api_client = ApiClient.default) # @param network_id [String] The ID of the blockchain network # @param address_id [String] The ID of the address to fetch the identity for # @param [Hash] opts the optional parameters + # @option opts [Array] :roles A filter by role of the names related to this address (managed or owned) # @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 [OnchainNameList] @@ -37,6 +38,7 @@ def resolve_identity_by_address(network_id, address_id, opts = {}) # @param network_id [String] The ID of the blockchain network # @param address_id [String] The ID of the address to fetch the identity for # @param [Hash] opts the optional parameters + # @option opts [Array] :roles A filter by role of the names related to this address (managed or owned) # @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<(OnchainNameList, Integer, Hash)>] OnchainNameList data, response status code and response headers @@ -52,6 +54,10 @@ def resolve_identity_by_address_with_http_info(network_id, address_id, opts = {} if @api_client.config.client_side_validation && address_id.nil? fail ArgumentError, "Missing the required parameter 'address_id' when calling OnchainIdentityApi.resolve_identity_by_address" end + allowable_values = ["managed", "owned", "unknown_default_open_api"] + if @api_client.config.client_side_validation && opts[:'roles'] && !opts[:'roles'].all? { |item| allowable_values.include?(item) } + fail ArgumentError, "invalid value for \"roles\", must include one of #{allowable_values}" + 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 OnchainIdentityApi.resolve_identity_by_address, the character length must be smaller than or equal to 5000.' end @@ -61,6 +67,7 @@ def resolve_identity_by_address_with_http_info(network_id, address_id, opts = {} # query parameters query_params = opts[:query_params] || {} + query_params[:'roles'] = @api_client.build_collection_param(opts[:'roles'], :csv) if !opts[:'roles'].nil? query_params[:'limit'] = opts[:'limit'] if !opts[:'limit'].nil? query_params[:'page'] = opts[:'page'] if !opts[:'page'].nil? diff --git a/lib/coinbase/client/models/create_fund_operation_request.rb b/lib/coinbase/client/models/create_fund_operation_request.rb new file mode 100644 index 00000000..d8fee1ed --- /dev/null +++ b/lib/coinbase/client/models/create_fund_operation_request.rb @@ -0,0 +1,249 @@ +=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 + +Generated by: https://openapi-generator.tech +Generator version: 7.8.0 + +=end + +require 'date' +require 'time' + +module Coinbase::Client + class CreateFundOperationRequest + # The amount of the asset to fund the address with in atomic units. + attr_accessor :amount + + # The ID of the asset to fund the address with. + attr_accessor :asset_id + + # The Optional ID of the fund quote to fund the address with. If omitted we will generate a quote and immediately execute it. + attr_accessor :fund_quote_id + + # Attribute mapping from ruby-style variable name to JSON key. + def self.attribute_map + { + :'amount' => :'amount', + :'asset_id' => :'asset_id', + :'fund_quote_id' => :'fund_quote_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', + :'asset_id' => :'String', + :'fund_quote_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::CreateFundOperationRequest` 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::CreateFundOperationRequest`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect + end + h[k.to_sym] = v + } + + if attributes.key?(:'amount') + self.amount = attributes[:'amount'] + else + self.amount = nil + end + + if attributes.key?(:'asset_id') + self.asset_id = attributes[:'asset_id'] + else + self.asset_id = nil + end + + if attributes.key?(:'fund_quote_id') + self.fund_quote_id = attributes[:'fund_quote_id'] + end + end + + # Show invalid properties with the reasons. Usually used together with valid? + # @return Array for valid properties with the reasons + def list_invalid_properties + warn '[DEPRECATED] the `list_invalid_properties` method is obsolete' + invalid_properties = Array.new + if @amount.nil? + invalid_properties.push('invalid value for "amount", amount cannot be nil.') + end + + if @asset_id.nil? + invalid_properties.push('invalid value for "asset_id", asset_id cannot be nil.') + end + + invalid_properties + end + + # Check to see if the all the properties in the model are valid + # @return true if the model is valid + def valid? + warn '[DEPRECATED] the `valid?` method is obsolete' + return false if @amount.nil? + return false if @asset_id.nil? + true + end + + # Checks equality by comparing each attribute. + # @param [Object] Object to be compared + def ==(o) + return true if self.equal?(o) + self.class == o.class && + amount == o.amount && + asset_id == o.asset_id && + fund_quote_id == o.fund_quote_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, asset_id, fund_quote_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_fund_quote_request.rb b/lib/coinbase/client/models/create_fund_quote_request.rb new file mode 100644 index 00000000..23952537 --- /dev/null +++ b/lib/coinbase/client/models/create_fund_quote_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 + +Generated by: https://openapi-generator.tech +Generator version: 7.8.0 + +=end + +require 'date' +require 'time' + +module Coinbase::Client + class CreateFundQuoteRequest + # The amount of the asset to fund the address with in atomic units. + attr_accessor :amount + + # The ID of the asset to fund the address with. + attr_accessor :asset_id + + # Attribute mapping from ruby-style variable name to JSON key. + def self.attribute_map + { + :'amount' => :'amount', + :'asset_id' => :'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', + :'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::CreateFundQuoteRequest` 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::CreateFundQuoteRequest`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect + end + h[k.to_sym] = v + } + + if attributes.key?(:'amount') + self.amount = attributes[:'amount'] + else + self.amount = nil + end + + if attributes.key?(:'asset_id') + self.asset_id = attributes[:'asset_id'] + else + self.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 @asset_id.nil? + invalid_properties.push('invalid value for "asset_id", asset_id cannot be nil.') + end + + invalid_properties + end + + # Check to see if the all the properties in the model are valid + # @return true if the model is valid + def valid? + warn '[DEPRECATED] the `valid?` method is obsolete' + return false if @amount.nil? + return false if @asset_id.nil? + true + end + + # Checks equality by comparing each attribute. + # @param [Object] Object to be compared + def ==(o) + return true if self.equal?(o) + self.class == o.class && + amount == o.amount && + asset_id == o.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, 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/onchain_name_text_records_inner.rb b/lib/coinbase/client/models/crypto_amount.rb similarity index 84% rename from lib/coinbase/client/models/onchain_name_text_records_inner.rb rename to lib/coinbase/client/models/crypto_amount.rb index 549ec022..41702fb7 100644 --- a/lib/coinbase/client/models/onchain_name_text_records_inner.rb +++ b/lib/coinbase/client/models/crypto_amount.rb @@ -14,18 +14,18 @@ require 'time' module Coinbase::Client - class OnchainNameTextRecordsInner - # The key for the text record - attr_accessor :key + # An amount in cryptocurrency + class CryptoAmount + # The amount of the crypto in atomic units + attr_accessor :amount - # The value for the text record - attr_accessor :value + attr_accessor :asset # Attribute mapping from ruby-style variable name to JSON key. def self.attribute_map { - :'key' => :'key', - :'value' => :'value' + :'amount' => :'amount', + :'asset' => :'asset' } end @@ -37,8 +37,8 @@ def self.acceptable_attributes # Attribute type mapping. def self.openapi_types { - :'key' => :'String', - :'value' => :'String' + :'amount' => :'String', + :'asset' => :'Asset' } end @@ -52,23 +52,27 @@ def self.openapi_nullable # @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::OnchainNameTextRecordsInner` initialize method" + fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::CryptoAmount` 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::OnchainNameTextRecordsInner`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect + fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::CryptoAmount`. 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?(:'key') - self.key = attributes[:'key'] + if attributes.key?(:'amount') + self.amount = attributes[:'amount'] + else + self.amount = nil end - if attributes.key?(:'value') - self.value = attributes[:'value'] + if attributes.key?(:'asset') + self.asset = attributes[:'asset'] + else + self.asset = nil end end @@ -77,6 +81,14 @@ def initialize(attributes = {}) def list_invalid_properties warn '[DEPRECATED] the `list_invalid_properties` method is obsolete' invalid_properties = Array.new + if @amount.nil? + invalid_properties.push('invalid value for "amount", amount cannot be nil.') + end + + if @asset.nil? + invalid_properties.push('invalid value for "asset", asset cannot be nil.') + end + invalid_properties end @@ -84,6 +96,8 @@ def list_invalid_properties # @return true if the model is valid def valid? warn '[DEPRECATED] the `valid?` method is obsolete' + return false if @amount.nil? + return false if @asset.nil? true end @@ -92,8 +106,8 @@ def valid? def ==(o) return true if self.equal?(o) self.class == o.class && - key == o.key && - value == o.value + amount == o.amount && + asset == o.asset end # @see the `==` method @@ -105,7 +119,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [key, value].hash + [amount, asset].hash end # Builds the object from hash diff --git a/lib/coinbase/client/models/faucet_transaction.rb b/lib/coinbase/client/models/faucet_transaction.rb index c9535580..d607f53c 100644 --- a/lib/coinbase/client/models/faucet_transaction.rb +++ b/lib/coinbase/client/models/faucet_transaction.rb @@ -22,11 +22,14 @@ class FaucetTransaction # Link to the transaction on the blockchain explorer. attr_accessor :transaction_link + attr_accessor :transaction + # Attribute mapping from ruby-style variable name to JSON key. def self.attribute_map { :'transaction_hash' => :'transaction_hash', - :'transaction_link' => :'transaction_link' + :'transaction_link' => :'transaction_link', + :'transaction' => :'transaction' } end @@ -39,7 +42,8 @@ def self.acceptable_attributes def self.openapi_types { :'transaction_hash' => :'String', - :'transaction_link' => :'String' + :'transaction_link' => :'String', + :'transaction' => :'Transaction' } end @@ -75,6 +79,12 @@ def initialize(attributes = {}) else self.transaction_link = 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? @@ -90,6 +100,10 @@ def list_invalid_properties invalid_properties.push('invalid value for "transaction_link", transaction_link cannot be nil.') end + if @transaction.nil? + invalid_properties.push('invalid value for "transaction", transaction cannot be nil.') + end + invalid_properties end @@ -99,6 +113,7 @@ def valid? warn '[DEPRECATED] the `valid?` method is obsolete' return false if @transaction_hash.nil? return false if @transaction_link.nil? + return false if @transaction.nil? true end @@ -108,7 +123,8 @@ def ==(o) return true if self.equal?(o) self.class == o.class && transaction_hash == o.transaction_hash && - transaction_link == o.transaction_link + transaction_link == o.transaction_link && + transaction == o.transaction end # @see the `==` method @@ -120,7 +136,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [transaction_hash, transaction_link].hash + [transaction_hash, transaction_link, transaction].hash end # Builds the object from hash diff --git a/lib/coinbase/client/models/fiat_amount.rb b/lib/coinbase/client/models/fiat_amount.rb new file mode 100644 index 00000000..6fcbfc40 --- /dev/null +++ b/lib/coinbase/client/models/fiat_amount.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 + +Generated by: https://openapi-generator.tech +Generator version: 7.8.0 + +=end + +require 'date' +require 'time' + +module Coinbase::Client + # An amount in fiat currency + class FiatAmount + # The amount of the fiat in whole units. + attr_accessor :amount + + # The currency of the fiat + attr_accessor :currency + + # Attribute mapping from ruby-style variable name to JSON key. + def self.attribute_map + { + :'amount' => :'amount', + :'currency' => :'currency' + } + 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', + :'currency' => :'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::FiatAmount` 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::FiatAmount`. 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?(:'currency') + self.currency = attributes[:'currency'] + else + self.currency = 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 @currency.nil? + invalid_properties.push('invalid value for "currency", currency 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 @currency.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 && + currency == o.currency + 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, currency].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/fund_operation.rb b/lib/coinbase/client/models/fund_operation.rb new file mode 100644 index 00000000..9c6ea439 --- /dev/null +++ b/lib/coinbase/client/models/fund_operation.rb @@ -0,0 +1,373 @@ +=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 + +Generated by: https://openapi-generator.tech +Generator version: 7.8.0 + +=end + +require 'date' +require 'time' + +module Coinbase::Client + # An operation to fund a wallet with crypto + class FundOperation + # The ID of the fund operation + attr_accessor :fund_operation_id + + # The ID of the blockchain network + attr_accessor :network_id + + # The ID of the wallet that will receive the crypto + attr_accessor :wallet_id + + # The ID of the address that will receive the crypto + attr_accessor :address_id + + attr_accessor :crypto_amount + + attr_accessor :fiat_amount + + attr_accessor :fees + + # The status of the fund operation + 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 + { + :'fund_operation_id' => :'fund_operation_id', + :'network_id' => :'network_id', + :'wallet_id' => :'wallet_id', + :'address_id' => :'address_id', + :'crypto_amount' => :'crypto_amount', + :'fiat_amount' => :'fiat_amount', + :'fees' => :'fees', + :'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 + { + :'fund_operation_id' => :'String', + :'network_id' => :'String', + :'wallet_id' => :'String', + :'address_id' => :'String', + :'crypto_amount' => :'CryptoAmount', + :'fiat_amount' => :'FiatAmount', + :'fees' => :'FundOperationFees', + :'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::FundOperation` 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::FundOperation`. 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?(:'fund_operation_id') + self.fund_operation_id = attributes[:'fund_operation_id'] + else + self.fund_operation_id = nil + end + + 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?(:'crypto_amount') + self.crypto_amount = attributes[:'crypto_amount'] + else + self.crypto_amount = nil + end + + if attributes.key?(:'fiat_amount') + self.fiat_amount = attributes[:'fiat_amount'] + else + self.fiat_amount = nil + end + + if attributes.key?(:'fees') + self.fees = attributes[:'fees'] + else + self.fees = nil + end + + if attributes.key?(:'status') + self.status = attributes[:'status'] + else + self.status = nil + end + end + + # Show invalid properties with the reasons. Usually used together with valid? + # @return Array for valid properties with the reasons + def list_invalid_properties + warn '[DEPRECATED] the `list_invalid_properties` method is obsolete' + invalid_properties = Array.new + if @fund_operation_id.nil? + invalid_properties.push('invalid value for "fund_operation_id", fund_operation_id cannot be nil.') + end + + 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 @crypto_amount.nil? + invalid_properties.push('invalid value for "crypto_amount", crypto_amount cannot be nil.') + end + + if @fiat_amount.nil? + invalid_properties.push('invalid value for "fiat_amount", fiat_amount cannot be nil.') + end + + if @fees.nil? + invalid_properties.push('invalid value for "fees", fees 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 @fund_operation_id.nil? + return false if @network_id.nil? + return false if @wallet_id.nil? + return false if @address_id.nil? + return false if @crypto_amount.nil? + return false if @fiat_amount.nil? + return false if @fees.nil? + return false if @status.nil? + status_validator = EnumAttributeValidator.new('String', ["pending", "complete", "failed", "unknown_default_open_api"]) + 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", "complete", "failed", "unknown_default_open_api"]) + 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 && + fund_operation_id == o.fund_operation_id && + network_id == o.network_id && + wallet_id == o.wallet_id && + address_id == o.address_id && + crypto_amount == o.crypto_amount && + fiat_amount == o.fiat_amount && + fees == o.fees && + 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 + [fund_operation_id, network_id, wallet_id, address_id, crypto_amount, fiat_amount, fees, 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/fund_operation_fees.rb b/lib/coinbase/client/models/fund_operation_fees.rb new file mode 100644 index 00000000..f27416e9 --- /dev/null +++ b/lib/coinbase/client/models/fund_operation_fees.rb @@ -0,0 +1,238 @@ +=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 + +Generated by: https://openapi-generator.tech +Generator version: 7.8.0 + +=end + +require 'date' +require 'time' + +module Coinbase::Client + # The fees for a fund operation. + class FundOperationFees + attr_accessor :buy_fee + + attr_accessor :transfer_fee + + # Attribute mapping from ruby-style variable name to JSON key. + def self.attribute_map + { + :'buy_fee' => :'buy_fee', + :'transfer_fee' => :'transfer_fee' + } + 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 + { + :'buy_fee' => :'FiatAmount', + :'transfer_fee' => :'CryptoAmount' + } + 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::FundOperationFees` 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::FundOperationFees`. 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?(:'buy_fee') + self.buy_fee = attributes[:'buy_fee'] + else + self.buy_fee = nil + end + + if attributes.key?(:'transfer_fee') + self.transfer_fee = attributes[:'transfer_fee'] + else + self.transfer_fee = 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 @buy_fee.nil? + invalid_properties.push('invalid value for "buy_fee", buy_fee cannot be nil.') + end + + if @transfer_fee.nil? + invalid_properties.push('invalid value for "transfer_fee", transfer_fee 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 @buy_fee.nil? + return false if @transfer_fee.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 && + buy_fee == o.buy_fee && + transfer_fee == o.transfer_fee + 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 + [buy_fee, transfer_fee].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/fund_operation_list.rb b/lib/coinbase/client/models/fund_operation_list.rb new file mode 100644 index 00000000..2e25b453 --- /dev/null +++ b/lib/coinbase/client/models/fund_operation_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 + +Generated by: https://openapi-generator.tech +Generator version: 7.8.0 + +=end + +require 'date' +require 'time' + +module Coinbase::Client + # Paginated list of fund operations + class FundOperationList + 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 fund operations + 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::FundOperationList` 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::FundOperationList`. 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/fund_quote.rb b/lib/coinbase/client/models/fund_quote.rb new file mode 100644 index 00000000..7e867d0f --- /dev/null +++ b/lib/coinbase/client/models/fund_quote.rb @@ -0,0 +1,339 @@ +=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 + +Generated by: https://openapi-generator.tech +Generator version: 7.8.0 + +=end + +require 'date' +require 'time' + +module Coinbase::Client + # A quote for a fund operation + class FundQuote + # The ID of the fund quote + attr_accessor :fund_quote_id + + # The ID of the blockchain network + attr_accessor :network_id + + # The ID of the wallet that will receive the crypto + attr_accessor :wallet_id + + # The ID of the address that will receive the crypto + attr_accessor :address_id + + attr_accessor :crypto_amount + + attr_accessor :fiat_amount + + # The time at which the quote expires + attr_accessor :expires_at + + attr_accessor :fees + + # Attribute mapping from ruby-style variable name to JSON key. + def self.attribute_map + { + :'fund_quote_id' => :'fund_quote_id', + :'network_id' => :'network_id', + :'wallet_id' => :'wallet_id', + :'address_id' => :'address_id', + :'crypto_amount' => :'crypto_amount', + :'fiat_amount' => :'fiat_amount', + :'expires_at' => :'expires_at', + :'fees' => :'fees' + } + 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 + { + :'fund_quote_id' => :'String', + :'network_id' => :'String', + :'wallet_id' => :'String', + :'address_id' => :'String', + :'crypto_amount' => :'CryptoAmount', + :'fiat_amount' => :'FiatAmount', + :'expires_at' => :'Time', + :'fees' => :'FundOperationFees' + } + 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::FundQuote` 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::FundQuote`. 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?(:'fund_quote_id') + self.fund_quote_id = attributes[:'fund_quote_id'] + else + self.fund_quote_id = nil + end + + 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?(:'crypto_amount') + self.crypto_amount = attributes[:'crypto_amount'] + else + self.crypto_amount = nil + end + + if attributes.key?(:'fiat_amount') + self.fiat_amount = attributes[:'fiat_amount'] + else + self.fiat_amount = nil + end + + if attributes.key?(:'expires_at') + self.expires_at = attributes[:'expires_at'] + else + self.expires_at = nil + end + + if attributes.key?(:'fees') + self.fees = attributes[:'fees'] + else + self.fees = 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 @fund_quote_id.nil? + invalid_properties.push('invalid value for "fund_quote_id", fund_quote_id cannot be nil.') + end + + 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 @crypto_amount.nil? + invalid_properties.push('invalid value for "crypto_amount", crypto_amount cannot be nil.') + end + + if @fiat_amount.nil? + invalid_properties.push('invalid value for "fiat_amount", fiat_amount cannot be nil.') + end + + if @expires_at.nil? + invalid_properties.push('invalid value for "expires_at", expires_at cannot be nil.') + end + + if @fees.nil? + invalid_properties.push('invalid value for "fees", fees 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 @fund_quote_id.nil? + return false if @network_id.nil? + return false if @wallet_id.nil? + return false if @address_id.nil? + return false if @crypto_amount.nil? + return false if @fiat_amount.nil? + return false if @expires_at.nil? + return false if @fees.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 && + fund_quote_id == o.fund_quote_id && + network_id == o.network_id && + wallet_id == o.wallet_id && + address_id == o.address_id && + crypto_amount == o.crypto_amount && + fiat_amount == o.fiat_amount && + expires_at == o.expires_at && + fees == o.fees + 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 + [fund_quote_id, network_id, wallet_id, address_id, crypto_amount, fiat_amount, expires_at, fees].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/onchain_name.rb b/lib/coinbase/client/models/onchain_name.rb index 5fe4e556..b4c04f45 100644 --- a/lib/coinbase/client/models/onchain_name.rb +++ b/lib/coinbase/client/models/onchain_name.rb @@ -37,9 +37,15 @@ class OnchainName # The ID of the blockchain network attr_accessor :network_id + # The expiration date for this name's ownership + attr_accessor :expires_at + # The metadata attached to this name attr_accessor :text_records + # Whether this name is the primary name for the owner (This is when the ETH coin address for this name is equal to the primary_address. More info here https://docs.ens.domains/ensip/19) + attr_accessor :is_primary + # Attribute mapping from ruby-style variable name to JSON key. def self.attribute_map { @@ -50,7 +56,9 @@ def self.attribute_map :'domain' => :'domain', :'avatar' => :'avatar', :'network_id' => :'network_id', - :'text_records' => :'text_records' + :'expires_at' => :'expires_at', + :'text_records' => :'text_records', + :'is_primary' => :'is_primary' } end @@ -69,7 +77,9 @@ def self.openapi_types :'domain' => :'String', :'avatar' => :'String', :'network_id' => :'String', - :'text_records' => :'Array' + :'expires_at' => :'Time', + :'text_records' => :'Hash', + :'is_primary' => :'Boolean' } end @@ -132,11 +142,23 @@ def initialize(attributes = {}) self.network_id = nil end + if attributes.key?(:'expires_at') + self.expires_at = attributes[:'expires_at'] + else + self.expires_at = nil + end + if attributes.key?(:'text_records') - if (value = attributes[:'text_records']).is_a?(Array) + if (value = attributes[:'text_records']).is_a?(Hash) self.text_records = value end end + + if attributes.key?(:'is_primary') + self.is_primary = attributes[:'is_primary'] + else + self.is_primary = nil + end end # Show invalid properties with the reasons. Usually used together with valid? @@ -164,6 +186,14 @@ def list_invalid_properties invalid_properties.push('invalid value for "network_id", network_id cannot be nil.') end + if @expires_at.nil? + invalid_properties.push('invalid value for "expires_at", expires_at cannot be nil.') + end + + if @is_primary.nil? + invalid_properties.push('invalid value for "is_primary", is_primary cannot be nil.') + end + invalid_properties end @@ -176,6 +206,8 @@ def valid? return false if @manager_address.nil? return false if @domain.nil? return false if @network_id.nil? + return false if @expires_at.nil? + return false if @is_primary.nil? true end @@ -191,7 +223,9 @@ def ==(o) domain == o.domain && avatar == o.avatar && network_id == o.network_id && - text_records == o.text_records + expires_at == o.expires_at && + text_records == o.text_records && + is_primary == o.is_primary end # @see the `==` method @@ -203,7 +237,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [token_id, owner_address, manager_address, primary_address, domain, avatar, network_id, text_records].hash + [token_id, owner_address, manager_address, primary_address, domain, avatar, network_id, expires_at, text_records, is_primary].hash end # Builds the object from hash diff --git a/lib/coinbase/faucet_transaction.rb b/lib/coinbase/faucet_transaction.rb index 8cdf6cc6..79fcebf2 100644 --- a/lib/coinbase/faucet_transaction.rb +++ b/lib/coinbase/faucet_transaction.rb @@ -12,22 +12,80 @@ def initialize(model) @model = model end + # Returns the Faucet transaction. + # @return [Coinbase::Transaction] The Faucet transaction + def transaction + @transaction ||= Coinbase::Transaction.new(@model.transaction) + end + + # Returns the status of the Faucet transaction. + # @return [Symbol] The status + def status + transaction.status + end + # Returns the transaction hash. # @return [String] The onchain transaction hash def transaction_hash - model.transaction_hash + transaction.transaction_hash end # Returns the link to the transaction on the blockchain explorer. # @return [String] The link to the transaction on the blockchain explorer def transaction_link - model.transaction_link + transaction.transaction_link + end + + # Returns the Network of the Transaction. + # @return [Coinbase::Network] The Network + def network + transaction.network + end + + # Waits until the FaucetTransaction is completed or failed by polling on the given interval. + # @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 + # @raise [Timeout::Error] if the FaucetTransaction takes longer than the given timeout + # @return [Transfer] The completed Transfer object + def wait!(interval_seconds = 0.2, timeout_seconds = 20) + start_time = Time.now + + loop do + reload + + return self if transaction.terminal_state? + + raise Timeout::Error, 'Faucet transaction timed out' if Time.now - start_time > timeout_seconds + + self.sleep interval_seconds + end + + self + end + + def reload + @model = Coinbase.call_api do + addresses_api.get_faucet_transaction( + network.normalized_id, + transaction.to_address_id, + transaction_hash + ) + end + + @transaction = Coinbase::Transaction.new(@model.transaction) + + self end # Returns a String representation of the FaucetTransaction. # @return [String] a String representation of the FaucetTransaction def to_s - "Coinbase::FaucetTransaction{transaction_hash: '#{transaction_hash}', transaction_link: '#{transaction_link}'}" + Coinbase.pretty_print_object( + self.class, + status: transaction.status, + transaction_hash: transaction_hash, + transaction_link: transaction_link + ) end # Same as to_s. @@ -38,6 +96,8 @@ def inspect private - attr_reader :model + def addresses_api + @addresses_api ||= Coinbase::Client::ExternalAddressesApi.new(Coinbase.configuration.api_client) + end end end diff --git a/lib/coinbase/transaction.rb b/lib/coinbase/transaction.rb index 2d0f1653..b5edbfe3 100644 --- a/lib/coinbase/transaction.rb +++ b/lib/coinbase/transaction.rb @@ -41,6 +41,12 @@ def initialize(model) @model = model end + # Returns the Network of the Transaction. + # @return [Coinbase::Network] The Network + def network + @network ||= Coinbase::Network.from_id(@model.network_id) + end + # Returns the Unsigned Payload of the Transaction. # @return [String] The Unsigned Payload def unsigned_payload diff --git a/spec/e2e/end_to_end.rb b/spec/e2e/end_to_end.rb index 71f00489..2b9287a5 100644 --- a/spec/e2e/end_to_end.rb +++ b/spec/e2e/end_to_end.rb @@ -103,6 +103,9 @@ def transfer_test(imported_address, new_address) # Fund the new address with faucet. begin faucet_tx = new_address.faucet + + faucet_tx.wait! + puts "Requested faucet funds: #{faucet_tx}" rescue Coinbase::FaucetLimitReachedError puts 'Faucet has reached limit. Will continue with test' diff --git a/spec/factories/faucet_transaction.rb b/spec/factories/faucet_transaction.rb new file mode 100644 index 00000000..b824be33 --- /dev/null +++ b/spec/factories/faucet_transaction.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :faucet_tx_model, class: Coinbase::Client::FaucetTransaction do + transient do + status { 'broadcasted' } + network_trait { :base_sepolia } + to_address_id { nil } + transaction_hash { nil } + end + + # Default traits + base_sepolia + pending + + TX_TRAITS.each do |status| + trait status do + status { status } + end + end + + NETWORK_TRAITS.each do |network| + trait network do + network_trait { network } + end + end + + after(:build) do |transfer, transients| + transfer.transaction = build( + :transaction_model, + transients.status, + transients.network_trait, + { + to_address_id: transients.to_address_id, + transaction_hash: transients.transaction_hash + }.compact + ) + end + end +end diff --git a/spec/factories/transaction.rb b/spec/factories/transaction.rb index c0227e98..c43b81f3 100644 --- a/spec/factories/transaction.rb +++ b/spec/factories/transaction.rb @@ -10,6 +10,13 @@ # Default trait. pending + base_sepolia + + NETWORK_TRAITS.each do |network| + trait network do + network_id { Coinbase.normalize_network(network) } + end + end trait :pending do status { 'pending' } diff --git a/spec/support/shared_examples/address_balances.rb b/spec/support/shared_examples/address_balances.rb index f7ecd741..0d29d245 100644 --- a/spec/support/shared_examples/address_balances.rb +++ b/spec/support/shared_examples/address_balances.rb @@ -141,10 +141,10 @@ end describe '#faucet' do - let(:tx_hash) { '0xdeadbeef' } let(:faucet_tx) do - instance_double(Coinbase::Client::FaucetTransaction, transaction_hash: tx_hash) + build(:faucet_tx_model, network_id, :broadcasted, to_address_id: address_id) end + let(:tx_hash) { faucet_tx.transaction.transaction_hash } context 'when the request is successful' do subject(:faucet_response) { address.faucet } @@ -152,7 +152,7 @@ before do allow(external_addresses_api) .to receive(:request_external_faucet_funds) - .with(normalized_network_id, address_id, {}) + .with(normalized_network_id, address_id, { skip_wait: true }) .and_return(faucet_tx) end @@ -161,7 +161,7 @@ expect(external_addresses_api) .to have_received(:request_external_faucet_funds) - .with(normalized_network_id, address_id, {}) + .with(normalized_network_id, address_id, { skip_wait: true }) end it 'returns the faucet transaction' do @@ -173,11 +173,34 @@ end end - context 'when the request is unsuccesful' do + context 'when using specified asset' do + subject(:faucet_response) { address.faucet(asset_id: :usdc) } + + before do + allow(external_addresses_api) + .to receive(:request_external_faucet_funds) + .with(normalized_network_id, address_id, { asset_id: :usdc, skip_wait: true }) + .and_return(faucet_tx) + end + + it 'requests external faucet funds for the address for the specified asset' do + faucet_response + + expect(external_addresses_api) + .to have_received(:request_external_faucet_funds) + .with(normalized_network_id, address_id, { asset_id: :usdc, skip_wait: true }) + end + + it 'returns the faucet transaction' do + expect(faucet_response).to be_a(Coinbase::FaucetTransaction) + end + end + + context 'when the request is unsuccessful' do before do allow(external_addresses_api) .to receive(:request_external_faucet_funds) - .with(normalized_network_id, address_id, {}) + .with(normalized_network_id, address_id, { skip_wait: true }) .and_raise(api_error) end diff --git a/spec/unit/coinbase/faucet_transaction_spec.rb b/spec/unit/coinbase/faucet_transaction_spec.rb index e5566c16..e47cbdc3 100644 --- a/spec/unit/coinbase/faucet_transaction_spec.rb +++ b/spec/unit/coinbase/faucet_transaction_spec.rb @@ -3,14 +3,29 @@ describe Coinbase::FaucetTransaction do subject(:faucet_transaction) { described_class.new(model) } + let(:network_id) { :base_sepolia } let(:transaction_hash) { '0x6c087c1676e8269dd81e0777244584d0cbfd39b6997b3477242a008fa9349e11' } let(:transaction_link) { "https://sepolia.basescan.org/tx/#{transaction_hash}" } - let(:model) do - Coinbase::Client::FaucetTransaction.new( + let(:address_id) { Eth::Key.new.address.to_s } + let(:transaction_model) do + build( + :transaction_model, + :broadcasted, + network_id, + to_address_id: address_id, transaction_hash: transaction_hash, transaction_link: transaction_link ) end + let(:model) do + Coinbase::Client::FaucetTransaction.new(transaction: transaction_model) + end + + let(:external_addresses_api) { instance_double(Coinbase::Client::ExternalAddressesApi) } + + before do + allow(Coinbase::Client::ExternalAddressesApi).to receive(:new).and_return(external_addresses_api) + end describe '#initialize' do it 'initializes a new FaucetTransaction' do @@ -18,22 +33,104 @@ end end + describe '#transaction' do + it 'returns the transaction' do + expect(faucet_transaction.transaction).to be_a(Coinbase::Transaction) + end + end + describe '#transaction_hash' do it 'returns the transaction hash' do expect(faucet_transaction.transaction_hash).to eq(transaction_hash) end end + describe '#status' do + it 'returns the transaction status' do + expect(faucet_transaction.status).to eq(Coinbase::Transaction::Status::BROADCAST) + end + end + describe '#transaction_link' do it 'returns the transaction link' do expect(faucet_transaction.transaction_link).to eq(transaction_link) end end + describe '#network' do + it 'returns the network' do + expect(faucet_transaction.network).to be_a(Coinbase::Network) + end + end + + describe '#reload' do + let(:updated_transaction_model) do + build( + :transaction_model, + :completed, + to_address_id: address_id, + transaction_hash: transaction_hash, + transaction_link: transaction_link + ) + end + let(:updated_model) do + Coinbase::Client::FaucetTransaction.new(transaction: updated_transaction_model) + end + + before do + allow(external_addresses_api) + .to receive(:get_faucet_transaction) + .with('base-sepolia', address_id, transaction_hash) + .and_return(updated_model) + end + + it 'updates the faucet transaction' do + expect(faucet_transaction.reload.transaction.status).to eq(Coinbase::Transaction::Status::COMPLETE) + end + end + + describe '#wait!' do + before do + allow(faucet_transaction).to receive(:sleep) # rubocop:disable RSpec/SubjectStub + + allow(external_addresses_api) + .to receive(:get_faucet_transaction) + .with('base-sepolia', address_id, transaction_hash) + .and_return(model, model, updated_model) + end + + context 'when the faucet transaction is completed' do + let(:updated_model) { build(:faucet_tx_model, network_id, :completed) } + + it 'returns the completed FaucetTransaction' do + expect(faucet_transaction.wait!.status).to eq(Coinbase::Transaction::Status::COMPLETE) + end + end + + context 'when the faucet transaction is failed' do + let(:updated_model) { build(:faucet_tx_model, network_id, :failed) } + + it 'returns the failed FaucetTransaction' do + expect(faucet_transaction.wait!.status).to eq(Coinbase::Transaction::Status::FAILED) + end + end + + context 'when the faucet transaction times out' do + let(:updated_model) { build(:faucet_tx_model, network_id, :broadcasted) } + + it 'raises a Timeout::Error' do + expect { faucet_transaction.wait!(0.2, 0.00001) }.to raise_error(Timeout::Error, 'Faucet transaction timed out') + end + end + end + describe '#to_s' do it 'returns a string representation of the FaucetTransaction' do - expect(faucet_transaction.to_s).to eq( - "Coinbase::FaucetTransaction{transaction_hash: '#{transaction_hash}', transaction_link: '#{transaction_link}'}" + expect(faucet_transaction.to_s).to include( + 'Coinbase::FaucetTransaction', + transaction_hash, + transaction_link, + 'broadcast' ) end end diff --git a/spec/unit/coinbase/smart_contract_spec.rb b/spec/unit/coinbase/smart_contract_spec.rb index feff0879..40d447de 100644 --- a/spec/unit/coinbase/smart_contract_spec.rb +++ b/spec/unit/coinbase/smart_contract_spec.rb @@ -866,7 +866,7 @@ def build_nested_solidity_value(hash) end describe '#inspect' do - it 'includes smart contractdetails' do + it 'includes smart contract details' do expect(smart_contract.inspect).to include( address_id, Coinbase.to_sym(network_id).to_s, diff --git a/spec/unit/coinbase/transaction_spec.rb b/spec/unit/coinbase/transaction_spec.rb index c03e8dc2..e0ffb9c9 100644 --- a/spec/unit/coinbase/transaction_spec.rb +++ b/spec/unit/coinbase/transaction_spec.rb @@ -3,6 +3,7 @@ describe Coinbase::Transaction do subject(:transaction) { build(:transaction, model: transaction_model) } + let(:network_id) { :base_sepolia } let(:from_key) { build(:key) } let(:to_address_id) { '0xe317065De795eFBaC71cf00114c7252BFcd23c29'.downcase } let(:transaction_model) { build(:transaction_model, from_address_id: from_key.address.to_s) } @@ -21,6 +22,12 @@ end end + describe '#network' do + it 'returns the network' do + expect(transaction.network.id).to eq(network_id) + end + end + describe '#unsigned_payload' do it 'returns the unsigned payload' do expect(transaction.unsigned_payload).to eq(transaction_model.unsigned_payload) diff --git a/spec/unit/coinbase/wallet_spec.rb b/spec/unit/coinbase/wallet_spec.rb index be9a271b..32e02e7f 100644 --- a/spec/unit/coinbase/wallet_spec.rb +++ b/spec/unit/coinbase/wallet_spec.rb @@ -1190,8 +1190,14 @@ def match_create_address_request(req, expected_public_key, expected_address_inde end describe '#faucet' do + let(:tx_hash) { SecureRandom.hex(32) } let(:faucet_transaction_model) do - Coinbase::Client::FaucetTransaction.new({ transaction_hash: '0x123456789' }) + build( + :faucet_tx_model, + :broadcasted, + transaction_hash: tx_hash, + to_address_id: first_address_model.address_id + ) end let(:wallet) { described_class.new(model_with_default_address, seed: '') } @@ -1206,7 +1212,7 @@ def match_create_address_request(req, expected_public_key, expected_address_inde allow(external_addresses_api) .to receive(:request_external_faucet_funds) - .with(normalized_network_id, first_address_model.address_id, {}) + .with(normalized_network_id, first_address_model.address_id, { skip_wait: true }) .and_return(faucet_transaction_model) end @@ -1215,7 +1221,7 @@ def match_create_address_request(req, expected_public_key, expected_address_inde end it 'contains the transaction hash' do - expect(faucet_transaction.transaction_hash).to eq(faucet_transaction_model.transaction_hash) + expect(faucet_transaction.transaction_hash).to eq(tx_hash) end end @@ -1230,7 +1236,7 @@ def match_create_address_request(req, expected_public_key, expected_address_inde allow(external_addresses_api) .to receive(:request_external_faucet_funds) - .with(normalized_network_id, first_address_model.address_id, { asset_id: :usdc }) + .with(normalized_network_id, first_address_model.address_id, { asset_id: :usdc, skip_wait: true }) .and_return(faucet_transaction_model) end @@ -1239,7 +1245,7 @@ def match_create_address_request(req, expected_public_key, expected_address_inde end it 'contains the transaction hash' do - expect(faucet_transaction.transaction_hash).to eq(faucet_transaction_model.transaction_hash) + expect(faucet_transaction.transaction_hash).to eq(tx_hash) end end end