Using txCreate
You use txCreate to send the content of your travel rule message to Notabene and subsequently, to your counterparty:
For more details, you can check out the txCreate
full API reference here and at some postman examples in the section here.
Status jump
When you call txCreate, it will try to jump as far ahead as it can before returning the response.
This means that the status can be NEW in the response, or it can be SENT if you have rules configured to automatically perform that action if certain criterias are met.
txCreate content
txCreate contains quite a lot of data, and its payload can be broken down into three sections:
- Blockchain data
- Identifiers/references
- IVMS data
1. Blockchain data
Idempotency
Ensure to provide a idempotency key in the
transactionRef
field to prevent duplicate TR transfers and proactively manage disruptions arising from the idempotency key becoming mandatory in the future.If you pass the same key as a previous request, you can get two different responses:
a) You get a 409 error if the server has received the payload, but has not yet completed processing it;
b) If it is completed, you get a 200 status + the existing message in the response.
{
"transactionRef": "{{$randomUUID}}",
"transactionAsset": "BTC",
"transactionAmount": "{{$randomInt}}00000",
"transactionBlockchainInfo": {
"origin": "{{$randomBitcoin}}",
"destination": "{{$randomBitcoin}}"
}
}
transactionRef | Idempotency key. |
transactionAsset | The Notabene name of the asset being sent. |
transactionAmount | The amount of that asset is being sent, in its smallest denominator. |
origin | Where the asset is sent from (wallet address). |
destination | Where the asset is sent to (wallet address). |
2. Identifiers/references
{
"originatorVASPdid": "{{vaspDID}}",
"beneficiaryVASPdid": "{{vaspDIDse}}",
"beneficiaryRef": "[email protected]",
"originatorRef": "[email protected]",
}
}
originatorVASPdid | This is your DID as described here. |
beneficiaryVASPdid | This is the DID of the counterparty VASP, where you send the travel rule message. You get this from the widget or txValidateFull . |
beneficiaryRef | This is an internal reference that you can assign to the person your customer is sending to. It is also used when calling blockchain analytics. |
originatorRef | This is your internal reference for your own customer. |
Additional options:
beneficiaryVASPname
: if the counterparty VASP you are looking to send a TR transfer to is not in the Network, you can provide the name of the VASP in this field as a string and a request to add a new VASP in the network will be created- If you do not know who the counterparty of the transaction is, you can still create the TR transfer by enabling the
skipBeneficiaryDataValidation
flag true.
3. IVMS data
IVMS (InterVASP messaging system) data is where you will put all of the PII data of the involved parties in the transaction and is nested below the beneficiary
and originator
sections of the payload.
One critical thing to keep in mind is that these two sections have two layers of validation:
- the jurisdictional requirements of the jurisdiction where the originatorVASP is incorporated, you can check them using our jurisdictions endpoint
- the IVMS fields requirements, such as the one for a valid
geographicAddress
, you can check the technical standard for all the details.
"originator": {
"originatorPersons": [
{
"naturalPerson": {
"name": [
{
"nameIdentifier": [
{
"primaryIdentifier": "{{$randomLastName}}",
"secondaryIdentifier": "{{$randomFirstName}}"
}
]
}
],
"geographicAddress": [
{
}
],
"nationalIdentification": {
}
}
}
],
"accountNumber": [
"{{$randomBitcoin}}"
]
},
"beneficiary": {
"beneficiaryPersons": [
{
"naturalPerson": {
"name": [
{
"nameIdentifier": [
{
"primaryIdentifier": "{{$randomLastName}}",
"secondaryIdentifier": "{{$randomFirstName}}"
}
]
}
]
}
}
],
"accountNumber": [
"{{$randomBitcoin}}"
]
}
Unhosted wallets
If your customer has declared that the destination wallet is unhosted
, either using the widget or txValidateFull:
If the transfer is going to an unhosted wallet, there is no beneficiaryVASPdid
in the txCreate payload. Instead, you need to add the beneficiaryProof to your txCreate payload:
"beneficiaryProof": {
"proof": "0x3be0fccefc6b5daaa55c942436c89a789dad1067967a336cba5e7bed92cd429568a9277841e1836748509a7987212f59e6a1e6994ba397de91624e6da6f763c61b",
"attestation": "I certify that ETH account 0x7bf5D5Cc990cbFb3f170a36C5579B45dC757E57c belonged to did:ethr:0x010484208e7267a00ad5ebb23517abf5c14d97e3 on Wed, 11 Sep 2024 01:17:40 GMT",
"type": "eip-191"
}
If another VASP does not host the destination wallet (non-custodial wallet), you need to add the beneficiaryProof
object to your txCreate payload.
- Since the travel rule message cannot be sent to an unhosted wallet, the final status for these is
SAVED
.
beneficiaryVASPdid
There should be NO beneficiaryVASPdid or beneficiaryVASPname in the txCreate payload if the wallet is unhosted. Adding any of those will change the type of the message and you might not be compliant with your regulation.
Preparing the content
- Ensure you use the correct number of decimal points in the amount.
- make sure you have the counterparty identified or have the
skipBeneficiaryDataValidation
flag enabled - Are you going to also comply with the jurisdictional requirements of the beneficiary VASP when sending the travel rule message? Then you need txValidateFull
- Have you already executed the value transfer on the blockchain? If so, you can add the
txhash
already. - Is the value transfer going to or from a natural or legal person?
Non-Latin characters
According to the IVMS101 standard:
" Data shall be submitted using UTF-8 character encoding. Unless otherwise specified, data shall be represented in Latin script (i.e. A to Z, a to z) and Arabic numerals (i.e. 1234567890)".
Where data is in a national language that does not use Latin script, it must be either:
• Transliterated into Latin characters; or
• Translated into a language to which it may be more commonly known to the international community.Some fields support national language when the elements are prefixed ‘local’.
You can see a list of scripts and which standard to use for transliteration on page 50-51.
Sending coins that have a memo/tag
If you are sending a virtual asset that has a unique ID in addition to the wallet address to identify the correct recipient, please follow our guide here.
Examples
Example | Description | Link |
---|---|---|
TransactionAsset - Polymorphic | Three ways of specifying which asset and network | here |
Postman - all display fields | Request all fields visible in the Notabene dashboard | here |
Postman - using travelRuleBehavior | Checking both jurisdictions against thresholds | here |
Postman - using skipBeneficiaryDataValidation | Creating without beneficiary details | here |
Postman - adding customerRef | Provide your customerRef to easily link a message to the user | here |
Postman - with txHash | If you are sending the message once the value transfer happens | here |
Postman - with non-Latin characters | Using non-Latin characters in the message | here |
Postman - using addressLine | If your customers address is in a single string | here |
Postman - using address fields | If your customers address is separated into fields | here |
Postman - legalPerson | If the counterparty is a company | here |
Postman - coins with tag/memo | Providing the tag or memo as the accountNumber | here |
Postman - unknown VASP | If the beneficiary VASP is not currently in the network | here |
Postman - unhosted wallet | Sending to an unhosted wallet with beneficiaryProof | here |
Postman - complete IVMS101 | With all the possible fields in IVMS101 | here |
Unknown origin wallet
If you don't know which wallet address the virtual assets will be sent from when the travel rule message is created, you can append it later using txUpdate:
POST https://api.notabene.dev/tx/update
{
"id": "{{txID}}",
"origin": "{{$randomBitcoin}}"
}
We suggest you do this at the same time as you're adding the transaction hash.
Calling txCreate for a UTXO transaction
WIP
Going to multiple destinations
Here, you would create txCreate 10 times:
// Message 1:
{
"transactionRef": "{{$randomUUID}}",
"transactionAsset": "BTC",
"transactionAssetDecimals": 8,
"transactionAmount": "000100000",
"originatorVASPdid": "{{vaspDID}}",
"beneficiaryVASPdid": "{{vaspDIDse}}",
"beneficiaryRef": "[email protected]",
"originatorRef": "[email protected]",
"transactionBlockchainInfo": {
"origin": "bc1q6aj79aj75e4wqfq7tukeu4w2r3udczkkwr4ms7",
"destination": "bc1qlnwcj7vx0r9tsut334davfhjtcneejn0fdpcjx"
},
...
// Message 2:
{
"transactionRef": "{{$randomUUID}}",
"transactionAsset": "BTC",
"transactionAssetDecimals": 8,
"transactionAmount": "000046160",
"originatorVASPdid": "{{vaspDID}}",
"beneficiaryVASPdid": "{{vaspDIDse}}",
"beneficiaryRef": "[email protected]",
"originatorRef": "[email protected]",
"transactionBlockchainInfo": {
"origin": "bc1q6aj79aj75e4wqfq7tukeu4w2r3udczkkwr4ms7",
"destination": "bc1qqy204a7z4a36y0zr0sr6j65kaycewp5dnm8d0u"
},
// Message 3:
etc.
Coming from multiple wallets
Scenario 1:
This is the same as above. Even if there are multiple outputs, they are all from the same wallet.
Scenario 2:
Calling txCreate with a new beneficiary VASP
WIP
Updated 1 day ago