> ## Documentation Index
> Fetch the complete documentation index at: https://trustodian-recovery.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Tron vaults

> Reading the account permissions from the chain and co-signing a transfer out of the vault

A Tron vault is an ordinary Tron account whose **permissions** were replaced. Both of them — `owner`
and `active` — list the same owner addresses, each with weight 1, under the vault's threshold.

Nothing about it is stored off the chain, so this page is a procedure rather than a restore.

## What you need

**1. The vault's address**

From your [Recovery Kit](https://trustodian-recovery.mintlify.site/recovery-kit.md), on the vault's page. It is an ordinary `T...` address.

**2. Enough owners' keys to reach the threshold**

Each key is an owner's **ordinary Tron wallet key** — not a separate cosigner key. Each owner
derives theirs from their own recovery phrase at the index they joined with, as described on
[Tron](https://trustodian-recovery.mintlify.site/tron.md).

**3. TronWeb**

`npm install tronweb`. A public node such as `https://api.trongrid.io` is enough.

**4. TRX in the vault account**

Transactions are paid for in bandwidth and energy, charged to the **vault**, not to the signer. A
vault holding only TRC-20 tokens and no TRX cannot send them. See [Fees](#fees).

## Read the permissions from the chain

Do this first. It is authoritative — the kit records what the vault was configured with, the chain
holds what it actually has.

```js theme={null}
const { TronWeb } = require('tronweb')
const tronWeb = new TronWeb({ fullHost: 'https://api.trongrid.io' })

const account = await tronWeb.trx.getAccount(VAULT_ADDRESS)

console.log(account.owner_permission)   // { threshold, keys: [{ address, weight }] }
console.log(account.active_permission)  // [{ id: 2, threshold, keys, operations }]
```

Check the threshold and the key addresses against the **Threshold** and **Owners** printed on the
vault's page in your kit. If they disagree, trust the chain and find out why before signing anything.

> [!NOTE]
>
> Addresses inside a permission come back as hex. `tronWeb.address.fromHex(...)` converts one to the
> `T...` form printed in your kit.

## Permission 2, not 0

Both permissions carry the same owners and the same threshold, but they authorise different things:

| Permission | Id | What it signs |
| :- | :- | :- |
| `active` | 2 | Spending: transfers, contract calls |
| `owner` | 0 | Changing the permissions themselves |

To move funds you use **2**. Passing the wrong id produces a transaction the network refuses.

## Move the funds

**1. Build the transaction under permission 2**

```js theme={null}
const tx = await tronWeb.transactionBuilder.sendTrx(
  DESTINATION_ADDRESS,
  AMOUNT_IN_SUN,
  VAULT_ADDRESS,
  { permissionId: 2 },
)
```

1 TRX is 1,000,000 SUN.

**2. Have each owner sign in turn, until the threshold is met**

Each call adds one signature to the same transaction object and returns it.

```js theme={null}
let signed = await tronWeb.trx.multiSign(tx, PRIVATE_KEY_A, 2)
signed = await tronWeb.trx.multiSign(signed, PRIVATE_KEY_B, 2)
```

Owners can do this on their own machines, passing the partially signed object along. It carries
signatures, never a private key.

**3. Broadcast**

```js theme={null}
const result = await tronWeb.trx.broadcast(signed)
console.log(result.result) // true
```

## Sending a TRC-20 token

Same two permissions, same signing. Only the build step differs:

```js theme={null}
const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(
  TOKEN_CONTRACT_ADDRESS,
  'transfer(address,uint256)',
  { feeLimit: 100_000_000, permissionId: 2 },
  [
    { type: 'address', value: DESTINATION_ADDRESS },
    { type: 'uint256', value: AMOUNT },
  ],
  VAULT_ADDRESS,
)
```

`AMOUNT` is in the token's own smallest unit, which is not always six decimals — read `decimals()`
off the contract rather than assuming.

## Fees

Bandwidth and energy are charged to the vault account. Neither is bought as such: they come from
staked TRX, or are paid for by burning TRX held by the account.

The practical rule for a recovery: **send a small amount of TRX to the vault address first**, then
move the tokens.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.