Investor: Swap tokens

This guide explains how to integrate with our Token Swaps, which allows qualified investors to execute delivery-versus-delivery (DvD) token swap transfers which ensures secure and compliant transfers between parties. For detailed explanations on all types of security token transfers, please view this article.

Swaps can involve any combination of ERC-3643 and ERC-20 tokens. However, for ERC-3643 tokens, both sender and recipient must be qualified and compliant for the specific token. ERC-20 tokens are permissionless and do not require qualification. For detailed parameter specifications and error codes, please refer to the Swagger documentation.

In this article, we will use the testing environment in the path, please note that you may be using a different environment.

📘

Prerequisites:

To complete this use case, you will need to authenticate your request(s). You can generate your token by following these steps:

  • Make sure to leverage an existing account, e.g. Agent, Owner, etc.
  • Sign into your Servicing portal to disable your 2FA.
  • Navigate to the "Getting API access" page to generate the required JWT, thanks to your credentials.
  • Add the JWT to the header of your request.

Complete Swap Transfer Workflow

Step 1: Getting the tokenId

Before you can interact with the swaps endpoints, you must first obtain the tokenId associated with the tokens you want to use. This ID is retrieved from the endpoint:

GET /v2/assets/investor/tokens/me

Each token listed includes a unique id, this id will serve as the tokenId when making requests to the swaps endpoints.

 Step 2: Getting the tokenId of counterpart tokens

On Tokeny ecosystem we use tokens as counterpart payment of different operations with TREX tokens. Examples:

  • ERC20 stable coins: USDT, USDC, EURC, etc.
  • ERC20 native tokens: ETH, POL, AVAX, etc.
  • TREX stable coins: KYPAY, etc.

Before you can interact with the swaps endpoints, you must first obtain the tokenId associated with the counterpart tokens you want to use. This ID is retrieved from the endpoint:

GET /v2/assets/payment-tokens

Each token listed includes a unique id, this id will serve as the tokenId when making requests to the swaps endpoints.

Step 3: Check Existing Allowances

GET /v2/assets/investor/tokens/{tokenId}/allowances?senderAddress=<wallet_address>&type=DVD

Check if the wallet already has sufficient allowances for the token to be swapped.

Response: Returns current allowances for the specified token and wallet

Step 4: Set Allowances (if needed)

POST /v2/assets/investor/tokens/{tokenId}/allowances

If the previous check reveals that there is not enough allowance, it is required to set or increase the allowance for each token to be swapped.

New allowances will replace older ones. If there is “ amount : 6” allowed, and you send another allowance of 6, it will remain 6.

Request Body:

{  
  "senderAddress": "\<wallet_address>",  
  "amount": "\<token_amount>",  
  "type": "DVD"  // Use DVD for delivery-versus-delivery swaps  
}

Response: Returns a task_id used in step 4 and a transaction payload that must be signed by the token investor.

Step 5: Sign and Submit the Allowance Transaction

Refer to the guide based on the specific sign and broadcast solution your API integration requires by visiting the following link: Blockchain signature flow.

You can only complete transfers that you have initiated. Additionally, include the taskId returned in the previous endpoint's response when calling the transaction logging endpoint.

Logging the transaction is essential to reconcile on-chain and off-chain flows. Since the user handles blockchain interactions on their own, we use the taskId to:

  • Identify the workflow uniquely.
  • Maintain a consistent link between off-chain logic and on-chain activity.
  • Ensure traceability and reliability.

Option A: Sign and Broadcast Yourself

Sign the transaction payload with your private key.

Broadcast, on your end, the signed transaction to the blockchain.

Log the transaction hash:

POST /v2/assets/investor/tokens/{tokenId}/allowances/{allowanceId}/transactions

You can use the allowanceId retrieved in the answer body of the previous step.

With Payload:

{  
  "taskId": "\<task_id>",  
  "txHash": "\<transaction_hash>"  
}

Option B: Sign and Let Tokeny Broadcast

Sign the transaction payload with your private key

Send the signed payload for broadcasting:

POST /v2/assets/investor/tokens/{tokenId}/allowances/{allowanceId}/payloads

With payload:

{  
  "taskId": "\<task_id>",  
  "signedPayload": "\<signed_transaction_data>"  
}

 Step 6: Initiate Swap Transfer

POST /v2/assets/investor/swaps

