TRON (tron-sign-request)
BitTool Signer uses the public Keystone TRON UR types. Do not send TronLink or TokenPocket action JSON, URL schemes or the old keystone-sign-request; they are rejected.
tron-sign-request
| Key | Field | Type | Content |
|---|---|---|---|
| 1 | request-id | 37(bytes) | Exactly 16 random bytes |
| 2 | sign-data | bytes | data-type 1: the raw_data protobuf bytes · data-type 2: the message bytes |
| 3 | data-type | uint | 1 transaction · 2 personal message |
| 4 | derivation-path | 304(crypto-keypath) | m/44'/195'/0'/0/i with master fingerprint |
| 5 | address | bytes (21) | 0x41 ‖ 20-byte account ID: the Base58Check-decoded address, not the text |
| 6 | origin | text | Shown to the user |
data-type 1: transactions
sign-data is the transaction's raw_data serialized as protobuf: the bytes of raw_data_hex, as returned by TronWeb or the /wallet/createtransaction and /wallet/triggersmartcontract APIs. Not the whole Transaction message (which wraps raw_data and signature), not hex text, and not the txID.
The signer computes txID = SHA-256(raw_data) and signs that digest. Rules:
| Rule | Detail |
|---|---|
| One contract | Exactly one entry in raw_data.contract. |
| Timing fields | ref_block_bytes (2 bytes), ref_block_hash (8 bytes), timestamp > 0 and expiration > timestamp. |
| Fee limit | Required (> 0) for TriggerSmartContract. A high fee limit is shown as a warning. |
| Permission | Permission_id 0 (owner) or an active permission ID; 1 (witness) is rejected. |
| Strict protobuf | Unknown fields, duplicate fields and non-canonical varints are rejected. |
| TRC-10 | Not supported, including call_token_value in contract calls. |
Supported contracts:
| Type | Contract | Review |
|---|---|---|
| 1 | TransferContract | TRX amount and recipient |
| 31 | TriggerSmartContract | TRC-20, TRC-721 and TRC-1155 transfers and approvals are decoded (e.g. USDT transfer); other calls are shown as raw calldata and need explicit consent |
| 46 | AccountPermissionUpdateContract | Owner/active permissions, keys, weights, thresholds; always high risk |
| 54–59 | Stake 2.0 and resources: FreezeBalanceV2, UnfreezeBalanceV2, WithdrawExpireUnfreeze, DelegateResource, UnDelegateResource, CancelAllUnfreezeV2 | Amounts, resource type, receiver, lock |
data-type 2: messages
sign-data is the message bytes (1–8,192). The signer follows TIP-191, the scheme of TronWeb's signMessageV2:
digest = Keccak-256( 0x19 ‖ "TRON Signed Message:\n" ‖ decimal(length of message) ‖ message )
Text is displayed as text; other bytes are shown as hex, marked opaque, and need explicit consent.
tron-signature
tron-signature = {
1: 37(request-id bytes),
2: signature ; 65 bytes: r (32) ‖ s (32) ‖ recovery id (0 or 1)
}
The recovery byte is 0 or 1, not 27/28. For transactions, append the 65 bytes as hex to the transaction's signature array, keep raw_data and raw_data_hex unchanged, and broadcast with /wallet/broadcasttransaction (TronWeb: trx.sendRawTransaction).
For messages, many TRON tools (TronWeb's verifyMessageV2, dApps over WalletConnect) expect the last byte as 27/28: add 27 when you hand the signature on. Do not change the transaction signature format.
Code
TRON has no widely used UR registry library, so this sample writes the CBOR directly with cborg, using the keypath helper:
import { randomBytes } from 'node:crypto';
import { UR, UREncoder, URDecoder } from '@ngraveio/bc-ur';
import { base58check } from '@scure/base';
import { sha256 } from '@noble/hashes/sha2.js';
import { encode, decode, Tagged } from 'cborg';
import { SigningKey, computeAddress } from 'ethers';
import { keypath } from './keypath.mjs';
const b58 = base58check(sha256);
// `tx` is an unsigned transaction from TronWeb / the TRON HTTP API: { txID, raw_data, raw_data_hex }
export function buildTronRequest(tx, { path, masterFingerprint, address }) {
const requestId = randomBytes(16);
const cbor = encode(new Map([
[1, new Tagged(37, requestId)], // request-id (uuid)
[2, Buffer.from(tx.raw_data_hex, 'hex')], // raw_data protobuf bytes
[3, 1], // data-type: 1 transaction, 2 message
[4, keypath(path, masterFingerprint)], // "m/44'/195'/0'/0/0"
[5, b58.decode(address)], // 21 bytes: 0x41 ‖ 20-byte account ID
[6, 'BitTool Wallet'], // origin
]));
const encoder = new UREncoder(new UR(Buffer.from(cbor), 'tron-sign-request'), 400);
const frames = [];
for (let i = 0; i < encoder.fragmentsLength; i++) frames.push(encoder.nextPart().toUpperCase());
return { requestId, frames };
}
const tags = { 37: (decode) => decode() }; // tag 37 (uuid): keep the raw bytes
export function attachTronSignature(frames, tx, { requestId, address }) {
const decoder = new URDecoder();
for (const frame of frames) decoder.receivePart(frame);
if (!decoder.isSuccess()) throw new Error('Incomplete or invalid QR');
const ur = decoder.resultUR();
if (ur.type !== 'tron-signature') throw new Error(`Expected tron-signature, got ${ur.type}`);
const response = decode(ur.cbor, { useMaps: true, tags, strict: true });
if (!Buffer.from(response.get(1)).equals(requestId)) throw new Error('Signature is for another request');
const sig = Buffer.from(response.get(2)); // r (32) ‖ s (32) ‖ recovery id (0 or 1)
if (sig.length !== 65 || sig[64] > 1) throw new Error('Unexpected signature format');
const txID = Buffer.from(sha256(Buffer.from(tx.raw_data_hex, 'hex'))).toString('hex');
if (txID !== tx.txID) throw new Error('txID does not match raw_data');
const evmStyle = { r: '0x' + sig.subarray(0, 32).toString('hex'), s: '0x' + sig.subarray(32, 64).toString('hex'), v: 27 + sig[64] };
const recovered = computeAddress(SigningKey.recoverPublicKey('0x' + txID, evmStyle)); // 0x + 20 bytes
if (b58.encode(Buffer.from('41' + recovered.slice(2), 'hex')) !== address) throw new Error('Signed by an unexpected key');
return { ...tx, signature: [...(tx.signature ?? []), sig.toString('hex')] }; // broadcast with sendRawTransaction
}
Test vectors
All from m/44'/195'/0'/0/0 (TUEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH) of the test phrase. The reference block, timestamps and txIDs are synthetic; the transactions were never broadcast.
- TRX transfer
- TRC-20 (USDT)
- Message
Send 1.5 TRX (1,500,000 sun) to TJRabPrwbZy45sbavfcjinPJC18kjpRTv8.
{
"txID": "b396c11e25482bc348d39e620000ef16290d0d17b7649cb94fee63d0203695eb",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"amount": 1500000,
"owner_address": "41c8599111f29c1e1e061265b4af93ea1f274ad78a",
"to_address": "415cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb"
},
"type_url": "type.googleapis.com/protocol.TransferContract"
},
"type": "TransferContract"
}
],
"ref_block_bytes": "a1b2",
"ref_block_hash": "0123456789abcdef",
"expiration": 1792310460000,
"timestamp": 1792310400000
},
"raw_data_hex": "0a02a1b222080123456789abcdef40e0fc9cf094345a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541c8599111f29c1e1e061265b4af93ea1f274ad78a1215415cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb18e0c65b7080a899f09434"
}
Request (your wallet → BitTool Signer)
{
"1 request-id": {
"uuid (tag 37)": "5f1e9b2c7d3a4e6f8a0b1c2d3e4f5a08"
},
"2 sign-data": "0a02a1b222080123456789abcdef40e0fc9cf094345a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541c8599111f29c1e1e061265b4af93ea1f274ad78a1215415cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb18e0c65b7080a899f09434",
"3 data-type": 1,
"4 derivation-path": {
"crypto-keypath (tag 304)": {
"1 components": [
44,
true,
195,
true,
0,
true,
0,
false,
0,
false
],
"2 source-fingerprint": 1942346250
}
},
"5 address": "41c8599111f29c1e1e061265b4af93ea1f274ad78a",
"6 origin": "BitTool Wallet"
}
Show the QR text and raw CBOR
UR:TRON-SIGN-REQUEST/1-2/LPADAOCSURCYBDFNCLLAHDJOOLADTPDAGDHECKNDDWKIFTGLJLLEBDCEDPFMGWHTAYAOHDLPBKAOOYPRCPAYADCNFEIOLDPYSNWSFZVTZTNSWTMWEEHTIOAYADBGIABKDPJYKKJOIHDMIOJLJLIOJZIHHSJOINJKDMIAJLJNDLJOJPJLJYJLIAJLJZDMGHJPHSJTJKIYIHJPFXJLJTJYJPHSIAJYBGEYBKBZFPSPHKMEBYWZNSCKCKAMKIYKMUHK
UR:TRON-SIGN-REQUEST/2-2/LPAOAOCSURCYBDFNCLLAHDJOBGIHQZPEMUWDCTDIGETSLEBGBZFPHHRYTPIMDLPDUOGRUTTPPDYNNTRDFDHGDMWPATZOCSVTSWHPJOLAPDNLWTMWEEAXADAATAADDYOEADLECSDWYKCSSRYKAEYKAEWKAEWKAOCYJKSKTNBKAHGOFPSPHKMEBYWZNSCKCKAMBGIHQZPEMUWDCTDIGETSLEAMJTFWINJYGHJLJLJZCXHGHSJZJZIHJYAECEGYGWVW
a601d825505f1e9b2c7d3a4e6f8a0b1c2d3e4f5a080258850a02a1b222080123456789abcdef40e0fc9cf094345a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541c8599111f29c1e1e061265b4af93ea1f274ad78a1215415cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb18e0c65b7080a899f09434030104d90130a2018a182cf518c3f500f500f400f4021a73c5da0a055541c8599111f29c1e1e061265b4af93ea1f274ad78a066e426974546f6f6c2057616c6c6574
Response (BitTool Signer → your wallet)
{
"request-id": {
"uuid": "5f1e9b2c7d3a4e6f8a0b1c2d3e4f5a08"
},
"signature": "32c82fe12ddef67b967c836692f7a729003481e6b0f070b1ac6ee7742ac27e18611174e6a54efb7f5f5e14adfbb9118bb137f064881777316ed593ea5da4a25d01"
}
Show the QR text and raw CBOR
UR:TRON-SIGNATURE/OEADTPDAGDHECKNDDWKIFTGLJLLEBDCEDPFMGWHTAYAOHDFPEYSPDLVYDPUEYNKGMTKELSIYMOYLOSDTAEEELYVAPFWTJOPAPSJTVDJYDRSAKBCSHSBYJYVAONGLZOLBHEHYBBPMZORHBYLUPAEMWTIELOCHKTEHJTTLMUWDHLOXOEHLADEEFEIELE
a201d825505f1e9b2c7d3a4e6f8a0b1c2d3e4f5a0802584132c82fe12ddef67b967c836692f7a729003481e6b0f070b1ac6ee7742ac27e18611174e6a54efb7f5f5e14adfbb9118bb137f064881777316ed593ea5da4a25d01
Assembled by your wallet
{
"txID": "b396c11e25482bc348d39e620000ef16290d0d17b7649cb94fee63d0203695eb",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"amount": 1500000,
"owner_address": "41c8599111f29c1e1e061265b4af93ea1f274ad78a",
"to_address": "415cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb"
},
"type_url": "type.googleapis.com/protocol.TransferContract"
},
"type": "TransferContract"
}
],
"ref_block_bytes": "a1b2",
"ref_block_hash": "0123456789abcdef",
"expiration": 1792310460000,
"timestamp": 1792310400000
},
"raw_data_hex": "0a02a1b222080123456789abcdef40e0fc9cf094345a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541c8599111f29c1e1e061265b4af93ea1f274ad78a1215415cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb18e0c65b7080a899f09434",
"signature": [
"32c82fe12ddef67b967c836692f7a729003481e6b0f070b1ac6ee7742ac27e18611174e6a54efb7f5f5e14adfbb9118bb137f064881777316ed593ea5da4a25d01"
]
}
Send 10 USDT: a TriggerSmartContract to the USDT contract TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t with transfer(address,uint256) calldata and a 30 TRX fee limit.
{
"txID": "2e5c3786422acf86e667ebfc0afcce8261407c39117d9b2c20f386064822f60b",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"data": "a9059cbb0000000000000000000000005cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb0000000000000000000000000000000000000000000000000000000000989680",
"owner_address": "41c8599111f29c1e1e061265b4af93ea1f274ad78a",
"contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c"
},
"type_url": "type.googleapis.com/protocol.TriggerSmartContract"
},
"type": "TriggerSmartContract"
}
],
"ref_block_bytes": "a1b2",
"ref_block_hash": "0123456789abcdef",
"expiration": 1792310460000,
"fee_limit": 30000000,
"timestamp": 1792310400000
},
"raw_data_hex": "0a02a1b222080123456789abcdef40e0fc9cf094345aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a1541c8599111f29c1e1e061265b4af93ea1f274ad78a121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb0000000000000000000000005cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb00000000000000000000000000000000000000000000000000000000009896807080a899f0943490018087a70e"
}
Request (your wallet → BitTool Signer)
{
"1 request-id": {
"uuid (tag 37)": "5f1e9b2c7d3a4e6f8a0b1c2d3e4f5a09"
},
"2 sign-data": "0a02a1b222080123456789abcdef40e0fc9cf094345aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a1541c8599111f29c1e1e061265b4af93ea1f274ad78a121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb0000000000000000000000005cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb00000000000000000000000000000000000000000000000000000000009896807080a899f0943490018087a70e",
"3 data-type": 1,
"4 derivation-path": {
"crypto-keypath (tag 304)": {
"1 components": [
44,
true,
195,
true,
0,
true,
0,
false,
0,
false
],
"2 source-fingerprint": 1942346250
}
},
"5 address": "41c8599111f29c1e1e061265b4af93ea1f274ad78a",
"6 origin": "BitTool Wallet"
}
Show the QR text and raw CBOR
UR:TRON-SIGN-REQUEST/1-2/LPADAOCFADDPCYFYCYDLTOHDMSOLADTPDAGDHECKNDDWKIFTGLJLLEBDCEDPFMGWHTASAOHDTEBKAOOYPRCPAYADCNFEIOLDPYSNWSFZVTZTNSWTMWEEHTPLADAYCTBGPTADBKEHJYKKJOIHDMIOJLJLIOJZIHHSJOINJKDMIAJLJNDLJOJPJLJYJLIAJLJZDMGHJPINIOIOIHJPGUJNHSJPJYFXJLJTJYJPHSIAJYBGJYBKBZFPSPHKMEBYWZNSCKCKAMBGIHQZPEMUWDCTDIGETSLEBGBZFPOLBBYAAXRPZCKSASLNOXDWKSWPNSLBKTVAUETTJSFXCFGD
UR:TRON-SIGN-REQUEST/2-2/LPAOAOCFADDPCYFYCYDLTOHDMSFNCPFYPTAHNSRKAEAEAEAEAEAEAEAEAEAEAEAEHHRYTPIMDLPDUOGRUTTPPDYNNTRDFDHGDMWPATZOAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEMKMTLAJOLAPDNLWTMWEEMHADLALTOSBAAXADAATAADDYOEADLECSDWYKCSSRYKAEYKAEWKAEWKAOCYJKSKTNBKAHGOFPSPHKMEBYWZNSCKCKAMBGIHQZPEMUWDCTDIGETSLEAMJTFWINJYGHJLJLJZCXHGHSJZJZIHJYAESFYNZELT
a601d825505f1e9b2c7d3a4e6f8a0b1c2d3e4f5a090258d30a02a1b222080123456789abcdef40e0fc9cf094345aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a1541c8599111f29c1e1e061265b4af93ea1f274ad78a121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb0000000000000000000000005cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb00000000000000000000000000000000000000000000000000000000009896807080a899f0943490018087a70e030104d90130a2018a182cf518c3f500f500f400f4021a73c5da0a055541c8599111f29c1e1e061265b4af93ea1f274ad78a066e426974546f6f6c2057616c6c6574
Response (BitTool Signer → your wallet)
{
"request-id": {
"uuid": "5f1e9b2c7d3a4e6f8a0b1c2d3e4f5a09"
},
"signature": "3a4b9d2c4b9872ee24d74a88919640d24ad760dd80399aa872844010f3b5141e7ddad3c3067f1e875c0bd18d176e8ea9995304d16395c81b98973dc55173293e01"
}
Show the QR text and raw CBOR
UR:TRON-SIGNATURE/OEADTPDAGDHECKNDDWKIFTGLJLLEBDCEDPFMGWHTASAOHDFPFTGRNTDWGRMKJPWYDKTSGELOMEMTFZTDGETSHNUTLAESNYPDJPLRFZBEWFREBBCKKITNTESRAMLBCKLTHHBDTTLGCHJTMNPTNLGUAATTIAMDSPCWMKMSFSSKGYJKDTFMADSACKWEWN
a201d825505f1e9b2c7d3a4e6f8a0b1c2d3e4f5a090258413a4b9d2c4b9872ee24d74a88919640d24ad760dd80399aa872844010f3b5141e7ddad3c3067f1e875c0bd18d176e8ea9995304d16395c81b98973dc55173293e01
Assembled by your wallet
{
"txID": "2e5c3786422acf86e667ebfc0afcce8261407c39117d9b2c20f386064822f60b",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"data": "a9059cbb0000000000000000000000005cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb0000000000000000000000000000000000000000000000000000000000989680",
"owner_address": "41c8599111f29c1e1e061265b4af93ea1f274ad78a",
"contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c"
},
"type_url": "type.googleapis.com/protocol.TriggerSmartContract"
},
"type": "TriggerSmartContract"
}
],
"ref_block_bytes": "a1b2",
"ref_block_hash": "0123456789abcdef",
"expiration": 1792310460000,
"fee_limit": 30000000,
"timestamp": 1792310400000
},
"raw_data_hex": "0a02a1b222080123456789abcdef40e0fc9cf094345aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a1541c8599111f29c1e1e061265b4af93ea1f274ad78a121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb0000000000000000000000005cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb00000000000000000000000000000000000000000000000000000000009896807080a899f0943490018087a70e",
"signature": [
"3a4b9d2c4b9872ee24d74a88919640d24ad760dd80399aa872844010f3b5141e7ddad3c3067f1e875c0bd18d176e8ea9995304d16395c81b98973dc55173293e01"
]
}
A sign-in message. The digest below is what the signature covers; walletConnectResult shows the signature with the recovery byte as 27/28, the form a dApp expects.
776428ce260fe31d65dc919f1d241a4508bef2660770202dc20c537e391ce070
Request (your wallet → BitTool Signer)
{
"1 request-id": {
"uuid (tag 37)": "5f1e9b2c7d3a4e6f8a0b1c2d3e4f5a0a"
},
"2 sign-data": "5369676e20696e20746f204578616d706c6520417070206f6e2054524f4e2e204e6f6e63653a20346339643231",
"3 data-type": 2,
"4 derivation-path": {
"crypto-keypath (tag 304)": {
"1 components": [
44,
true,
195,
true,
0,
true,
0,
false,
0,
false
],
"2 source-fingerprint": 1942346250
}
},
"5 address": "41c8599111f29c1e1e061265b4af93ea1f274ad78a",
"6 origin": "BitTool Wallet"
}
Show the QR text and raw CBOR
UR:TRON-SIGN-REQUEST/OLADTPDAGDHECKNDDWKIFTGLJLLEBDCEDPFMGWHTBKAOHDDPGUINIOJTCXINJTCXJYJLCXFEKSHSJNJOJZIHCXFPJOJOCXJLJTCXGHGMGWGLDMCXGLJLJTIAIHFTCXEEIAESIEEYEHAXAOAATAADDYOEADLECSDWYKCSSRYKAEYKAEWKAEWKAOCYJKSKTNBKAHGOFPSPHKMEBYWZNSCKCKAMBGIHQZPEMUWDCTDIGETSLEAMJTFWINJYGHJLJLJZCXHGHSJZJZIHJYOERLBKNE
a601d825505f1e9b2c7d3a4e6f8a0b1c2d3e4f5a0a02582d5369676e20696e20746f204578616d706c6520417070206f6e2054524f4e2e204e6f6e63653a20346339643231030204d90130a2018a182cf518c3f500f500f400f4021a73c5da0a055541c8599111f29c1e1e061265b4af93ea1f274ad78a066e426974546f6f6c2057616c6c6574
Response (BitTool Signer → your wallet)
{
"request-id": {
"uuid": "5f1e9b2c7d3a4e6f8a0b1c2d3e4f5a0a"
},
"signature": "8dc0ce437fd46a9acfec62c7eb1632ab7fe6b8fb3308a629a656ece0d899968f37830d8cafa7356903bd0ca8159bc6bc41d6caac62c5613c042396769bb8aa2301"
}
Show the QR text and raw CBOR
UR:TRON-SIGNATURE/OEADTPDAGDHECKNDDWKIFTGLJLLEBDCEDPFMGWHTBKAOHDFPLGRTTOFXLBTYIMNYTKWPIDSTWMCMEYPYLBVAROZOEOAYOLDTOLHFWPVTTPNLMTMYEMLSBTLKPEOSECINAXRYBNPDBZNDSWRFFPTBSGPSIDSKHSFNAACNMTKONDROPKCNADGYMKCHTD
a201d825505f1e9b2c7d3a4e6f8a0b1c2d3e4f5a0a0258418dc0ce437fd46a9acfec62c7eb1632ab7fe6b8fb3308a629a656ece0d899968f37830d8cafa7356903bd0ca8159bc6bc41d6caac62c5613c042396769bb8aa2301
Assembled by your wallet
0x8dc0ce437fd46a9acfec62c7eb1632ab7fe6b8fb3308a629a656ece0d899968f37830d8cafa7356903bd0ca8159bc6bc41d6caac62c5613c042396769bb8aa231c
Multisig accounts
For an account with multisig permissions, each member signs separately:
- Put the member's path and address in keys 4 and 5. The account in
owner_addressmay be a different address, and BitTool Signer never picks a signer just because it appears as owner or as a permission member. - Set
Permission_idin the contract to the permission being used. - BitTool Signer only sees
raw_data. Your wallet keeps the signatures already collected, adds each new one, removes duplicates, and checks the on-chain permission (members, weights, threshold, operations) before broadcasting. The signer cannot verify current on-chain permissions offline.