Rising Tide Developers
SDKCore

rtClient.pendingTransactions

SDK methods for registering and polling broadcast transactions whose confirmation is reconciled against the chain.

Substrate records (instances, payments, status flips) are created confirmed straight from the chainhook. If a chainhook is missed or delayed, that confirmation never lands and there is no server-side trace of the expected transaction. The pendingTransactions surface closes that gap: register a broadcast transaction id and a reconciler cron re-reads the chain and replays any stuck confirmation through the same idempotent handler.

When to call it:

  • Bring-your-own-wallet flows call register right after broadcasting, then poll getStatus to drive settling UX.
  • Privy flows self-register server-side at broadcast time - they only need to poll getStatus.

See How State Syncs for what the protocol guarantees between broadcast and confirmation.

Register

rtClient.pendingTransactions.register(input)

Records that a broadcast transaction is expected to produce a chainhook event. Idempotent on txId - a repeat call returns the existing row.

const { data } = await rtClient.pendingTransactions.register({
  txId: "0xabc...",          // required - the broadcast transaction id
  network: "testnet",        // optional - "mainnet" | "testnet"
  sourceApp: "grammata",     // optional - cosmetic label for operator debugging
  context: { kind: "edition" }, // optional - free-form, never branched on
});

RegisterPendingTransactionInput:

FieldTypeRequiredNotes
txIdstringyesBroadcast transaction id. The only required field.
network"mainnet" | "testnet"noDefaults to the server's configured network.
sourceAppstringnoClient/operator label. Never affects reconciliation.
contractAddress / contractNamestringnoThe target contract. Passing both lets the server resolve the row's chainhookUuid at registration; omit and it resolves lazily on recovery.
contextRecord<string, unknown>noFree-form context, e.g. { kind: "edition" }.

Status

rtClient.pendingTransactions.getStatus(txId)

Reads the current reconciliation status for a transaction. Poll this to drive a settling indicator; stop when status is CONFIRMED or FAILED. See Status Machines for every transition.

const { data } = await rtClient.pendingTransactions.getStatus("0xabc...");
if (data.status === "CONFIRMED") {
  // confirmation landed - the chainhook applied its effects
}

PendingTransactionStatus:

FieldTypeNotes
txIdstringThe transaction id.
statusPendingTxStatusSee lifecycle below.
blockHeightnumber | nullSet once the transaction is mined.
resolvedAtstring | nullISO timestamp when the row reached a terminal state.
lastErrorstring | nullPopulated on a failure terminal.

Status lifecycle

PendingTxStatus:

ValueMeaningTerminal?
BROADCASTRegistered, awaiting confirmationNo
REPLAYINGThe reconciler is replaying a missed confirmationNo
CONFIRMEDThe chainhook (or a replay) applied the transaction's effectsYes
FAILEDThe transaction aborted on chainYes
DROPPEDNever mined within the mempool window, or recovery exhaustedNo - an operator can reopen it
HANDLER_FAILEDThe chainhook arrived but the handler threw - owned by the dead-letter queue, which can still confirm itNo

The happy path is BROADCAST -> CONFIRMED; recovery from a missed chainhook is BROADCAST -> REPLAYING -> CONFIRMED. "Mined" is not a status - it is recorded as the blockHeight column, because a mined transaction can still be reversed by a reorg before it confirms.

Operator surface

Operators reconcile and browse pending transactions through RisingTideAdmin.pendingTransactions (list, reconcile). See Admin.