Skip to main content
Try Cobo WaaS Skill in your AI coding assistant (Claude Code, Cursor, etc.). Describe your needs in natural language to auto-generate production-ready SDK code and debug faster 🚀
Your TSS Node can notify your own server when it finishes an operation such as key generation (KeyGen), key resharing (KeyReshare), signing (KeySign), or key share signing (KeyShareSign). The node sends each notification as an HTTP POST request to the endpoints you configure. Each message is carried in a JSON Web Token (JWT) signed with RS256. Your receiving server verifies the signature with the node’s RSA public key, which confirms that the message came from your node.
These notifications are not the same as Cobo webhook events. Cobo sends wallets.mpc.tss_request.* webhook events from the Cobo platform to the endpoint you register in Cobo Portal, and signs them with Cobo’s webhook signature. The events on this page are sent by your own TSS Node, use the request.* event names, are signed with your node’s RSA key, and are configured in the node configuration file. Subscribing to one does not deliver the other. For Cobo webhook events, see Webhook event types.

Before you start

Event notifications use an RSA 2048 key pair. Generate the key pair and store it in the node database before you start the node for the first time:
The public key is printed in PEM format. Copy it to your receiving server.

Configure event notifications

Add or uncomment the event section in the TSS Node configuration file, such as cobo-tss-node-config.yaml:

Top-level parameters

Per-server parameters

Each entry under server inherits the top-level values, and can override any of them. The following example sends signing events to one server and the full set of events to an audit server, with a longer retry budget for the audit server:
The same event can go to several servers. Each server keeps its own retry state, so a failure on one server does not affect delivery to another.

Supported event types

Subscribe only to the event types your integration acts on, so the node does not spend delivery attempts on events you discard.

KeyGen

KeySign

KeyReshare

KeyShareSign

Request format

The node sends each event as a form-encoded POST request, with the JWT in the TSS_JWT_MSG field:
The JWT is signed with RS256, using the RSA 2048 private key stored locally by the node. The JWT header is:
The JWT payload is:
Your server must return 200 OK or 201 Created. The node treats every other status code as a failure and retries.

Event payload

After you decode package_data, the event body has the following shape:
Every data object carries data_type, request_id, request_type, request_status, request_detail, extra_info, failed_reason, and result. The fields inside request_detail and result differ per operation.

Delivery and retries

When a delivery attempt fails, the node waits sleep_seconds and tries again, up to retry_times attempts. The interval is fixed, so the wait between attempts does not grow. The following behavior applies to every configured server:
  • Setting retry_times to 0 retries without limit, until the push succeeds or the node stops.
  • The node writes each event to its database before the first attempt, with the status pending. After a restart, it resumes delivery of up to 1000 pending events.
  • After a successful push, the node deletes the event record. After the retry budget is exhausted, it marks the event failed.
Because a failed attempt is retried, your server can receive the same event more than once. Deduplicate on event_id. The following table shows how the two retry parameters combine:

Health checks

When monitor_interval is not empty, the node periodically sends a ping request to each event server:
A ping request uses the same JWT mechanism as an event, and its package_data carries event_type set to ping. The node retries a failed ping up to two times, at 3-second intervals. Handle ping separately from business events: return 200 OK and do no further processing.

Implement a receiving server

Cobo publishes Go and Java event server templates that you can clone and complete with your own business logic: Both templates follow the same flow:
  1. Listen for POST /v2/event and read the JWT from the TSS_JWT_MSG form field.
  2. Verify the signature with the node’s RSA public key, stored at configs/tss-node-event-pub.key. Return 400 Bad Request when verification fails.
  3. Decode the event JSON from the package_data claim.
  4. Deserialize it into a TSSEvent with the cobo-waas2 SDK, then dispatch on the event type.
  5. Return 200 OK on success. Return 200 OK for ping events without further processing.
For implementation details, see the README.md and source of each template in the repository. The following configuration keeps critical events from being dropped, and sets token_expire_minutes above request_timeout so a token does not expire before the request times out:
The node generates a new JWT for each retry, so raise token_expire_minutes when you use a long sleep_seconds.

FAQ

Run ./tss-node event key info on the node. The command prints the public key in PEM format. Configure that key on your receiving server.
Yes. The node retries when the network fails or when your server does not return 200 OK or 201 Created. Deduplicate on event_id, which is a UUID.
No. The node writes each event to its database with the status pending before the first delivery attempt, and resumes delivery after a restart.
Setting retry_times to 0 retries without limit. Omitting it applies the default of 60.
Use a value between 2 and 5 minutes, and keep it above request_timeout so the token does not expire before the request times out. Raise it further when sleep_seconds is large, because the node generates a new JWT for each retry.
Yes. Add an entry per server under server. Each server receives events and retries independently.