Coinbase Wallet Gem
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.
Installation
Add this line to your application's Gemfile:
gem 'coinbase'
Then execute:
bundle install
Or install it yourself as:
gem install coinbase
Authentication
API Key (HMAC Client)
We 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>)
OAuth2 Client
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
Two factor authentication
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")
end
Requests
We 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')
Pagination
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
end
If 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|
...
end
Responses
We 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']
end
You 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'] }
end
If 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}"
end
Response 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!
Warnings
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.
Errors
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 |
Usage
This is not intended to provide complete documentation of the API. For more detail, please refer to the official documentation.
Market Data
List supported native currencies
client.currencies
List exchange rates
client.exchange_rates
Buy 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.time
Users
Get authorization info
client.auth_info
Lookup user info
client.user(user_id)
Get current user
client.current_user
Update current user
client.update_current_user(name: "New Name")
Accounts
List all accounts
client.accounts
List account details
client.account(account_id)
List primary account details
client.primary_account
Set 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!
Addresses
List receive addresses for account
account.addresses
Get receive address info
account.address(address_id)
List transactiona for address
account.address_transactions(address_id)
Create a new receive address
account.create_address
Transactions
List transactions
account.transactions
Get 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)
Buys
List buys
account.list_buys
Get 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)
Sells
List sells
account.list_sells
Get 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)
Deposit
List deposits
account.list_deposits
Get 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)
Withdrawals
List withdrawals
account.list_withdrawals
Get 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)
Payment Methods
List payment methods
client.payment_methods
Get payment method
client.payment_method(payment_method_id)
Merchants
Get merchant
client.merchant(merchant_id)
Verify a merchant callback
client.verify_callback(request.raw_post, request.headers['CB-SIGNATURE']) # true/false
Orders
List orders
client.orders
Get order
client.order(order_id)
Create order
client.create_order(amount: "1", currency: "BTC", name: "Order #1234")
Refund order
order = client.orders.first
order.refund!
Checkouts
List checkouts
client.checkouts
Get checkout
client.checkout(checkout_id)
Get checkout's orders
checkout = client.checkout(checkout_id)
checkout.orders
Create order for checkout
checkout = client.checkout(checkout_id)
checkout.create_order
Contributing and testing
Any 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