TRISA API

The TRISA Network Protocol implementation exposes several RPCs needed to build TRISA into your organization’s application, which are defined within the protocol buffers. All TRISA members must implement both services described by the TRISA protocol (the TRISANetwork service and the TRISAHealth service) to ensure that exchanges are conducted correctly and securely.

The protocol buffers can be compiled into the language of your choice. This section describes the protocol buffers for the TRISANetwork endpoint and the protocol buffer API in Go.

Note

You will need to download and install the protocol buffer compiler if you have not already.

The TRISANetwork Service

The TRISANetwork service defines the peer-to-peer interactions between Virtual Asset Providers (VASPs) necessary to conduct compliance information exchanges.

The TRISANetwork Service has two primary RPCs, Transfer and TransferStream. Transfer and TransferStream allow VASPs to exchange compliance information before conducting a virtual asset transaction. KeyExchange allows public keys to exchange so that transaction envelopes can be encrypted and signed.

service TRISANetwork {
    rpc Transfer(SecureEnvelope) returns (SecureEnvelope) {}
    rpc TransferStream(stream SecureEnvelope) returns (stream SecureEnvelope) {}
    rpc ConfirmAddress(Address) returns (AddressConfirmation) {}
    rpc KeyExchange(SigningKey) returns (SigningKey) {}
}
Note

The ConfirmAddress RPC is not currently implemented.

Transfer and TransferStream RPCs

The Transfer and TransferStream RPCs conduct the information exchange before a virtual asset transaction. The RPCs enable an originating VASP to send an encrypted transaction envelope to the beneficiary VASP containing a unique ID for the transaction, the encrypted transaction bundle, and metadata associated with the transaction cipher. In response, the beneficiary can validate the transaction request, then return the beneficiary’s transaction information using the same unique transaction ID.

The Transfer RPC is a unary RPC for simple, single transactions. The TransferStream RPC is a bidirectional streaming RPC for high throughput transaction workloads.

SecureEnvelope

A SecureEnvelope is the encrypted transaction envelope that is the outer layer of the TRISA information exchange protocol and facilitates the secure storage of Know Your Client (KYC) data in a transaction. The envelope specifies a unique id to reference the transaction out-of-band (e.g., in the blockchain layer). It provides the necessary information so only the originator and the beneficiary can decrypt the transaction data. For more information about Secure Envelopes, this section of the documentation further describes this primary data structure for the TRISA exchange.

A SecureEnvelope message contains different types of metadata. The Anatomy of Secure Envelope section of this documentation further describes the envelope metadata, cryptographic metadata, and an encrypted payload and HMAC signature within the SecureEnvelope.

