TSS Node callback
TSS Node callback mechanism
After the successful setup of the TSS Node, it will automatically establish a connection with Cobo Portal and await tasks sent by the Cobo Portal backend. Currently, there are three task types: key generation (KeyGen), transaction signing (KeySign), and soft key recovery (KeyReshare).
In cases where the callback mechanism is not configured, the TSS Node promptly executes each task upon receipt from the Cobo Portal backend. If the callback mechanism is enabled, the TSS Node sends an approval request to the callback server upon task reception. Task execution occurs only upon approval from the callback server.
The communication between the TSS Node and the callback server utilizes the HTTP protocol, and Cobo Portal implements JSON Web Token (JWT) signed with the RS256 algorithm. For more information on JWT, please click here.
- During TSS Node initialization, both the TSS Node and the callback server generate and configure an RSA private/public key pair.
- Upon task reception, the TSS Node constructs a CallbackRequest and generates a JWT token using its RSA private key. This request is then sent to the callback server via the HTTP POST method.
- Upon receipt, the callback server validates the JWT signature using the TSS Node’s RSA public key. It constructs a CallbackRequest and signs it using its RSA private key before sending the JWT back to the TSS Node.
- Upon receiving the HTTP response, the TSS Node validates the JWT signature using the callback server’s RSA public key.
- Once validated, the TSS Node executes or rejects the task based on the response received from the callback server.
Callback server requirements
HTTP API
The callback server operates as an HTTP server with the following supported endpoints:
- Path: /v1/check
- Method: POST
- Body: Encoded with x-www-form-urlencoded
HTTP request parsing
The callback server will send HTTP Request in the following manner:
- Generate CallbackRequest.
- Serialize CallbackRequest to derive CallbackRequestJsonString.
- Utilize CallbackRequestJsonString as the JWT payload and sign it using its RSA private key to create a JWT.
- Submit the HTTP POST request via an HTML form with TSS_JWT_MSG as the key and JWT as the value.
The callback server will process the HTTP Request in the following manner:
- Retrieve the data in the HTTP POST request using TSS_JWT_MSG as the key and the JWT as the value.
- Use the TSS Node’s RSA public key to validate the signed JWT.
- Retrieve the payload in the JWT and deserialize it using CallbackRequest.
- Deserialize the meta field to retrieve the information in the request.
Risk controls
For each CallbackRequest, it is essential to conduct a risk control assessment in accordance with your organization’s security requirements. This step is crucial to ensure the validation of the request.
HTTP responses
The callback server will structure and send the HTTP response in the following manner:
- Generate CallbackResponse.
- Serialize CallbackResponse to derive CallbackResponseJsonString.
- Utilize CallbackResponseJsonString as the JWT payload and sign it using its RSA private key to create a JWT.
- Use the JWT as the HTTP response and return it to the TSS Node.
CallbackRequest descriptions
Parameter | Type | Description |
---|---|---|
request_id | string | Unique ID of the callback request. |
request_type | int | The types of callback requests are enumerated as follows: TypePing: 0 TypeKeyGen: 1 TypeKeySign: 2 TypeKeyReshare: 3 |
request_detail | string | The specifics of the callback request. Each type of callback request includes a distinct request_detail structure. The format for this information is a serialized JSON string. |
extra_info | string | Additional information associated with the callback request. Each type of callback request includes a unique extra_info structure. The format for this information is a serialized JSON string. |
When request_type is equal to TypeKeyGen, the structure of request_detail is as follows:
Parameter | Type | Description |
---|---|---|
threshold | int | Signature threshold. |
node_ids | []string | Node IDs associated with the generation of all private key shares under the MPC Wallet. |
curve | int | Signature algorithm that has been used: 0: SECP256K1 2: ED25519 |
task_id | string | Task ID |
The structure of extra_info is as follow:
Parameter | Type | Description |
---|---|---|
cobo_id | string | Unique ID of the key generation (KeyGen) request. |
api_request_id | string | Request ID either passed in by the client using APIs or, if the request is not sent via APIs, Cobo will automatically generate a Request ID. |
When request_type is equal to TypeKeySign, the structure of request_detail is as follows:
Parameter | Type | Description |
---|---|---|
group_id | string | Group ID used during transaction signing. |
root_pub_key | string | Root extended public key. |
used_node_ids | []string | TSS Node IDs used during transaction signing. |
bip32_path_list | []string | Address paths (BIP32). |
msg_hash_list | []string | Hashes to be signed. |
tweak_list | []string | Tweaks to be signed. |
signature_type | int32 | Signature algorithm that has been used: 1: ECDSA 2: EdDSA 3: Schnorr |
tss_protocol | int32 | TSS signature protocol that has been used: 0: Unknown 1: GG18 2: Lindell 3: EDDSATss |
task_id | string | Task ID. |
The structure of extra_info is as follow:
Parameter | Type | Description |
---|---|---|
cobo_id | string | Unique ID of the transaction signing (KeySign) request. |
api_request_id | string | Request ID of the withdrawal request. If the request is initialized via API, the value should be the same as request_id. If the request is initialized via Cobo Portal, Cobo will automatically generate a Request ID. |
transaction_type | TransactionTypeEnum | Please refer to TransactionTypeEnum. |
operation | TransactionOperationEnum | Please refer to TransactionOperationEnum. |
coin | string | Asset name. |
decimal | int | Decimal precision. |
from_address | string | The address from which assets are withdrawn. |
amount | string | (Optional) This transaction amount may contain decimal places (e.g., 1 BTC is divisible to eight decimal places, and 100,000,000 represents 1 BTC). |
to_address | string | Deposit address. |
to_address_details | json | (Optional) A list of deposit addresses, applicable to the UTXO model. The value must adhere to the JSON structure of list[ToAddressDetail]. |
fee | int | (Optional) For BTC transactions, this field returns the transaction fees per byte, with the unit being satoshi. |
gas_price | int | (Optional) For ETH transactions, this field returns gas fees, with the unit being gwei. |
gas_limit | int | (Optional) For ETH transactions, this field returns the gas limits. |
extra_parameters | json | Additional parameters for the transaction. Please refer to the description of create_transaction. |
replace_cobo_id | string | (Optional) ID of a Cobo transaction that has been designated as Replace-By-Fee (RBF). |
api_key | string | (Optional) API_KEY of the withdrawal request initialized through APIs. |
spender | string | (Optional) Email information of the withdrawer. This is applicable when the withdrawal is initiated through Cobo Portal. |
raw_tx_hex | string | Transaction hash. |
custody_wallet_name | string | Wallet name. |
gas_station_child_id | string | Cobo ID for gas station transactions. |
note | string | Transaction remarks. |
raw_tx_info | json | Raw information necessary for constructing the transaction to be signed. |
The structure of ToAddressDetail is as follows:
Parameter | Type | Description |
---|---|---|
to_address | string | Withdrawal address. |
amount | string | This transaction amount may contain decimal places (e.g., 1 BTC is divisible to eight decimal places, and 100,000,000 represents 1 BTC). |
The structure of extra_parameters is as follows:
Parameter | Type | Description |
---|---|---|
inputs_to_spend | list[Input] | Unspent Transaction Output (UTXO) to spend. This applies to UTXO-type blockchains, such as Bitcoin. |
inputs_to_exclude | list[Input] | Unspent Transaction Output (UTXO) to exclude from spending. This applies to UTXO-type blockchains, such as Bitcoin. |
The structure of input is as follows:
Parameter | Type | Description |
---|---|---|
tx_hash | string | Transaction hash. |
vout_n | int | Transaction index or number. |
The structure of TransactionTypeEnum is as follows:
Value | Name | Description |
---|---|---|
100 | TRANSACTION_FROM_WEB | Transaction initiated via Cobo Portal. |
102 | TRANSACTION_FROM_API | Transaction initiated via APIs. |
103 | TRANSACTION_RBF_API_SPEEDUP | The transaction to speed up, which was initiated via API. |
104 | TRANSACTION_RBF_WEB_SPEEDUP | The transaction to speed up, which was initiated via Cobo Portal. |
105 | TRANSACTION_RBF_API_DROP | The transaction to cancel, which was initiated via API. |
106 | TRANSACTION_RBF_WEB_DROP | The transaction to cancel, which was initiated via Cobo Portal. |
The structure of TransactionOperationEnum is as follows:
Value | Name | Description |
---|---|---|
100 | TRANSFER | Transfer. |
200 | CONTRACT_CALL | Smart contract calls. |
When request_type is equal to TypeKeyReshare, the structure of request_detail is as follows:
Parameter | Type | Description |
---|---|---|
old_group_id | string | Old group ID. |
root_pub_key | string | Root extended public key. |
curve | int | Signature algorithm that has been used: 0: SECP256K1 2: ED25519 |
used_node_ids | []string | Selected Node IDs from the previous group that have been used for soft key recovery. |
old_threshold | int | Old signature threshold. |
new_threshold | int | New signature Threshold. |
new_node_ids | []string | New TSS Node IDs associated with the generation of all private key shares under the MPC Wallet. |
task_id | string | Task ID. |
The structure of extra_info is as follows:
Parameter | Type | Description |
---|---|---|
cobo_id | string | Unique ID of the soft key recovery (KeyReshare) request. |
api_request_id | string | Request ID either passed in by the client using APIs or, if the request is not sent via APIs, Cobo will automatically generate a Request ID. |
CallbackResponse descriptions
Parameter | Type | Description |
---|---|---|
status | int | If the status is 0, it indicates that the callback server is normal. Other values suggest that the callback server has encountered an error. |
request_id | string | Request ID of the callback. The value must be the same as the request_id in CallbackRequest. |
action | string | Instructions for task execution, represented as an enum with two possible values: APPROVE: The task should be executed. REJECT: The task should be rejected, and the reason can be retrieved from the error field. |
error | string | If the returned status is not 0, it indicates an error within the callback server. If the returned status is 0 and the action returns a “REJECT,” it provides the reason for task rejection. |
Callback server examples
Cobo Portal offers callback server examples in various programming languages. You can refer to these examples to swiftly deploy a callback server. Alternatively, JWT code libraries are available for multiple programming languages. You can refer to JWT’s official website to deploy a callback server.
Callback server configuration
On the server where the callback server is deployed, you’ll need to complete the following configurations.
- Generate the callback server’s RSA private key.
- Export the callback server’s RSA public key.
-
Copy the exported RSA’s public key (i.e. the callback-server-pub.key file) to the server where the TSS Node is deployed.
-
Copy the RSA’s public key of the TSS Node to the config files of the callback server.
- If you are using the callback server codes provided by Cobo Portal, refer to the configuration instructions provided in the samples.
-
After successfully completing TSS Node initialization, use the following command to query the RSA’s public key of the TSS Node:
The output example is as follows.
TSS Node configuration & callback server startup
TSS Node configuration
On the server where the callback server is deployed, you’ll need to complete the following configurations.
- Copy the callback server’s RSA public key file to the configs directory of the TSS Node.
-
Modify the cobo-tss-node-config.yaml file.
-
cb_server
- service_address indicates the callback server address.
- pubkey_path indicates the file path of the callback server’s RSA.
-
token_expire_minutes indicates the timeout period of the JWT (unit: minutes).
-
retry_time indicates the number of retries if the callback request fails.
-
sleep_seconds indicates the time interval between each retry (unit: minutes).
-
You can configure multiple callback servers. The following output uses two callback servers as an example:
After completing the aforementioned configurations, you can initiate the startup of both the callback server and the TSS Node.