Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,17 @@
"pages": [
"v2/guides/webhooks-callbacks/introduction",
"v2/guides/webhooks-callbacks/set-up-endpoint",
"v2/guides/webhooks-callbacks/webhook-event-type"
"v2/guides/webhooks-callbacks/webhook-event-type",
"v2/guides/webhooks-callbacks/transaction-events",
"v2/guides/webhooks-callbacks/mpc-tss-request-events",
"v2/guides/webhooks-callbacks/webhook-operations"
]
},
{
"group": "Transactions",
"pages": [
"v2/guides/transactions/sources-and-destinations",
"v2/guides/transactions/transaction-fields",
"v2/guides/transactions/transfer-routing",
"v2/guides/transactions/estimate-fees",
"v2/guides/transactions/solana-token-account-rent",
Expand Down Expand Up @@ -858,13 +862,17 @@
"pages": [
"v2_cn/guides/webhooks-callbacks/introduction",
"v2_cn/guides/webhooks-callbacks/set-up-endpoint",
"v2_cn/guides/webhooks-callbacks/webhook-event-type"
"v2_cn/guides/webhooks-callbacks/webhook-event-type",
"v2_cn/guides/webhooks-callbacks/transaction-events",
"v2_cn/guides/webhooks-callbacks/mpc-tss-request-events",
"v2_cn/guides/webhooks-callbacks/webhook-operations"
]
},
{
"group": "交易",
"pages": [
"v2_cn/guides/transactions/sources-and-destinations",
"v2_cn/guides/transactions/transaction-fields",
"v2_cn/guides/transactions/transfer-routing",
"v2_cn/guides/transactions/estimate-fees",
"v2_cn/guides/transactions/solana-token-account-rent",
Expand Down Expand Up @@ -1598,4 +1606,4 @@
"destination": "https://www.cobo.com/payments/cn/guides/overview"
}
]
}
}
12 changes: 11 additions & 1 deletion v2/guides/transactions/status.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,16 @@ After a transaction is approved, it enters the `PendingSignature` status and mus
A transaction in the `Confirming` status with the sub-status `PendingBlockConfirmations` is waiting for the required number of block confirmations on its chain. This is a normal part of processing and does not mean the transaction is stuck. The required number of confirmations and the expected confirmation time vary by chain.
</Note>

## When to credit a deposit

Treat `Confirming` and its `wallets.transaction.updated` events as progress only. A blockchain deposit in `Confirming` is not yet safe to credit. Its `confirmed_num` must reach `confirming_threshold` before the transaction can complete confirmation processing.

