This is the official client library for the Coinbase Wallet API v2. We provide an intuitive, stable interface to integrate Coinbase Wallet into your Ruby project.
Important: As this library is targeted for newer API v2, it requires v2 permissions (i.e. wallet:accounts:read). If you're still using v1, please use older version of this library.
Add this line to your application's Gemfile:
gem 'coinbase'Then execute:
bundle installOr install it yourself as:
gem install coinbaseWe provide a synchronous client based on Net::HTTP as well as a asynchronous client based on the EM-HTTP-Request gem. For most users, the synchronous client will suffice.
require 'coinbase/wallet'
client = Coinbase::Wallet::Client.new(api_key: <api key>, api_secret: <api secret>)The primary intention of the asynchronous client is to integrate nicely with the Coinbase Exchange Gem. If your project interfaces with our Exchange as well, please consider using this. To use this interface, you must include em-http-request gem on your own.
require 'coinbase/wallet'
require 'em-http'
client = Coinbase::Wallet::AsyncClient.new(api_key: <api_key>, api_secret: <api secret>)We provide an OAuth client if you need access to user accounts other than your own. Currently, the gem does not handle the handshake process, and assumes you have an access token when it's initialized. The OAuth client is synchronous. Please reach out if you would like us to add an asynchronous OAuth client as well.
require 'coinbase/wallet'
# Initializing OAuthClient with both access and refresh token
client = Coinbase::Wallet::OAuthClient.new(access_token: <access token>, refresh_token: <refresh_token>)
# Initializing OAuthClient with only access token
client = Coinbase::Wallet::OAuthClient.new(access_token: <access token>)The OAuth client provides a few extra methods to refresh and revoke the access token.
client.refresh!client.revoke!Protip:tm:: You can test OAuth2 authentication easily with Developer Access Tokens which can be created under your OAuth2 application settings. These are short lived tokens which authenticate but don't require full OAuth2 handshake to obtain.
Send money endpoint requires 2FA token in certain situations (read more here). Specific exception is thrown when this is required:
account = client.primary_account
begin
account.send(to: '[email protected]', amount: '1', currency: "BTC")
rescue Coinbase::Client::TwoFactorRequiredError
# Show 2FA dialog to user and collect 2FA token
# Re-try call with `two_factor_token` param
account.send(to: '[email protected]', amount: '1', currency: "BTC", two_factor_token: "123456")
endWe provide one method per API endpoint. Several methods require one or more identifiers to be passed as arguments. Additionally, all parameters can be appended as keyword arguements. If a required parameter is not supplied, the client will raise an error. For instance, the following call will send 100 bitcoin to the account registered with [email protected].
account = client.primary_account
account.send(to: '[email protected]', amount: 100, currency: "USD", description: 'Sending 100 bitcoin')Several endpoints are paginated. By default, the gem will only fetch the first page of data for a given request. You can implement your own pagination scheme, such as pipelining, by setting the starting_after parameter in your response.
client.transactions(account_id) do |data, resp|
transactions = data
end
more_pages = true
while more_pages
client.transactions(account_id, starting_after: transactions.last['id']) do |data, resp|
more_pages = resp.has_more?
transactions << data
transactions.flatten!
end
endIf you want to automatically download the entire dataset, you may pass fetch_all=true as a parameter.
client.transactions(account_id, fetch_all: true) do |data, resp|
...
endWe provide several ways to access return data. Methods will return the data field of the response in hash format.
txs = account.transactions(account_id)
txs.each do |tx|
p tx['id']
endYou can also handle data inside a block you pass to the method. You must access data this way if you're using the asynchronous client.
account.transactions(account_id) do |txs|
txs.each { |tx| p tx['id'] }
endIf you need to access the response metadata (headers, pagination info, etc.) you can access the entire response as the second block paramenter.
account.transactions(account_id) do |txs, resp|
p "STATUS: #{resp.status}"
p "HEADERS: #{resp.headers}"
p "BODY: #{resp.body}"
endResponse Object
The default representation of response data is a JSON hash. However, we further abstract the response to allow access to response fields as though they were methods.
account = client.primary_account
p "Account:\t account.name"
p "ID:\t account.id"
p "Balance:\t #{account.balance.amount} #{account.balance.currency}"All values are returned directly from the API unmodified, except the following exceptions:
- Money amounts are always converted into BigDecimal objects. You should always use BigDecimal when handing bitcoin amounts for accurate precision.
- Timestamps are always converted into Time objects.
Most methods require an associated account. Thus, responses for the account endpoints contain methods for accessing all the relevant endpoints. This is convenient, as it doesn't require you to supply the same account id over and over again.
account = client.primary_account
account.send(to: "[email protected]", amount: 100, description: "Sending 100 bitcoin")Alternatively you can pass the account ID straight to the client:
client.transactions(<account_id>)Account response objects will automatically update if they detect any changes to the account. The easiest way to refresh an account is to call the refresh! method.
account.refresh!It's prudent to be conscious of warnings. By default, the gem will print all warning to STDERR. If you wish to redirect this stream to somewhere else, such as a log file, then you can simply change the $stderr global variable.
If the request is not successful, the gem will raise an error. We try to raise a unique error for every possible API response. All errors are subclasses of Coinbase::Wallet::APIError.
| Error | Status |
|---|---|
| APIError | * |
| BadRequestError | 400 |
| ParamRequiredError | 400 |
| InvalidRequestError | 400 |
| PersonalDetailsRequiredError | 400 |
| AuthenticationError | 401 |
| UnverifiedEmailError | 401 |
| InvalidTokenError | 401 |
| RevokedTokenError | 401 |
| ExpiredTokenError | 401 |
| TwoFactorRequiredError | 402 |
| InvalidScopeError | 403 |
| NotFoundError | 404 |
| ValidationError | 422 |
| RateLimitError | 429 |
| InternalServerError | 500 |
| ServiceUnavailableError | 503 |
This is not intended to provide complete documentation of the API. For more detail, please refer to the official documentation.
List supported native currencies
client.currenciesList exchange rates
client.exchange_ratesBuy price
client.buy_price
# or
client.buy_price(currency_pair: 'BTC-USD')Sell price
client.sell_price
# or
client.sell_price(currency_pair: 'ETH-BTC')Spot price
client.spot_price
# or
client.spot_price(currency_pair: 'BTC-EUR')Current server time
client.timeGet authorization info
client.auth_infoLookup user info
client.user(user_id)Get current user
client.current_userUpdate current user
client.update_current_user(name: "New Name")List all accounts
client.accountsList account details
client.account(account_id)List primary account details
client.primary_accountSet account as primary
account.make_primary!Create a new bitcoin account
client.create_account(name: "New Account")Update an account
account.update!(name: "New Account Name")Delete an account
account.delete!List receive addresses for account
account.addressesGet receive address info
account.address(address_id)List transactiona for address
account.address_transactions(address_id)Create a new receive address
account.create_addressList transactions
account.transactionsGet transaction info
account.transaction(transaction_id)Send funds
account.send(to: <bitcoin address>, amount: "5.0", currency: "USD", description: "Your first bitcoin!")Transfer funds to a new account
account.transfer(to: <account ID>, amount: "1", currency: "BTC", description: "Your first bitcoin!")Request funds
account.request(to: <email>, amount: "8.0", currency: "USD", description: "Burrito")Resend request
account.resend_request(request_id)Cancel request
account.cancel_request(request_id)Fulfill request
account.complete_request(request_id)List buys
account.list_buysGet buy info
account.list_buy(buy_id)Buy bitcoins
account.buy(amount: "1", currency: "BTC")Commit a buy
You only need to do this if you pass commit=true when you call the buy method.
buy = account.buy(amount: "1", currency: "BTC", commit: false)
account.commit_buy(buy.id)List sells
account.list_sellsGet sell info
account.list_sell(sell_id)Sell bitcoins
account.sell(amount: "1", currency: "BTC")Commit a sell
You only need to do this if you pass commit=true when you call the sell method.
sell = account.sell(amount: "1", currency: "BTC", commit: false)
account.commit_sell(sell.id)List deposits
account.list_depositsGet deposit info
account.list_deposit(deposit_id)Deposit funds
account.deposit(amount: "10", currency: "USD")Commit a deposit
You only need to do this if you pass commit=true when you call the deposit method.
deposit = account.deposit(amount: "1", currency: "BTC", commit: false)
account.commit_deposit(deposit.id)List withdrawals
account.list_withdrawalsGet withdrawal
account.list_withdrawal(withdrawal_id)Withdraw funds
account.withdraw(amount: "10", currency: "USD")Commit a withdrawal
You only need to do this if you pass commit=true when you call the withdrawal method.
withdraw = account.withdraw(amount: "1", currency: "BTC", commit: false)
account.commit_withdrawal(withdrawal.id)List payment methods
client.payment_methodsGet payment method
client.payment_method(payment_method_id)client.merchant(merchant_id)client.verify_callback(request.raw_post, request.headers['CB-SIGNATURE']) # true/falseclient.ordersclient.order(order_id)client.create_order(amount: "1", currency: "BTC", name: "Order #1234")order = client.orders.first
order.refund!client.checkoutsclient.checkout(checkout_id)checkout = client.checkout(checkout_id)
checkout.orderscheckout = client.checkout(checkout_id)
checkout.create_orderAny and all contributions are welcome! The process is simple: fork this repo, make your changes, add tests, run the test suite, and submit a pull request. Tests are run via rspec. To run the tests, clone the repository and then:
# Install the requirements
gem install coinbase
# Run tests
rspec spec