Skip to content

Step 5: Perform a transfer

With Qredo, a transfer transaction means to move assets from one Qredo wallet (originating) ID to another Qredo wallet (destination) ID. Note that when we talk a transfer on the Qredochain, this is a L2 to L2 transaction and the wallets are identified by their IDs and not their wallet addresses. Naturally, the transfer flow means you submit a transfer request which will remain in pending status until custody approval / rejection or expiry.

Use wallet IDs for transfers

From a Qredo standpoint, L2 wallets on both sides of a transfer transactions are always identified by their wallet IDs and never by their L1 addresses.

From an approver's standpoint, the transfer transaction is also called a transfer out transaction.

To complete this step, you must:

  1. Use GET /fund to retrieve your Qredo wallet ID.
  2. Use POST /transfer to submit transfer request.
  3. Wait for custodial approval to take place.
  4. Use GET /transfer/{tx_id} to verify that the transaction is approved.

1. Retrieve wallet ID

This example retrieves detailed information about the fund, including the custodial policies, list of trusted network members, and all wallets that belong to the fund.

Example request: GET /fund

With this request, you pass company_id and the fund_id as URL parameters.

curl -X GET "https://play-api.qredo.network/api/v1/p/company/{company_id}/fund/{fund_id}"

No body parameters are sent with this request.

Example response: GET /fund

The response returns a large object with fund-specific data. For sake of brevity, objects and lists are collapsed in the example.

{
  "fund_id": "<ID of your fund>",
  "name": "<name of your fund>",
  "description": "<description of your fund>",
  "custodygroup withdraw": "<fund custodial policy ID for withdrawals>",
  "custodygroup tx": "<fund custodial policy ID for transactions>",
  "policy withdraw": "<object containing fund withdraw policy info>",  
  "policy tx": "<object containing fund withdraw policy info>",
  "members": "<list of fund trusted members and details of each>",
  "assets": "<list of supported assets in your fund>",
  "wallets": [
    {
      "wallet_id": "<ID of wallet>",
      "name": "<wallet name>",
      "asset": "BTC-TESTNET",
      "type": 0,
      "status": "ready",
      "address": "n3L2rkVup9xGbCfP4rnoJZJF5MqJFAiBS1",
      "address_type": "P2PKH",
      "short_code": "<firstword secondword thirdword>",
      "balance": 10000,
      "custodygroup_withdraw": "<wallet custodial policy ID for withdrawals>",
      "custodygroup_tx": "<wallet custodial policy ID for transactions>",
      "policy_withdraw": "<object containing wallet withdraw policy info>",
      "policy_tx": "<object containing wallet withdraw policy info>"
    }
  ]
}

Note that a wallet always holds one asset type. In this example, there are 10000 satoshis worth of BTC-TESTNET available in the wallet.

Shortcodes vs wallet IDs

Wallets on the Qredo Network have short_code values which are interchangeable with wallet IDs. The "short code" is a combination of three unique English words separated by space intervals, in the format:

"short_code": "firstword secondword thirdword".

To view the short code of a wallet, you can either call GET fund/{fund_id} or GET wallet/{wallet_ID}.

This example does not provide a specific combination of shortcode words as it may turn out to correspond to an actual wallet on the Qredo Network.

2. Submit a transfer request

This example submits a request for transferring assets from one Qredo wallet to another.

Example request: POST /transfer

This example submits a transfer request. With this API resource, you pass company_id as a URL parameter.

curl POST "https://api.qredo.network/api/v1/p/company/{company_id}/transfer"

Request body

All described fields are required. Note the distinction the originating wallet is specified by wallet_id while the destination wallet is defined by counterparty_wallet_address.

{
  "wallet_id": "<wallet ID of origin wallet: not the address>",
  "counterparty_wallet_address": "<wallet ID of destination wallet: not the address>",
  "expires": "<Epoch timestamp when transfer request expires if not approved>",
  "benefit_of": "<beneficiary name",
  "account_no": "<account number: a custom field>",
  "reference": "<reference value: a custom field>",
  "partner_txID": "<a transaction ID: a custom field>",
  "send": {
    "symbol": "<asset symbol (BTC, ETH, etc.)>",
    "amount": "<asset amount (satoshis, gweis, etc.)>"
  }
}

