Skip to content

Latest commit

 

History

History
352 lines (306 loc) · 17.3 KB

travel_rule_data_exchange.md

File metadata and controls

352 lines (306 loc) · 17.3 KB

Travel Rule Data Exchange

In the initial version of the off-chain APIs, the usage is intended as a means of transferring travel-rule information between VASPs. The following will detail the request and response payloads utilized for this purpose.

Request/Response Payload

All requests between VASPs are structured as CommandRequestObjects and all responses are structured as CommandResponseObjects. The resulting request takes a form of the following:

Request Payload Example
{
    "_ObjectType": "CommandRequestObject",
    "command_type": "PaymentCommand",
    "seq": 1,
    "command": {
	    "_ObjectType": "PaymentCommand",
	    "_creates_versions": [
	        "08697804e12212fa1c979283963d5c71"
	    ],
	    "_dependencies": [],
	    "payment": {
	        {
			    "sender": {
				    "address": "lbr1pgfpyysjzgfpyysjzgfpyysjzgf3xycnzvf3xycsm957ne",
				    "kyc_data": {
					    "payload_type": "KYC_DATA"
					    "payload_version": 1,
					    "type": "individual",
					    "given_name": "ben",
					    "surname": "maurer",
					    "address": {
					        "city": "Sunnyvale",
					        "country": "US",
					        "line1": "1234 Maple Street",
					        "line2": "Apartment 123",
					        "postal_code": "12345",
					        "state": "California",
					    },
					    "dob": "1920-03-20",
					    "place_of_birth": {
					        "city": "Sunnyvale",
					        "country": "US",
					        "postal_code": "12345",
					        "state": "California",
					    }
					},
				    "status": "ready_for_settlement",
				},
			    "receiver": {
				    "address": "lbr1pgfpnegv9gfpyysjzgfpyysjzgf3xycnzvf3xycsmxycyy",
				},
			    "reference_id": "lbr1qg9q5zs2pg9q5zs2pg9q5zs2pgy7gvd9u_ref1001",
			    "action": {
				    "amount": 100,
				    "currency": "USD",
				    "action": "charge",
				    "timestamp": 72322,
				},
			    "description": "A free form or structured description of the payment.",
			},
	    }
	},
    "command_seq": 1,
}

A response would look like the following:

CommandRequestObject example
{
    "_ObjectType": "CommandResponseObject",
    "seq": 1,
    "command_seq": 1,
    "status": "success",
}

CommandRequestObject

All requests between VASPs are structured as CommandRequestObjects. For a travel rule exchange, the command is a PaymentCommand as follows:

Field Type Required? Description
_ObjectType str Y Fixed value: CommandRequestObject
command_type str Y A string representing the type of command contained in the request. Set to PaymentCommand for travel rule data exchange
seq int Y The sequence of this request in the sender local sequence.
command PaymentCommand object Y The payment command to sequence.
command_seq int Server The sequence of this command in the joint command sequence. Only set if the server is the sender. See Command Sequencing
CommandRequestObject example
{
    "_ObjectType": "CommandRequestObject",
    "command_type": "PaymentCommand",
    "seq": 1,
    "command": PaymentCommand(),
    "command_seq": 1,
}

PaymentCommand object

Field Type Required? Description
_ObjectType str Y The fixed string PaymentCommand
_creates_versions list of str Y Must be a list containing a single str representing the version of the new or updated PaymentObject resulting from the success of this payment command. A list with any other number of items results in a command error. This string must be a unique random string between this pair of VASPs and is used to represent the version of the item created. These should be at least 16 bytes long and encoded to string in hexadecimal notation using characters in the range[A-Za-z0-9]
_dependencies list of str Y Can be an empty list or a list containing a single previous version. If the list is empty this payment command defines a new payment. If the list contains one item, then this command updates the shared PaymentObject with the given version. It is an error to include more versions, and it results in a command error response. The value in this field must match a version previously specified by the _creates_versions parameter on a prior command.
payment PaymentObject Y contains a PaymentObject that either creates a new payment or updates an existing payment. Note that strict validity check apply when updating payments, that are listed in the section below describing these objects. An invalid update or initial payment object results in a command error
PaymentCommand example
{
    "_ObjectType": "PaymentCommand",
    "_creates_versions": [
        "08697804e12212fa1c979283963d5c71"
    ],
    "_dependencies": [],
    "payment": {
        PaymentObject(),
    }
}

PaymentObject