The successful internal outcome is surfaced publicly as the `Completed` status and the [`wallets.transaction.succeeded`](/v2/guides/webhooks-callbacks/transaction-events#walletstransactionsucceeded) event. Credit a deposit after receiving that event, or after verifying `Completed` with [Get transaction information](/v2/api-references/transactions/get-transaction-information) or [List all transactions](/v2/api-references/transactions/list-all-transactions). Make reconciliation idempotent according to the [endpoint handling guidance](/v2/guides/webhooks-callbacks/set-up-endpoint#important-notes).

<Note>
This crediting guidance applies only to blockchain deposits. It does not apply to `MessageSign` or other transaction types that do not move funds.
</Note>

## Available actions

You can perform the following actions based on the transaction status:
Expand All @@ -302,4 +312,4 @@ You can perform the following actions based on the transaction status:

For details on how a replaced transaction's status changes, see [RBF (Replace-By-Fee) transaction lifecycle](/v2/guides/transactions/rbf-transaction-lifecycle).

For more details, refer to [Manage transactions](/v2/guides/transactions/manage-transactions).
For more details, refer to [Manage transactions](/v2/guides/transactions/manage-transactions).
38 changes: 38 additions & 0 deletions v2/guides/transactions/transaction-fields.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: "Transaction field reference"
lang: "en"
description: "Reconcile transactions by understanding identifiers, direction fields, replacement links, and Cobo-defined categories."
---

import WaasSkillReminder from '/snippets/waas_skill_reminder.mdx';

<WaasSkillReminder />

## Overview

Use this reference to distinguish transaction fields that look similar but serve different reconciliation purposes. See [Transaction event payload](/v2/guides/webhooks-callbacks/transaction-events) for the complete payload contract, [Transaction sources and destinations](/v2/guides/transactions/sources-and-destinations) for direction shapes, [RBF transaction lifecycle](/v2/guides/transactions/rbf-transaction-lifecycle) for replacement behavior, and [Manage transactions](/v2/guides/transactions/manage-transactions#cobo-defined-categories) for the full `cobo_category` table.

## Field dictionary

| Field | Meaning and conditionality | Preferred reconciliation use |
| --- | --- | --- |
| `chain_id` | Identifies the blockchain network. It is present for on-chain transactions and differs from the asset identifiers below. | Use it with `token_id` when routing chain-specific processing. |
| `token_id` | Identifies an on-chain token in Cobo's catalog. Native assets and contract tokens have different values, and the same economic asset on different chains has different `token_id` values. | Use it for token-specific balances, decimals, and chain transfers. |
| `asset_id` | Identifies an asset in an Exchange Wallet, where the balance is not represented by an on-chain `token_id`. | Use it for exchange-account reconciliation; do not treat it as a network identifier. |
| `request_id` | Your idempotency and correlation identifier for a client-initiated request. It is `null` when no client request created the transaction, such as for a deposit. | Match a webhook or API result to the local request that initiated an outbound transaction. |
| `source` | Describes the origin selected by `source_type`. For a deposit it normally represents the external sender; for a withdrawal it represents the sending wallet. | Determine direction and the account or address from which value moved. |
| `destination` | Describes the target selected by `destination_type`. For a deposit it identifies the receiving wallet address; for a withdrawal it identifies the external target. | Determine direction and the account, address, contract, or signing input receiving the operation. |
| `replaced_by_transaction_hash` | Appears in `replacement` only on the original transaction after replacement and points to the new transaction's hash. | Follow the original record to the effective RBF transaction. |
| `cobo_category` | Contains Cobo-defined operational classifications when applicable. High-signal values include `AutoSweep`, `ComplianceRefund`, `ComplianceIsolate`, `ScreenAppRefund`, and `ScreenAppIsolate`. | Branch on the explicit category instead of inferring system activity from addresses. |

## Example mappings

| Asset | `chain_id` | `token_id` | `asset_id` |
| --- | --- | --- | --- |
| Ethereum native asset | `ETH` | `ETH` | `ETH` |
| USDT on Ethereum | `ETH` | `ETH_USDT` | `USDT` |
| TRON native asset | `TRON` | `TRON` | `TRON` |
| USDT on TRON | `TRON` | `TRON_USDT` | `USDT` |
| Bitcoin | `BTC` | `BTC` | `BTC` |

The `asset_id` column shows the corresponding Exchange Wallet asset identifier. An Exchange Wallet transaction returns `asset_id` instead of the on-chain `chain_id` and `token_id` pair.
71 changes: 71 additions & 0 deletions v2/guides/webhooks-callbacks/mpc-tss-request-events.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
title: "MPC TSS request event payload"
lang: "en"
description: "Understand the shared TSSRequest payload for Portal key-generation and resharing webhook events."
---

import WaasSkillReminder from '/snippets/waas_skill_reminder.mdx';

<WaasSkillReminder />

## Overview

The `wallets.mpc.tss_request.*` event family reports MPC key-generation and resharing requests initiated in Cobo Portal. The four events use the same `TSSRequest` payload. See [Webhook event types](/v2/guides/webhooks-callbacks/webhook-event-type) for the catalog.

## TSSRequest payload fields

| Field | Type | Conditional | Description |
| --- | --- | --- | --- |
| `tss_request_id` | string | No | Unique identifier of the TSS request. |
| `source_key_share_holder_group` | object, nullable | Yes | Existing source group for a resharing request. It is absent for initial key generation. |
| `source_key_share_holder_group.key_share_holder_group_id` | string | When the parent is present | Identifier of the source key share holder group. |
| `source_key_share_holder_group.tss_node_ids` | array of strings | When the parent is present | TSS Node identifiers participating from the source group. |
| `target_key_share_holder_group_id` | string | No | Group that the request creates or updates. |
| `type` | string | No | Request type, such as `KeyGen` or `KeyGenFromKeyGroup`. |
| `status` | string | No | Current state of the request. |
| `description` | string, nullable | Yes | Description supplied with the request; it is `null` when none was provided. |
| `created_timestamp` | integer | No | Request creation time as a Unix timestamp in milliseconds. |

<a id="walletsmpctssrequestcreated"></a>
## `wallets.mpc.tss_request.created`

Emitted when the request record is created in its initial state.

### Initial key generation example

```json
{"tss_request_id":"20260721114129000132315000003970","source_key_share_holder_group":null,"target_key_share_holder_group_id":"11111111-1111-4111-8111-111111111111","type":"KeyGen","status":"PendingKeyHolderConfirmation","description":"Create the first Main Group","created_timestamp":1784563200000}
```

<a id="walletsmpctssrequestupdated"></a>
## `wallets.mpc.tss_request.updated`

Emitted when the request moves to a different intermediate state while key holders and MPC processing complete their work.

### Resharing update example

```json
{"tss_request_id":"20260721114129000132315000003971","source_key_share_holder_group":{"key_share_holder_group_id":"22222222-2222-4222-8222-222222222222","tss_node_ids":["cobo5yb7BNEBwwp5XXedbhnzQfvQtp132W4dH4Jz4x4eDp4KA"]},"target_key_share_holder_group_id":"33333333-3333-4333-8333-333333333333","type":"KeyGenFromKeyGroup","status":"MPCProcessing","description":null,"created_timestamp":1784563300000}
```

<a id="walletsmpctssrequestsucceeded"></a>
## `wallets.mpc.tss_request.succeeded`

Emitted when the request reaches the terminal `Success` state.

### Successful resharing example

```json
{"tss_request_id":"20260721114129000132315000003972","source_key_share_holder_group":{"key_share_holder_group_id":"22222222-2222-4222-8222-222222222222","tss_node_ids":["cobo5yb7BNEBwwp5XXedbhnzQfvQtp132W4dH4Jz4x4eDp4KA"]},"target_key_share_holder_group_id":"33333333-3333-4333-8333-333333333333","type":"KeyGenFromKeyGroup","status":"Success","description":null,"created_timestamp":1784563300000}
```

<a id="walletsmpctssrequestfailed"></a>
## `wallets.mpc.tss_request.failed`

Emitted when the request reaches `KeyHolderConfirmationFailed` or `KeyGeneratingFailed`.

### Failed key generation example

```json
{"tss_request_id":"20260721114129000132315000003973","source_key_share_holder_group":null,"target_key_share_holder_group_id":"11111111-1111-4111-8111-111111111111","type":"KeyGen","status":"KeyGeneratingFailed","description":"Create the first Main Group","created_timestamp":1784563200000}
```
32 changes: 26 additions & 6 deletions v2/guides/webhooks-callbacks/set-up-endpoint.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ First, choose a server environment, such as a cloud service like AWS, Google Clo

After you create the endpoint, you need to implement the logic on the server to handle the webhook events or callback messages, including parsing the API request, verifying the signature, responding to the request and adding other handling logic if necessary.

### Callback message payload

A callback message's `data` field uses the same `Transaction` shape as a transaction webhook event. See [Transaction event payload](/v2/guides/webhooks-callbacks/transaction-events) for the complete field table. The values reflect what is known when your endpoint must return `ok` or `deny`; do not treat the callback as the transaction's final state.

| Field | Population at callback time |
| --- | --- |
| `cobo_id` | Can be `null` when Cobo has not yet assigned the tracking identifier. |
| `asset_id` | Populated for an Exchange Wallet asset when that value is available; otherwise `null`. On-chain wallet transactions use `token_id` instead. |
| `result` | `null` until a `MessageSign` result is available, and remains `null` for transaction types that do not produce a signing result. |

Other optional fields depend on transaction type and value availability. Use the [Transaction event payload](/v2/guides/webhooks-callbacks/transaction-events) for the full contract and [Transaction field reference](/v2/guides/transactions/transaction-fields) for reconciliation semantics. Retrieve the transaction through the API or process later transaction events when you need its subsequent state.

### Verify the signature

To prevent unauthorized access, when you receive a webhook event or a callback message, you need to validate the authenticity of the API request by verifying the signature.
Expand Down Expand Up @@ -80,11 +92,12 @@ The verification steps are as follows:

Properly responding to webhook events and callback messages is crucial for ensuring that webhooks and callbacks are processed as expected. This section describes the expected response from both webhook and callback endpoints.

#### Webhook events
<a id="webhook-events"></a>
#### Webhook delivery policy

When your webhook endpoint receives a webhook event, it should respond with a status code of `200` or `201` to indicate that the event has been successfully received and processed. Once this response is sent, the WaaS service will stop retrying to send the event and the event status will become `Delivered` on Cobo Portal.

The default timeout for each webhook event is 2 seconds. If the webhook endpoint does not respond or responds with a status code other than `200` or `201`, the WaaS service will continue to retry sending the event. If the number of retry attempts reaches 10 , the WaaS service will stop sending the event and the event status will become `Failed`· You can resend the event by clicking **Retry** on **Cobo Portal** > **Developer** > **WaaS 2.0** > **Webhook Events**.
The default timeout for each webhook event is 2 seconds. If the webhook endpoint does not respond or responds with a status code other than `200` or `201`, the WaaS service will continue to retry sending the event. If the number of retry attempts reaches 10, the WaaS service will stop sending the event and the event status will become `Failed`. You can resend the event by clicking **Retry** on **Cobo Portal** > **Developer** > **WaaS 2.0** > **Webhook Events**.

Cobo does not guarantee that events will be delivered in the order they are generated. For example, creating a transfer will generate the following events:

Expand All @@ -94,11 +107,14 @@ Cobo does not guarantee that events will be delivered in the order they are gene

Your endpoint should not assume that events will arrive in this sequence and must handle delivery appropriately.

#### Callback messages
<a id="callback-messages"></a>
#### Callback delivery policy

When your callback endpoint receives a callback message, it should respond with a status code of `200` or `201` and a response body of `ok` or `deny` to indicate transaction approval or rejection. Once this response is sent, the WaaS service will stop retrying to send the message and the callback message status will become `Delivered`on Cobo Portal.
When your callback endpoint receives a callback message, it should respond with a status code of `200` or `201` and a response body of `ok` or `deny` to indicate transaction approval or rejection. Once this response is sent, the WaaS service will stop retrying to send the message and the callback message status will become `Delivered` on Cobo Portal.

If the callback endpoint does not respond, responds with a status code other than `200` or `201`, or the response body does not contain `ok` or `deny`, the WaaS service will continue to retry sending the message. If the number of retry attempts reaches 30, the WaaS service will stop sending the message and the callback message status will become `Failed`. You can resend the message by using the [Retry callback message](/v2/api-references/developers/retry-callback-message) operation.
If the callback endpoint does not respond, responds with a status code other than `200` or `201`, or the response body does not contain `ok` or `deny`, the WaaS service will continue to retry sending the message. If the number of retry attempts reaches 30, the WaaS service will stop sending the message and the callback message status will become `Failed`. You can resend the message by using the [Retry callback message](/v2/api-references/developers/retry-callback-message) operation.

Webhook event and callback message records expose their delivery `status` and retry information. For webhooks, inspect the endpoint-scoped attempts with [List webhook event logs](/v2/api-references/developers--webhooks/list-webhook-event-logs). You can also inspect the response status and body for each webhook or callback attempt through the Portal path below. For a full recovery workflow, see [Recover missed or failed events](/v2/guides/webhooks-callbacks/webhook-operations#recover-missed-or-failed-events) in Webhook and callback operations.

### Common delivery failures

Expand Down Expand Up @@ -126,6 +142,10 @@ To see examples of how to implement the handling logic, refer to the following f

## Advanced usage

### Multiple endpoints

When you operate multiple webhook endpoints, or a webhook endpoint together with a callback endpoint, inspect each endpoint's event or message record and endpoint-scoped delivery logs separately. Do not assume that different endpoints share one delivery state. Make every endpoint handler idempotent according to [Important notes](#important-notes).

### Wallet-level webhook routing

In certain business scenarios, you may need to apply different Webhook handling logic for different wallets. For example:
Expand Down Expand Up @@ -188,4 +208,4 @@ async def handle_webhook(
<Warning>
- When receiving the webhook events, your endpoint should first return the correct status code promptly and then handle any subsequent processing asynchronously to prevent timeouts.
- Due to the retry mechanism of webhook events, webhook endpoints may sometimes receive the same event multiple times. To protect against duplicate event processing, please log the event IDs, transaction hashes, or transaction IDs you've already processed and refrain from processing those that are already logged.
</Warning>
</Warning>
Loading