# Stacks

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

## Stacks

<a href="https://docs.stacks.co/" target="_blank" rel="noreferrer">Stacks</a> can be accessed with the following coin types:

| Environment    | Coin Type | Faucet                                                                                                                                                                                                             |
|:---------------|:----------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| STX Production | stx       |                                                                                                                                                                                                                    |
| STX Testnet    | tstx      | <a href="https://docs.stacks.co/learn/network-fundamentals/mainnet-and-testnets#faucets" target="_blank" rel="noreferrer">https://docs.stacks.co/learn/network-fundamentals/mainnet-and-testnets#faucets</a> |

### Explorer
<a href="https://explorer.hiro.so/" target="_blank" rel="noreferrer">https://explorer.hiro.so/</a>


### Generating wallets

```javascript
bitgo
  .coin('tstx')
  .wallets()
  .generateWallet({
    label: 'My Test Wallet',
    passphrase: 'secretpassphrase1a5df8380e0e30',
  })
  .then(function (wallet) {
    // print the new wallet
    console.dir(wallet);
  });
```
```shell
LABEL="My Test Wallet"
PASSPHRASE="secretpassphrase1a5df8380e0e30"

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"label\": \"$LABEL\", \"passphrase\": \"$PASSPHRASE\" }" \
http://$BITGO_EXPRESS_HOST/api/v2/tbtc4/wallet/generate
```

### Creating addresses

```javascript
bitgo
  .coin('tstx')
  .wallets()
  .getWallet({ id: '585c51a5df8380e0e3082e46' })
  .then(function (wallet) {
    return wallet.createAddress();
  })
  .then(function (newAddress) {
    // print new address details
    console.dir(newAddress);
  });
```
```shell
WALLET=585c51a5df8380e0e3082e46

curl -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://app.bitgo-test.com/api/v2/tstx/wallet/$WALLET/address
```

### Balances

<a href="https://docs.stacks.co/learn/network-fundamentals/network-basics" target="_blank" rel="noreferrer">Stacks</a> (STX) is the native asset of the Stacks blockchain. It is called a "token," but as a layer-1 asset BitGo treats it as a coin. The base unit of STX is a micro-STX:

- 1 micro-STX is (<code>10<sup>-6</sup></code>) or 0.000001 STX.
- 1 STX is (<code>10<sup>6</sup></code>) or 1000000 micro-STX (1 million).

BitGo supports balances in string format: `balanceString`, `confirmedBalanceString`, and `spendableBalanceString`.

### Tokens

The Stacks blockchain natively support tokens. To view all BitGo supported tokens on the Stacks blockchain, see [Stacks - SIP10 Tokens](/docs/stacks-sip10-tokens)

### Fee rate

<a href="https://docs.stacks.co/learn/transactions/how-transactions-work" target="_blank" rel="noreferrer">Fees</a> calculate based on the estimated fee rate and the size of the raw transaction in bytes. The market determines the fee rate. For the testnet, it is set to 1 micro-STX.

### Set the fee manually

To set the fee manually, add `feeRate` param to the body of the request.

Example for single recipient transfer:

```javascript
{
    recipients: [{
        amount: amount, //string - amount in micro-stx
        address: receiverAddress, //string
    }],
    feeRate: 500000 // amount in micro-stx as number or string, equal to 0.5 STX
}
```

### Send-Many: send to multiple recipients

Stacks doesn't provide a native capability to send to many recipients in the same transaction but there is <a href="https://explorer.stacks.co/txid/SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.send-many-memo?chain=mainnet" target="_blank" rel="noreferrer">smart contract</a> that allows doing it. It also supports for memos on each receiver. To use it, the recipients params in the body of a transfer transaction should have more than 1 recipient object.

```javascript
{
    recipients: [{
        amount: "amount1", //string - amount in micro-stx
        address: "receiverAddress1", //string
        memo: "memo1", //string - optional
    },{
        amount: "amount2", //string - amount in micro-stx
        address: "receiverAddress2", //string
        memo: "memo2", //string - optional
    },{
        amount: "amount3", //string - amount in micro-stx
        address: "receiverAddress3", //string
        memo: "memo3", //string - optional
    },{
        amount: "amount4", //string - amount in micro-stx
        address: "receiverAddress4", //string
        memo: "memo4", //string - optional
    }],
}
```

