wallet-cli permission update¶
Replace the account's permission structure.
Synopsis¶
wallet-cli permission update (--file <path> | --json <str>)
[--dry-run | (--sign-only | --build-only) [--expiration <ms>] | --wait [--wait-timeout <ms>]]
[--permission-id <n>] [options]
Description¶
Replaces the account's entire permission structure with the new one given by --file (a JSON file) or --json (an inline JSON string) — TRON's UpdateAccountPermission has replace semantics, so the JSON you supply becomes the whole structure. The chain burns 100 TRX for the change.
The command runs without a confirmation prompt. It requires an account. The master password via --password-stdin is needed only when the selected mode signs — --dry-run and --build-only do not unlock the wallet and run without it. Watch-only accounts fail with watch_only_no_signer in a signing mode.
Input format. The permission JSON is the same shape as permission show -o json's data (owner / witness / actives; a key's local field may be omitted). You write the contract-type names for each active group's operations, not the raw bitmap — the CLI encodes it. A convenient way to produce a valid input is to export the current structure, edit it, and submit the file.
The structure is validated strictly before anything is built, and a violation is a usage error (exit 2) rather than a silent normalisation. In particular a group's threshold may not exceed the sum of its key weights — an unreachable threshold is itself a lockout, so it is refused with invalid_permission (owner.threshold exceeds the total key weight). Thresholds and weights are parsed losslessly, so a value beyond the safe-integer range is rejected rather than rounded.
Editing an exported structure. permission show -o json emits both operations (contract-type names) and operationsHex (the raw bitmap) for each active group. Supplying both is allowed, but they must agree — two disagreeing descriptions of the same group would mean the structure you reviewed is not the structure that goes on chain, so the mismatch is refused. After editing operations, delete that group's operationsHex and the CLI regenerates it:
wallet-cli permission show -o json --network tron:3448148188 | jq '.data' > perms.json
# edit operations, then drop the stale operationsHex from the same active group
Changing only keys, threshold or name needs no such deletion.
⚠️ The chain applies no safety checks. Even if the new structure contains no key you can sign with, the transaction still succeeds and the account is permanently locked, with no on-chain recovery. This CLI can surface four local warning codes but does not block the submission (in JSON they go to meta.warnings, and success stays true):
- Lockout risk — when the combined weight of your locally-signable owner keys (software / Ledger) is below the new owner threshold, a
warning:line on stderr spells out that you can no longer meet the owner threshold on your own (owner_lockoutif you hold no weight,owner_lockout_partialif you now need co-signers). Multi-party custody legitimately means "I alone can't reach the threshold", so this is a notice, not a block. - Dangerous operations — when an active group includes
Update Account Permissions(that group could then change the permissions themselves, effectively owner-level), awarning:line on stderr flags it (active_can_update_permission). - Unknown operations — when an active bitmap grants contract-type ids this build cannot name, the ids are preserved and reported as
active_unknown_operationsrather than silently dropped.
Options¶
| Option | Description |
|---|---|
--file <path> |
Required (one of). JSON file with the new structure (same shape as permission show -o json data); replaces the whole thing |
--json <string> |
Required (one of). Inline JSON string with the new structure (same shape) |
--dry-run |
Mock receipt — fee, resulting-structure card, and warnings — matching a real submission; no signature, no broadcast, no password. Excludes --sign-only / --build-only |
--sign-only |
Build and sign, output the signed hex without broadcasting (feed tx broadcast for on-chain co-signing). Excludes --dry-run / --build-only; pairs with --expiration |
--build-only |
Build and estimate, output the unsigned hex (feed tx multisig --create for service-relayed multi-sig). Excludes --dry-run / --sign-only; pairs with --expiration |
--expiration <ms> |
Transaction expiration in ms, up to 86400000 (24h); only with --sign-only or --build-only; omitted = node default (~60s) |
--permission-id <n> |
Permission group to sign with (0=owner, 1=witness, 2-9=active) — changing permissions is owner-level, so normally 0 (default 0) |
--wait / --wait-timeout <ms> |
Poll after broadcast until confirmed/failed (cap default: config waitTimeoutMs, built-in 60000) |
--password-stdin |
Master password from stdin |
Plus the global options.
Examples¶
In the examples, $PW is your master password, fed on stdin via --password-stdin.
Prepare the new structure by exporting, then editing (no need to hand-write the operations bitmap):
wallet-cli permission show --network tron:3448148188 -o json | jq '.data' > perms.json
# edit perms.json — e.g. turn the owner group into a 2-of-3
$EDITOR perms.json
Submit with --wait. Safety warnings are written to stderr as warning: ... before the stdout receipt. After confirmation, the receipt includes the resulting on-chain structure when the follow-up read succeeds, using the same cards as permission show:
echo "$PW" | wallet-cli permission update --file perms.json --network tron:3448148188 --wait --password-stdin
warning: local keys hold 1 of 2 owner weight; co-signers are required for owner-level operations
✅ Permissions updated
TxID b3c...
Block #84,335,102
Fee 100.268 TRX
Status success
Account TQkXm4vN8pR2sD6fWbYc3LhJa9Ee5Zt7Uw
Permission Name owner (id 0)
Threshold 2
Authorized To Address Weight
TQkXm4vN8pR2sD6fWbYc3LhJa9Ee5Zt7Uw 1 (this wallet: main)
TBy6mQ7Y3nJ8sD2fWpXk4LhVc9Ra1Zt5Ub 1
TXe4Kd8nP2rF9gH5jL3mV6cW1bN7yS0aQz 1
Permission Name finance (id 2, active)
Operation(s) Transfer TRX · Transfer TRC10 · Trigger Smart Contract (3 total)
Threshold 2
Authorized To Address Weight
TQkXm4vN8pR2sD6fWbYc3LhJa9Ee5Zt7Uw 1 (this wallet: main)
TBy6mQ7Y3nJ8sD2fWpXk4LhVc9Ra1Zt5Ub 1
TXe4Kd8nP2rF9gH5jL3mV6cW1bN7yS0aQz 1
When present, the JSON receipt's data.permissions is structurally identical to permission show's data, so you can diff it against the pre-change export. If the confirmed post-check cannot be read, the field is omitted and meta.warnings contains permission_postcheck_unavailable; the confirmed transaction still has success: true. The lockout warning is also in meta.warnings:
echo "$PW" | wallet-cli permission update --file perms.json --network tron:3448148188 --wait --password-stdin -o json
{"schema":"wallet-cli.result.v1","success":true,"command":"permission.update","data":{"kind":"permission-update","stage":"confirmed","txId":"b3c...","confirmed":true,"blockNumber":84335102,"feeSun":100268000,"failed":false,"permissions":{"address":"TQkXm4vN8pR2sD6fWbYc3LhJa9Ee5Zt7Uw","owner":{"id":0,"name":"owner","threshold":2,"keys":[{"address":"TQkXm4vN8pR2sD6fWbYc3LhJa9Ee5Zt7Uw","weight":1,"local":"main"},{"address":"TBy6mQ7Y3nJ8sD2fWpXk4LhVc9Ra1Zt5Ub","weight":1,"local":null},{"address":"TXe4Kd8nP2rF9gH5jL3mV6cW1bN7yS0aQz","weight":1,"local":null}]},"witness":null,"actives":[{"id":2,"name":"finance","threshold":2,"operations":["TransferContract","TransferAssetContract","TriggerSmartContract"],"operationLabels":["Transfer TRX","Transfer TRC10","Trigger Smart Contract"],"operationsHex":"0600008000000000000000000000000000000000000000000000000000000000","unknownOperationIds":[],"keys":[{"address":"TQkXm4vN8pR2sD6fWbYc3LhJa9Ee5Zt7Uw","weight":1,"local":"main"},{"address":"TBy6mQ7Y3nJ8sD2fWpXk4LhVc9Ra1Zt5Ub","weight":1,"local":null},{"address":"TXe4Kd8nP2rF9gH5jL3mV6cW1bN7yS0aQz","weight":1,"local":null}]}]}},"meta":{"durationMs":6810,"warnings":[{"code":"owner_lockout_partial","message":"local keys hold 1 of 2 owner weight; co-signers are required for owner-level operations"}]},"chain":{"family":"tron","network":"tron:3448148188","chainId":"3448148188"}}
Output¶
data varies by mode:
| Mode | Fields |
|---|---|
| default (submit) | kind: "permission-update", stage: "submitted", txId |
--wait (confirmed) |
the above, but stage: "confirmed", plus confirmed, blockNumber, feeSun, failed, and optional permissions (same shape as permission show data when the post-check read succeeds) |
--dry-run |
kind, mode: "dry-run", tx, fee (the account-permission fee), and permissions (the resulting structure); no txId |
--sign-only |
kind, mode: "sign-only", signed, hex (signed tx hex — feed tx broadcast --hex), fee, address, txId, and permissions |
--build-only |
kind, mode: "build-only", tx, hex (unsigned tx hex — feed tx multisig --create), fee, and permissions |
Local warnings (owner_lockout, owner_lockout_partial, active_can_update_permission, active_unknown_operations) are emitted before the transaction is built, appear in meta.warnings as {code, message} objects, and do not affect success — see reading meta.warnings.
Post-confirmation warnings use permission_postcheck_unavailable when the read-back fails and permission_postcheck_mismatch when the returned structure differs. In either case the transaction is already confirmed, so the command remains successful and callers must treat permissions as optional.
Exit status¶
0 submitted (or built/signed/dry-run in early-exit modes) · 1 execution failure (not_authorized, watch_only_no_signer, auth_failed, insufficient_balance, rpc_error, timeout) · 2 usage error (invalid_permission — malformed JSON or an invalid permission structure; invalid_value).
On a multi-sig account, a submission whose accumulated signature weight is below the permission threshold is refused after signing and before broadcasting with not_authorized (signature threshold is not reached; missing N weight) — nothing is sent and no fee is burned. Collect the remaining signatures through --sign-only + tx sign and submit with tx broadcast instead. --sign-only and --build-only still return a partial signature, which is how a co-signing flow starts.
See also¶
permission show · tx sign · tx broadcast · tx multisig · Security