After setting the necessary allowances, the sender creates a new swap request by providing:

  • Source token details
  • Destination token details
  • Amount to swap
  • Recipient wallet information

Response: Returns a transaction payload that must be signed by the sender.

Step 7: Sign and Submit the Swap Transaction

Refer to the guide based on the specific sign and broadcast solution your API integration requires by visiting the following link: Blockchain signature flow.

You can only complete transfers that you have initiated. Additionally, include the taskId returned in the previous endpoint's response when calling the transaction logging endpoint.

Logging the transaction is essential to reconcile on-chain and off-chain flows. Since the user handles blockchain interactions on their own, we use the taskId to:

  • Identify the workflow uniquely.
  • Maintain a consistent link between off-chain logic and on-chain activity.
  • Ensure traceability and reliability.

Option A: Sign and Broadcast Yourself

  1. Sign the transaction payload
  2. Broadcast the signed transaction
  3. Log the transaction hash:

POST /v2/assets/investor/swaps/{swapId}/transactions

Option B: Sign and Let Tokeny Broadcast

  1. Sign the transaction payload
  2. Send the signed payload:

POST /v2/assets/investor/swaps/{swapId}/payloads

Step 8: Recipient - Retrieve Existing Swaps (Optional)

This endpoint allows you to query existing swap requests associated with a specific tokenId. You can use it to review the status of any pending, completed, or cancelled swaps before initiating a new one.

The response will include a unique swapId for each swap. This swapId is required in a later step when submitting the approve transaction, so make sure to store or reference it appropriately.

GET /v2/assets/investor/swaps?tokenId={{token_id}}

 Step 9: Recipient - Check Existing Allowances

GET /v2/assets/investor/tokens/{tokenId}/allowances?senderAddress=<recipient_wallet_address>&type=DVD

Recipient checks if their wallet has sufficient allowances for their token to be swapped.

 Step 10: Recipient - Set Allowances (if needed)

POST /v2/assets/investor/tokens/{tokenId}/allowances

If the previous check reveals that there is not enough allowance, the recipient should sets or increases the allowance for their token.

Request Body:

{  
  "senderAddress": "\<recipient_wallet_address>",  
  "amount": "\<token_amount>",  
  "type": "DVD"  
}`

Response: Returns a transaction payload that must be signed.

 Step 11: Recipient - Sign and Submit the Allowance Transaction

The recipient follows the same signing process as in Step 4.

 Step 12: Recipient - Approve or Reject the Swap

Option A: Approve the Swap

POST /v2/assets/investor/swaps/{swapId}/approve

The recipient approves the swap request.

Option B: Reject the Swap

POST /v2/assets/investor/swaps/{swapId}/reject

Response: For approval, returns a transaction payload that must be signed.

Step 13: Recipient - Sign and Submit Approval Transaction

If approved, the recipient signs and processes the approval transaction following the same process as in Step 4.

 Step 14: Monitor Swap Status

GET /v2/assets/investor/swaps

Both parties can check the status of the swap to confirm completion.

Status Transitions

A swap workflow transitions through these states:

  • CREATED - Initial state after swap initiation
  • PENDING_APPROVAL - Waiting for recipient action
  • APPROVED - Recipient has approved the swap
  • COMPLETED - Swap has been fully executed on blockchain
  • CANCELLED - Swap was cancelled by the initiator
  • REJECTED - Swap was rejected by the recipient
  • FAILED - An error occurred during the blockchain execution or processing of the swap, preventing its successful completion

 Cancellation Flow

At any point before completion, the initiator can cancel the swap:

Step 1: Request Cancellation

POST /v2/assets/investor/swaps/{swapId}/cancel

Response: Returns a transaction payload that must be signed.

Step 2: Sign and Submit the Cancellation Transaction

Option A: Sign and Broadcast Yourself

  1. Sign the cancellation transaction payload
  2. Broadcast the signed transaction
  3. Log the transaction hash:

POST /v2/assets/investor/swaps/{swapId}/transactions

With payload:

{  
  "taskId": "\<task_id>",  
  "txHash": "\<transaction_hash>"  
}

Option B: Sign and Let Us Broadcast

  1. Sign the cancellation transaction payload
  2. Send the signed payload:

POST /v2/assets/investor/swaps/{swapId}/payloads

With Payload:

{  
  "taskId": "\<task_id>",  
  "signedPayload": "\<signed_transaction_data>"  
}