# Cryptocurrency Exchange

## Solution Architecture

<figure><img src="https://3218614644-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoAQr9l0l72LlC4cHtGP0%2Fuploads%2FNl6FIFjYJiaey7ri9hom%2FSOLUTION_ARCHITECTURE.png?alt=media&#x26;token=f98a295c-de11-4a65-a481-dad532ae1b84" alt=""><figcaption></figcaption></figure>

## Users model

In this example, user authentication and authorization is done outside of the Orangepill platform. Integration on the users level is done using `Identities` object of Orangepill platform. Use identities to map both your system user and your end users.

<figure><img src="https://3218614644-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoAQr9l0l72LlC4cHtGP0%2Fuploads%2FyFbZPvtnlQ98R6uUtDdX%2FUSER_MODEL.png?alt=media&#x26;token=fe39e5ef-6bd9-41ab-99d4-b59fb5b44a13" alt=""><figcaption></figcaption></figure>

### System identity

We will need user object and identity object that will represent your system user. System user will provide security context for all API calls to Orangepill platform.

Use Orangepill Dashboard to create new Realm. Realm will provide physical and logical sepration of your data in Orangepill project. Default user and Default identity will be auto-created during that process. Use this identity as system identity.

**IMPORTANT:** Make sure to have id of your system identity available as a constant inside your project.

#### API Authentication

Use **username** and **password** of system user to authenticate to Orangepill API. Additionally you will need to copy **Realm key** from Dashboard to build x-api-key authentication token.

Add **x-api-key** header parameter as authentication token.

Value for **x-api-key** is: **base64encode(username:password:Realm.key)**

### End user identities

Identities are acting as holders of accounts.

Use Identities to map your users to Orangepill platform. Store **username** or **user\_id** from your Users table in Identity `data` object to maintain relation between two identity systems.

```jsx
curl --location --request POST '<https://api.orangepill.cloud/v1/identities>' \\
--header 'x-api-key: AXVubzpwQDU1dzByYM==' \\
--header 'Content-Type: application/json' \\
--data-raw '{
    "country": "COUNTRY",
    "currency": "CURRENCY",
    "data": {
        "username": "USERNAME"
    }
}'
```

#### Import current users

If you already have users table with real data, build a batch script to pre-create identities for your existing users.

#### Map new user

Add code that will create Identity in Orangepill platform upon creation of user in your main system.

## Operational model

Make sure you have clear model on movement of digital assets. Each movement of digital assets balance will have a relation to manual administrative or automated operation.

### Accounting model

Use Orangepill platform to build accounts necessary to maintain information about movement of all assets included in your exchange operations.

<figure><img src="https://3218614644-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoAQr9l0l72LlC4cHtGP0%2Fuploads%2FSnEOf4U7Cnaj3Ph2Dnj9%2FACCOUNTING_MODEL.png?alt=media&#x26;token=87158620-f5ff-461a-bd1e-bfff8aefafc7" alt=""><figcaption></figcaption></figure>

#### Liquidity accounts

Create ramp accounts for each digital asset in your exchange project. You will use those accounts to maintain liquidity of digital assets.

```jsx
curl --location --request POST '<https://api.orangepill.cloud/v1/accounts>' \\
--header 'x-api-key: AXVubzpwQDU1dzByYM==' \\
--header 'idempotency-key: 27373fabc392933deffdb' \\
--header 'Content-Type: application/json' \\
--data-raw '{
    "holder": "SYSTEM_IDENTIYTY",
    "asset": "ASSET",
    "type": "ramp",
    "data": {
        "description": "Master ASSET account."
    }
}'
```

#### Fees accounts

Create virtual account for each digital asset for the purpose of collecting fees.

```jsx
curl --location --request POST '<https://api.orangepill.cloud/v1/accounts>' \\
--header 'x-api-key: AXVubzpwQDU1dzByYM==' \\
--header 'idempotency-key: 27373fabc392933deffdb' \\
--header 'Content-Type: application/json' \\
--data-raw '{
    "holder": "SYSTEM_IDENTIYTY",
    "asset": "ASSET",
    "type": "virtual",
    "data": {
        "description": "Fees ASSET account."
    }
}'
```

#### FIAT accounts

To support FIAT transactions you will need to create a Virtual currency. Virtual currency will create master virtual account to maintain supply.

Initial supply should be amount of FIAT money currently available for exchange in your bank account.

```jsx
curl --location --request POST '<https://api.orangepill.cloud/v1/currencies> \\
--header 'x-api-key: AXVubzpwQDU1dzByYM==' \\
--header 'idempotency-key: 27373fabc392933deffdb' \\
--header 'Content-Type: application/json' \\
--data-raw '{
    "name": "VIRTUAL_USD",
    "supply": "1000",
    "base": "USD",
    "rate": "1",
    "currency": "USD"
}'
```

