The TestNet hosts three convenience “robot VASPs” (rVASPs) services to facilitate integration and testing with the TRISA TestNet. These services are as follows:
- Alice (
api.alice.vaspbot.net:443): the primary integration rVASP used to trigger and receive TRISA messages.
- Bob (
api.bob.vaspbot.net:443): a demo rVASP to view exchanges with Alice.
- Evil (
api.evil.vaspbot.net:443): an “evil” rVASP that is not a TRISA TestNet member, used to test non-authenticated interactions.
Note: the rVASPs are currently primarily configured for demos. Work has begun on making them more robust for integration purposes; please check in with this documentation regularly for any changes. If you notice any bugs in the rVASP code or behavior, please open an issue.
Getting Started with rVASPs
There are two ways that you can use the rVASPs to develop your TRISA service:
- You can trigger the rVASP to send a TRISA exchange message to your service.
- You can send a TRISA message to the rVASP with a valid (or invalid) rVASP customer.
The rVASPs have a built-in database of fake customers with fake wallet addresses. Their response to TRISA messages or to a triggered transfer requires the originator/beneficiary customer to be valid for the rVASP. E.g. if the customer wallet address is a valid Alice address and Alice is the beneficiary, the rVASP will respond with the customer’s fake KYC data but if not, it will return an TRISA error code.
The following table of “customers” for Alice, Bob, and Evil can be used as a reference for interacting with each rVASP:
Note that all rVASP data was generated using a Faker tool to produce realistic/consistent test data and fixtures; this data is completely fictional. For example, the records for Alice VASP (a fake US company) are primarily in North America, etc.
If you’re a Traveler customer, the bold addresses above have some attribution data associated with them, and are a good candidate for Traveler-based rVASP interactions.
In order to support multiple behaviors at once, such as synchronous and asynchronous responses, each wallet address is configured with an originator policy and a beneficiary policy. The originator policy defines how the rVASP will behave when initiating transfers to a remote VASP. The beneficiary policy defines how the rVASP will behave when responding to transfers from a remote VASP. These policies are described in depth below.
There are two wallets for each customer to support wallet addresses that look like either testnet or mainnet crypto addresses, however the rVASP behavior and data is exactly the same for each pair. Note that rVASPs don’t interact with any real chain; the wallet addresses are simply a mechanism to configure behavior as described below.
This documentation assumes that you have a service that is running the latest
TRISANetwork service and that this service has been registered in the TRISA TestNet and has TestNet certificates correctly installed. See TRISA Integration Overview for more information. WARNING: the rVASPs do not participate in the TRISA production network. They will only respond to verified TRISA TestNet mTLS connections.
To interact with the rVASP API, you may either:
- Use the
- Use the rVASP protocol buffers and interact with the API directly
To install the CLI tool, either download the
rvasp executable for the appropriate architecture at the TestNet releases page, clone the TestNet repository and build the
cmd/rvasp binary or install with
go install as follows:
$ go install github.com/trisacrypto/testnet/cmd/rvasp@latest
To use the rVASP protocol buffers, clone or download them from the TestNet repository then compile them to your preferred language using
Triggering an rVASP to send a message
The rVASP admin endpoints are used to interact with the rVASP directly for development and integration purposes. Note that this endpoint is different than the TRISA endpoint, which was described above.
To use the command line tool to trigger a message, run the following command:
$ rvasp transfer -e admin.alice.vaspbot.net:443 \
-a firstname.lastname@example.org \
-d 0.3 \
-B trisa.example.com \
-b cryptowalletaddress \
This message sends the Alice rVASP a message using the
--endpoint flag, and specifies that the originating account should be “email@example.com” using the
--account flag. The originating account is used to determine what IVMS101 data to send to the beneficiary. The
--amount flag specifies the amount of “AliceCoin” to send. Finally, the
--beneficiary flag specifies the crypto wallet address of the beneficiary you intend as the recipient.
The next two parts are critical. The
--external-demo flag tells the rVASP to trigger a request to your service rather than to perform a demo exchange with another rVASP. This flag is required! Finally, the
--beneficiary-vasp flag specifies where the rVASP will send the request. This field should be searchable in the TRISA TestNet directory service; e.g. it should be your common name or the name of your VASP if it is searchable.
Note that you can set the
$RVASP_CLIENT_ACCOUNT environment variables to specify the
-a flags respectively.
To use the protocol buffers directly, use the
Transfer RPC with the following
These values have the same exact specification as the ones in the command line program.
Responding to a TRISA message from an rVASP
Envelopes received from rVASPs can be decrypted using the private unsealing key paired with the public key you exchanged with the rVASP. The payload that you receive from the rVASP will be determined by the originator policy associated with the originator address in the transaction payload.
It is then up to your TRISA node to determine how to handle the payload. Your options are:
- Reject: return an error in the secure envelope without a payload
- Pending: return a
trisa.data.generic.v1beta1.Pendingin the transaction payload
- Accept: ensure the identity payload is complete and return payload with
The rVASP handles each type of response appropriately. If a reject message is returned, the rVASP fails the transaction; if accept it “executes” the transaction.
The pending message initiates an asynchronous transaction as defined in the TRISA whitepaper. The transaction is placed into an “await” state until the rVASP receives a follow-up reject or accept response with the same envelope id.
An originator policy determines how the rVASP constructs an outgoing payload and handles the response from the transfer. The originator policy is loaded when the
rvasp command is used to instruct the rVASP to send an outgoing message either to another rVASP or to your own TRISA node. Originator policies are mapped to wallet addresses, and the rVASP identifies the originator address using the wallet address in the transaction payload. A description of the originator policies follow:
SendPartial policy, the rVASP sends an envelope containing a transaction payload and a partial identity payload containing a full originator identity and a partial beneficiary identity. For acceptance, the recipient must complete the identity payload by filling in the beneficiary identity.
SendFull policy, the rVASP sends an envelope containing a transaction payload and a complete identity payload. For acceptance, the recipient must reseal and echo the envelope back with a
SendError policy, the rVASP will simply send an envelope containing a
ComplianceCheckFail TRISA error. The rVASP expects the recipient to also return an envelope with an error in it, otherwise an error will be returned by the CLI to the user. This is useful for simulating synchronous rejections or cancellations from the rVASP.
Sending a TRISA message to an rVASP
The rVASP expects a
trisa.data.generic.v1beta1.Transaction as the transaction payload and an
ivms101.IdentityPayload as the identity payload. The transaction payload must contain a beneficiary address that matches the rVASP beneficiaries from the table above; e.g. use:
You may specify any
originator “wallet address” string. The
asset_type fields can be ignored if you would like to simulate other transaction information.
The identity payload cannot be null and must be valid IVMS101, but may be partially or completely filled in depending on the corresponding beneficiary policy.
- Partial Identity: Contains only the originator and originating vasp identities
- Complete Identity: Contains the originator, beneficiary, and originating and beneficiary vasp identities
Create a sealed envelope using either the directory service or direct key exchange to fetch the rVASP RSA public keys and use
HMAC-SHA256 as the envelope cryptography. Then, use the
Transfer RPC to send the sealed envelope to the rVASP.
The beneficiary policy determines how an rVASP responds to an incoming TRISA transfer message to its TRISA endpoint. Beneficiary policies are mapped to wallet addresses found in the transaction payload, which the rVASP uses to identify the beneficiary address. A description of the beneficiary policies follow:
SyncRepair policy, the identity payload does not have to include the beneficiary identity, although it must be not null. The rVASP will respond synchronously by sending an accept response containing a
received_at timestamp and the complete beneficiary identity.
SyncRequire policy, the identity payload must contain a complete beneficiary identity as defined in the TRISA whitepaper. The rVASP will respond synchronously by sending an accept response containing a
received_at timestamp in the payload. If the beneficiary information is incomplete or incorrect, the rVASP will respond with a rejection error.
AsyncRepair policy, the identity payload does not have to include the beneficiary identity. In order to complete the transaction, the originator must:
- Send a
Transferrequest to the rVASP containing “partial” transaction and identity information. The transaction payload must contain a valid beneficiary address but the identity payload does not have to contain full beneficiary info.
- Receive a
trisa.data.generic.v1beta1.Pendingresponse from the rVASP containing
reply_not_aftertimestamps, specifiying the beginning of an asynchronous transaction.
- Be ready to receive an asynchronous callback from the rVASP within the time window. This can be done by caching the original pending message and waiting for a
Transferrequest from the rVASP with the same envelope
Idand within the time window specified in the pending message.
- Respond to the callback RPC with a resealed envelope containing a
received_attimestamp in the payload.
- Initiate a new
Transferrequest to the rVASP containing any final transaction details (
- Receive another pending response from the rVASP which initiates a final asynchronous handshake.
- Receive a second
Transfercallback request from the rVASP containing the full transaction payload and full identity payload along with a
- Finalize the transaction by echoing the envelope back to the rVASP.
AsyncRepair workflow between two rVASPs is displayed below, where Alice is acting as the originator and Bob is acting as the beneficiary.
AsyncReject policy simulates a synchronous rejected transaction. In this policy, the identity payload does not have to include the beneficiary identity, and the rVASP will respond with a pending message as in the
AsyncRepair policy. The difference is that the rVASP will send a callback
Transfer within the time window containing an TRISA rejection error, indicating that the transaction has been rejected.