Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Outgoing Transactions

This page walks you through each step of sending funds to a beneficiary at another VASP, including address discovery and responding to TRP approvals or rejections using the 21 Travel Rule API.

Setting the Scene

In this scenario, your customer is the originator. The customer wants to withdraw funds to a beneficiary who is a customer of a third party VASP, a.k.a. a counterparty VASP.

In this guide, the necessary steps are listed to integrate the described scenario using the 21 Travel Rule GraphQL API.

Accept Travel and Wallet Addresses in UI

The customer facing UI needs to accept Travel Addresses and wallet addresses in the same field.

Your customer can paste either address received from the beneficiary.

Discover the Counterparty and Send Travel Rule Data

Use the { autod { sendTxToAddrOwner } } mutation with the destination address and IVMS101 data, including the asset, amount, originator, and beneficiary name:

mutation Send($address: String!, $ivms101: TrustdTxDetailsInput!) {
    autod {
        sendTxToAddrOwner(address: $address, ivms101: $ivms101) {
            __typename
            ... on TrpdTx {
                trpd {
                    id
                }
            }
            ... on TrustdTx {
                trustd {
                    id
                }
            }
        }
    }
}

The mutation uses TRP for a Travel Address or a wallet address found in the TRP directory. Otherwise, it checks TRUST for the wallet address owner. Provide ivms101.txId when the transaction has already been executed; it is required if TRUST handles the notification. For TRP, submit the TxID after approval using trpd.confirmTx. If neither protocol finds an owner, use encrypted email with a selected counterparty VASP.

The returned __typename identifies the protocol. A TrustdTx means the Travel Rule data has been sent through TRUST. For a TrpdTx, continue with the TRP approval or rejection flow below.

Note that if the VASP corresponding to the Travel Address is unknown, it will be automatically added to the counterparty VASP table as untrusted and the TRP message is only sent after it has been marked as trusted.

React to TRUST Events

The { trustdTransactions } subscription will emit events whenever a TRUST transaction is received, returning a complete TrustdTxDetails object. You can listen to the subscription using the integration client SDK.

React to TRP Events

The { trpdTransactions } subscription will emit events whenever a TRP transaction's status changes, returning a complete TrpdTxUnion object. You can listen to the subscription using the integration client SDK.

At some point, you will receive TRP approval or rejection messages from your counterparty VASP about your inquiries through TRP. You can identify them using the status and type fields on the object returned from the subscription.

In case of an approval, you can proceed by executing the transaction on the blockchain using the beneficiary.walletAddress field on the returned object as a recipient address. Then, the resulting transaction ID needs to be submitted to the { trpd { confirmTx } } mutation to finalise the TRP protocol flow.

In case of a rejection, there's no further steps required for TRP. However, you should notify your user about the declined transaction. Maybe the counterparty VASP has provided a reason in the comment field.