Solo Stack
This doc assumes you are familiar with stacking at a conceptual level. If not, you may want to read the Stacking concept guide.
The guide below applies to those who want to solo stack, meaning they meet the minimum stacking requirement and need to either run a signer or collaborate with a signer.
There is a dapp created by DegenLabs for solo stacking without needing a signer, as DegenLabs operates a signer. This is likely the easiest option for solo stacking. We'll cover this option below.
However, if you prefer to participate in a pool by delegating your STX, you do not need to also operate a signer. If you fall into this category, check out the Stack in a Pool guide.
Solo Stacker Flow
Note that in order to solo stack, you need to have the minimum number of STX tokens. This number can be found by visiting the pox endpoint of Hiro's API at https://api.mainnet.hiro.so/v2/pox and looking at the min_threshold_ustx
field. (1 STX = 1,000,000 uSTX)
Call the function stack-stx
stack-stx
The first thing solo stackers will need to do is call the stack-stx
function.
Just like in previous versions of PoX, Stackers call stack-stx
, but with the new arguments added in Nakamoto. The arguments are:
Amount: Denoted in ustx (1 stx = 1,000,000 ustx)
PoX Address: the BTC wallet to receive Stacking rewards
Start burn height: the current BTC block height
Lock period: the number of cycles to lock for (1 minimum, 12 max)
Signer key: the public key that your signer is using
Signer signature: the signature that proves control of this signer key
max-amount: This parameter is used to validate the signer signature provided. It represents the maximum number of ustx that can be locked in this transaction.
auth-id: This parameter is used to validate the signer signature provided. auth-id is a random integer that prevents re-use of this particular signer signature.
Solo stackers have two choices when it comes to operating as a signer. They can choose to run a signer themselves or work with a signer on their behalf.
Option 1: Act as a signer
In the “prepare phase” before the next stacking cycle (100 blocks), the exact set of Stackers will be selected based on the amount of STX stacked. Just like in previous versions of PoX, each Stacker will have some number of reward slots based on the amount of STX locked.
It is critical that solo stackers have their signer running during this period. The prepare phase is when distributed key generation (DKG) occurs, which is used when validating blocks by signers.
In general, you don’t need to do anything actively during this period, other than monitoring your signer software to ensure it’s running properly.
Option 2: Work with a signer
If you do not want to operate a signer on your own, you can work with another signer. To do this, you will need to collaborate with them to get their signer signature (details in the following sections) and you will need to pass that signature when you call your stacking functions.
Rather than needing to find a signer to collaborate with, you can use the solo stacking dapp created by DegenLabs in order to use their signer to solo stack. They've created a UI that makes this process really simple.
They also have a tool for you to generate a signer signature if you prefer to call the stacking functions yourself.
Extending their stacking period
Just like in the current version of PoX, you can extend your lock period while still Stacking. The function called is stack-extend
.
You can “rotate” your signing key when extending your lock period.
The arguments are:
Extend count: the number of cycles to add to your lock period. The resulting lock period cannot be larger than 12. For example, if currently locked with 6 cycles remaining, the maximum number you can extend is 6.
Pox Address: the BTC address to receive rewards
Signer public key: the public key used for signing. This can stay the same, or you can use a new key.
Signer signature: a signature proving control of your signing key
max-amount: This parameter is used to validate the signer signature provided. It represents the maximum number of ustx (1 stx = 1,000,000 ustx) that can be locked in this transaction.
auth-id: This parameter is used to validate the signer signature provided. auth-id is a random integer that prevents re-use of this particular signer signature.
Step by Step Stacking Guide
Now that you are familiar with the overall stacking flow and the different roles played, let's dive into the step-by-step guide for actually conducting the stacking process.
There are several ways you can go about stacking. This guide will cover using Lockstacks, which is a stacking web application and the simplest option.
Additionally, you can choose to call the stacking functions directly from the deployed contract in the explorer.
The fields and process will be the same, but the UI will differ.
Finally, you can stack using JS and the @stacks/stacking package if you prefer. Again, the functions and parameters will be the same, you will just be writing your JS code directly instead of using a UI.
If you are interested in using this method, you'll want to follow the stacking guide created by Hiro, and be sure to integrate the new parameters described in Hiro's Nakamoto update doc.
Step 1: Run or work with a signer
This is a necessary prerequisite to stacking as a solo stacker or pool operator.
Running a signer involves setting up a hosted production environment that includes both a Stacks Node and the Stacks Signer. For more information, refer to the running a signer doc.
Once the signer software is running, you'll to keep track of the stacks_private_key
that you used when configuring your signer software. This will be used in subsequent Stacking transactions.
In the note above about pool operator vs signer keys, this corresponds to your signer key, not your pool operator wallet
Alternatively, you can work with a signer and have them perform step 2 below on your behalf.
Step 2: Generate a signer key signature
Overview of signer keys and signatures
The main difference with Stacking in Nakamoto is that the Signer (either solo Stacker or signer running a pool) needs to include new parameters in their Stacking transactions. These are Clarity transactions that pool operators will call when interacting with the pox-4.clar
contract. Interacting with that contract is how you as a pool operator actually stack your STX tokens.
Here is an overview of the fields you will need to pass. We'll cover how to get and pass these fields as we dive further into this doc.
The current pox-4 contract address can be found by visiting the following endpoint of the Hiro API: https://api.testnet.hiro.so/v2/pox.
You can then visit the Nakamoto Explorer to view the contract and pass in the contract id.
You may want to review this contract to familiarize yourself with it.
signer-key
: the public key that corresponds to thestacks_private_key
your signer is usingsigner-signature
: a signature that demonstrates that you actually controls yoursigner-key
. Because signer keys need to be unique, this is also a safety check to ensure that other Stackers can’t use someone else’s public keymax-amount
: The maximum amount of ustx (1 stx = 1,000,000 ustx) that can be locked in the transaction that uses this signature. For example, if callingstack-increase
, then this parameter dictates the maximum amount of ustx that can be used to add more locked STXauth-id
: a random integer that prevents re-use of a particular signature, similar to how nonces are used with transactions
Signer signatures are signatures created using a particular signer key. They demonstrate that the controller of that signer key is allowing a Stacker to use their signing key. The signer signature’s message hash is created using the following data:
method
: a string that indicates the Stacking method that is allowed to utilize this signature. The valid options arestack-increase
,stack-stx
,stack-extend
, oragg-commit
(for stack-aggregation-commit)max-amount
: described aboveauth-id
: described aboveperiod
: a value from 0-12, which indicates how long the Stacker is allowed to lock their STX for in this particular Stacking transaction. Foragg-commit
, this must be equal to 1reward-cycle
: This represents the reward cycle in which the Stacking transaction can be confirmed (see the note above on passing in the correct reward cycle forstack-stx
vsstack-aggregation-commit
)pox-address
: The Bitcoin address that is allowed to be used for receiving rewards. This corresponds to the Bitcoin address associated with your signer
Now that we have an overview of role and contents of signatures, let's see how to actually generate them. You have several options available.
Generating your signature with Degen Labs stacks.tools
Degen Labs has a signature generation tool that will generator a signature using their signer. This is the quickest and simplest option. To generate a signature using this method, all you need to do is visit their signature tool and pass in the relevant information as covered on this page.
Generating your signature with stacks.js
The @stacks/stacking NPM package provides interfaces to generate and use signer signatures. You'll need to use @stacks/stacking
package version 6.13.0.
There is a new function called signPoxSignature
that will allow you to generate this signature and pass it in to the stacking function.
More information and code samples can be found on Hiro's Nakamoto docs.
Generating your signature using the stacks-signer CLI
If you already have your signer configured and set up, you can use the stacks-signer CLI to generate this signature. You can either SSH into your running signer or use the stacks-signer CLI locally. If using the CLI locally, you will need to ensure you have a matching configuration file located on your filesystem. Having a matching configuration file is important to ensure that the signer public key you make in Stacking transactions is the same as in your hosted signer.
The CLI command is:
These arguments match those described in section Overview of signer keys and signatures, with the addition of:
--config
, to provide the configuration file path;--json
, to optionally output the resulting signature in JSON.
You can use the following command to generate a random 128
bit integer as auth-id
:
Once the generate-stacking-signature
command is run, the CLI will output a JSON:
You will use the JSON when calling Stacking transactions from your pool operator address as outlined above. Remember that this may be different than your signer address.
Generating your signature with Lockstacks
Lockstacks is a web application that provides an easy-to-use interface for stacking and generating signatures. We'll cover using Lockstacks for stacking at the end of this document, here we will cover how to use it to generate a signature.
At the time of writing, this has only been tested using the Leather wallet.
You can visit lockstacks.com to generate a signer key signature. Make sure you’re connected to the correct network. To generate a signer key signature, it’s important that you’ve logged in Leather with the same secret key that was used to generate your signer key, not the account that will serve as your pool operator address. Once you’ve setup that account on Leather, you can log in to Lockstacks. Click the link “Signer key signature” at the bottom of the page. This will open the “generate a signer key signature” page.
The fields are:
Reward cycle:
For all solo stacking transactions, this must equal the current reward cycle, not the cycle in which they will start stacking. The field defaults to the current reward cycle.
For stack-aggregation-commit, this field must equal the cycle used in that function’s “reward cycle” argument. Typically, that equates to current_cycle + 1.
Bitcoin address: the PoX reward address that can be used
Topic: the stacking function that will use this signature
Max amount: max amount of STX that can be used. Defaults to “max possible amount”
Auth ID: defaults to random int
Duration: must match the number of cycles used in the stacking transaction. For stack-aggregation-commit, use “1”.
Each of these fields must be exactly matched in order for the Stacking transaction to work. Future updates to Lockstacks will verify the signature before the transaction is made.
Click the “generate signature” button to popup a Leather page where you can generate the signature. Once you submit that popup, Lockstacks will have the signer key and signature you generated.
After you sign that message, you'll see the information you need to share with Stackers who are delegating to you, including the signer public key and signature.
You can click the “copy” icon next to “signer details to share with stackers”. This will copy a JSON string, which can be directly pasted into the Lockstacks page where you make your Stacking transaction. Alternatively, this information can be shared and entered manually.
We'll cover the Lockstacks pages for actually making those transactions in the next section of this document.
Using a hardware or software wallet to generate signatures
When the signer is configured with a stacks_private_key
, the signer may want to be able to use that key in a wallet to make stacking signatures.
If the signer uses a tool like @stacks/cli to generate the key, the CLI also outputs a mnemonic (aka “seed phrase”) that can be imported into a wallet. Because the Stacks CLI uses the standard derivation path for generating Stacks keys, any Stacks wallet will default to having that same private key when the wallet is imported from a derivation path. Similarly, if a hardware wallet is setup with that mnemonic, then the Signer can use a wallet like Leather to make stacking signatures.
The workflow for using a setting up a wallet to generate signatures would be:
Use @stacks/cli to generate the keychain and private key.
Typically, when using a hardware wallet, it’s better to generate the mnemonic on the hardware wallet. For this use case, however, the signer software needs the private key, and hardware wallets (by design) don’t allow exporting private keys.
Take the
privateKey
from the CLI output and add it to your signer’s configuration.Take the mnemonic (24 words) and either:
Setup a new hardware wallet with this mnemonic
Store it somewhere securely, like a password manager. When the signer needs to generate signatures for Stacking transactions, they can import it into either Leather or XVerse.
When the user needs to generate signatures:
Setup your wallet with your signer key’s private key. Either:
Setup your Leather wallet with a Ledger hardware wallet
Import your mnemonic into Leather, XVerse, or another Stacks wallet
Open an app that has stacking signature functionality built-in
Connect your wallet to the app (aka sign in)
In the app, enter your PoX address and “submit”
The app will popup a window in your wallet that prompts you to sign the information
The app will show clear information about what you’re signing
Create the signature
If using a Ledger, confirm on your device
The app will display two results:
Your signer key, which is the public key associated with your signer’s key
Your signer signature
Finally, make a Stacking transaction using the signer key and signer signature.
Now that you have your signer signature generated, it's time to start stacking. This process will vary depending on your chosen method. We've included instructions for solo stacking and stacking as a pool operator below.
Step 3: Stack your STX
stack-stx
To start, you'll visit Lockstacks and click the “Stack independently” button on the home page.
This page will allow you to input the following input:
The amount of STX you want to lock
The duration (in number of cycles) to lock for
Your BTC address where you will receive Stacking rewards
New fields:
Your signer public key
Your signer key signature (this is what you generated in the previous step)
Auth ID
Max amount
stack-extend
If you want to extend the amount of time that your STX will be locked for, you can use the stack-extend page on Lockstacks.
If you’re already stacking, the home page will provide a link to “view stacking details”. From there, you can choose to extend.
On this page are the following fields:
The number of cycles you want to extend for
Your BTC address to receive rewards
New fields:
Signer public key
Signer key signature
Last updated