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:

  1. Blockchain data
  2. Identifiers/references
  3. 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}}"
    }
}
transactionRefIdempotency key.
transactionAssetThe Notabene name of the asset being sent.
transactionAmountThe amount of that asset is being sent, in its smallest denominator.
originWhere the asset is sent from (wallet address).
destinationWhere the asset is sent to (wallet address).

2. Identifiers/references

{
    "originatorVASPdid": "{{vaspDID}}",
    "beneficiaryVASPdid": "{{vaspDIDse}}",
    "beneficiaryRef": "[email protected]",
    "originatorRef": "[email protected]",
    }
}
originatorVASPdidThis is your DID as described here.
beneficiaryVASPdidThis is the DID of the counterparty VASP, where you send the travel rule message. You get this from the widget or txValidateFull .
beneficiaryRefThis is an internal reference that you can assign to the person your customer is sending to. It is also used when calling blockchain analytics.
originatorRefThis 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:

Widget

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

ExampleDescriptionLink
TransactionAsset - PolymorphicThree ways of specifying which asset and networkhere
Postman - all display fieldsRequest all fields visible in the Notabene dashboardhere
Postman - using travelRuleBehaviorChecking both jurisdictions against thresholdshere
Postman - using skipBeneficiaryDataValidationCreating without beneficiary detailshere
Postman - adding customerRefProvide your customerRef to easily link a message to the userhere
Postman - with txHashIf you are sending the message once the value transfer happenshere
Postman - with non-Latin charactersUsing non-Latin characters in the messagehere
Postman - using addressLineIf your customers address is in a single stringhere
Postman - using address fieldsIf your customers address is separated into fieldshere
Postman - legalPersonIf the counterparty is a companyhere
Postman - coins with tag/memoProviding the tag or memo as the accountNumberhere
Postman - unknown VASPIf the beneficiary VASP is not currently in the networkhere
Postman - unhosted walletSending to an unhosted wallet with beneficiaryProofhere
Postman - complete IVMS101With all the possible fields in IVMS101here


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