hirosystems / hirosystems/multisig-stx-btc
Documentation on Usage
- Dominant language
- JavaScript
- Stars
- 4
- Forks
- 6
- PR merge metrics
- No merged PRs in 30d
Description
Now that I've used this library quite a few times I wanted to share what documentation I've built so far around the process.
There was an original issue opened in one of the docs repos but I cannot find it anymore, so I'll create the issue here then link it back in the Discord documentation channel.
Some of the information comes straight from the README and just lays it out in a new format to get from a standing start to over the finish line, including some of the additional steps required for a Trezor.
---
The instructions below assume you are signing with a Trezor.
# Table of Contents
- [Setup Trezor Bridge](#setup-trezor-bridge)
- [Setup Trezor Device](#setup-trezor-device)
- [Downgrade Firmware](#downgrade-firmware)
- [Confirm Trezor Config](#confirm-trezor-config)
- [Create BTC Legacy Account](#create-btc-legacy-account)
- [Export xPub of Legacy Account](#export-xpub-of-legacy-account)
- [Setup multisig in Electrum](#setup-multisig-in-electrum)
- [Compressed Public Keys](#compressed-public-keys)
- [Convert multisig BTC to multisig STX address](#convert-multisig-btc-to-multisig-stx-address)
- [Install and Usage](#install-and-usage)
- [Commands](#commands)
- [Setup `multisig-stx-btc` tool](#setup-multisig-stx-btc-tool)
- [Installation](#installation)
- [Sending a Transaction](#sending-a-transaction)
- [Fund appropriate accounts](#fund-appropriate-accounts)
- [Verifying Payloads](#verifying-payloads)
- [Pre-STX Transfer](#pre-stx-transfer)
- [Setup](#setup)
- [Signing](#signing)
- [Submitting](#submitting)
- [STX Transfer](#stx-transfer)
- [Setup](#setup-1)
- [Signing](#signing-1)
- [Submitting](#submitting-1)
- [Stacking STX](#stacking-stx)
- [Setup](#setup-2)
- [Signing](#signing-2)
- [Submitting](#submitting-2)
- [Verifying Status](#verifying-status)
- [Bitcoin Transaction Fees](#bitcoin-transaction-fees)
## Setup Trezor Bridge
This software is used for the Trezor to connect to external services.
The website below will check if its installed and provide installation instructions if not.
https://suite.trezor.io/web/bridge/
## Setup Trezor Device
> ⚠️ Be sure to have a backup of the secret key before changing the firmware on the device. ⚠️
### Downgrade Firmware
1. Download [firmware version 2.0.7](https://github.com/trezor/webwallet-data/blob/master/firmware/2/trezor-2.0.7.bin)
2. In [Trezor Suite](https://suite.trezor.io), click on Wallet top-left
3. Click on Settings gear
4. Under Settings > Device at bottom, click Install Firmware
5. Select downloaded firmware file `trezor-2.0.7.bin` and click Install Firmware
6. Confirm recovery seed phrase saved
7. Reconnect in bootloader mode (swipe while plugging in)
8. Confirm current firmware on Trezor
9. Connect to Trezor Suite, click Install Firmware
10. Confirm on Trezor (seed will be erased)
11. Confirm when done and Trezor will automatically reboot
### Confirm Trezor Config
1. Connect Trezor to [Trezor Suite](https://suite.trezor.io)
2. Click on Setup Trezor
3. Skip firmware update
4. Click Recover Wallet
5. On recover wallet from seed, click Start Recovery
6. Confirm number of words on Trezor
7. Type in each word on the Trezor (old school texting style)
8. Trezor suite will confirm phrase is entered when done
9. Click to set a pin, confirm on Trezor
10. Trezor suite will confirm pin is entered when done
11. Click to Continue to account screen
12. Under activate coins, choose Bitcoin if not selected
13. Click Complete Setup
**Note:** If prompted for a passphrase, do not enter anything and use the green check on the device to skip.
### Create BTC Legacy Account
**Note:** If the account already existed, this adds it on the list again for Trezor Suite.
**Note:** Multiple legacy accounts can be created, but the prior account must have at least one transaction before creating a new one.
From the [Trezor Suite](https://suite.trezor.io) dashboard:
1. Click the + to add a new account
2. Select Bitcoin
3. Select Legacy BIP44, P2PKH, Base58
4. Click Add Account
5. Click on Receive and confirm on Trezor
6. Copy and save the address for reference
### Export xPub of Legacy Account
From the Trezor Suite accounts tab:
1. Click on the Legacy Accounts header to show Legacy Account
2. Click on the Account tab for the Legacy Account
3. Click on show public key
4. Copy and save the xpub for reference
**Note:** Before moving on to the next step, this process should be repeated for each account that represents the multsig address until all required xpubs are saved.
## Setup multisig in Electrum
The [Electrum wallet](https://electrum.org) is used to obtain the bitcoin address and correctly formatted public keys required by the multisig-stx-btc tool.
**Note:** If you are using a custodial solution for any of the Bitcoin keys, try to obtain the xPub for the account through their service. If another public key format is provided (e.g. yPub or zPub), [this tool can help convert it to an xPub](https://jlopp.github.io/xpub-converter/).
Download and verify the signatures for the latest version, then open Electrum and:
1. Create a new wallet
2. Select multi-signature wallet
3. Set number of cosigners (e.g. From 3 cosigners / require 2 signatures)
4. Select Use a master key
5. Enter xPub for Key 1
6. Click Next to confirm public key
7. Select Enter cosigner key
8. Enter xPub for Key 2
9. Select Enter cosigner key
10. Enter xPub for Key 3
11. Set a password to encrypt the file
**Note:** Pay attention to the order of the keys used above, as the multisig-stx-btc tool will expect them to be in the same order.
The electrum wallet is now operating in watch-only mode and will show the balance for the account.
The **BTC address of the multisig wallet** is the first address listed on the Addresses tab. (e.g. `37qEjwRbionPc9MkK8WHH8GTbj2GC8mWix`)
### Compressed Public Keys
By right-clicking on the first address listed on the Addresses tab, select `Details` to find the compressed public keys for the address, which are prefixed with `02` or `03`.
Save the public keys for reference.
## Convert multisig BTC to multisig STX address
The [c32check](https://github.com/stacks-network/c32check) allows us to convert between BTC and STX addresses.
### Install and Usage
First clone the repo, then run:
```
npm i
npm run build
cd dist
node
.load c32check.js
```
### Commands
Convert the BTC address to a STX address:
```
> c32check.b58ToC32('37qEjwRbionPc9MkK8WHH8GTbj2GC8mWix')
'SM11NXJ0RJVJ6AV9DHJJB3DS5TK7RMCZCGWPNDT2P'
```
Convert the STX address to a BTC address:
```
> c32check.c32ToB58('SM11NXJ0RJVJ6AV9DHJJB3DS5TK7RMCZCGWPNDT2P')
'37qEjwRbionPc9MkK8WHH8GTbj2GC8mWix'
```
## Setup `multisig-stx-btc` tool
The [Stacks Address Transaction Signing Tool](https://github.com/hirosystems/multisig-stx-btc) tool helps build and manage Stacks operations that are sent on Bitcoin using a multisig wallet.
### Installation
First clone the repo, then run:
```
npm i
npm run build
```
This will create a `dist` folder with the following files:
```
bootstrap.min.css
distribute.js
index.html
transacter.js
```
Open the `index.html` file in a browser to use the tool.
## Sending a Transaction
According to [SIP-007](https://github.com/stacksgov/sips/blob/main/sips/sip-007/sip-007-stacking-consensus.md#stx-operations-on-bitcoin), both a STX transfer and a STX stacking operation require two Bitcoin transactions.
The first is a pre-op transaction that should receive at least 1 confirmation before sending the transfer or stacking operation.
The transaction ID of the pre-op transaction is used by the transaction for the second operation.
### Fund appropriate accounts
1. Send enough BTC to cover two transaction fees to the multisig BTC address (~$50)
2. Send a small amount of STX to the multisig STX address (e.g. 1 STX)
**Note:** Do not send any other type of token to this address (e.g. SIP-009/SIP-010), **only STX**.
### Verifying Payloads
To verify a payload generated by the tool, copy the entire paragraph of text and paste it into the "Decode/Check Partial Transaction" box under "Partial transaction:".
Click "Check/Decode" and a new field will appear validating the transaction information.
Examples:
```
================== Pre-STX Op =========================
STX from address: SM11NXJ0RJVJ6AV9DHJJB3DS5TK7RMCZCGWPNDT2P
partially signed: false
BTC consumed: 139192
=======================================================
```
```
================== Pre-STX Op =========================
STX from address: SM11NXJ0RJVJ6AV9DHJJB3DS5TK7RMCZCGWPNDT2P
partially signed: true
BTC consumed: 102264
=======================================================
```
```
================== STX Transfer =======================
STX from address: SM11NXJ0RJVJ6AV9DHJJB3DS5TK7RMCZCGWPNDT2P
STX to address: SPBSN61W5ADNG9VJ6AYC48QRTV4BBWVRYDZ97WFN
microstacks amount: 9000000
partially signed: false
BTC consumed: 15050
=======================================================
```
```
================== Stack STX Op =========================
STX from address: SM11NXJ0RJVJ6AV9DHJJB3DS5TK7RMCZCGWPNDT2P
PoX reward address: 37qEjwRbionPc9MkK8WHH8GTbj2GC8mWix
microstacks to stack: 1000000000000
reward cycles: 5
partially signed: false
=======================================================
```
### Pre-STX Transfer
#### Setup
Fill in the first three fields below to generate the pre-stx transaction:
- From Address (C32): The multisig STX address either sending or stacking STX generated earlier
- From public keys (comma separate): The compressed public keys of the multisig wallet in the same order, prefixed with `02` or `03`
- Required signers (number): The number of signatures required to sign the transaction (e.g. 2 if a 2-of-3 multisig wallet)
Click "Generate Pre-STX TX" and a new field will appear at the bottom of the screen titled "Unsigned Pre-STX Operation Transaction" with the payload below it.
#### Signing
To sign the payload, copy the entire paragraph of text and paste it into the "Transaction Signing" box under "Partial transaction:".
Fill in the following information based on the configuration supplied in this documentation. If you did not follow the instructions above, the Signer Path may be different.
- Signer Path: `m/44'/0'/0'/0/0`
- Device: Trezor
- Partial transaction: Unsigned Pre-STX Operation generated above
**Note:** If using multiple legacy accounts on the same Trezor, increment the 3rd digit of the signer path for each account (e.g. `m/44'/0'/1'/0/0` for the second account).
Click "Start Sign TX" and a new window will open to connect to the Trezor and sign the transaction.
Once complete, a new field will appear at the bottom of the screen titled "Partially Signed Pre-STX Operation Transaction" with the payload below it.
The next signer will follow the same steps above.
The last signer will follow the same steps above **except** click "Finish Sign TX" at the end.
Once complete, a new field will appear at the bottom of the screen titled "Signed Pre-STX Operation Transaction" with the payload below it.
#### Submitting
Once the fully-signed transaction is generated, it is ready to be broadcast to the Bitcoin blockchain. There are several ways to do this, and one simple approach is using [BlockCypher's pushtx tool](https://live.blockcypher.com/btc/pushtx/).
After pushing the transaction, allow for **at least 1 confirmation** before broadcasting the transaction generated in to the next step.
Also, record the Bitcoin transaction ID to be used while generating the next STX operation.
### STX Transfer
#### Setup
Fill in the required fields below to generate the STX transfer transaction:
- From Address (C32): The multisig STX address sending STX generated earlier
- From public keys (comma separate): The compressed public keys of the multisig wallet in the same order, prefixed with `02` or `03`
- Required signers (number): The number of signatures required to sign the transaction (e.g. 2 if a 2-of-3 multisig wallet)
- To Address (C32): The recipient STX address
- microSTACKS (10^-6 STACKS) to send or stack (number): The total amount of uSTX to send (1 STX = 1,000,000 uSTX)
- Pre-Stx TX TXID to consume: The Bitcoin transaction ID of the pre-stx transaction generated earlier
Click "Generate Transfer TX" and a new field will appear at the bottom of the screen titled "Unsigned STX Transfer Operation Transaction" with the payload below it.
#### Signing
To sign the payload, copy the entire paragraph of text and paste it into the "Transaction Signing" box under "Partial transaction:".
Fill in the following information based on the configuration supplied in this documentation. If you did not follow the instructions above, the Signer Path may be different.
- Signer Path: `m/44'/0'/0'/0/0`
- Device: Trezor
- Partial transaction: Unsigned STX Transfer Operation Transaction generated above
**Note:** If using multiple legacy accounts on the same Trezor, increase the 3rd digit of the signer path for each account (e.g. `m/44'/0'/1'/0/0` for the second account).
Click "Start Sign TX" and a new window will open to connect to the Trezor and sign the transaction.
Once complete, a new field will appear at the bottom of the screen titled "Partially Signed STX Transfer Operation Transaction" with the payload below it.
The next signer will follow the same steps above.
The last signer will follow the same steps above **except** click "Finish Sign TX" at the end.
Once complete, a new field will appear at the bottom of the screen titled "Signed STX Transfer Operation Transaction" with the payload below it.
#### Submitting
Once the fully-signed transaction is generated, it is ready to be broadcast to the Bitcoin blockchain. There are several ways to do this, and one simple approach is using [BlockCypher's pushtx tool](https://live.blockcypher.com/btc/pushtx/).
Record the Bitcoin transaction ID to be used to verify the transaction status.
### Stacking STX
#### Setup
Fill in the required fields below to generate the STX stacking transaction:
- From Address (C32): The multisig STX address stacking STX generated earlier
- From public keys (comma separate): The compressed public keys of the multisig wallet in the same order, prefixed with `02` or `03`
- Required signers (number): The number of signatures required to sign the transaction (e.g. 2 if a 2-of-3 multisig wallet)
- microSTACKS (10^-6 STACKS) to send or stack (number): The total amount of uSTX to stack (1 STX = 1,000,000 uSTX)
- Pox Address (stacking only): The PoX reward address (BTC address) to send the reward to
- Cycles to Stack (stacking only): The number of cycles to stack for
- Pre-Stx TX TXID to consume: The Bitcoin transaction ID of the pre-stx transaction generated earlier
Click "Generate Stacking TX" and a new field will appear at the bottom of the screen titled "Unsigned STX Stacking Operation Transaction" with the payload below it.
#### Signing
To sign the payload, copy the entire paragraph of text and paste it into the "Transaction Signing" box under "Partial transaction:".
Fill in the following information based on the configuration supplied in this documentation. If you did not follow the instructions above, the Signer Path may be different.
- Signer Path: `m/44'/0'/0'/0/0`
- Device: Trezor
- Partial transaction: Unsigned STX Stacking Operation Transaction generated above
**Note:** If using multiple legacy accounts on the same Trezor, increase the 3rd digit of the signer path for each account (e.g. `m/44'/0'/1'/0/0` for the second account).
Click "Start Sign TX" and a new window will open to connect to the Trezor and sign the transaction.
Once complete, a new field will appear at the bottom of the screen titled "Partially Signed STX Stacking Operation Transaction" with the payload below it.
The next signer will follow the same steps above.
The last signer will follow the same steps above **except** click "Finish Sign TX" at the end.
Once complete, a new field will appear at the bottom of the screen titled "Signed STX Stacking Operation Transaction" with the payload below it.
#### Submitting
Once the fully-signed transaction is generated, it is ready to be broadcast to the Bitcoin blockchain. There are several ways to do this, and one simple approach is using [BlockCypher's pushtx tool](https://live.blockcypher.com/btc/pushtx/).
Record the Bitcoin transaction ID to be used to verify the transaction status.
### Verifying Status
In order for the transaction to be accepted and executed by miners, the second operation must confirm in a Bitcoin block that corresponds with a Stacks block, and the _next_ Bitcoin block must correspond with a Stacks block as well.
If either of those blocks are missed by the Stacks chain, the operation will not be carried out and the process must be restarted.
To verify the status of a transaction:
- Use the Bitcoin transaction ID saved above to get the Bitcoin block height the transaction was accepted in
- Use the [Stacks Explorer Blocks page](https://explorer.stacks.co/blocks) to check which Stacks block corresponds to the Bitcoin block height
- Use the Stacks Explorer Blocks page to verify the _next_ Stacks block is anchored to the _next_ Bitcoin block height
Example (success):
| Operation | Bitcoin Block | Stacks Block |
| -------------- | ------------- | ------------ |
| BTC Pre-Op STX | 732900 | 56992 |
| BTC Send STX | 732904 | **56996** |
| Next block | 732905 | **56997** |
In this example, Stacks block 56,997 would contain the STX transfer operation from the Stacks multisig wallet.
Example (lost):
| Operation | Bitcoin Block | Stacks Block |
| -------------- | ------------- | ------------ |
| BTC Pre-Op STX | 732800 | 56892 |
| BTC Send STX | 732814 | **56906** |
| Flash block | 732815 | **none** |
| Next block | 732816 | **56907** |
In this example, the Stacks operation would not be picked up by miners, and the entire process must be started over again.
### Bitcoin Transaction Fees
The fee estimation can be a bit aggressive at times, and the "Use Whole Pre-Stx UTXO" option may spend more than expected depending on the balance in the account.
If the tool is constantly returning the error below or if the fee estimates seem too high, it is possible to manually change the fee rate.
> The transaction generator doesn't think the PreStxOp has enough funds to pay the transaction fees. Try to generate using the "use whole UTXO" option.
To reduce the recommended fee rate, modify the `getFeeRate` function in `transacter.js` to reduce the multiplier.
Example: default is `2.3`, reduces it to `1`
```js
bsk.config.network.getFeeRate = function () {
return fetch("https://bitcoinfees.earn.com/api/v1/fees/recommended")
.then((resp) => resp.json())
.then((rates) => Math.floor(1 * rates.fastestFee));
};
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by comparing the proposed guide with the README and the generated dist/c32check.js and index.html references. Confirm where this workflow belongs in the project documentation, then validate the Trezor, Electrum, c32check, and transaction steps; done means the documentation has an agreed location and an accurate, maintainable procedure.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- blockchain, documentation
- Issue type
- Documentation
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100