# Bittensor

Source: https://developers.bitgo.com/docs/bittensor

## Overview

Bittensor (TAO) is the native asset of the Bittensor blockchain. It utilizes:
- Nominated Proof-of-stake (NPoS) model
- EdDSA signature algorithm

Bittensor is a blockchain platform that facilitates interoperability between different blockchains through its native cryptocurrency, TAO.

### Explorer
<a href="https://bittensor.com/scan/" target="_blank" rel="noreferrer">https://bittensor.com/scan/</a>


## Wallets Types

BitGo enables holding tao in the following wallet types:

| | Multisig Cold | Multisig Hot | MPC Cold | MPC Hot |
|-| ------------- | ------------ | -------- | ------- |
| **Custody** | ❌ | ❌ | ✅ | ❌ |
| **Self-Custody** | ❌ | ❌ | ✅ | ✅ |

## Ticker Symbols

| Mainnet | Testnet |
| ------- | ------- |
| TAO | TTAO |


## Units

The smallest unit for the Bittensor chain is RAO
- 1 RAO =	0.000000001 TAO
- 10^9 RAO = 1.0000000000 TAO

You can pass balances in string or integer format. However, BitGo recommends using string format to ensure values don't exceed the programmable number limit.

### Native Token

TAO is the native token of the Bittensor network in a similar way that BTC is the native token of Bitcoin or Ether is the native token of the Ethereum blockchain.

### Fees

Bittensor fees consists of three parts:

- Base fee: a fixed fee that the runtime applies to every transaction.
- Length fee: a fee that gets multiplied by the length of the transaction, in bytes.
- Weight fee: a fee for each, varying runtime function. Runtime implementers need to implement a conversion mechanism which determines the corresponding amount for the calculated weight.

The final fee can be summarized as:

```
fee = base_fee + length_of_transaction_in_bytes * length_fee + weight_fee
```

Additionally, a minimum deposit of 0.0000005 TAO is required to initialize a wallet.

##### Fee Multiplier

Bittensor can add an additional fee to transactions if the network becomes too busy and starts to decelerate the system. This fee can create an incentive to avoid the production of low priority or insignificant transactions.

The network calculates the final fee as:

```
final_fee = fee * fee_multiplier
```


### Create wallets

```shell cURL
LABEL="My Test Wallet"
PASSPHRASE="secretpassphrase1a5df8380e0e30"

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"label\": \"$LABEL\", \"passphrase\": \"$PASSPHRASE\", \"multisigType\": \"tss\" }" \
http://$BITGO_EXPRESS_HOST/api/v2/ttao/wallet/generate
```
```javascript JavaScript
bitgo
  .coin('ttao')
  .wallets()
  .generateWallet({
    label: 'My Test Wallet',
    passphrase: 'secretpassphrase1a5df8380e0e30',
    multisigType: 'tss'
  })
  .then(function (wallet) {
    // print the new wallet
    console.dir(wallet);
  });
```

### Receive addresses

TAO has no minimum balance for receive addresses. However, at least 0.0000005 TAO is required in each receive address to consolidate token balances to the base address.

To create a receive address:

```shell cURL
WALLET=<WALLET_ID>

curl -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://app.bitgo-test.com/api/v2/ttao/wallet/$WALLET/address
```
```javascript JavaScript
bitgo
  .coin('ttao')
  .wallets()
  .getWallet({ id: '<WALLET_ID>' })
  .then(function (wallet) {
    return wallet.createAddress();
  })
  .then(function (newAddress) {
    // print new address details
    console.dir(newAddress);
  });
```

## Estimate Fee

```shell cURL
export COIN="ttao"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"

curl -X GET \
 https://app.bitgo-test.com/api/v2/$COIN/tx/fee \
 -H 'Content-Type: application/json' \
 -H "Authorization: Bearer $ACCESS_TOKEN"

```
```js JavaScript
const BitGoJS = require('../../../src/index.js');
const bitgo = new BitGoJS.BitGo({ env: 'test' });
const accessToken = '<YOUR_ACCESS_TOKEN>';
const coin = 'ttao';

async function getFeeEstimate() {
  try {
    await bitgo.authenticateWithAccessToken({ accessToken });
    const res = await bitgo.coin(coin).feeEstimate({ numBlocks: 2 });
    console.dir(res);
  } catch (err) {
    console.error('Error fetching fee estimate:', err);
  }
}

getFeeEstimate();

```

## Transact

```shell cURL
export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>"
export COIN="ttao"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export ADDRESS="<DESTINATION_ADDRESS>"
export AMOUNT="<AMOUNT_IN_BASE_UNITS>"
export WALLET_PASSPHRASE="<YOUR_WALLET_PASSPHRASE>"

curl -X POST \
  http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/$WALLET_ID/sendcoins \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "address": "'"$ADDRESS"'",
    "amount": "'"$AMOUNT"'",
    "walletPassphrase": "'"$WALLET_PASSPHRASE"'"
}'
```
```js JavaScript
const tx = await fundedWallet.send({
    address: `<DESTINATION_ADDRESS>`,
    amount: `<AMOUNT>`,
    walletPassphrase: process.env.PASSWORD as string,
  });
```

## Consolidation

```shell cURL
export BITGO_EXPRESS_HOST="<YOUR_LOCAL_HOST>"
export COIN="<ASSET_ID>"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export WALLET_PASSPHRASE="<WALLET_PASSPHRASE>"

curl -X POST \
  http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/$WALLET_ID/consolidateAccount \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
  "walletPassphrase": "'"$WALLET_PASSPHRASE"'"
}'
```
```js JavaScript
const BitGoJS = require('bitgo');
const Promise = require('bluebird');

const bitgo = new BitGoJS.BitGo({ env: 'test' });

const coin = 'ttao';

// Set your wallet id
const walletId = '';

// Set your wallet passphrase
const walletPassphrase = '';

// Set OTP code
const otp = '000000';

// Set your access token here
  bitgo.authenticateWithAccessToken({ accessToken });

  const wallet = await bitgo.coin(coin).wallets().get({ id: walletId });
  // Wallet's base address - only address in the wallet that can send assets to other accounts
  console.log('Base Address:', wallet.coinSpecific().baseAddress);
  // Confirmed balance - sum of the balance of all the wallet's addresses
  console.log('Confirmed Balance:', wallet.confirmedBalanceString());
  // Spendable balance - balance of the base address
  console.log('Spendable Balance:', wallet.spendableBalanceString());

  // unlock the session for sending assets
  const unlock = await bitgo.unlock({ otp, duration: 3600 });
  if (!unlock) {
    throw new Error('error unlocking session');
  }

  const consolidationTxes = await wallet.buildAccountConsolidations();

  try {
    for (const unsignedConsolidation of consolidationTxes) {
      const res = await wallet.sendAccountConsolidation({ walletPassphrase, prebuildTx: unsignedConsolidation });
      console.dir(res, { depth: 6 });
    }
  } catch (e) {
    console.error(e);
  }
);
```
