Skip to content

omgnetwork/ruby-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status Gem Version

OmiseGO

OmiseGO is a Ruby SDK meant to communicate with an OmiseGO eWallet setup.

For more details about the web API being wrapped by this SDK, take a look at the OpenAPI Specification. You are free to use that web API directly if you prefer, this SDK is only provided as a convenient way to make those HTTP calls and return Ruby objects as responses.

Installation

Add this line to your application's Gemfile:

gem 'omisego'

And then execute:

$ bundle

Or install it yourself as:

$ gem install omisego

Initialization

The OmiseGO SDK can either be initialized on a global level, or a on client basis. However, initializing on a global level is not necessarily what you want and won't be thread-safe. If using Rails, Sticking a client method in your ApplicationController will probably be a better solution than using an initializer as shown below.

In the end, the choice is yours and the optimal solution depends on your needs.

Global init

# config/initializers/omisego.rb
OmiseGO.configure do |config|
  config.access_key = ENV['OMISEGO_ACCESS_KEY']
  config.secret_key = ENV['OMISEGO_SECRET_KEY']
  config.base_url   = ENV['OMISEGO_BASE_URL']
end

If initialized this way, the OmiseGO classes can be used without specifying the client.

user = OmiseGO::User.find(provider_user_id: 'provider_user_id01')

Client init

With this approach, the client needs to be passed in every call and will be used as the call initiator.

client = OmiseGO::Client.new(
  access_key: ENV['OMISEGO_ACCESS_KEY'],
  secret_key: ENV['OMISEGO_SECRET_KEY'],
  base_url:   ENV['OMISEGO_BASE_URL']
)

user = OmiseGO::User.find(provider_user_id: 'provider_user_id01', client: client)

Logging Configuration

The Ruby SDK comes with the possibility to log requests to the eWallet. For example, within a Rails application, the following can be defined:

# config/initializers/omisego.rb
OmiseGO.configure do |config|
  config.access_key = ENV['OMISEGO_ACCESS_KEY']
  config.secret_key = ENV['OMISEGO_SECRET_KEY']
  config.base_url   = ENV['OMISEGO_BASE_URL']
  config.logger     = Rails.logger
end

This would provide the following in the logs:

[OmiseGO] Request: POST login
User-Agent: Faraday v0.13.1
Authorization: [FILTERED]
Accept: application/vnd.omisego.v1+json
Content-Type: application/vnd.omisego.v1+json

{"provider_user_id":"aeab0d51-b3d9-415d-98ef-f9162903f024"}

[OmiseGO] Response: HTTP/200
Connection: close
Server: Cowboy
Date: Wed, 14 Feb 2018 04:35:52 GMT
Content-Length: 140
Content-Type: application/vnd.omisego.v1+json; charset=utf-8
Cache-Control: max-age=0, private, must-revalidate

{"version":"1","success":true,"data":{"object":"authentication_token","authentication_token":[FILTERED]}}

Usage

All the calls below will communicate with the OmiseGO wallet specified in the base_url configuration. They will either return an instance of OmiseGO:Error or of the appropriate model (User, Balance, etc.), see the list of models for more information.

The method #error? can be used on any model to check if it's an error or a valid result.

Using the API directly

Almost all the calls presented in the API documentation can be accessed from this Ruby SDK as a provider. A lof ot the endpoints are, however, not fully supported yet. If you wish to use an endpoint not supported by the SDK, you can do the following:

client = Client.new # Will use global configuration

response = client.request.send({
  "account.get_wallets",
  {
    id: "acc_123"
  }, # body
})

response will contain the full payload returned from the server, where the data field contains the actual response data.

Understanding Idempotency

Some of the calls in the web API (and in the methods below) contain a parameter called idempotency_token.

Understanding wallet types

Not all wallets are created equals. We have 3 different types of wallets:

  • primary: Only one primary wallet per account or user is allowed. This is the default used if you don't want to deal with wallets.
  • secondary: An additional wallet that can be created if you need to keep separate balances.
  • burn: A special type of wallets where value goes and never comes back. If you want to get rid of tokens (remove them from circulation), send them to a burn wallet. Accounts get one created by default, and more can be created if needed.

Understanding Metadata and Encrypted Metadata

metadata and encrypted_metadata are fields you can use to store any kind of data. Formatted as dictionnaries (json/map/hash), they are stored in the database with the referenced record. encrypted_metadata will be encrypted and not readable directly from a dump of the DB without the key, while metadata are stored in clear (and will potentially be searchable later).

All available methods

Managing Users

Find User

Retrieve a user from the eWallet API.