### Staking

Stacks refers to staking as <a href="https://www.stacks.co/stacking" target="_blank" rel="noreferrer">stacking</a>. Stacks is a proof of stake protocol where users
can delegate part of their assets to a validator (or "stacker") to stake and get rewards for participating in securing
the network. Stacks has a unique staking mechanism where users delegate STX but earn BTC as reward. When users delegate,
assets remain locked in the wallet. Users must undelegate to “unlock” the assets to be withdrawn or sent out.

Currently, BitGo allows users to act as delegators which means that from their wallets they can:

- Delegate (or stake) STX
- Undelegate (or unstake) STX
- Receive rewards for delegating STX.

### Delegating

Staking cycles run in sequence. Users must delegate their assets before the cycle ends to generate rewards from
a stacker (validator).

> 📘 **Note:** BitGo recommends that users use a specific BTC address solely for generating rewards.

### Stacks staking examples

These examples are for wallet endpoints like:

```
https://app.bitgo.com/api/v2/stx/wallet/walletId/tx/build
https://app.bitgo.com/api/v2/stx/wallet/walletId/tx/initiate
```

#### Delegate

To get the BTC Address hash and version BitGo recommends that you use a script like this:

> 📘 **Note:** Addresses must be in legacy format (and start with a `1` or a `3`). Native SegWit addresses (that start with
`bc1`) are not supported.

```javascript
const bitcoinjs = require('bitcoinjs-lib');

const btcAddress = '1QF7K4izEcgDxu9yRBLpFe6viFihiL1w5j';
const parsedAddress = bitcoinjs.address.fromBase58Check(btcAddress);

const btcAddressVersionToHashMode = (version) => {
  switch (version) {
    case '0': // BTC version for mainnet P2PKH
    case '111': // BTC version for testnet P2PKH
      return { data: [0], type: 'Buffer' };
    case '5': // BTC version for mainnet P2SH
    case '196': // BTC version for testnet P2SH
      return { data: [1], type: 'Buffer' };
    default:
      break;
  }
};
const AddressHash = bas58.hash.toJSON();
const AddressVersion = btcAddressVersionToHashMode(parsedAddress.version.toString());
console.log(AddressHash); //{type: 'Buffer',data: [ 254, 245, 252,  42, 179, 220, 238, 122, 241, 132, 202, 47, 217,  13,  20,  38, 151, 116, 250, 128]}
console.log(AddressVersion); //{ data: [ 0 ], type: 'Buffer' }
```

The body of the request transaction should look like this:

```javascript
{
    type: "stakingLock",
    recipients: [{
        amount: amount, //string - amount in micro-stx
        address: validatorAddress, //string
    }],
    stakingOptions: {
        contractName: 'pox',
        functionName: 'delegate-stx',
        functionArgs: [
            // First param is the amount in micro-stx do delegate
            {
                type: 'uint128',
                val: amount //string - amount in micro-stx
            },
            // Second param is validator address
            {
                type: 'principal',
                val: validatorAddress //string
            },
            // Third param is the delegation cycles that delegate permisions will last.
            // Is a required parameter and must be a 1 or higher.
            {
                type: 'optional',
                val: numberOfCycles //string
            },
            // Fourth param is the BTC address in which you will receive the rewards.
            // Is required.
            {
                type: 'optional',
                val: {
                    type: 'tuple',
                    val: [{
                            key: 'hashbytes',
                            type: 'buffer',
                            val: AddressHash
                        },
                        {
                            key: 'version',
                            type: 'buffer',
                            val: AddressVersion
                        },
                    ],
                },
            },
        ],
    };
}
```

#### Revoke delegate

The body of the request transaction should look like this:

```javascript
{
    type: "stakingUnlock",
    recipients: [{
        amount: '0', // string
        address: '', // empty string
    }],
    stakingOptions: {
        contractName: 'pox',
        functionName: 'revoke-delegate-stx',
        functionArgs: [] // empty array
        },
}
```
