Deposit BTC
To use BTC on Sui, you deposit it with Hashi and receive hBTC, a fungible
Coin<BTC>, at your Sui address. You can make a deposit with the Hashi CLI or
with the TypeScript SDK. Both follow the same 3 steps: derive your deposit
address, send BTC to it, and record the funding transaction on Sui. This page
covers the steps. For what the committee does with your request, see the
Deposit lifecycle.
- Prerequisites
- A Sui address funded with SUI for gas, and its private key in one of the accepted key formats.
- A Bitcoin wallet holding BTC on the network that matches your Sui network. Hashi pairs Sui Mainnet with Bitcoin Mainnet and Sui Testnet with Bitcoin Signet. See the Networks table.
- For the CLI: a
hashibinary built as described in Software dependencies and a CLI config file from CLI config. - For the SDK: a Node.js project with
@mysten/hashiand@mysten/suiinstalled as described in TypeScript SDK.
Before you deposit
Keep the following rules in mind:
- Minimum amount: Each deposit must be at least
bitcoin_deposit_minimum. Hashi rejects smaller deposits onchain. - Your keys do not control the deposit address: The address is spendable only by the Hashi committee together with the Guardian. See Bitcoin Address Scheme.
- One address per Sui address: Hashi derives the deposit address from the
Sui address that receives the
hBTC. Sending to the wrong address credits the wrong Sui account. - Record the deposit yourself: Hashi does not scan Bitcoin for incoming
funds. It mints
hBTConly after you record the funding transaction on Sui.
Deposit with the CLI
CLI global options such as -c belong after the first-level subcommand, so
-c goes after deposit. See
Global options for the full
rule and the environment variables that replace the flags.
Step 1: Generate your deposit address
Run the following command with the Sui address that receives the hBTC:
hashi deposit -c hashi-cli.toml generate-address --recipient 0x<sui-address>
The command derives a Taproot address from the onchain MPC public key and the Guardian key. The result is the same every time for the same Sui address.
Step 2: Send BTC to the address
Send at least the minimum deposit amount to the address from any Bitcoin wallet. Record the Bitcoin transaction ID (txid) and the output index (vout) that paid your deposit address.
Step 3: Record the deposit on Sui
Tell Hashi about the funding transaction:
hashi deposit -c hashi-cli.toml request --txid <btc-txid> --outputs '[[<vout>, <amount-sats>]]' --recipient 0x<sui-address>
If you omit --outputs, the CLI looks the transaction up through the Bitcoin
RPC endpoint in your CLI config and finds the outputs that paid the deposit
address. If one funding transaction paid the address on several outputs, list
them all in --outputs and the CLI batches them into one Sui transaction.
The command prints a deposit request ID. Keep it for the next step.
Step 4: Track the deposit
Check the request and your balance:
hashi deposit -c hashi-cli.toml status <request-id>
hashi balance -c hashi-cli.toml 0x<sui-address>
Expect to wait. The committee waits for
bitcoin_confirmation_threshold
Bitcoin blocks, then approves the deposit, then waits through the
bitcoin_deposit_time_delay_ms
window before minting. See
How long does a deposit take? for the
defaults.
Deposit with the TypeScript SDK
The SDK attaches to a Sui client and exposes every Hashi method under
client.hashi.*. Install it and create a client as described in
TypeScript SDK. The SDK page also lists which Sui
networks the SDK supports.
Step 1: Derive the deposit address and record the deposit
The following example derives the deposit address for the signer's Sui address and, after you send BTC to it, records the funding transaction on Sui:
const recipient = signer.toSuiAddress();
// 1. Get the deposit address.
const btcAddress = await client.hashi.generateDepositAddress({
suiAddress: recipient,
});
// 2. Send BTC to `btcAddress` from any wallet, then collect the
// funding tx's display-order txid and the vout that paid the
// deposit address. (Display-order = the form mempool.space and
// `bitcoin-cli` show — the SDK reverses internally.)
// 3. Record the deposit on Sui.
const result = await client.hashi.deposit({
signer,
txid: '0x<64-hex display-order txid>',
utxos: [{ vout: 0, amountSats: 100_000n }],
recipient,
});
if (result.$kind !== 'Transaction') {
throw new Error(`deposit failed: ${JSON.stringify(result.FailedTransaction)}`);
}
// `hBTC` lands in `recipient`'s balance once the committee confirms.
Pass every output that paid the deposit address in utxos. The SDK batches
them into one atomic Sui transaction.
Before you submit, check that the outputs are not already recorded. Submitting a consumed UTXO aborts onchain.
const results = await client.hashi.view.findUsedUtxos([
{ txid: '0x<64-hex display-order txid>', vout: 0 },
]);
// results[0]: { utxoId, inActivePool, inSpentPool, isUsed }
Step 2: Track the deposit
Use the transaction digest to check status once or to wait for a terminal state:
const digest = result.Transaction?.digest;
// One-shot status check — returns null if the digest has no Hashi event.
const deposit = await client.hashi.view.depositStatus(digest);
// deposit?.status: "pending" | "confirmed" | "expired" | "unknown"
// deposit?.approvalTimestampMs — when the committee approved (null until approved)
// deposit?.confirmableAtMs — earliest mint time = approval + bitcoinDepositTimeDelayMs
// (null until approved)
const info = await client.hashi.waitForDeposit(digest, {
intervalMs: 15_000, // default
signal: AbortSignal.timeout(600_000), // optional cancellation
});
Step 3: Check your hBTC balance
const { totalBalance, coinObjectCount } = await client.hashi.view.balance(signer.toSuiAddress());
// totalBalance — hBTC in satoshis; coinObjectCount — number of coin objects held.
Try a deposit on Testnet
Hashi's Testnet deployment uses Bitcoin Signet, so a test deposit needs Signet BTC. Signet coins have no value, and you cannot buy or mine them in any practical sense. You get them from a faucet.
The Signet faucets below are third-party services that the Hashi team does not operate or verify. Availability, rate limits, and URLs change without notice, and this page makes no guarantee that any of them work at the time you read it. Never send real BTC to a Signet faucet or a Signet address.
Commonly used public faucets for the default Signet network include signetfaucet.com and its alternate at alt.signetfaucet.com. Confirm that a faucet serves default Signet before using it. Some communities run custom signets whose coins are not valid on the network Hashi's Testnet uses. Your own Signet node cannot create spendable coins for you, because a central authority signs Signet blocks.
For the CLI, set network = "signet" under [bitcoin] in hashi-cli.toml,
or pass --btc-network signet. The CLI otherwise assumes regtest and derives
a bcrt1 address. Then follow the CLI steps above. Expect to wait for several
Signet blocks between recording the deposit and seeing hBTC in your balance.