Bridge Operations
Bridge Operations
Section titled “Bridge Operations”This section covers core asset bridging between Bittensor and EVM chains (e.g. Ethereum) using sdk.bridge.
1. Supported Chains & Assets
Section titled “1. Supported Chains & Assets”Before initiating a bridge, fetch supported chains and assets to populate your UI.
// Get all supported chainsconst chains = await sdk.api.getSupportedChains();console.log('Supported Chains:', chains);
// Get all supported assets (paginated)const assetsResponse = await sdk.api.getAssetList();const assets = Array.isArray(assetsResponse?.data?.assets) ? assetsResponse.data.assets : Array.isArray(assetsResponse?.data) ? assetsResponse.data : Array.isArray(assetsResponse) ? assetsResponse : [];console.log('Supported Assets:', assets);2. Estimate Fees
Section titled “2. Estimate Fees”Calculate the bridge fee and the estimated amount the recipient will receive before initiating a transaction.
const estimate = await sdk.bridge.getBridgeFeeEstimate({ fromToken: 'wtao', toToken: 'tao', amount: 1.5,});
if (estimate.success) { console.log(`Fee: ${estimate.data.fee}`); console.log(`Recipient gets: ${estimate.data.recipientAmount}`);}See the Fee Schedule for a full breakdown of base and percentage fees per direction.
3. Initiate a Bridge Transaction
Section titled “3. Initiate a Bridge Transaction”Bridging is a two-step process:
- Request bridge data — Call
sdk.bridge.bridge()to receive the transaction payload. - Sign & send — Use your connected wallet to broadcast the transaction on-chain.
Request Type: BridgeSwapRequest
Section titled “Request Type: BridgeSwapRequest”| Property | Type | Required | Description |
|---|---|---|---|
fromWallet | string | ✅ | Sender wallet address. |
toWallet | string | ✅ | Recipient wallet address on the destination chain. |
fromToken | string | ✅ | Source token symbol, lowercase (e.g. wtao). |
toToken | string | ✅ | Destination token symbol, lowercase (e.g. tao). |
fromChain | string | ✅ | Source chain ID (e.g. ethereum). |
toChain | string | ✅ | Destination chain ID (e.g. bittensor). |
amount | number | ✅ | Amount to bridge. |
subnetId | number | ⚠️ Conditional | Required for Bittensor bridging. Use 0 for TAO, or the subnet ID for Alpha. |
Bridge Directions
Section titled “Bridge Directions”EVM → Bittensor (wTAO → TAO)
Section titled “EVM → Bittensor (wTAO → TAO)”The SDK returns a constructed evmTransaction object ready to sign and send.
// Step 1 — Request bridge payloadconst response = await sdk.bridge.bridge({ fromChain: 'ethereum', toChain: 'bittensor', fromToken: 'wtao', toToken: 'tao', fromWallet: '0xEvmSender...', toWallet: '5BitRecip...', amount: 10,});
// Step 2 — Send via wallet providerif (response.evmTransaction) { const { to, data, value } = response.evmTransaction;
const txHash = await window.ethereum.request({ method: 'eth_sendTransaction', params: [{ from: '0xEvmSender...', to, data, value }], }); console.log('Bridge transaction sent:', txHash);}Bittensor → EVM (TAO → wTAO)
Section titled “Bittensor → EVM (TAO → wTAO)”The SDK response includes:
| Field | Description |
|---|---|
identifier | Unique transaction ID — must be included in the on-chain remark. |
toAddress | Bridge admin coldkey (destination of the stake transfer). |
subnetDestinationHotkey | Target hotkey for the stake transfer. |
// Step 1 — Request bridge payloadconst response = await sdk.bridge.bridge({ fromChain: 'bittensor', toChain: 'ethereum', fromToken: 'tao', toToken: 'wtao', fromWallet: '5BitSender...', toWallet: '0xEvmRecip...', amount: 5, subnetId: 0, // TAO always uses subnetId 0});
const { identifier, toAddress, subnetDestinationHotkey } = response;
// Step 2 — Construct and send the batched Bittensor transactionasync function sendTaoStakeBridgeTx( sender, amount, adminColdkey, hotkey, subnetId, bridgeIdentifier,) { const provider = new WsProvider('wss://finney.opentensor.ai:443'); const api = await ApiPromise.create({ provider }); const injector = await web3FromSource(sender.source);
// Convert amount to RAO (1 TAO = 1e9 RAO) const amountRao = api.createType('Balance', amount * 1e9).toString();
const transferStakeTx = api.tx.subtensorModule.transferStake( adminColdkey, // Bridge coldkey (from toAddress) hotkey, // Destination hotkey (from subnetDestinationHotkey) subnetId, // Origin subnet (0 for TAO) subnetId, // Destination subnet (0 for TAO) amountRao, ); const remarkTx = api.tx.system.remarkWithEvent(bridgeIdentifier); const batchTx = api.tx.utility.batchAll([transferStakeTx, remarkTx]);
await batchTx.signAndSend(sender.address, { signer: injector.signer }, (result) => { console.log('Tx status:', result.status.type); });}Bittensor → EVM (Alpha → wAlpha)
Section titled “Bittensor → EVM (Alpha → wAlpha)”Bridging subnet Alpha tokens uses the same transferStake + remark batch pattern. The subnetId corresponding to the subnet must be provided.
// Step 1 — Request bridge payloadconst response = await sdk.bridge.bridge({ fromChain: 'bittensor', toChain: 'ethereum', fromToken: 'alpha', toToken: 'walpha', fromWallet: '5BitSender...', toWallet: '0xEvmRecip...', amount: 100, subnetId: 1, // Required — use the correct subnet ID for this Alpha token});
const { identifier, toAddress, subnetDestinationHotkey } = response;
// Step 2 — Construct and send the batched Bittensor transactionasync function sendAlphaBridgeTx(sender, amount, adminColdkey, hotkey, subnetId, bridgeIdentifier) { const provider = new WsProvider('wss://finney.opentensor.ai:443'); const api = await ApiPromise.create({ provider }); const injector = await web3FromSource(sender.source);
const amountRao = api.createType('Balance', amount * 1e9).toString();
const transferStakeTx = api.tx.subtensorModule.transferStake( adminColdkey, // Bridge coldkey (from toAddress) hotkey, // Subnet hotkey (from subnetDestinationHotkey) subnetId, // Origin subnet ID subnetId, // Destination subnet ID amountRao, ); const remarkTx = api.tx.system.remarkWithEvent(bridgeIdentifier); const batchTx = api.tx.utility.batchAll([transferStakeTx, remarkTx]);
await batchTx.signAndSend(sender.address, { signer: injector.signer }, (result) => { console.log('Tx status:', result.status.type); });}EVM → Bittensor (wAlpha → Alpha)
Section titled “EVM → Bittensor (wAlpha → Alpha)”This follows the same pattern as the standard EVM burn (wTAO → TAO).
// Step 1 — Request bridge payloadconst response = await sdk.bridge.bridge({ fromChain: 'ethereum', toChain: 'bittensor', fromToken: 'walpha', toToken: 'alpha', fromWallet: '0xEvmSender...', toWallet: '5BitRecip...', amount: 100, subnetId: 1, // Required for Alpha — must match the target subnet});
// Step 2 — Execute EVM burn via walletif (response.evmTransaction) { await window.ethereum.request({ method: 'eth_sendTransaction', params: [response.evmTransaction], });}Direction Summary
Section titled “Direction Summary”| Direction | Method | On-chain Action | subnetId Required |
|---|---|---|---|
| EVM → Bittensor (wTAO → TAO) | bridge() | EVM burn via evmTransaction | No |
| Bittensor → EVM (TAO → wTAO) | bridge() | transferStake + remark batch | Yes (0) |
| Bittensor → EVM (Alpha → wAlpha) | bridge() | transferStake + remark batch | Yes (subnet ID) |
| EVM → Bittensor (wAlpha → Alpha) | bridge() | EVM burn via evmTransaction | Yes (subnet ID) |