Signer Quickstart
The commands below take a fresh Ubuntu machine to a running signer and Stacks node. And this dApp can be used after the software is running for the necessary steps to start signing.
If you are not familiar with how signing works yet, be sure to check out the Signing concept guide.
Prerequisites
# Create the required directories
mkdir -p ~/stacks-signer/data
mkdir -p ~/stacks-node/data
# Install needed packages
sudo apt install -y npm wget unzip jq tar
# Install Stacks CLI globally
npm install --global @stacks/cli
# Generate a new account and store details in a file
stx make_keychain | jq > ~/stacks-signer/keychain.json# Create the required directories
mkdir -p ~/stacks-signer/data
mkdir -p ~/stacks-node/data
# Install needed packages
sudo apt install -y npm wget unzip jq tar
# Install Stacks CLI globally
npm install --global @stacks/cli
# Generate a new account and store details in a file
# '-t' option makes this a testnet account
stx make_keychain -t | jq > ~/stacks-signer/keychain.jsonThe account file looks like this:
{
"mnemonic": "aaa bbb ccc ddd ...",
"keyInfo": {
"privateKey": "65f3...",
"publicKey": "03a3...",
"address": "SP1G...",
"btcAddress": "19tg...",
"wif": "Kzdt...",
"index": 0
}
}From this file, you'll need the privateKey value.
Set Up Your Stacks Signer
Get the stacks-signer
Download the latest signer release ZIP file for your server's architecture and decompress it. Inside that folder is a stacks-signer binary.
Assuming a Linux x64 glibc machine:
# Enter the signer directory
cd ~/stacks-signer
# Download the signer binary zip
wget https://github.com/stacks-network/stacks-core/releases/latest/download/linux-glibc-x64.zip
# Unzip the signer binary archive
unzip linux-glibc-x64.zipPull the image, pinned by digest so the same bytes land on every architecture:
IMG="ghcr.io/stacks-network/stacks-signer"
VER="4.0.1@sha256:815b5518ec0f3a9b4c30d7fdca8f048a1fe8c263790ca65c5785e119b87d8590"
docker pull $IMG:$VERCreate the configuration file
Create the configuration file required to start the signer (be sure to replace <your_token> and <your_private_key> with your auth token and private key values). Every option is documented in Signer Configuration.
# Set environment variables
AUTH_TOKEN=<your_token> # Used for signer-node authentication
PRIVATE_KEY=<your_private_key> # privateKey from Step 1, this is the signer's private key
# Create the signer's configuration file
cat <<EOF> ~/stacks-signer/signer-config.toml
node_host = "127.0.0.1:20443"
endpoint = "127.0.0.1:30000"
network = "mainnet"
db_path = "$HOME/stacks-signer/data/signer.sqlite"
auth_password = "$AUTH_TOKEN"
stacks_private_key = "$PRIVATE_KEY"
metrics_endpoint = "127.0.0.1:9154"
EOF# Set environment variables
AUTH_TOKEN=<your_token> # Used for signer-node authentication
PRIVATE_KEY=<your_private_key> # privateKey from Step 1, this is the signer's private key
# Create the signer's configuration file
cat <<EOF> ~/stacks-signer/signer-config.toml
node_host = "127.0.0.1:20443"
endpoint = "127.0.0.1:30000"
network = "testnet"
db_path = "$HOME/stacks-signer/data/signer.sqlite"
auth_password = "$AUTH_TOKEN"
stacks_private_key = "$PRIVATE_KEY"
metrics_endpoint = "127.0.0.1:9154"
EOFVerify the setup
Check the version and the config file:
# Verify the signer's version
~/stacks-signer/stacks-signer --version
# Output:
stacks-signer 4.0.1 (62e03cc, release build, linux [x86_64])
# Verify the config file
~/stacks-signer/stacks-signer check-config -c ~/stacks-signer/signer-config.toml
# Output:
Signer version: stacks-signer 4.0.1 (62e03cc, release build, linux [x86_64])
Config:
Stacks node host: 127.0.0.1:20443
Signer endpoint: 127.0.0.1:30000
Stacks address: SP1G... # address from keychain file
Public key: 03a3... # publicKey from keychain file
Network: mainnet # or testnet
Chain ID: 0x1 # or 0x80000000 for testnet
Database path: /home/user/stacks-signer/data/signer.sqlite
Metrics endpoint: 127.0.0.1:9154
Dry run: falseStart the signer
If the output is correct, start the signer:
The port you set as endpoint has to reach your Stacks node and nothing else, and the volume holding db_path needs a few GB free.
On a host that is not x64, add --platform=linux/amd64, or the run fails with a manifest or platform mismatch.
Set up a Bitcoin node
Run your own, dedicated to this signer. A shared or third-party node is the usual reason a Stacks node falls behind tip, and a signer whose node is behind tip stops signing.
Follow either the full Bitcoin node or pruned Bitcoin node guide.
Set Up Your Stacks Node
Get the stacks-node
Download the latest node release ZIP file for your server's architecture and decompress it. Inside that folder is a stacks-node binary.
Assuming a Linux x64 glibc machine:
# Enter the node directory
cd ~/stacks-node
# Download the node binary zip
wget https://github.com/stacks-network/stacks-core/releases/latest/download/linux-glibc-x64.zip
# Unzip the node binary archive
unzip linux-glibc-x64.zipNODE_IMG="ghcr.io/stacks-network/stacks-core"
NODE_VER="4.0.1@sha256:ceb768f881ef52a1d2792a2b4a89d81e092b1df11293b04c31ce36613c3f9711"
docker pull $NODE_IMG:$NODE_VERCreate the configuration file
Create the configuration file required to start the node (be sure to replace <your_token> with your auth token value). Every option is documented in Stacks Node Configuration.
If you run your own bitcoin node, you'll have to update peer_host and optionally add rpc_port, peer_port, username and password fields under the [burnchain] section of the node's configuration file.
# Set environment variables
AUTH_TOKEN=<your_token> # Used for signer-node authentication, same token as the one set up in the signer configuration
# Create the node's configuration file
cat <<EOF> ~/stacks-node/node-config.toml
[node]
working_dir = "$HOME/stacks-node/data"
rpc_bind = "127.0.0.1:20443"
p2p_bind = "0.0.0.0:20444"
prometheus_bind = "127.0.0.1:9153"
bootstrap_node = "02196f005965cebe6ddc3901b7b1cc1aa7a88f305bb8c5893456b8f9a605923893@seed.mainnet.hiro.so:20444,02539449ad94e6e6392d8c1deb2b4e61f80ae2a18964349bc14336d8b903c46a8c@cet.stacksnodes.org:20444,02ececc8ce79b8adf813f13a0255f8ae58d4357309ba0cedd523d9f1a306fcfb79@sgt.stacksnodes.org:20444,0303144ba518fe7a0fb56a8a7d488f950307a4330f146e1e1458fc63fb33defe96@est.stacksnodes.org:20444"
stacker = true
[burnchain]
chain = "bitcoin"
mode = "mainnet"
peer_host = "bitcoin.mainnet.stacks.org"
[connection_options]
auth_token = "$AUTH_TOKEN"
[[events_observer]]
endpoint = "127.0.0.1:30000"
events_keys = ["stackerdb", "block_proposal", "burn_blocks"]
EOFBased on the mainnet follower example, with stacker, the auth token and the events observer added so the node can serve a signer.
Based on the Stacks node testnet config, which is the follower config plus the fields a node serving a signer needs.
Optional: Start the node with a data archive
You can download a chainstate archive instead of syncing from genesis.
Verify the setup
Check the version and the config file:
# Verify the node's version
~/stacks-node/stacks-node version
# Output:
INFO [1786366428.758607] [stacks-node/src/main.rs:329] [main] stacks-node 4.0.1 (62e03cc, release build, linux [x86_64])
stacks-node 4.0.1 (62e03cc, release build, linux [x86_64])
# Verify the node's config
~/stacks-node/stacks-node check-config --config ~/stacks-node/node-config.toml
# Output:
INFO [1786366428.987308] [stacks-node/src/main.rs:329] [main] stacks-node 4.0.1 (62e03cc, release build, linux [x86_64])
INFO [1786366428.987352] [stacks-node/src/main.rs:359] [main] Loading config at path /home/user/stacks-node/node-config.toml
INFO [1786366429.090617] [stacks-node/src/main.rs:372] [main] Loaded config!Start the node
Start the signer first. The node will not run unless it can reach the endpoint it is configured to send events to.
Expose p2p_bind to the internet and keep rpc_bind reachable only by your signer. working_dir needs 500 GB to 1 TB.
In Docker's default bridge network, localhost inside a container is that container, not the host, so events_observer.endpoint has to name the signer container rather than 127.0.0.1. Connection refused errors here almost always mean that.
Monitoring
If you would like to learn more about monitoring your signer and its corresponding node, you can check the How to Monitor a Signer guide.
Next Steps: Register Your Signer
Once your signer and Stacks node are running and verified, this signer key has to be bound to a signer-manager contract before stakers can route to it. PoX-5 replaces the PoX-4 per-transaction signer signature with a standing on-chain grant:
You produce a SIP-018 signature off-chain with this signer's private key, binding it to a specific signer-manager and an
auth-id. See Generate a Signer Signature.That signer-manager submits
grant-signer-keycarrying your signature, then callsregister-signerto bind itself to your key on chain.
See Staking STX for the full PoX-5 staking flow, and Key and Address Rotation for changing this key later.
Last updated
Was this helpful?