Skip to content

Multi-Signature Transfer

Overview

For this section, you may refer to General Transfer

Prerequisite: The DApp connection has been authorized via eth_requestAccounts (see Start Developing).

Query active permissions

multiSign requires a valid permissionId for an active permission on the signing account. Active permissions are returned by tronWeb.trx.getAccount(address) under the active_permission[] field; each entry exposes id, permission_name, threshold, and the keys[] array (address + weight). Owner permissions have a fixed id of 0 and are exposed under owner_permission separately.

const tronweb = window.tron.tronWeb;
const account = await tronweb.trx.getAccount(tronweb.defaultAddress.base58);
// account.active_permission is the array — pick the id whose keys[] includes
// the address you intend to sign with, and whose weight + threshold allow the tx.
const activePermissions = account.active_permission ?? [];
console.log(activePermissions.map(p => ({ id: p.id, name: p.permission_name, threshold: p.threshold })));

Use the resulting id as permissionId below.

Specification

Example

const tronweb = window.tron.tronWeb;
const toAddress = "TRKb2nAnCBfwxnLxgoKJro6VbyA6QmsuXq";
const activePermissionId = 2; // obtained via tronWeb.trx.getAccount(...).active_permission
const tx = await tronweb.transactionBuilder.sendTrx(
  toAddress, 10,
  { permissionId: activePermissionId }
); // Step 1
try {
  const signedTx = await tronweb.trx.multiSign(tx, undefined, activePermissionId); // Step 2
  await tronweb.trx.sendRawTransaction(signedTx); // Step 3
} catch (e) {}

If the user chooses “Reject” in the pop-up window, an exception will be thrown, which the developer can catch for further processing. If the user chooses “Sign” in the pop-up window, the DApp receives and broadcasts the signed transaction.

Note that the broadcast only collects one signature in this call — a fully signed multi-sig tx requires the threshold to be met across multiple multiSign calls (one per co-signer). Track the partially-signed transaction off-chain (or via the MCP tl_multisig_* tools) until the threshold is reached, then broadcast.

Errors

Code Meaning Where it comes from Retryable?
4001 User clicked Reject in the signing popup tronWeb.trx.multiSign(...) No — user declined
(thrown) permission_id not active / permission_id not exist transactionBuilder.sendTrx({permissionId}) — wrong or revoked permission No — re-query getAccount(...).active_permission
(thrown) Signature weight below threshold after broadcast sendRawTransaction No — collect more signatures (one multiSign call per co-signer)
REVERT / OUT_OF_ENERGY / FAILED Broadcast succeeded but execution failed on-chain getTransactionInfo(txid) No — the tx is final; never auto-retry

For cross-surface translation see the Error Code Map.