#### End User digital asset accounts

Build virtual accounts for each supported digital asset for each one of your users.

```jsx
curl --location --request POST '<https://api.orangepill.cloud/v1/accounts>' \\
--header 'x-api-key: AXVubzpwQDU1dzByYM==' \\
--header 'idempotency-key: 27373fabc392933deffdb' \\
--header 'Content-Type: application/json' \\
--data-raw '{
    "holder": "USER_IDENTIYTY",
    "asset": "ASSET",
    "type": "virtual",
    "data": {
        "description": "User ASSET account."
    }
}'
```

### Liquidity

Use blockchain address of liquidity accounts to maintain liquidity of your exchange. Use this address to deposit digital assets from your liquidity provider.

<figure><img src="https://3218614644-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoAQr9l0l72LlC4cHtGP0%2Fuploads%2FOrUjBl4loawd6Y0BgNbb%2FLIQUIDITY.png?alt=media&#x26;token=4dc0f3bb-05ea-4d1e-a5d4-737e2e32a557" alt=""><figcaption></figcaption></figure>

Populate address field to retrieve blockchain address from ramp account.

```jsx
curl --location --request POST '<https://api.orangepill.cloud/v1/accounts/ACCOUNT?populate=address>' \\
--header 'x-api-key: AXVubzpwQDU1dzByYM==' \\
--header 'Content-Type: application/json'
```

In response you will get account object with populated address field.

```jsx
{
    "id": "63ab92d694bdaeb815cb4365",
    "asset": "ETH",
    "chain": "ethereum",
    "data": null,
    "holder": "639675ab191e9023f356dfa7",
    "currency": "USD",
    "type": "ramp",
    "testnet": false,
    "reference": "63ab92d611da79ce37322335",
    "subscription": "63ab92d750dede50c4c7e6af",
    "balance": {
        "available": 0,
        "total": 0,
        "assets": 0
    },
    "ramp": null,
    "owner": "639675ab191e9023f356dfa6",
    "created_at": 1672188630240,
    "error": null,
    "active": true,
    "frozen": false,
    "deleted": false,
    "address": {
        "id": "63ab92d794bdaeb815cb4367",
        "account": "63ab92d694bdaeb815cb4365",
        "data": null,
        "asset": "ETH",
        "address": "0x4e5ac860ee4c2db16a3bd4450bdeb21e14cf281e",
        "derivation_key": "1",
        "xpub": "xpub6ET1YuT1WEHNzdyoBYMhYScEZMTSBRixirKAps5FJcBTz2KNq2eRsRzEKQvmLearYNe9JXHpLFuPfYokQvr9emohL7ZQuo7U4CSBswYzZfw",
        "destination_tag": null,
        "memo": null,
        "message": null,
        "notification": null,
        "created_at": 1672188631469,
        "error": null
    }
}
```

Supply of digital assets deposited to liquidity accounts will maintain there until it is withdrawn.

You can get a list of all deposits.

```jsx
curl --location --request GET '<https://api.orangepill.cloud/v1/deposits>' \\
--header 'x-api-key: AXVubzpwQDU1dzByYM==' \\
--header 'Content-Type: application/json'
```

Also, you can withdraw digital assets from liquidity account.

```jsx
curl --location --request POST '<https://api.orangepill.cloud/v1/withdrawals> \\
--header 'x-api-key: AXVubzpwQDU1dzByYM==' \\
--header 'idempotency-key: 27373fabc392933deffff' \\
--header 'Content-Type: application/json' \\
--data-raw '{
    "source": {
        "account": "634b56217f6a7b0be52dffca"
    },
    "destination": {
        "address": "bc1qxyvqcwepfwsxstemz626uc73n0w6nxh3swgh68"
    },
    "asset": "BTC",
    "value": 0.15,
    "fee": {
        "paid_by": "receiver",
        "speed": "fast"
    },
    "data": {
        "description": "Withdrawal X"
    }
}'
```

### FIAT Integration

To support FIAT operations you must integrate a processes of debit and credit in your FIAT account, to processes of issue and destroy of your virtual FIAT currency.

<figure><img src="https://3218614644-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoAQr9l0l72LlC4cHtGP0%2Fuploads%2F8ZFYJkGah2bEg2EzUpn2%2FFIAT_CASHIN__CASHOUT.png?alt=media&#x26;token=e47516fd-e774-4cee-a5b3-a60b591f941b" alt=""><figcaption></figcaption></figure>

#### Cash-in operation

When you receive FIAT amount from your end user, make sure you issue a new supply of virtual FIAT currency. You can map this operation to your other system using `data` object.

