SettleMint
Events

token.transfer.final

Reference for the DALP token.transfer.final webhook event that confirms an indexed token transfer reached finality.

token.transfer.final tells a webhook consumer that DALP indexed a token transfer and the transfer passed the configured reorg depth.

Use this event to update downstream ledgers, reconciliation queues, and notification systems only after the transfer is no longer provisional.

The event is part of the token transfer lifecycle. Pending observations can arrive before block inclusion; final events confirm the indexed on-chain log after finality checks. Consumers should treat the event payload as the stable transfer record and use the delivery envelope for idempotent processing.

Delivery contract

FieldValue
Event typetoken.transfer.final
Version1
Lifecycle statefinal
Counter-signed receipt requiredtrue
SDK typeWebhook.TokenTransferFinalV1

Related references:

  • idxr_token: the indexed token that emitted the transfer.
  • idxr_transfer: the indexed transfer row for the finalized log.

When to consume this event

Consume token.transfer.final when your integration needs a final transfer outcome rather than an early observation. Typical consumers include accounting exports, settlement reconciliation, investor notifications, and compliance monitoring systems that should not react to a transfer until the chain observation is final.

Do not use this event as a replacement for webhook verification. Verify the signature, timestamp, and event identifier before you process the payload.

Store evt_id, request.idempotency_key when present, and the transfer identifiers. These values keep a retry or replay from creating a duplicate downstream action.

See webhook idempotency and on-chain outcome for retry, replay, and lifecycle handling across pending, final, retracted, and recalled events.

Payload fields

FieldTypeMeaning
tokenAddressEVM addressToken contract that emitted the transfer.
chainIdIntegerEVM chain identifier for the indexed transfer.
fromEVM addressSender address recorded on the transfer log.
toEVM addressRecipient address recorded on the transfer log.
amountStringRaw token amount from the transfer event. Interpret decimals from the token metadata used by your integration.
transactionHash32-byte EVM hashTransaction that contained the transfer log.
blockNumberIntegerBlock that contained the finalized transfer log.
logIndexIntegerLog index of the transfer within the transaction receipt.

Payload schema

{
  "type": "object",
  "properties": {
    "tokenAddress": {
      "type": "string",
      "pattern": "^0x[a-fA-F0-9]{40}$"
    },
    "chainId": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    },
    "from": {
      "type": "string",
      "pattern": "^0x[a-fA-F0-9]{40}$"
    },
    "to": {
      "type": "string",
      "pattern": "^0x[a-fA-F0-9]{40}$"
    },
    "amount": {
      "type": "string"
    },
    "transactionHash": {
      "type": "string",
      "pattern": "^0x[a-fA-F0-9]{64}$"
    },
    "blockNumber": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "logIndex": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "tokenAddress",
    "chainId",
    "from",
    "to",
    "amount",
    "transactionHash",
    "blockNumber",
    "logIndex"
  ],
  "additionalProperties": false
}

TypeScript SDK example

import { verifyWebhook, type Webhook } from "@settlemint/dalp-sdk";

const result = verifyWebhook({
  rawBody,
  headers,
  secret: process.env.DALP_WEBHOOK_SECRET!,
});

if (!result.ok) {
  throw new Error(`Webhook verification failed: ${result.code}`);
}

if (result.event.type === "token.transfer.final") {
  const event: Webhook.Event<"token.transfer.final"> = result.event;
  const { transactionHash, logIndex, amount } = event.payload;

  await recordFinalTransfer({
    eventId: event.evt_id,
    idempotencyKey: event.request?.idempotency_key,
    transactionHash,
    logIndex,
    amount,
  });
}

curl example

curl -X POST https://consumer.example.com/dalp/webhooks \
  -H "content-type: application/json" \
  -H "webhook-id: evt_docs_token_transfer_final_001" \
  -H "webhook-timestamp: 1778112000" \
  -H "webhook-signature: v1,docs-example-signature" \
  --data '{"evt_id":"evt_docs_token_transfer_final_001","type":"token.transfer.final","version":1,"lifecycle_state":"final","request":{"idempotency_key":"idem_01JZP7R5W8M9N0P1Q2R3S4T5"},"related":{"idxr_token":"idxr_token_example","idxr_transfer":"idxr_transfer_example"},"payload":{"tokenAddress":"0x5555555555555555555555555555555555555555","chainId":537001,"from":"0x6666666666666666666666666666666666666666","to":"0x7777777777777777777777777777777777777777","amount":"250000000000000000000","transactionHash":"0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc","blockNumber":18445240,"logIndex":7}}'

Version history

  • Version 1: Initial registry entry for token.transfer.final.

Deprecation

This event type is not deprecated.

Manifest

The machine-readable AsyncAPI entry is published in the DALP events manifest.

On this page