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.