For the complete documentation index, see llms.txt. This page is also available as Markdown.

buildGrantSignerKey

Builds an unsigned contract call to pox-5 grant-signer-key, which records that a signer key authorizes a signer-manager to register it. The authorization is a SIP-018 signature from the signer key over the signer-manager and an authId.


Usage

import {
  buildGrantSignerKey,
  fetchEligibleGrantSignerKey,
  signSignerGrant,
} from '@stacks/bitcoin-staking';
import { STACKS_MAINNET } from '@stacks/network';
import {
  fetchNonce,
  privateKeyToAddress,
  privateKeyToPublic,
  publicKeyToHex,
} from '@stacks/transactions';

const network = 'mainnet';
const signerPrivateKey = process.env.SIGNER_KEY!;
const signerKey = publicKeyToHex(privateKeyToPublic(signerPrivateKey));
const signerManager = 'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.my-signer-manager';
const authId = 1n;

const signerSignature = signSignerGrant({
  signerManager,
  authId,
  chainId: STACKS_MAINNET.chainId,
  privateKey: signerPrivateKey,
});

const check = await fetchEligibleGrantSignerKey({ signerKey, signerManager, authId, signerSignature, network });
if (!check.ok) throw new Error(`grant-signer-key would fail: ${check.reasons}`);

// contract-caller must equal signerManager: see Notes.
const senderKey = process.env.SENDER_KEY!;
const tx = await buildGrantSignerKey({
  signerKey,
  signerManager,
  authId,
  signerSignature,
  publicKey: publicKeyToHex(privateKeyToPublic(senderKey)),
  fee: 10_000n, // micro-STX
  nonce: await fetchNonce({ address: privateKeyToAddress(senderKey, network), network }),
  network,
});

Notes

  • pox-5 requires contract-caller to equal signerManager and fails with ERR_UNAUTHORIZED_SIGNER_REGISTRATION (u26) otherwise (pox-5.clar L2743-L2811). This builder calls pox-5 directly, so contract-caller is the transaction's origin account. With a signer-manager contract as signerManager, the call fails with u26: the signer-manager contract has to submit the grant itself. signSignerGrant and verifySignerGrant produce and check the signature it forwards. See Deploy a signer-manager contract.

  • Each (signerKey, signerManager, authId) can be granted once (ERR_SIGNER_KEY_GRANT_USED (u12)). Check with fetchSignerKeyGrantUsed.

  • pox-5 recovers a public key from signerSignature over the grant hash and compares it with signerKey. An unrecoverable signature fails with ERR_INVALID_SIGNATURE_RECOVER (u13), a different key with ERR_INVALID_SIGNATURE_PUBKEY (u14). The hash includes the chain ID pox-5 runs on, so sign with the target network's chainId.

  • fetchEligibleGrantSignerKey dry-runs the replay and signature checks. It does not run the caller check.

  • On success, pox-5 marks the authId used and sets the grant for (signerKey, signerManager). register-signer and every staking entry point require that grant. Remove it with buildRevokeSignerGrant.

  • No asset moves, so the call needs no post conditions.

  • A txid from broadcastTransaction confirms submission only. The call can still fail on-chain: read the mined transaction's result and pass an (err uN) to parsePox5Error.


Signature

args is a BuildGrantSignerKeyTxArgs, which includes TxParams.


Returns

Promise<StacksTransactionWire>

Resolves to an unsigned StacksTransactionWire that calls pox-5 grant-signer-key. Sign it with TransactionSigner, then send it with broadcastTransaction.


Parameters

args.signerKey (required)

  • Type: Uint8Array | string

Compressed secp256k1 public key of the signer, 33 bytes, as bytes or hex.

args.signerManager (required)

  • Type: string

Stacks principal of the signer-manager being authorized.

args.authId (required)

  • Type: IntegerType

Replay nonce. It must be the value the signer signed.

args.signerSignature (required)

  • Type: Uint8Array | string

65-byte recoverable signature in RSV order, as bytes or hex, from signSignerGrant.

args.fee (required)

  • Type: IntegerType

Transaction fee in micro-STX.

args.nonce (required)

  • Type: IntegerType

Nonce of the origin account. Read it with fetchNonce.

args.network (required)

  • Type: StacksNetworkName | StacksNetwork

A name such as 'mainnet' or 'testnet', or a StacksNetwork object. Sets the contract address (the network's boot address, SP000000000000000000002Q6VF78 on mainnet) and the transaction version and chain ID.

args.publicKey (required for a single-sig origin)

  • Type: string

Hex public key of the account that signs the transaction.

args.publicKeys and args.numSignatures (required for a multisig origin)

  • Type: PublicKey[] and number

Pass these instead of publicKey to build for an M-of-N multisig origin. This package defaults useNonSequentialMultiSig to true; pass false for the sequential hash mode. Pass address to check the key order against the multisig address.

args.postConditions (optional)

  • Type: PostCondition[]

Post conditions to attach. The builder adds none.

args.postConditionMode (optional)

  • Type: PostConditionModeName

'allow', 'deny' or 'originator'. Defaults to 'deny'.

Was this helpful?