Account management

Overview

This page describes how accounts are maintained the Solaris Digital Assets (SDA) platform. It contains information about the following SDA API resources:

Entities

The SDA platform uses Entities to represent SDA partners and customers. An Entity can have one of the following types:

  • PARTNER: An SDA partner (i.e., you).
  • PERSON: A retail customer. Each PERSON Entity must correspond with a Person resource created using the Solaris Digital Banking API.
  • BUSINESS: A business customer. Each BUSINESS Entity must correspond with a Business resource created using the Solaris Digital Banking API.
  • REPRESENTATIVE_PERSON: An individual who can approve ApprovalRequests on a Transaction that belongs to another Entity. Each REPRESENTATIVE_PERSON Entity must correspond with a Person resource created using the Solaris Digital Banking API.

During onboarding, Solaris will create an Entity of type PARTNER to represent you as an account holder.

Multiple Entities of type REPRESENTATIVE_PERSON can have the same underlying person_id as long as that person_id is not associated with another Entity of type PERSON.

note

Before you can create an Entity for a customer, the customer must have successfully completed the Solaris Digital Banking onboarding and KYC processes. See the SDA overview page for an explanation on how to onboard customers onto SDA.

Entity states

An Entity can have one of the following states:

  • ACTIVE: The Entity can use the platform without restrictions.
  • CLOSING: A ClosureRequest has been created for the Entity, but the closure process has not yet finished.
  • LEGALLY_CLOSED: The contractual relationship between SDA and the associated customer has ended, but the customer can still withdraw their remaining funds.
  • CLOSED: The contractual relationship between SDA and the associated customer has ended, and the customer cannot use the platform at all.

Entity API endpoints

POST Create an Entity

This endpoint creates an Entity of a given type.

You must specify a person_id attribute when creating an Entity of type PERSON or REPRESENTATIVE_PERSON, and you must specify a name attribute (i.e., the name of the associated business) when creating an Entity of type BUSINESS.

Request URL:

POST /v1/entities

Request example:

Copy
Copied
{
  "type": "PERSON",
  "person_id": "5b1c711ef5cf4b7012b688616ed052d3cper"
}

Response example:

Copy
Copied
// 201 Created

{
  "id": "10ef67dc895d6c19c273b1ffba0c1692enty",
  "type": "PERSON",
  "person_id": "5b1c711ef5cf4b7012b688616ed052d3cper",
  "terms_conditions_signed_at": null,
  "state": "ACTIVE",
  "legally_closed_at": null,
  "closed_at": null,
  "created_at": "2019-04-02T12:27:33Z",
  "updated_at": "2019-04-02T12:27:33Z",
}

Click here to view the full API reference.

GET List all Entities

This endpoint returns an array containing all Entities under your control.

Request URL:

GET /v1/entities

Response example:

Copy
Copied
{
  "items": [
    {
      "id": "1cbce42a62fc0cdeb1cf17df3ecd6fd6enty",
      "type": "PARTNER",
      "state": "ACTIVE",
      "business_id": "880bbac68a34add190786b9c74f4c82fcbiz",
      "trading_terms_conditions_signed_at": "2019-03-01T22:45:06Z",
      "created_at": "2019-03-01T22:31:06Z",
      "updated_at": "2019-03-01T22:31:06Z"
    }
  ],
  "pagination": {
    "next": 0,
    "prev": 0
  }
}

Click here to view the full API reference.

GET Retrieve an Entity

This endpoint returns information about the Entity specified in the request URL.

Request URL:

GET /v1/entities/{entity_id}

Response example:

Copy
Copied
{
  "id": "7d57be2d17a328150abd28daaae76d47enty",
  "type": "PERSON",
  "person_id": "e3c4bc7bdfeaed3c0a3cebd2addcd5accper",
  "created_at": "2019-03-01T22:31:06Z",
  "updated_at": "2019-03-01T22:31:06Z"
}

Click here to view the full API reference.

Solaris Digital Assets Terms and Conditions

Entities of type PERSON and BUSINESS are required to accept SDA's Terms and Conditions in order to use the platform. Once they do so, call the endpoint below to register their acceptance of the T&Cs.

warning

You are required to display all of the Solaris Digital Assets Terms and Conditions documents to the customer before calling the endpoint below. The customer must agree to all of them.

You can find the relevant documents under the following permalinks:

POST Accept SDA Terms and Conditions

This endpoint records an Entity's acceptance of the Solaris Digital Assets Terms and Conditions. The API will store a UTC timestamp from when the Entity accepted the Terms and Conditions in its terms_conditions_signed_at property.