Use shortcodes instead of both wallet IDs

As a reminder, note that with transactions, you can use short codes instead of:

  • wallet_id - interchangeable with short_code value of origin wallet.
  • counterparty_wallet_address - interchangeable with short_code value of destination wallet.
TX request body: use partner_txID to prevent duplicate transactions

The partner_txID is a custom parameter, and is used as a separate unique identifier of this transaction. This might be an ID with a system external to Qredo, that you want to map the current transaction to, so its value is coupled with the specific tx_id. This allows you to:

  • map a tx_id to another identifier which is unique in whatever way you choose.
  • prevent you from making a duplicate transaction with the same partner_txID. If you try to re-use this ID, the response of POST /transfer you will return the tx_id value of the original transaction with that partner_txID and with "status": "existing".
Summary: use partner_txID to prevent duplicate transactions

The partner_txIDs is a custom parameter, an external a unique identifier of this transaction that you can map the current transaction to. Qredo stores its value and will prevent you from making a duplicate transaction: one with the same partner_txID.

Example response: POST /transfer

A successful response returns the transaction ID and transfer request status.

{
  "tx_id": "<transaction ID>",
  "status": "new"
}

View tx status using tx_id

From this point on, completion of the transfer is pending custodial actions. Save the tx_id to view the transaction status. The Partner API offers several API calls that pass the tx_id of transactions.

3. Undergo custodial approval

The custodial approval process is outside the scope of this tutorial. We assume the transfer transaction is approved in order for this step to be completed.

4. View transaction status

As in a regular case you might not know when the custodial process is complete, you can check the transaction status using the GET /transfer/{tx_id} API resource.

Example request: GET /transfer/{tx_id}

This example retrieves transfer transaction info. With this API resource, you pass company_id and the transfer tx_id as URL parameters.

curl -X GET /company/{company_id}/transfer/{tx_id}

No body parameters are sent with this request.

Example response: GET /transfer/{tx_id}

A successful response returns an object containing transaction-specific data.

{
  "approvedCount": "<number of custody approvals>",
  "expires": "<Epoch timestamp when tx request expires if not approved>",
  "initiatedTimestamp": "<Epoch timestamp when tx request is initiated>",
  "initiatorAuthorized": "<a flag if tx underwent custody: 'true' or 'false'>",
  "initiatorName": "<name of initiator company>",
  "reference": "<your reference>",
  "status": [
    {
      "actionID": "<action ID>",
      "firstName": "<approver first name>",
      "lastName": "<approver first name>",
      "status": "<approval status with current approver: e.g. 'approved'>",
      "timestamp": "<Epoch time when custody action took place>",
      "userID": "<approver user ID>", 
      "username": "<approver Qredo account>"
    }
  ],
  "statusDetails": {
    "accountNo": "123-XX",
    "amount": "<tx amount in base units>",
    "asset": "<asset symbol: BTC, ETH, etc.>",
    "benefitOf": "<recipient full name>",
    "expires": 0,
    "fees": 1,
    "fundID": "<fund ID>",
    "netAmount": 800,
    "recipientAddress": "<destination wallet ID>",
    "recipientEmail": "<destination account email address>",
    "recipientFirstName": "<recipient first name>",
    "recipientLastName": "<recipient last name>",
    "recipientUsername": "<recipient Qredo account>",
    "reference": "CX15R99XX",
    "requestedBy": "Rosa Parks" 
  },
  "thresholdRequired": "<number of required custody approvals>",
  "txID": "<transaction id>",
  "txStatus": "<tx status: pending, approved, rejected, expired>" 
}

Details on some tx-specific objects

  • approvedCount: the number of approvals. With approved transactions this value is the same as the value of thresholdRequired.
  • status: an object with user data about each approver of the transaction, including their userID, and username, etc. Obviously, the number of status objects returned must correspond to the approvedCount value.
    • With Core Client transactions, firstName, lastName and username fields under status are blank and userID is the Core Client ID.
  • statusDetails: details including fees incurred, the net amount transferred, and recipient / beneficiary info, etc.

Once approved, the transfer is written to the Qredo Blockchain.


Last update: 2022-07-28