user = OmiseGO::User.find(
  provider_user_id: 'provider_user_id01',
  client: nil # optional, defauls to nil and uses the client
              # defined in config
)

Returns either:

  • An OmiseGO::User instance
  • An OmiseGO::Error instance

Create User

Create a user in the eWallet API database. The provider_user_id is how a user is identified and cannot be changed later on.

user = OmiseGO::User.create(
  provider_user_id: 'provider_user_id01',
  username: '[email protected]',
  metadata: {
    first_name: 'John',
    last_name: 'Doe'
  },                      # optional, defaults to {}
  encrypted_metadata: {}, # optional, defaults to {}
  client: nil             # optional, defauls to nil and uses the client
                          # defined in config
)

Returns either:

  • An OmiseGO::User instance
  • An OmiseGO::Error instance

Update User

Update a user in the eWallet API database. All fields need to be provided and the values in the eWallet database will be replaced with the sent ones (behaves like a HTTP PUT). Sending metadata: {} in the request below would remove the first_name and last_name fields for example.

user = OmiseGO::User.update(
  provider_user_id: 'provider_user_id01',
  username: '[email protected]',
  metadata: {},           # optional, defaults to {}
  encrypted_metadata: {}, # optional, defaults to {}
  client: nil             # optional, defauls to nil and uses the client
                          # defined in config
)

# or

user = OmiseGO::User.find(provider_user_id: 'provider_user_id01')
user = user.update(
  username: '[email protected]',
  metadata: {},           # optional, defaults to {}
  encrypted_metadata: {}, # optional, defaults to {}
  client: nil             # optional, defauls to nil and uses the client
                          # defined in config
)

Returns either:

  • An OmiseGO::User instance
  • An OmiseGO::Error instance

Get all wallets for a user

Retrieve a list of wallets (with only one primary wallet for now) containing a list of balances.

wallets = OmiseGO::User.wallets(
  provider_user_id: 'provider_user_id01',
  client: nil # optional, defauls to nil and uses the client
              # defined in config
)

# or

user = OmiseGO::User.find(provider_user_id: 'provider_user_id01')
wallets = user.wallets(
  client: nil # optional, defauls to nil and uses the client
              # defined in config
)

Returns either:

  • An OmiseGO::List of OmiseGO::Wallet instances
  • An OmiseGO::Error instance

Managing Sessions

Login User

Login a user and retrieve an authentication_token that can be passed to a mobile client to make calls to the eWallet API directly.

auth_token = OmiseGO::User.login(
  provider_user_id: 'provider_user_id01',
  client: nil # optional, defauls to nil and uses the client
              # defined in config
)

# or

user = OmiseGO::User.find(provider_user_id: 'provider_user_id01')
auth_token = user.login(
  client: nil # optional, defauls to nil and uses the client
              # defined in config
)

Returns either:

  • An OmiseGO::AuthenticationToken instance
  • An OmiseGO::Error instance

Managing Wallets

All Wallets

Retrieve a list of wallets (with only one address for now) containing a list of balances.

wallets = OmiseGO::Wallet.all(
  provider_user_id: 'provider_user_id01',
  client: nil # optional, defauls to nil and uses the client
              # defined in config
)

Returns either:

  • An OmiseGO::List of OmiseGO::Wallet instances
  • An OmiseGO::Error instance

Credit Wallet