Request URL:

POST /v1/entities/{entity_id}/terms_and_conditions

Response example:

201 Created

Click here to view the full API reference.

ClosureRequests (Entity and Account Closures)

The contractual relationship between a customer and Solaris Digital Assets can be terminated by both parties. To initiate a contract termination, you must create a ClosureRequest. This resource keeps track of the termination status.

After a ClosureRequest has been created, the customer will have 30 days (if the reason is CUSTOMER_WISH or COMPLIANCE_IMMEDIATE_INTERNAL) or 90 days (if the reason is ORDINARY_INTERNAL) to withdraw their assets from their accounts.

There are two options for withdrawing the full balance from an account:

  1. Create a Withdrawal and set the total_amount value to the full balance of the Account. The withdrawn amount will equal total_amount minus the applicable fee_amount.

    • Example: The total amount to withdraw is 1 BTC, and the fee is calculated at 0.01 BTC. The Withdrawal will leave 0 BTC in the Account, and the customer will receive 0.99 BTC in their external wallet.
  2. Create a Withdrawal and set the amount value to the full balance of the Account and specify an Account for paying the fee in the fee_account_id attribute. The withdrawn amount will equal the full balance of the Account.

    • Example: The total amount to withdraw is 1 BTC, and the fee is calculated at 0.01 BTC. The Withdrawal will leave 0 BTC in the Account, and the customer will receive 1 BTC in their external wallet. The fee is deducted from a different Account that belongs to you.
Note