message SecureEnvelope {
    string id = 1;
    bytes payload = 2;
    bytes encryption_key = 3;
    string encryption_algorithm = 4;
    bytes hmac = 5;
    bytes hmac_secret = 6;
    string hmac_algorithm = 7;
    Error error = 9;
    string timestamp = 10;
    bool sealed = 11;
    string public_key_signature = 12;
    TransferState transfer_state = 13;

New in v1.1: the TransferState describes the condition of the transfer the sending party feels the Transfer of Travel Rule data is in. This can be optionally used to signal to the counterparty the intent of a transfer message. See TRISA Workflows for more information on how the transfer state works.

enum TransferState {
    UNSPECIFIED = 0;  // the transfer state is unknown or not specified
    STARTED = 1;      // this is the first message in the TRISA workflow
    PENDING = 2;      // action is required by the sending party
    REVIEW = 3;       // action is required by the receiving party (rarely used)
    REPAIR = 4;       // some state of the travel rule exchange requires repair
    ACCEPTED = 5;     // the travel rule exchange is accepted and awaiting the transaction
    COMPLETED = 6;    // the travel rule and on-chain transaction have been completed
    REJECTED = 7;     // the travel rule exchange is rejected and should not proceed
}

ConfirmAddress RPC

Note

Address confirmation was initially described in the TRISA whitepaper as a mechanism to allow an originator VASP to establish that a beneficiary VASP has control of a crypto wallet address before sending transaction information with sensitive PII data.

Currently, there are three proposed address confirmation methods being tested: simple, key/token, and on-chain. Simple involves a simple yes/no check with the counterparty. Key/Token requires the counterparty to decrypt a token encrypted with the crypto address public keys, and on-chain implements a simple Satoshi test.

All three methods are available in the protocol buffers, but note that these are still being tested and developed, and may change at any time. No backward compatibility is guaranteed for these message types, nor is there any guarantee that any TRISA VASP will implement any of these confirmation methods.

KeyExchange RPC

The KeyExchange RPC allows VASPs to exchange public signing keys to facilitate transaction signatures if they have not already obtained them from the directory service.

SigningKey

SigningKey provides metadata for decoding a PEM encoded PKIX public key for RSA encryption and transaction signing. The SigningKey is a lightweight version of the certificate information stored in the Directory Service.

message SigningKey {
    // x.509 metadata for reference without parsing the key
    int64 version = 1;
    bytes signature = 2;
    string signature_algorithm = 3;
    string public_key_algorithm = 4;

    // Validity information
    string not_before = 8;
    string not_after = 9;
    bool revoked = 10;

    // The serialized public key to PKIX, ASN.1 DER form.
    bytes data = 11;
}

The TRISAHealth Service and Status RPC

The TRISAHealth service contains the Status RPC, which is optional but highly recommended for VASP members to implement. The Status endpoint allows TRISA members and the TRISA Directory Service to perform health checks with a VASP’s TRISA Node and report the service conditions of the TRISA network. Because a down TRISA node will prevent travel rule compliant virtual asset transactions, the health service is intended to quickly identify network problems and notify members as quickly as possible.

Note

The TRISAHealth service must also be behind mTLS so that the health check service can verify the identity certificates used for the TRISANetwork service.

service TRISAHealth {
    rpc Status(HealthCheck) returns (ServiceState) {}
}

HealthCheck

HealthCheck specifies attempts, which is the number of failed health checks that proceeded the current check, and last_checked, which is the timestamp of the last health check, successful or otherwise.

message HealthCheck {
    uint32 attempts = 1;
    string last_checked_at = 2;
}

ServiceState

ServiceState returns the status, which is the Current service status as defined by the receiving system. The system must respond with the closest matching status in a best-effort fashion. Alerts will be triggered on service status changes if the system does not respond and the previous system state was not unknown. not_before and not_after are also returned; they suggest to the directory service when to recheck the health status.

message ServiceState {
    enum Status {
        UNKNOWN = 0;
        HEALTHY = 1;
        UNHEALTHY = 2;
        DANGER = 3;
        OFFLINE = 4;
        MAINTENANCE = 5;
    }

    Status status = 1;

    // When to check the health status again.
    string not_before = 2;
    string not_after = 3;
}

TRISA API in Go

The implementation of the TRISA Protocol Buffers in Go is compiled using protoc when go generate ./... is executed in the root of the repository. The compiled files in the TRISA repository contain the TRISA Network Protocol implemented in Go.

The TRISANetworkServer is the server API for TRISANetwork, while the TRISANetworkClient is the client API for the TRISANetwork service. Both contain the Transfer, TransferStream, ConfirmAddress, and KeyExchange methods described above as RPCs under the TRISANetwork service.

type TRISANetworkClient interface {
	Transfer(ctx context.Context, in *SecureEnvelope, opts ...grpc.CallOption) (*SecureEnvelope, error)
	TransferStream(ctx context.Context, opts ...grpc.CallOption) (TRISANetwork_TransferStreamClient, error)
	ConfirmAddress(ctx context.Context, in *Address, opts ...grpc.CallOption) (*AddressConfirmation, error)
	KeyExchange(ctx context.Context, in *SigningKey, opts ...grpc.CallOption) (*SigningKey, error)
}

type TRISANetworkServer interface {
	Transfer(context.Context, *SecureEnvelope) (*SecureEnvelope, error)
	TransferStream(TRISANetwork_TransferStreamServer) error
	ConfirmAddress(context.Context, *Address) (*AddressConfirmation, error)
	KeyExchange(context.Context, *SigningKey) (*SigningKey, error)
}

For further information, a reference implementation of the TRISA Network protocol is available in Go in the TRISA TestNet Repository,