spox is a binary that monitors the Bitcoin blockchain for sBTC deposits made to a set of addresses, and when found
informs Emily about them so the sBTC signers can then process them.
sBTC is a 1:1 BTC-backed asset on the Stacks blockchain: every sBTC token on Stacks corresponds to a real BTC deposit on Bitcoin.
To mint sBTC, a user submits a Bitcoin transaction whose details the sBTC signers need to verify the deposit. Those details are compactly encoded within the deposit transaction itself, and must be relayed via the Emily API before the signers can process a deposit.
The spox application uses the deposit-transaction data in its configuration file and/or an on-chain registry
to monitor the Bitcoin network for matching transactions and automatically notify Emily when a confirmed deposit appears.
To build spox, run:
cargo build --bin spox --release --lockedThe binary will be built in target/release/spox.
You can specify which deposits to look for and the endpoints to use in a toml file.
See src/config/default.toml for a config starting point.
A Bitcoin node is required to run the binary (monitoring mode), while it is not used for specific CLI commands; note that the entry in the config is still required (but not used).
A Stacks node is required when using an on-chain registry or by certain subcommands. It can be omitted otherwise.
To monitor the deposit addresses, spox can either use the scantxoutset RPC or a Bitcoin core watch-only wallet.
scantxoutset: doesn't require managing wallet state on the node but each scan can take a couple of minutes and may conflict with other scans already happening.- watch-only wallet: can take some time to rescan when adding new addresses but after that each query is instantaneous.
The default config uses a wallet; note that you shouldn't create the wallet on the node, spox will manage it.
The wallet can then be removed by deleting the wallet directory under Bitcoin Core's wallets/ folder.
When configuring a deposit, you must specify the sBTC signers' public key using the signers_xonly field in the config.
This key changes over time after sBTC key rotations. To fetch the current key, fill the stacks stanza with the Stacks
endpoint and deployer address (for Stacks mainnet, see https://github.com/stacks-sbtc/sbtc/blob/58669393deadfa2b786c34f7a575cdc3fcb58d0a/docker/mainnet/sbtc-signer/signer-config.toml.in#L109).
Then you can run:
./spox -c <config file> get-signers-xonly-keyto get the latest key from the sBTC registry smart contract. The config file will be searched for in the current working directory, but it's also possible to specify an absolute path.
Once you have configured a deposit, you can run:
./spox -c <config file> get-deposit-addressto get the bitcoin address for each configured deposit.
In addition to listing deposits in the config file, spox can watch deposit addresses
registered in an on-chain smart contract (see contracts/contracts/registry.clar).
Set registry_contract in the config to the qualified contract identifier
(e.g. ST2SBXRBJJTH7GV5J93HJ62W2NRRQ46XYBK92Y039.registry) and fill in the stacks stanza.
spox will poll the registry and monitor any addresses it finds there alongside the ones defined under [deposit.*].
To inspect the Bitcoin address for a given registry entry:
./spox -c <config file> get-registry-address <address id> -n <network>Once the configuration is completed, you can run spox:
./spox -c <config file>The binary will monitor the Bitcoin blockchain for payments made to the monitored addresses, and when a new payment is confirmed, it will notify Emily about it so that the sBTC signers can process it.
The demo uses the sBTC devenv.
Install the node dependencies:
pnpm install --frozen-lockfileTo get the devenv ready, use:
# From sBTC repo
make devenv-up
# Wait for devenv bootstrap, then fund the sBTC signers
cargo run -p signer --bin demo-cli donationNow you need to specify the monitored deposit addresses either in the configuration file or via the on-chain registry.
The commands below fetch and overwrite the devenv aggregate key; as an alternative,
edit the config with the value returned from get-signers-xonly-key.
Get the deposit address from the config:
SPOX_DEPOSIT__DEMO__SIGNERS_XONLY=$(RUST_LOG=info cargo run -- -c src/config/default.toml get-signers-xonly-key) RUST_LOG=debug cargo run -- -c src/config/default.toml get-deposit-address -n regtestIt will output something like demo: bcrt1pny4nsp7vsrj7nmgy3mu0dq3cxpzxr4ez7eyzkpupmum7mq4h94asm7t0dx.
Send a payment to the deposit address above:
# From sBTC codebase
cargo run -p signer --bin demo-cli fund-btc --recipient <deposit address>Start spox (this can happen before or after the above payment):
SPOX_DEPOSIT__DEMO__SIGNERS_XONLY=$(RUST_LOG=info cargo run -- -c src/config/default.toml get-signers-xonly-key) RUST_LOG=debug cargo run -- -c src/config/default.tomlThis will look for deposits made to the signers pubkey with the devenv default values. Once the tx is confirmed it should appear on Emily, assuming it didn't expire in the meantime, and be processed by the signers, assuming the amount is not too low to be ignored.
Deploy the smart contract (will deploy at ST2SBXRBJJTH7GV5J93HJ62W2NRRQ46XYBK92Y039.registry)
(cd tests && pnpm exec tsx registry/registry.ts deploy)Run spox (the registry is specified in the configuration file):
cargo run -- -c tests/registry/spox.tomlNow register an address on the registry either manually or via the web app.
Register an address on the registry:
# Get the signers xonly key via (in sBTC codebase): `cargo run -p signer --bin demo-cli info`
# Replace `1cbc44709f590f939f52a831546169363e6403e96e1605b2e1996edb99029ffc` with the above
# or generate your deposit and reclaim scripts in any other way
export SPOX_DEMO_SIGNERS_XONLY=1cbc44709f590f939f52a831546169363e6403e96e1605b2e1996edb99029ffc
(cd tests && pnpm exec tsx registry/registry.ts add 1e0000000000001388051ab2bee17296a2786cb248e3230b82ae31721bbe5c7520${SPOX_DEMO_SIGNERS_XONLY}ac 0114b275206c44dfe47941b0271c642c549d9a763afce7c6b0495c72f1a32c2f09898ea3dfac)After a bit, spox should log about the new address.
Get the Bitcoin address for the registered address:
cargo run -- -c tests/registry/spox.toml get-registry-address 0 -n regtestIn webapp/ there is a simple web app to interact with the registry. See webapp/README.md for more details.
Run the web app:
(cd webapp && pnpm dev)Fund your wallet, e.g. (from sBTC codebase):
# Change the address to the wallet you will use with the web app
cargo run -p signer --bin demo-cli fund-stx --recipient ST2FQWJMF9CGPW34ZWK8FEPNK072NEV1VKRNBBMJ9Use the web app at http://localhost:3001 to create and register your address.
After a bit, spox should log about the new address.
Finally, send a payment to the above address (e.g.):
# From sBTC codebase
cargo run -p signer --bin demo-cli fund-btc --recipient bcrt1p3q78wuc2pvxrcal3dgwld94fd45khf08m3fekwk8p4s2tw68p8cqsn3nqyAfter a bit spox should notice the payment to the deposit address and it will notify Emily;
then the sBTC signers will fulfill it.
See tests/README.md