5. Checking blockchain deposits
Using txNotify check for travel rule messages
Every time your VASP receives a blockchain deposit, you can use txNotify to check if it has travel rule data:
{
"txHash": "0xc93e0d531a233fe207808feb3c9d224694fa8c5313ac59ff54ef50f67e1aa55a",
"transactionAmount": "1234000000000000",
"transactionAsset": "ETH",
"beneficiaryVASPdid": "{{vaspDID}}",
"destination": "0x95dceec19dcc8ea575e4acc9ded3e800b4170fda",
"origin": "0x061f7937b7b2bc7596539959804f86538b6368dc"
}
When you call txNotify, it will look into your received travel rule messages, and if we find a corresponding one that matches txHash
+ origin
address + destination
address + beneficiaryVASPdid
, it will return the details of that travel rule message.
Delay in adding txHash
Since the txNotify checks if there is a matching transaction hash to see if there is a travel rule message for it, this only works if the hash has been added by the originating VASP, after the value transfer has been processed on the blockchain.
In some cases it might take them a short while to add the hash, so we recommend having a small delay between recieving the deposit and calling txNotify for it.
You can also call txNotify with the same payload multiple times with an exponential delay in between retries. If the originator VASP suddenly adds the hash between those retries, txNotify will return the actual travel rule message instead of the one that was created as "incomplete."
The retries should probably not last longer than 1 hour.
If you do txNotify bfore the originating VASP has added the txHash to the travel rule message, you will end up with two "duplicates". You can keep both versions or cancel the one that is incomplete, if the data hasn't already been collected from the person receiving the deposit and added to the incomplete one.
If that corresponding message has been "ACCEPTED", you can release the funds to your customer. If it is still pending, you should withhold the funds until the travel rule information has been reviewed by the compliance team.
{
"id": "c5e0569a-edee-48ea-8946-9320fcdf9611",
"status": "ACCEPTED",
"transactionType": "TRAVELRULE",
"transactionAsset": "BTC",
"transactionAmount": "1234000000000000",
"chargedQuantity": 313078140000,
"showToBeneficiary": true,
"originatorDid": null,
"beneficiaryDid": "did:ethr:0x86f5388895c840b6b9ff45045df751e3bb8ee761",
"originatorVASPdid": "did:ethr:0x940a4b2a0932733b842e4aa906761bb3d3bd8148",
"beneficiaryVASPdid": "did:ethr:0xd4bd902ec78578f33a20ff601504d2ab324cfab9",
"transactionBlockchainInfo": {
"txHash": "0xc93e0d531a233fe207808feb3c9d224694fa8c5313ac59ff54ef50f67e1aa55a",
"origin": "0x061f7937b7b2bc7596539959804f86538b6368dc",
"destination": "0x95dceec19dcc8ea575e4acc9ded3e800b4170fda"
},
If no corresponding travel rule data for the transaction hash is found, a new one will be automatically created with the available data from your txNotify request. This travel rule message will be created with the INCOMPLETE status:
{
"id": "c5e0569a-edee-48ea-8946-9320fcdf9611",
"status": "INCOMPLETE",
"transactionType": "TRAVELRULE",
"transactionAsset": "BTC",
"transactionAmount": "1234000000000000",
"chargedQuantity": 313078140000,
"showToBeneficiary": true,
"originatorDid": null,
"beneficiaryDid": "did:ethr:0x86f5388895c840b6b9ff45045df751e3bb8ee761",
"originatorVASPdid": "did:ethr:0x940a4b2a0932733b842e4aa906761bb3d3bd8148",
"beneficiaryVASPdid": "did:ethr:0xd4bd902ec78578f33a20ff601504d2ab324cfab9",
"transactionBlockchainInfo": {
"txHash": "0xc93e0d531a233fe207808feb3c9d224694fa8c5313ac59ff54ef50f67e1aa55a",
"origin": "0x061f7937b7b2bc7596539959804f86538b6368dc",
"destination": "0x95dceec19dcc8ea575e4acc9ded3e800b4170fda"
},
"createdBy": "did:ethr:0xefbb14b73473ccfd610543af4b1c8fda027c57bf",
"updatedBy": "did:ethr:0xefbb14b73473ccfd610543af4b1c8fda027c57bf",
"isTest": null,
"ivms101": null,
"ivms101Encrypted": null,
"protocol": null,
"protocolData": null,
"originatorProof": null,
"beneficiaryProof": null,
"originatorPIIref": null,
"beneficiaryPIIref": null,
"createdAt": "2022-06-13T03:36:33.482Z",
"updatedAt": "2022-06-13T03:36:33.482Z"
}
OriginatorVASPdid information might be automatically returned if you have previously interacted with the origin blockchain address or if it identified by blockchain analytics. If the origin address is unknown, it will return "originatorVASPdid": null.
Extra
See the Sequence Diagrams for deposits that cover both of the scenarios above.
Completing an incomplete travel rule message
Depending on your jurisdiction, you might need to implement policies that dictates what you do with an incoming deposit that does not have travel rule information:
Lacking value transfer information
A payment service provider that is a beneficiary institution shall implement appropriate
internal risk-based policies, procedures and controls for determining ⎯
(a) when to execute, reject, or suspend a value transfer lacking required value
transfer originator or value transfer beneficiary information; and
(b) the appropriate follow-up action.Or, from another jurisdiction:
- The beneficiary TT Service Provider sets up effective, risk-based procedures with the help of which it can be determined whether a TT Transfer is to be rejected or suspended due to information that is not transmitted, not in accordance with the regulations, is incomplete or delayed in accordance with Art. 23d, and which further measures are to be taken are to be met.
- If the beneficiary TT Service Provider establishes that information pursuant to Art. 23d was not transmitted, not in accordance with the regulations, incomplete or late, it must reject the TT transfer order on a risk-oriented basis or provide the prescribed information pursuant to Art. 23d, setting a deadline of request three days. A TT transfer may only be completed once the requested data has been transmitted and made available to the TT beneficiary.
Also,
In the case of a transfer received by the VASP's client (beneficiary) from a third-party unhosted wallet, if information is missing or incomplete, the VASP of the beneficiary should decide on a risk basis whether to execute or block the transfer.
The VASP should also take into account missing or incomplete information, as well as potential inaccurate information, when assessing whether the transfer should be reported as suspicious to the FIU.
If your jurisdiction or internal policy requires this, there are a few ways to gather the required information you need to complete the travel rule message:
- Before releasing the funds to the recipient, ask them to provide details about the originator.
- If the originating VASP is identifiable and reachable, Notabene will automatically send a message to them and request that a travel rule message is sent.
- If neither of the options above are possible, you need to decide if you release the funds or withhold them until you have the information you need.
To facilitate the collection of information in #1, you can either set up an email that is sent to the beneficiary that asks for it, or create a page where customers go to fill it in:
You have received 1234 BTC from 0x061f7937b7b2bc7596539959804f86538b6368dc.
The transaction hash of this deposit is: 0xc93e0d531a233fe207808feb3c9d224694fa8c5313ac59ff54ef50f67e1aa55a.
Since the amount requires us to verify the originator before we can credit them to your account, please provide the following details:
First name: Bruce
Last name: Wayne
For Singapore requirements, also provide one of the following:
1. Address information
Building number:
Street:
City:
Country:
2. Date and place of birth
Date of Birth:
Place of Birth:
3. National ID
ID number: 123EE22
ID type: DRLC
Country of issue: DC
Our reference: cad5d297-d2df-41c9-b2d7-53c131f71927
SUBMIT
Can I collect originator information from my customer?
Further, countries should ensure that beneficiary institutions
(whether a VASP or other obliged entity, such as a FI) obtain and hold required (but
not necessarily accurate) originator information and required and accurate
beneficiary information, as set forth in INR. 16
Clicking on "submit" triggers txUpdate below.
Updating an incomplete travel rule message
Once you have collected the missing information, txUpdate can be used together with the travel rule ID and the other details to update the incomplete travel rule message:
{
"id": "c5e0569a-edee-48ea-8946-9320fcdf9611",
"originatorVASPdid": "did:ethr:0x940a4b2a0932733b842e4aa906761bb3d3bd8148",
"originatorVASPname": "",
"originator": {
"originatorPersons": [
{
"naturalPerson": {
"name": [
{
"nameIdentifier": [
{
"primaryIdentifier": "Wayne",
"secondaryIdentifier": "Bruce"
}
]
}
],
"nationalIdentification": {
"countryOfIssue": "DC",
"nationalIdentifier": "123EE22",
"nationalIdentifierType": "DRLC"
}
}
}
],
"accountNumber": [
"0x061f7937b7b2bc7596539959804f86538b6368dc"
]
},
"beneficiary": {
"beneficiaryPersons": [
{
"naturalPerson": {
"name": [
{
"nameIdentifier": [
{
"primaryIdentifier": "Wunderland",
"secondaryIdentifier": "Alice"
}
]
}
]
}
}
],
"accountNumber": [
"123456789"
]
}
}
Requesting the originating VASP to provide all details
{
"id": "c5e0569a-edee-48ea-8946-9320fcdf9611",
"originatorVASPdid": "did:ethr:0x049fc13a4f1e79d4d03f082ca96758179a91da29"
}
This will create an incomplete travel rule message for the originating VASP where they can provide the information about both the originator and the beneficiary.
Requesting the originating VASP to provide originator details
{
"id": "c5e0569a-edee-48ea-8946-9320fcdf9611",
"originatorVASPdid": "did:ethr:0x049fc13a4f1e79d4d03f082ca96758179a91da29",
"beneficiary": {
"beneficiaryPersons": [
{
"naturalPerson": {
"name": [
{
"nameIdentifier": [
{
"primaryIdentifier": "Wunderland",
"secondaryIdentifier": "Alice"
}
]
}
]
}
}
],
"accountNumber": [
"{{$randomBankAccount}}"
]
}
}
This will create an incomplete travel rule message for the originating VASP where they can provide the information about the originator.
The deposit came from an unhosted wallet
If you have identified the deposit as coming from an unhosted wallet, you can flag this when calling txUpdate by including the following flag: isNonCustodial: true
, together with the rest of the information required in your jurisdiction for this type.
{
"id": "{{txID}}",
"isNonCustodial": true,
"originator": {
"originatorPersons": [
{
"naturalPerson": {
"name": [
{
....
}
]
}
}
],
"accountNumber": [
"{{$randomBankAccount}}"
]
},
"beneficiary": {
"beneficiaryPersons": [
{
"naturalPerson": {
"name": [
{
....
}
]
}
}
],
"accountNumber": [
"{{$randomBankAccount}}"
]
}
}
Statuses for txNotify
Status flow
txNotify = ACCEPTED / REJECTED
txNotify = INCOMPLETE
txUpdate = SENT
txConfirm = ACK
txAccept/txReject = ACCEPTED / REJECTED
When calling txNotify:
a) If there is an existing travel rule message that matches the blockchain transaction details, it will return ACCEPTED or REJECTED.
b) If there is none, one will be created with INCOMPLETE status.
When calling txUpdate:
a) If you add the full set of information (originator VASP + originator + beneficiary) in the txUpdate call, it will go to SENT and from there it follows the standard travel rule flow as if it was sent from that VASP to you. This means that you need to confirm the address, then make a decision on either accepting or rejecting (keep in mind that you've already recieved the viritual assets), exactly as you would when reciveing a travel rule message.
b) If you do not add the full set of information, it will still be in INCOMPLETE status.
Calling txNotify too fast
Please see the below diagram of what happens when txNotify is called too soon, or if the originator deviates from the normal txCreate flow:
UTXO
If your deposit originates from multiple wallets, you can call txNotify once per originating wallet, so 10 times with the example below, or do it once without providing the "origin" address. That way, it will return the travel rule message matching the txHash + destination.
{
"txHash": "{{$randomUUID}}",
"transactionAmount": "6999000000",
"transactionAsset": "BTC",
"destination": "1AJ6Diengzacqh7RyKH4aswrCfggmhx54Y",
"origin": "1GXFT29AejdaMDi4Uy4xmwr5MKA4HckPgP",
"beneficiaryVASPdid": "{{vaspDID}}",
"customerRef": "[email protected]"
}
Updated 5 days ago