```jsx
curl --location --request POST '<https://api.orangepill.cloud/v1/currencies/VIRTUAL_FIAT_ACCOUNT/issue> \\
--header 'x-api-key: AXVubzpwQDU1dzByYM==' \\
--header 'idempotency-key: 27373fabc392933deffdb' \\
--header 'Content-Type: application/json' \\
--data-raw '{
    "account": "63a633e84ab7d02420b732ae",
    "amount": "AMOUNT",
		"data": {
			"description": "Cash in for user X",
			"reference":"REFERENCE_TO_EXTERNAL_OPERATION"
		}
}'
```

#### Cash-out operation

When you send FIAT amount to your end user, make sure you destroy a supply of virtual FIAT currency.

```jsx
curl --location --request POST '<https://api.orangepill.cloud/v1/currencies/VIRTUAL_FIAT_ACCOUNT/destroy> \\
--header 'x-api-key: AXVubzpwQDU1dzByYM==' \\
--header 'idempotency-key: 27373fabc392933deffdb' \\
--header 'Content-Type: application/json' \\
--data-raw '{
    "account": "63a633e84ab7d02420b732ae",
    "amount": "AMOUNT",
		"data": {
			"description": "Cash out for user X",
			"reference":"REFERENCE_TO_EXTERNAL_OPERATION"
		}
}'
```

### Fees model

To implement fees model, you will need to send fees to your fees accounts before end user executes operation. Make sure you define fees amounts you want to charge your end users for various operations. To implement fee charging you must calculate fee amount and move it to your fees accounts before you execute operation for end user.

**Example of charging fees for exchange**

1. user starts exchange operation
2. calculate fee amount
3. move fee amount to your fee account
4. continue executing exchange operation, diminished in amount for the fee amount

To move digital assets to your fee account use transaction operation.

```jsx
echo 'move 0.0000001 BTC from account to account'

curl --location --request POST '<https://api.orangepill.cloud/v1/transactions>' \\
--header 'x-api-key: AXVubzpwQDU1dzByYM==' \\
--header 'idempotency-key: 27373fabc392933dffabb' \\
--header 'Content-Type: application/json' \\
--data-raw '{
    "source": {
        "account": "634b56217f6a7b0be52dffbd"
    },
    "destination": {
        "account": "6340be52dffbdb56217f6a7b"
    },
    "value": 0.0000001,
    "asset": "BTC",
    "data": {
        "description": "Payment of 0.0000001 fee in Bitcoin",
        "external_reference": "REFERENCE"
    }
}'
```

## Exchange swap

Implementation of exchange operation must include both movements of digital assets in a swap operation.

### FIAT -> Digital Asset

1. (receive FIAT cash-in)
2. calculate fee amount
3. issue FIAT supply
4. send digital assets from liquidity account to fees virtual account
5. send digital assets from liquidity account to end user virtual account

<figure><img src="https://3218614644-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoAQr9l0l72LlC4cHtGP0%2Fuploads%2Fv7fWvJCQMvZw7vVpbEXk%2FUSD_BTC_SWAP.png?alt=media&#x26;token=400e59cf-6d27-4d62-a952-7b55ec5c883e" alt=""><figcaption></figcaption></figure>

### Digital Asset → FIAT

1. calculate fee amount
2. send digital assets from end user virtual account to fees virtual account
3. send digital assets from end user virtual account to Liquidity account
4. destroy FIAT supply
5. (send FIAT cash-out)

<figure><img src="https://3218614644-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoAQr9l0l72LlC4cHtGP0%2Fuploads%2FWaLmPFzJoCLwCnIIhMRD%2FBTC_USD_SWAP.png?alt=media&#x26;token=0283a503-8600-403a-b3c3-41d73a33dd1b" alt=""><figcaption></figcaption></figure>

### Digital Asset → Digital Asset

1. calculate fee amount
2. send digital assets from end user virtual account to fees virtual account
3. send digital assets from end user virtual account to Liquidity account
4. send digital assets from Liquidity virtual account to end user virtual account

## Front End Integration

Use Orangepill API to show data in your front end application. IMPORTANT: to filter data related to specific user add identity filter in URL of API call. For example: `?holder=IDENTITY`

### List accounts

To list user accounts and it’s balances for specific user, call `accounts` endpoint and add `identity` as a filter.

```jsx
curl --location --request POST '<https://api.orangepill.cloud/v1/accounts?holder=IDENTITY>' \\
--header 'x-api-key: AXVubzpwQDU1dzByYM==' \\
--header 'Content-Type: application/json'
```

### List transactions

Use filter to display transactions related to source or destination account.

```jsx
curl --location --request POST '<https://api.orangepill.cloud/v1/transaction?source.account=ACCOUNT>' \\
--header 'x-api-key: AXVubzpwQDU1dzByYM==' \\
--header 'Content-Type: application/json'
```