The structure in this object can be a full payment of just the fields of an existing payment object that need to be changed. Some fields are immutable after they are defined once (see below). Others can by updated multiple times. Updating immutable fields with a different value results in a command error, but it is acceptable to re-send the same value.

Field Type Required? Description
sender/receiver PaymentActorObject Required for payment creation Information about the sender/receiver in this payment
reference_id str Y Unique reference ID of this payment on the payment initiator VASP (the VASP which originally created this payment object). This value should be unique, and formatted as “<creator_vasp_onchain_address_bech32>_<unique_id>”. For example, ”lbr1x23456abcd_seqABCD“. This field is mandatory on payment creation and immutable after that.
original_payment_reference_id str N Used for updates to a payment after it has been committed on chain. For example, used for refunds. The reference ID of the original payment will be placed into this field. This value is optional on payment creation and invalid on updates.
recipient_signature str N Signature of the recipient of this transaction. The signature is over the LCS serialized representation of reference_id, sender_address, amount and is signed with the compliance key of the recipient VASP. This is used for on-chain attestation from the recipient party. This may be omitted on blockchains which do not require on-chain attestation
action PaymentActionObject Y Number of cryptocurrency + currency type (USD, LBR, EUR, BTC, etc.) + type of action to take. This field is mandatory and immutable
description str N Description of the payment. To be displayed to the user. Unicode utf-8 encoded max length of 255 characters. This field is optional but can only be written once.
PaymentObject example
{
    "sender": payment_actor_object(),
    "receiver": payment_actor_object(),
    "reference_id": "lbr1qg9q5zs2pg9q5zs2pg9q5zs2pgy7gvd9u_ref1001",
    "original_payment_reference_id": "lbr1qg9q5zs2pg9q5zs2pg9q5zs2pgy7gvd9u_ref0987",
    "recipient_signature": "...",
    "action": payment_action_object(),
    "description": "A free form or structured description of the payment.",
}

PaymentActorObject

A PaymentActorObject represents a participant in a payment - either sender or receiver. It also includes the status of the actor, indicates missing information or willingness to settle or abort the payment, and the Know-Your-Customer information of the customer involved in the payment.

Field Type Required? Description
address str Y Address of the sender/receiver account. Addresses may be single use or valid for a limited time, and therefore VASPs should not rely on them remaining stable across time or different VASP addresses. The addresses are encoded using bech32. The bech32 address encodes both the address of the VASP as well as the specific user's subaddress. They should be no longer than 80 characters. Mandatory and immutable. For Libra addresses, refer to (TODO) for format.
kyc_data KycDataObject N The KYC data for this account. This field is optional but immutable once it is set.
status str enum Y Status of the payment from the perspective of this actor. This field can only be set by the respective sender/receiver VASP and represents the status on the sender/receiver VASP side. This field is mandatory by this respective actor (either sender or receiver side) and mutable. Valid values are specified in StatusEnum
metadata list of str Y Can be specified by the respective VASP to hold metadata that the sender/receiver VASP wishes to associate with this payment. This is a mandatory field but can be set to an empty list (i.e. []). New string-typed entries can be appended at the end of the list, but not deleted.
PaymentActorObject example
{
    "address": "lbr1pgfpyysjzgfpyysjzgfpyysjzgf3xycnzvf3xycsm957ne",
    "kyc_data": kyc_data_object(),
    "status": "ready_for_settlement",
    "metadata": [],
}

KYCDataObject

A KYCDataObject represents the KYC data for a single subaddress. Proof of non-repudiation is provided by the signatures included in the JWS payloads. The only mandatory fields are payload_type, payload_version and type. All other fields are optional from the point of view of the protocol -- however they may need to be included for another VASP to be ready to settle the payment.

Field Type Required? Description
payload_type str Y Used to help determine what type of data this will deserialize into. Always set to KYC_DATA.
payload_version str Y Version identifier to allow modifications to KYC data object without needing to bump version of entire API set. Set to 1
type str Y Required field, must be either “individual” or “entity”
given_name str N Legal given name of the user for which this KYC data object applies.
surname str N Legal surname of the user for which this KYC data object applies.
address AddressObject N Physical address data for this account
dob str N Date of birth for the holder of this account. Specified as an ISO 8601 calendar date format: https://en.wikipedia.org/wiki/ISO_8601
place_of_birth AddressObject N Place of birth for this user. line1 and line2 fields should not be populated for this usage of the address object
national_id NationalIdObject N National ID information for the holder of this account
legal_entity_name str N Name of the legal entity
KYCDataObject example
{
    "payload_type": "KYC_DATA"
    "payload_version": 1,
    "type": "individual",
    "given_name": "ben",
    "surname": "maurer",
    "address": {
        AddressObject(),
    },
    "dob": "1920-03-20",
    "place_of_birth": {
        AddressObject(),
    }
    "national_id": {
    },
    "legal_entity_name": "Superstore",
}