Transfer the specified amount (as an integer, down to the subunit_to_unit) from an account's wallet to a user's wallet (defaults to the user's primary wallet).

In the following methods, an idempotency token is used to ensure that one specific credit/debit occurs only once. The implementer is responsible for ensuring that those idempotency tokens are unique - sending the same one two times will prevent the second transaction from happening

For both the user and the account, an address can be specified to use a different wallet than the primary one.

wallet = OmiseGO::Wallet.credit(
  provider_user_id: 'provider_user_id01',
  user_address: nil, # optional, defaults to the user's primary wallet
  account_id: 'acc_01C4T2Y5SFYASXXYANV96MQQC9',
  account_address: nil, # optional, defaults to the account's primary wallet
  token_id: 'tok_OMG_01ccmny8yne44b188287d44498',
  amount: 10_000,
  idempotency_token: "123",
  metadata: {}, # optional, defaults to {}
  encrypted_metadata: {}, # optional, defaults to {}
  client: nil # optional, defauls to nil and uses the client
              # defined in config
)

Returns either:

  • An OmiseGO::List of OmiseGO::Wallet instances (containing the 2 wallets involved in the transaction)
  • An OmiseGO::Error instance

Debit Wallet

Transfer the specified amount (as an integer, down to the subunit_to_unit) from the specified user's primary wallet back to the specified account's primary wallet. If you wish to use secondary or burn wallets, they can be specified in user_address and account_address.

wallet = OmiseGO::Wallet.debit(
  provider_user_id: 'provider_user_id01',
  user_address: nil, # optional, defaults to the user's primary wallet
  account_id: 'acc_01C4T2Y5SFYASXXYANV96MQQC9',
  account_address: nil, # optional, defaults to the account's primary wallet
  token_id: 'tok_OMG_01ccmny8yne44b188287d44498',
  amount: 10_000,
  idempotency_token: "123",
  metadata: {}, # optional, defaults to {}
  encrypted_metadata: {}, # optional, defaults to {}
  client: nil # optional, defauls to nil and uses the client
              # defined in config
)

By default, points won't be burned and will be returned to the specified account's primary balance. If you wish to burn points, send them to a burn address. You may also send them to a secondary wallet if you prefer.

Returns either:

  • An OmiseGO::List of OmiseGO::Wallet instances (containing the 2 wallets involved in the transaction)
  • An OmiseGO::Error instance

Managing transactions

Params

Some parameters can be given to the two following methods to customize the returned results. With them, the list of results can be paginated, sorted and searched.

  • page: The page you wish to receive.
  • per_page: The number of results per page.
  • sort_by: The sorting field. Available values: id, status, from, to, created_at, updated_at
  • sort_dir: The sorting direction. Available values: asc, desc
  • search_term: A term to search for in ALL of the searchable fields. Conflict with search_terms, only use one of them. See list of searchable fields below (same as search_terms).
  • search_terms: A hash of fields to search in:
{
  search_terms: {
    from: "address_1"
  }
}

Available values: id, idempotency_token, status, from, to

All

Get the list of transactions from the eWallet API.

transaction = OmiseGO::Transaction.all

Returns either:

  • An OmiseGO::List instance of OmiseGO::Transaction instances
  • An OmiseGO::Error instance

Parameters can be specified in the following way:

transaction = OmiseGO::Transaction.all(
  params: {
    page: 1,
    per_page: 10,
    sort_by: 'created_at',
    sort_dir: 'desc',
    search_terms: {
      from: "address_1",
      to: "address_2",
      status: "confirmed"
    }
  },
  client: nil # optional, defauls to nil and uses the client
              # defined in config
)

All for user

Get the list of transactions for a specific provider user ID from the eWallet API.

transaction = OmiseGO::Transaction.all(
  params: {
    provider_user_id: "provider_user_id01"
  },
  client: nil # optional, defauls to nil and uses the client
              # defined in config
)

Returns either:

  • An OmiseGO::List instance of OmiseGO::Transaction instances
  • An OmiseGO::Error instance

Parameters can be specified in the following way:

transaction = OmiseGO::Transaction.all(
  params: {
    provider_user_id: "provider_user_id01",
    page: 1,
    per_page: 10,
    sort_by: 'created_at',
    sort_dir: 'desc',
    search_terms: {
      from: "address_1",
      status: "confirmed"
    }
  },
  client: nil # optional, defauls to nil and uses the client
              # defined in config
)

Since those transactions are already scoped down to the given user, it is NOT POSSIBLE to specify both from AND to in the search_terms. Doing so will result in the API ignoring both of those fields for the search.

Creating transactions

Transactions can be created with the OmiseGO::Transaction.create() method (which will call the /transaction.create endpoint).

Two types of transactions can be made, depending if you intend to exchange tokens or if it's a simple transfer between two addresses.

Defining the sender and receiver

There are different ways to define who is supposed to send/receive the tokens. The server expects at least one of these sets of parameters to find the sender:

  • from_provider_user_id: Will find the user and takes his primary address as the sending address.
  • from_provider_user_id + from_address: Will find the user and ensures the given from_address belongs to him.
  • from_account_id: Will find the account and takes its primary address as the sending address.
  • from_account_id + from_address: Will find the account and ensures the given from_address belongs to that account.
  • from_address: Will simply set the sending address (and get the owner of that address for reference).

The parameters are the same for the other side, simply swap from with to.

  • to_provider_user_id
  • to_provider_user_id + to_address
  • to_account_id
  • to_account_id + to_address
  • to_address
Simple Transfer

In addition to the previous parameters, a simple transfer requires to pass:

  • token_id
  • amount
transaction = OmiseGO::Transaction.create({
  from_address: "abcd111111111111",
  to_address: "abcd111111111112",
  token_id: "tok_OMG_01ccmny8yne44b188287d44498",
  amount: 100
})

Returns either:

  • An OmiseGO::Transaction instance
  • An OmiseGO::Error instance
Exchange Transfer

Exchange transfers are a bit more complicated. In addition to defining the sender/receiver, you will also need to give it a from_token_id/to_token_id pair, a from_amount OR a to_amount and either an exchange_account_id OR an exchange_wallet_address.

  • from_token_id: The ID of the sending token.
  • to_token_id: The ID of the receive token.
  • from_amount: The amount of tokens (from_token_id) to send
  • to_amount: The amount of tokens (to_token_id) to receive
  • exchange_account_id: The ID of the account that will be used as an intermediary to exchange funds. The primary wallet of that account needs to have funds in the token identified by to_token_id, unless exchange_wallet_address is specified.
  • exchange_wallet_address: The ID of the wallet that will be used as an intermediary to exchange funds. That wallet needs to have funds in the token identified by to_token_id.
OmiseGO::Transaction.create({
  from_address: "abcd111111111111",
  to_address: "abcd111111111112",
  from_token_id: "tok_BTC_01chckv8eh2nq1zwkyfkh2pe40",
  to_token_id: "tok_ETH_01chckv8h6v355xgh629w4r27c",
  from_amount: 1,
  exchange_account_id: "acc_01chckv67se4eddn11nyz7y3ma"
})

Returns either:

  • An OmiseGO::Transaction instance
  • An OmiseGO::Error instance

Getting settings

All

Retrieve the settings from the eWallet API.

settings = OmiseGO::Setting.all(
  client: nil # optional, defauls to nil and uses the client
              # defined in config)
)

Returns either:

  • An OmiseGO::Setting instance
  • An OmiseGO::Error instance

Models

Here is the list of all the models available in the SDK with their attributes.

OmiseGO::AuthenticationToken

Attributes:

  • authentication_token (string)

OmiseGO::Pagination

Attributes

  • per_page (integer)
  • current_page (integer)
  • first_page? (boolean)
  • last_page? (boolean)

OmiseGO::List

Attributes:

  • data (array of models)
  • pagination (OmiseGO::Pagination)

OmiseGO::Token

Attributes:

  • id (string)
  • symbol (string)
  • name (string)
  • subunit_to_unit (integer)
  • metadata (object)
  • encrypted_metadata (object)

OmiseGO::Wallet

Attributes:

  • address (string)
  • balances (array of OmiseGO::Wallet)
  • socket_topic (string, the channel for this wallet's events)
  • name (string, the name of the wallet)
  • identifier (string, the type of the wallet)
  • metadata (object)
  • encrypted_metadata (object)
  • user_id (string, user owning the wallet if applicable)
  • user (OmiseGO::User)
  • account_id (string, account owning the wallet if applicable)
  • account (OmiseGO::Account)
  • created_at (string)
  • updated_at (string)

OmiseGO::Balance

Attributes:

  • amount (integer)
  • token (OmiseGO::Token)

OmiseGO::User

Attributes:

  • id (string)
  • username (string)
  • provider_user_id (string)
  • metadata (hash)
  • metadata (object)
  • encrypted_metadata (object)

OmiseGO::Account

Attributes:

  • id (string)
  • parent_id (string)
  • name (string)
  • description (string)
  • master (boolean)
  • avatar (hash)
  • metadata (object)
  • encrypted_metadata (object)
  • created_at (string)
  • updated_at (string)

OmiseGO::Exchange

  • rate (integer)

OmiseGO::TransactionSource

  • address (string)
  • amount (integer)
  • token (OmiseGO::Token)

OmiseGO::Transaction

  • id (string)
  • idempotency_token (string)
  • amount (integer)
  • token (OmiseGO::Token)
  • from (OmiseGO::TransactionSource)
  • to (OmiseGO::TransactionSource)
  • exchange (OmiseGO::Exchange)
  • status (string)
  • created_at (string)
  • updated_at (string)
  • metadata (object)
  • encrypted_metadata (object)

OmiseGO::Error

Attributes:

  • code (string)
  • description (string)
  • messages (hash)

Live Tests

Live tests are recorded using VCR. However, they have been updated to hide any access/secret key which means deleting them and re-running the live tests will fail. It is first required to update the spec/env.rb file with real keys. Once the VCR records have been re-generated, do not forget to replace the Authorization header in all of them using the base64 encoding of fake access and secret keys.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rspec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

License

The OmiseGO Ruby SDK is released under the Apache License.

About

OmiseGO Ruby SDK for integration with Wallet Server.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published