Transfer payload structure

Learn about Notabene's flexible agent-based model for cryptocurrency transfers, including roles, chains, and multi-party scenarios.


Overview

Notabene's transfer structure uses a flexible agent-based model to represent all parties involved in a cryptocurrency transfer, from simple peer-to-peer transactions to complex multi-party flows.

Basic Structure

{
  "originator": {
    "@id": "alice.example.com"
  },
  "beneficiary": {
    "@id": "bob.example.com"
  },
  "asset": "BTC" // or CAIP19 standard: bip122:000000000019d6689c085ae165831e93/slip44:0",
  "amount": "0.003",
  "agents": [
    // Agent details here
  ],
  "ref": "unique-transfer-id"
}

Understanding Agents

Agents represent the entities and wallets involved in executing the transfer. Each agent has:

  • @id: Unique identifier (DID - Decentralized Identifier, or Wallet address)
  • for: Who this agent represents
  • role: (Optional) The agent's function in the transfer

The for field is key to understanding transfer flows, creating chains of relationships that determine transfer direction, compliance requirements, and message routing.

Common Agent Roles

While the role field is optional and primarily descriptive, these common values help document the transfer structure:

  • VASP: Virtual Asset Service Provider (exchange, wallet service, etc.)
  • Custodian: Entity holding assets on behalf of a VASP
  • SourceAddress: The blockchain address sending the assets
  • SettlementAddress: The blockchain address receiving the assets

Agent Chains

Agents form chains through their for field.

Typical chain structure:

SourceAddress → originatorVASP → originator
SettlementAddress → beneficiaryVASP → beneficiary

Or with custodians:

SettlementAddress → custodian → beneficiaryVASP → beneficiary

Complete Example
{
  "originator": {
    "@id": "alice.example.com"
  },
  "beneficiary": {
    "@id": "bob.example.com"
  },
  "asset": "bip122:000000000019d6689c085ae165831e93/slip44:0",
  "amount": "0.003",
  "agents": [
    {
      "@id": "did:pkh:bip122:000000000019d6689c085ae165831e93:bc1qn9y...rld0f",
      "for": "did:web:vasps.id:exchange-a:us",
      "role": "SourceAddress"
    },
    {
      "@id": "did:web:vasps.id:exchange-a:us",
      "for": "alice.example.com",
      "role": "VASP"
    },
    {
      "@id": "did:web:vasps.id:custodian-x:jp",
      "for": "did:web:vasps.id:exchange-b:uk",
      "role": "Custodian"
    },
    {
      "@id": "did:web:vasps.id:exchange-b:uk",
      "for": "bob.example.com",
      "role": "VASP"
    },
    {
      "@id": "did:pkh:bip122:000000000019d6689c085ae165831e93:bc1q7av...ucrg",
      "for": "did:web:vasps.id:exchange-b:uk",
      "role": "SettlementAddress"
    }
  ],
  "ref": "550e8400-e29b-41d4-a716-446655440000"
}

This example shows:

  • Alice's funds originate from address bc1qn9y...rld0f controlled by Exchange A
  • Exchange A is Alice's VASP
  • Custodian X holds assets for Exchange B
  • Exchange B is Bob's VASP
  • Bob receives funds at address bc1q7av...ucrg
NameExplanation
originator.@idThe DID/IRI of your customer
beneficiary.@idThe DID/IRI of the person your customer is sending to
assetThe CAIP19 ID or Notabene asset abbreviation of the asset/token being sent
amountThe number of that asset being sent, use decimals where needed
agents.@idThe DID of the wallet or VASP
agents.foracting on behalf of
agents.roleWhat role the @id has to the "for"
refThe idempotency key

The different roles available:

RoleExplanation
SourceAddressThe wallet where the funds are going from
VASPVirtual Asset Service Provider
CustodianProviding custody services to VASPs
SettlementAddressThe wallet where the funds are going to

Multi-Party Scenarios

Custodial Arrangements

Many VASPs use third-party custodians to hold assets. The agent structure represents these relationships:

{
  "agents": [
    {
      "@id": "did:web:vasps.id:prime-custody:us",
      "for": "did:web:vasps.id:retail-exchange:de",
      "role": "Custodian"
    },
    {
      "@id": "did:web:vasps.id:retail-exchange:de",
      "for": "bob.example.com",
      "role": "VASP"
    },
    {
      "@id": "did:pkh:bip122:000000000019d6689c085ae165831e93:bc1q7av...ucrg",
      "for": "did:web:vasps.id:retail-exchange:de",
      "role": "SettlementAddress"
    }
  ]
}

The settlement address is controlled by the retail exchange, but custody is with Prime Custody. The for chain makes this relationship explicit: SettlementAddress → VASP → beneficiary and Custodian → VASP.


Partial Information Scenarios

The agent structure is flexible, handling cases where not all information is known at transfer creation time.


Missing Source Address

When the originating VASP creates a transfer but hasn't determined the sending address:

{
  "agents": [
    {
      "@id": "did:web:vasps.id:my-exchange:de",
      "for": "alice.example.com"
    },
    {
      "@id": "did:web:vasps.id:their-exchange:jp",
      "for": "bob.example.com"
    },
    {
      "@id": "did:pkh:bip122:000000000019d6689c085ae165831e93:bc1q7av...ucrg",
      "for": "did:web:vasps.id:their-exchange:jp",
      "role": "SettlementAddress"
    }
  ]
}

Missing Settlement Address

When the beneficiary VASP hasn't assigned a receiving address:

{
  "agents": [
    {
      "@id": "did:pkh:bip122:000000000019d6689c085ae165831e93:bc1qn9y...rld0f",
      "for": "did:web:vasps.id:my-exchange:us",
      "role": "SourceAddress"
    },
    {
      "@id": "did:web:vasps.id:my-exchange:us",
      "for": "alice.example.com"
    },
    {
      "@id": "did:web:vasps.id:their-exchange:ca",
      "for": "bob.example.com"
    }
  ]
}

First-Party Transfers

When the same person is both originator and beneficiary (e.g., moving funds between their own accounts at different VASPs):

{
  "originator": {
    "@id": "alice.example.com"
  },
  "beneficiary": {
    "@id": "alice.example.com"
  },
  "agents": [
    {
      "@id": "did:web:vasps.id:exchange-a:us",
      "for": "alice.example.com"
    },
    {
      "@id": "did:web:vasps.id:exchange-b:uk",
      "for": "alice.example.com"
    }
  ]
}

Did this page help you?