AddressObject

Represents a physical address

Field Type Required? Description
city str N The city, district, suburb, town, or village
country str N Two-letter country code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
line1 str N Address line 1
line2 str N Address line 2 - apartment, unit, etc.
postal_code str N ZIP or postal code
state str N State, county, province, region.
AddressObject example
{
    "city": "Sunnyvale",
    "country": "US",
    "line1": "1234 Maple Street",
    "line2": "Apartment 123",
    "postal_code": "12345",
    "state": "California",
}

NationalIdObject

Represents a national ID.

Field Type Required? Description
id_value str Y Indicates the national ID value - for example, a social security number
country str N Two-letter country code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
type str N Indicates the type of the ID
NationalIdObject example
{
    "id_value": "123-45-6789",
    "country": "US",
    "type": "SSN",
}

PaymentActionObject

Field Type Required? Description
amount uint Y Amount of the transfer. Base units are the same as for on-chain transactions for this currency. For example, if LibraUSD is represented on-chain where “1” equals 1e-6 dollars, then “1” equals the same amount here. For any currency, the on-chain mapping must be used for amounts.
currency enum Y One of the supported on-chain currency types - ex. LBR, BTC, USD, EUR, etc.
action enum Y Populated in the request. This value indicates the requested action to perform, and the only valid value is charge.
timestamp uint Y Unix timestamp indicating the time that the payment command was created.
PaymentActionObject example
{
    "amount": 100,
    "currency": "USD",
    "action": "charge",
    "timestamp": 72322,
}

StatusEnum

Valid values are:

  • none - No status is yet set from this actor.
  • needs_kyc_data - KYC data about the subaddresses is required by this actor.
  • needs_recipient_signature - Can only be associated with the sender actor. Means that the sender still requires that the recipient VASP provide the signature so that the transaction can be put on-chain.
  • ready_for_settlement - Transaction is ready for settlement according to this actor (i.e. the required signatures/KYC data have been provided)
  • settled - Payment has been settled on chain and funds delivered to the subaddress
  • abort - Indicates the actor wishes to abort this payment, instead of settling it.

Valid Status Transitions. Each side of the transaction is only allowed to mutate their own status (sender or receiver), and upon payment creation may only set the status of the other party to none. Subsequently, each party may only modify their own state to a higher or equal state in the order none, (needs_kyc_data, needs_recipient_signature, abort), ready_for_settlement, and settled. A status of abort and settle is terminal and must not be changed. As a consequence of this ordering of valid status updates once a transaction is in a ready_for_settlement state by both parties it cannot be aborted any more and can be considered final from the point of view of the off-chain protocol. It is therefore safe for a VASP sending funds to initiate an On-Chain payment to settle an Off-chain payment after it observed the other party setting their status to ready_for_settlement and it is also willing to go past this state.

CommandResponseObject

All responses to a CommandRequestObject are in the form of a CommandResponseObject

Field Type Required? Description
_ObjectType str Y The fixed string CommandResponseObject.
seq int Y The sequence number of the request responded to in the local sender request sequence.
command_seq int or str=null Y The sequence of the command responded to in the joint command sequence
status str Y Either success or failure.
error List of OffChainErrorObject N Details on errors when status == "failure"
CommandResponseObject example
{
    "_ObjectType": "CommandResponseObject",
    "command_seq": null,
    "error": [OffChainErrorObject()],
    "seq": 0,
    "status": "failure"
}

When the CommandResponseObject status field is failure, the error field is included in the response to indicate the nature of the failure. The error field (type OffChainError) is a list of OffChainError objects.

OffChainErrorObject

Represents an error that occurred in response to a command.

Field Type Required? Description
type str (enum) Y Either "command_error" or "protocol_error"
field str N The field on which this error occurred
code str (enum) Y The error code of the corresponding error
message str N Additional details about this error
OffChainErrorObject example
{
    "type": "command_error",
    "field": "0.sender.kyc_data.surname",
    "code": "missing_data",
    "message": "",
}

Previous: Command Sequencing