If you choose the second option, then the Account for paying the fee must have the correct base Asset (e.g., if the customer's Account is in USDC, then the fee_account_id must correspond with an Account in ETH). The Account must belong to either your Entity or the customer's Entity.

ClosureRequest reasons

ClosureRequests can have different reasons depending on which party initiates the contract termination and the circumstances under which the contract is terminated. Each reason is described in greater detail below.

note

As a partner, you can only create ClosureRequests with a reason of CUSTOMER_WISH.

CUSTOMER_WISH

CUSTOMER_WISH ClosureRequests are created when the customer decides to end their contractual relationship with Solaris Digital Assets. After a ClosureRequest of this type is submitted, the customer has 30 days to withdraw their assets from their Accounts.

COMPLIANCE_IMMEDIATE_INTERNAL

COMPLIANCE_IMMEDIATE_INTERNAL ClosureRequests are created when a Solaris compliance officer terminates the platform's relationship with the customer for compliance reasons.

When this type of ClosureRequest is created, you will receive a callback. Upon receiving the callback with the ClosureRequest, you must inform the end customer of the account closure. You must later confirm to Solaris via POST Confirm closure request that the end customer has acknowledged the account closure.

After confirming the ClosureRequest, the customer will have 30 days to withdraw their assets from their Accounts.

ORDINARY_INTERNAL

ORDINARY_INTERNAL ClosureRequests are created when a Solaris compliance, customer support, or seizures officer terminates the platform's relationship with the customer.

When this type of ClosureRequest is created, you will receive a callback. Upon receiving the callback with the ClosureRequest, you must inform the end customer of the account closure. You must later confirm to Solaris via POST Confirm closure request that the end customer has acknowledged the account closure.

After confirming the ClosureRequest, the customer will have 90 days to withdraw their assets from their Accounts.

ClosureRequest lifecycle

All ClosureRequests are created with an initial status of PENDING.

  • ClosureRequests of type CUSTOMER_WISH will transition immediately to PROCESSING.
  • ClosureRequests of type COMPLIANCE_IMMEDIATE_INTERNAL require confirmation from the customer. When the customer confirms the closure, it will transition to PROCESSING.
  • ClosureRequests of type ORDINARY_INTERNAL require confirmation from the customer. When the customer confirms the closure, it will transition to PROCESSING after 60 days.

When it reaches the PROCESSING state, Solaris will begin the process of closing down the account. Once this process is finished, the ClosureRequest will transition to COMPLETED and the customer will no longer be able to use their account.

If a ClosureRequest cannot be processed (e.g., if a ClosureRequest already exists for the customer), then it will transition to FAILED.

The diagram below explains the lifecycle for each type of ClosureRequest:

Diagram: ClosureRequest lifecycle

ClosureRequest API endpoints

Use the following endpoints to create, confirm, and query information about ClosureRequests:

POST Create a ClosureRequest

This endpoint creates a ClosureRequest for the Entity specified in the request URL.

Request URL:

POST /v1/entities/{entity_id}/closure_requests

Request example:

Copy
Copied
{
  "reason": "CUSTOMER_WISH"
}

Response example:

Copy
Copied
// 201 Created
{
  "id": "6138143133c91f3235a108d31dc90805creq",
  "entity_id": "5a991ba917c829ca2ab6ce9a4ee3f9fcenty",
  "reason": "CUSTOMER_WISH",
  "state": "PROCESSING",
  "valid_until": "2021-01-01T12:35:38Z",
  "created_at": "2020-12-02T12:35:38Z",
  "updated_at": "2020-12-02T12:35:38Z"
}

Click here to view the full API reference.

POST Confirm ClosureRequest

Use this endpoint to register the customer's confirmation of their closure for ClosureRequests of type COMPLIANCE_IMMEDIATE_INTERNAL and ORDINARY_INTERNAL.

Request URL:

POST /entities/{entity_id}/closure_requests/{closure_request_id}/confirm

Response example:

Copy
Copied
{
  "id": "ae93e4dcb3d0f5d0e36a227a94ff39e5creq",
  "reason": "COMPLIANCE_IMMEDIATE_INTERNAL",
  "entity_id": "275cf8f7559fd88710b4c919f85777aaenty",
  "state": "PROCESSING",
  "valid_until": "2019-04-01T22:31:06Z",
  "legal_closure_scheduled_at": "2019-03-01T22:31:06Z",
  "created_at": "2019-03-01T22:31:06Z",
  "updated_at": "2019-03-01T22:31:06Z"
}

Click here to view the full API reference.

GET List all ClosureRequests for an Entity

This endpoint returns an array containing all ClosureRequests for the Entity specified in the request URL.

Request URL:

GET /entities/{entity_id}/closure_requests

Response example:

Copy
Copied
{
  "items": [
    {
      "id": "ae93e4dcb3d0f5d0e36a227a94ff39e5creq",
      "reason": "ORDINARY_INTERNAL",
      "entity_id": "275cf8f7559fd88710b4c919f85777aaenty",
      "state": "APPROVED",
      "valid_until": "2019-07-01T22:31:06Z",
      "legal_closure_scheduled_at": "2019-05-01T22:31:06Z",
      "created_at": "2019-03-01T22:31:06Z",
      "updated_at": "2019-03-01T22:31:06Z"
    }
  ],
  "pagination": {
    "next": 0,
    "prev": 0
  }
}

Click here to view the full API reference.

GET Retrieve a ClosureRequest

This endpoint returns information about the ClosureRequest specified in the request URL.

Request URL:

GET /entities/{entity_id}/closure_requests/{closure_request_id}

Response example:

Copy
Copied
{
  "id": "ae93e4dcb3d0f5d0e36a227a94ff39e5creq",
  "reason": "CUSTOMER_WISH",
  "entity_id": "275cf8f7559fd88710b4c919f85777aaenty",
  "state": "PROCESSING",
  "valid_until": "2019-04-01T22:31:06Z",
  "legal_closure_scheduled_at": "2019-03-01T22:31:06Z",
  "created_at": "2019-03-01T22:31:06Z",
  "updated_at": "2019-03-01T22:31:06Z"
}

Click here to view the full API reference.

Assets

On the SDA platform, an Asset represents a single digital asset of some kind. This can be a cryptocurrency (e.g., Bitcoin), a token (e.g., ERC20), or some other type of digital asset.

Each Asset resource has the following properties:

  • id: A unique ID for the Asset on the SDA platform.
  • code: A non-unique and non-permanent ISO code-like identifier of the digital asset.
  • description: A human-readable description of the Asset.
  • precision: The number of decimal places to use for monetary amounts of this Asset.
  • address_validation: Regular expression to use to validate addresses for this Asset.
  • tx_min_amount: Minimum required amount for outgoing transactions of this Asset.
  • type: Indicates the type of asset (described in further detail below).

When using the SDA API, you must always reference an Asset using its unique id.

Types of Assets

Assets come in three different types:

  • BASE: Crypto assets that are native to their own blockchain (e.g., Bitcoin or Ethereum).
  • TOKEN: Crypto assets that have been created on an existing blockchain. For example, ERC-20 tokens would be considered a TOKEN Asset because they were created on the Ethereum blockchain.

    • Assets of this type always have a base_asset_id, which contains the ID of the Asset that represents the underlying blockchain.
  • FIAT: Fiat assets (e.g., USD or EUR). The SDA platform only uses FIAT Assets as a reference Asset for fiat currencies in trading pairs and for informational purposes.

    • Note: You cannot create Accounts with this type of Asset.

Asset API endpoints

Use the following endpoints to look up information about Assets:

GET List all Assets

This endpoint returns an array containing all Assets on the platform.

Request URL:

GET /assets

Response example:

Copy
Copied
{
  "items": [
    {
      "id": "00000000000000000000000000000001asst",
      "code": "BTC",
      "description": "Bitcoin",
      "precision": 8,
      "address_validation": "^(bc(0([ac-hj-np-z02-9]{39}|[ac-hj-np-z02-9]{59})|1[ac-hj-np-z02-9]{8,87})|[13][a-km-zA-HJ-NP-Z1-9]{25,35})$",
      "tx_min_amount": "0.00001",
      "type": "BASE",
      "created_at": "2019-03-01T22:46:38Z",
      "updated_at": "2019-03-01T22:46:38Z"
    }
  ],
  "pagination": {
    "next": 0,
    "prev": 0
  }
}

Click here to view the full API reference.

GET List all Assets

This endpoint returns information about the Asset specified in the request URL.

Request URL:

GET /assets/{asset_id}

Response example:

Copy
Copied
{
  "id": "00000000000000000000000000000001asst",
  "code": "BTC",
  "description": "Bitcoin",
  "precision": 8,
  "address_validation": "^(bc(0([ac-hj-np-z02-9]{39}|[ac-hj-np-z02-9]{59})|1[ac-hj-np-z02-9]{8,87})|[13][a-km-zA-HJ-NP-Z1-9]{25,35})$",
  "tx_min_amount": "0.00001",
  "type": "BASE",
  "created_at": "2019-03-01T22:46:38Z",
  "updated_at": "2019-03-01T22:46:38Z"
}

Click here to view the full API reference.

Accounts

An Account represents an aggregation of funds of a certain type owned by an Entity.

Each Account is associated with an Entity as well as an Asset. You can create many Accounts for an individual Entity, but you cannot transfer an Account between different Entities.

An Account can have two different types:

  • BASE: An Account associated with a native Asset of a blockchain (e.g., ETH for the Ethereum blockchain).
  • TOKEN: An Account for an Asset implemented on a blockchain using smart contracts (e.g., ERDC-20 tokens such as USDC on the Ethereum blockchain).

The Account's type depends on the type of its associated base Asset.

When creating an Account of type TOKEN, you must reference a corresponding BASE Account associated with the base Asset of the token.

When you conduct transactions using an Account of type TOKEN, then you can choose whether to have the Transaction fees collected from its associated BASE Account.

The Solaris Digital Assets platform will combine your customers' assets together in a liquidity pool. On the blockchain level, this means that all funds are grouped together instead of being separated among each Account.

Customers can send instant Transfers to other Accounts with the same Asset type without interacting with the blockchain (and thus without paying expensive fees).

Customers can associate multiple Addresses for depositing funds with each account they own.

Account balance

The SDA API represents an account balance using two properties on the corresponding Account resource:

  • balance: Indicates the current amount of funds on the account. The API does not factor open Transactions in calculating the balance property.
  • available_balance: Indicates the current amount of funds that the customer may transfer. The API includes open Transactions in calculating the available_balance.

When a customer requests to transfer funds out of their Account, the API does not immediately reduce the Account's balance. Instead, it subtracts the requested amount from the available_balance. The amount will be deducted from the balance once the platform has successfully processed the transaction.

Each successful Transaction increases or decreases the Account Balance by creating corresponding Ledger Entries. As such, the Account Balance equals the sum of all Ledger Entries on the Account.

Account API endpoints

Use the following API endpoints to create and query information about Accounts:

POST Create Account

This endpoint creates an Account for the Entity specified in the request URL. Note that you must specify the ID of an Asset for the Account.

Request URL:

POST /v1/entities/{entity_id}/accounts

Request example (BASE):

Copy
Copied
{
  "asset_id": "00000000000000000000000000000001asst"
}

Response example (BASE):

Copy
Copied
// 201 Created

{
  "id": "9c41ec8a82fb99b57cb5078ae0a8b569acct",
  "asset_id": "00000000000000000000000000000001asst",
  "entity_id": "10ef67dc895d6c19c273b1ffba0c1692enty",
  "balance": "0.00000000",
  "available_balance": "0.00000000",
  "type": "BASE",
  "created_at": "2019-02-02T13:41:34Z",
  "updated_at": "2019-02-02T13:41:34Z"
}

Request example (TOKEN):

Copy
Copied
{ 
  "asset_id": "00000000000000000000000000000012asst", 
  "base_account_id": "9c41ec8a82fb99b57cb5078ae0a8b569acct" 
}

Response example (TOKEN):

Copy
Copied
// 201 Created

{ 
  "id": "466c8676c414404d0a2ae64802398f50acct", 
  "asset_id": "00000000000000000000000000000012asst", 
  "base_account_id": "9c41ec8a82fb99b57cb5078ae0a8b569acct", 
  "entity_id": "10ef67dc895d6c19c273b1ffba0c1692enty", 
  "balance": "0.00000000", 
  "available_balance": "0.00000000", 
  "type": "TOKEN", 
  "created_at": "2019-02-02T13:41:34Z", 
  "updated_at": "2019-02-02T13:41:34Z" 
}

Click here to view the full API reference.

GET List all Accounts for an Entity

This endpoint returns an array containing all Accounts associated with the Entity specified in the request URL.

Request URL:

GET /v1/entities/{entity_id}/accounts

Response example:

Copy
Copied
{
  "items": [
    {
      "id": "09934947ffdd4bef50ba88ddc5eab0bfacct",
      "entity_id": "359fe08986bbc6b62ea406f864b1ab90enty",
      "asset_id": "00000000000000000000000000000001asst",
      "balance": "123.45670000",
      "available_balance": "123.45600000",
      "created_at": "2019-03-01T22:31:06Z",
      "updated_at": "2019-03-01T22:31:06Z"
    }
  ],
  "pagination": {
    "next": 0,
    "prev": 0
  }
}

Click here to view the full API reference.

GET Retrieve an account

This endpoint returns information about the Account specified in the request URL.

Request URL:

GET /v1/entities/{entity_id}/accounts/{account_id}

Response example:

Copy
Copied
{
  "id": "09934947ffdd4bef50ba88ddc5eab0bfacct",
  "entity_id": "359fe08986bbc6b62ea406f864b1ab90enty",
  "asset_id": "00000000000000000000000000000001asst",
  "balance": "123.45670000",
  "available_balance": "123.45600000",
  "created_at": "2019-03-01T22:31:06Z",
  "updated_at": "2019-03-01T22:31:06Z"
}

Click here to view the full API reference.

Addresses

An Address represents a blockchain-level digital asset address.

Customers can create and associate many Addresses with an Account and can use these Addresses to transfer funds to their Accounts. Once created, an Address will permanently remain valid and associated with the Account. Solaris uses the Address resource to track the ownership of funds deposited to blockchain-level addresses.

Address API endpoints

Use the following API endpoints to create and query information about Addresses:

POST Create an Address

This endpoint creates an Address and associates it with the Account specified in the request URL. The Address can immediately be used to receive funds on the blockchain. As each Account is associated with a specific Asset, the new Address will also be linked to this particular Asset.

note

You cannot create Addresses for TOKEN Accounts. Use the ID of the corresponding base Account instead.

Request URL:

POST /v1/entities/{entity_id}/accounts/{account_id}/addresses

Response example:

Copy
Copied
// 201 Created

{
  "id": "42049cb01a6962d0232223e632aac68baddr",
  "account_id": "9c41ec8a82fb99b57cb5078ae0a8b569acct",
  "address": "1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX",
  "created_at": "2019-02-02T13:43:34Z",
  "updated_at": "2019-02-02T13:43:34Z"
}

Click here to view the full API reference.

GET List all Addresses associated with an Account

This endpoint returns an array containing all Addresses associated with the Account specified in the request URL.

Request URL:

GET /entities/{entity_id}/accounts/{account_id}/addresses

Response example:

Copy
Copied
{
  "items": [
    {
      "id": "dfddb6ba632e3ee65e49f37b059763cdaddr",
      "account_id": "df10de8c583c8b2ca85ca169df349bffacct",
      "address": "1NgiUwkhYVYMy3eoMC9dHcvdHejGxcuaWm",
      "created_at": "2019-03-01T21:47:06Z",
      "updated_at": "2019-03-01T21:47:06Z"
    }
  ],
  "pagination": {
    "next": 0,
    "prev": 0
  }
}

Click here to view the full API reference.

GET Retrieve an Address

This endpoint returns information about the Address specified in the request URL.

Request URL:

GET /entities/{entity_id}/accounts/{account_id}/addresses/{address_id}

Response example:

Copy
Copied
{
  "id": "dfddb6ba632e3ee65e49f37b059763cdaddr",
  "account_id": "df10de8c583c8b2ca85ca169df349bffacct",
  "address": "1NgiUwkhYVYMy3eoMC9dHcvdHejGxcuaWm",
  "created_at": "2019-03-01T21:47:06Z",
  "updated_at": "2019-03-01T21:47:06Z"
}

Click here to view the full API reference.