Notabene Integration (Travel Rule Compliance)
Notabene is the leading Travel Rule messaging provider with coverage of 500+ VASPs in 30+ countries. SDK available for JavaScript/TypeScript, Python and Go. Integration takes 1-2 weeks.
SDK Setup and Authentication
import { NotabeneSDK } from "@notabene/javascript-sdk";
const sdk = new NotabeneSDK({
audience: "https://api.notabene.id",
clientId: process.env.NOTABENE_CLIENT_ID,
clientSecret: process.env.NOTABENE_CLIENT_SECRET,
vaspDID: process.env.MY_VASP_DID,
});
Outgoing Transfer: Complete Flow
async function processOutgoingTransferTravelRule(withdrawal: Withdrawal) {
// 1. Identify beneficiary VASP
const { vasp: beneficiaryVASP } = await sdk.addresses.lookup({
address: withdrawal.destinationAddress,
asset: withdrawal.asset,
});
if (!beneficiaryVASP) {
// Unhosted wallet — separate procedure
await handleUnhostedWallet(withdrawal);
return;
}
// 2. Create transfer record
const transfer = await sdk.transfers.create({
transactionAsset: withdrawal.asset,
transactionAmount: withdrawal.amount.toString(),
originatorVASPdid: process.env.MY_VASP_DID,
beneficiaryVASPdid: beneficiaryVASP.did,
originator: buildOriginatorInfo(withdrawal.user),
beneficiary: { beneficiaryPersons: [], accountNumber: [withdrawal.destinationAddress] },
transactionBlockchainInfo: {
origin: withdrawal.fromAddress,
destination: withdrawal.destinationAddress,
},
});
// 3. Wait for confirmation (ACK or NACK from beneficiary VASP)
const confirmed = await waitForTransferConfirmation(transfer.id);
if (!confirmed) {
// Best-efforts: log and continue (most regulators accept this)
await logTravelRuleAttempt(withdrawal.id, transfer.id, "NO_RESPONSE");
}
// 4. Execute withdrawal
await executeBlockchainWithdrawal(withdrawal);
}
Incoming Transfer: Receiving Travel Rule Data
// Webhook from Notabene when Travel Rule data is received
app.post("/webhooks/notabene", async (req, res) => {
const { type, transfer } = req.body;
if (type === "transfer.created") {
await handleIncomingTravelRuleData(transfer);
}
res.status(200).send();
});
async function handleIncomingTravelRuleData(transfer: NotabeneTransfer) {
// Save received data
await db.saveTravelRuleRecord({
externalId: transfer.id,
senderVASP: transfer.originatorVASPdid,
originator: transfer.originator,
destinationAddress: transfer.transactionBlockchainInfo.destination,
asset: transfer.transactionAsset,
amount: transfer.transactionAmount,
});
// Confirm receipt
await sdk.transfers.update(transfer.id, { status: "ACK" });
}
Transfer Statuses and Processing
| Status | Meaning | Action |
|---|---|---|
| CREATED | Created, awaiting | Nothing |
| SENT | Sent to beneficiary VASP | Wait for response |
| ACK | Recipient confirmed | Execute transfer |
| NACK | Recipient refused | Cancel or escalate |
| EXPIRED | No response on timeout | Best-efforts → execute with log |
Notabene integration into deposit and withdrawal process, including webhook handling and unhosted wallet flow — 1-2 weeks.







