@secondlayer/stacks 6.4.1 → 6.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/shared/{stacks-esm-w8kswk0r.js → stacks-esm-2g7h9sbq.js} +3 -3
  2. package/dist/shared/{stacks-esm-ss9ap75h.js → stacks-esm-47b3bb9e.js} +2 -2
  3. package/dist/shared/stacks-esm-51sysw9g.js +7 -0
  4. package/dist/shared/stacks-esm-51sysw9g.js.map +10 -0
  5. package/dist/shared/{stacks-esm-w36fvdxx.js → stacks-esm-5w6zn26c.js} +2 -2
  6. package/dist/shared/{stacks-esm-hcjqgrtm.js → stacks-esm-60wsk8b7.js} +3 -3
  7. package/dist/shared/{stacks-esm-zwbhghxb.js → stacks-esm-90bwm9ng.js} +3 -4
  8. package/dist/shared/{stacks-esm-zwbhghxb.js.map → stacks-esm-90bwm9ng.js.map} +3 -3
  9. package/dist/shared/{stacks-esm-z0rq3ejt.js → stacks-esm-fb1gh99a.js} +4 -7
  10. package/dist/shared/{stacks-esm-z0rq3ejt.js.map → stacks-esm-fb1gh99a.js.map} +4 -5
  11. package/dist/shared/{stacks-esm-hv11fdgy.js → stacks-esm-kd5gn8v3.js} +2 -2
  12. package/dist/shared/{stacks-esm-e2qhfgke.js → stacks-esm-ph2fd7hg.js} +8 -4
  13. package/dist/shared/{stacks-esm-e2qhfgke.js.map → stacks-esm-ph2fd7hg.js.map} +3 -3
  14. package/dist/shared/{stacks-esm-bragecm9.js → stacks-esm-s6tybkrn.js} +4 -4
  15. package/dist/shared/stacks-esm-zvpv6a06.js +28 -0
  16. package/dist/shared/stacks-esm-zvpv6a06.js.map +10 -0
  17. package/dist/src/accounts/index.cjs +7 -3
  18. package/dist/src/accounts/index.cjs.map +3 -3
  19. package/dist/src/accounts/index.js +1 -1
  20. package/dist/src/actions/index.cjs +2 -3
  21. package/dist/src/actions/index.cjs.map +3 -3
  22. package/dist/src/actions/index.js +5 -5
  23. package/dist/src/bitcoin/index.cjs +7 -3
  24. package/dist/src/bitcoin/index.cjs.map +3 -3
  25. package/dist/src/bitcoin/index.d.cts +6 -5
  26. package/dist/src/bitcoin/index.d.ts +6 -5
  27. package/dist/src/bitcoin/index.js +12 -23
  28. package/dist/src/bitcoin/index.js.map +3 -4
  29. package/dist/src/bns/index.cjs +2 -3
  30. package/dist/src/bns/index.cjs.map +3 -3
  31. package/dist/src/bns/index.js +5 -5
  32. package/dist/src/index.cjs +2 -3
  33. package/dist/src/index.cjs.map +3 -3
  34. package/dist/src/index.js +4 -4
  35. package/dist/src/postconditions/index.cjs +2 -3
  36. package/dist/src/postconditions/index.cjs.map +3 -3
  37. package/dist/src/postconditions/index.js +2 -2
  38. package/dist/src/pox/index.cjs +8 -5
  39. package/dist/src/pox/index.cjs.map +4 -4
  40. package/dist/src/pox/index.js +7 -7
  41. package/dist/src/pox5/index.cjs +8 -5
  42. package/dist/src/pox5/index.cjs.map +4 -4
  43. package/dist/src/pox5/index.js +11 -9
  44. package/dist/src/pox5/index.js.map +2 -2
  45. package/dist/src/sbtc/index.cjs +174 -17
  46. package/dist/src/sbtc/index.cjs.map +11 -8
  47. package/dist/src/sbtc/index.d.cts +117 -5
  48. package/dist/src/sbtc/index.d.ts +117 -5
  49. package/dist/src/sbtc/index.js +156 -13
  50. package/dist/src/sbtc/index.js.map +7 -6
  51. package/dist/src/simnet/index.cjs +2 -3
  52. package/dist/src/simnet/index.cjs.map +3 -3
  53. package/dist/src/simnet/index.js +2 -3
  54. package/dist/src/simnet/index.js.map +3 -3
  55. package/dist/src/stackingdao/index.cjs +2 -3
  56. package/dist/src/stackingdao/index.cjs.map +3 -3
  57. package/dist/src/stackingdao/index.js +5 -5
  58. package/dist/src/transactions/index.cjs +2 -3
  59. package/dist/src/transactions/index.cjs.map +3 -3
  60. package/dist/src/transactions/index.js +2 -2
  61. package/package.json +1 -1
  62. /package/dist/shared/{stacks-esm-w8kswk0r.js.map → stacks-esm-2g7h9sbq.js.map} +0 -0
  63. /package/dist/shared/{stacks-esm-ss9ap75h.js.map → stacks-esm-47b3bb9e.js.map} +0 -0
  64. /package/dist/shared/{stacks-esm-w36fvdxx.js.map → stacks-esm-5w6zn26c.js.map} +0 -0
  65. /package/dist/shared/{stacks-esm-hcjqgrtm.js.map → stacks-esm-60wsk8b7.js.map} +0 -0
  66. /package/dist/shared/{stacks-esm-hv11fdgy.js.map → stacks-esm-kd5gn8v3.js.map} +0 -0
  67. /package/dist/shared/{stacks-esm-bragecm9.js.map → stacks-esm-s6tybkrn.js.map} +0 -0
@@ -151,6 +151,111 @@ type Client<TExtended extends Record<string, unknown> = Record<string, unknown>>
151
151
  nonceManager?: NonceManager
152
152
  extend: <const TNew extends Record<string, unknown>>(fn: (client: Client<TExtended>) => TNew) => Client<TExtended & TNew> & TNew
153
153
  } & TExtended;
154
+ /** The registry's current signer set (`get-current-signer-data`). */
155
+ interface SbtcSignerSet {
156
+ /** 33-byte compressed signer public keys. */
157
+ signerPublicKeys: Uint8Array[];
158
+ /** Signatures needed to spend the peg UTXO. */
159
+ signaturesRequired: number;
160
+ /**
161
+ * Raw aggregate-key field: a 33-byte public key while DKG runs, or the v2
162
+ * marker `0xFF || block hash` once DKG is disabled. Not checked here.
163
+ */
164
+ aggregatePubkey: Uint8Array;
165
+ signerPrincipal: string;
166
+ }
167
+ /** Options for {@link getSignersAddress}. */
168
+ interface SbtcPegAddressOptions {
169
+ /**
170
+ * Peg script format. Leave it out to pick the format the signers lock to
171
+ * at `burnBlockHeight`.
172
+ */
173
+ version?: "v1" | "v2";
174
+ /** Bitcoin height to resolve the format at. Defaults to the node's burn tip. */
175
+ burnBlockHeight?: number;
176
+ /**
177
+ * Height at which the signers switch to v2. Defaults to
178
+ * {@link SBTC_V2_SIGNING_BURN_HEIGHT_MAINNET} on mainnet; required on other
179
+ * networks unless `version` is given.
180
+ */
181
+ v2ActivationBurnHeight?: number;
182
+ }
183
+ type BitcoinNetwork = "mainnet" | "testnet" | "regtest";
184
+ declare class BaseError extends Error {
185
+ private;
186
+ name: string;
187
+ shortMessage: string;
188
+ details?: string;
189
+ constructor(shortMessage: string, options?: {
190
+ cause?: Error
191
+ details?: string
192
+ code?: string
193
+ });
194
+ /**
195
+ * Stable identifier for programmatic handling; survives message
196
+ * rewording and minification. An explicit `code` option wins, else it
197
+ * is derived from `name` (`TimeoutError` gives `TIMEOUT_ERROR`).
198
+ */
199
+ get code(): string;
200
+ set code(value: string);
201
+ toJSON(): {
202
+ name: string
203
+ code: string
204
+ message: string
205
+ shortMessage: string
206
+ details: string | undefined
207
+ cause: string | undefined
208
+ };
209
+ }
210
+ /**
211
+ * Bitcoin height at which mainnet sBTC signers start locking the peg UTXO to
212
+ * the v2 script (`MAINNET_V2_SIGNING_BLOCK_HEIGHT` in the sBTC signer). From
213
+ * this height the next sweep pays the v2 output; until that sweep confirms,
214
+ * the peg funds still sit at the v1 address.
215
+ */
216
+ declare const SBTC_V2_SIGNING_BURN_HEIGHT_MAINNET = 972295;
217
+ /**
218
+ * Unspendable internal key of v2 peg outputs: the `/0/0` child of the
219
+ * BIP341 NUMS point with an all-zero chain code (`V2_NUMS_X_COORDINATE`).
220
+ */
221
+ declare const SBTC_V2_INTERNAL_KEY: Uint8Array;
222
+ /**
223
+ * The registry's aggregate-key field holds the v2 marker `0xFF || block hash`
224
+ * instead of a public key. There is no aggregate key to derive an address
225
+ * from: the v2 peg is derived from the signer set and threshold.
226
+ */
227
+ declare class SbtcV2MarkerError extends BaseError {
228
+ name: string;
229
+ }
230
+ /**
231
+ * Check a registry aggregate key and return it. A key is 33 bytes starting
232
+ * with `0x02`/`0x03`. Throws {@link SbtcV2MarkerError} on the v2 marker
233
+ * (`0xFF` prefix) and a plain `Error` on anything else.
234
+ */
235
+ declare function assertRegistryAggregateKey(key: Uint8Array): Uint8Array;
236
+ /**
237
+ * The x-only Bitcoin signing key of one registry signer: the unhardened
238
+ * `/0/0` BIP32 child of its 33-byte public key, with chain code
239
+ * `SHA256("sbtc/signer/chain-code/v1" || pubkey)`.
240
+ */
241
+ declare function deriveSbtcSigningKey(registryPublicKey: Uint8Array): Uint8Array;
242
+ /** A v2 sBTC peg output: the `multi_a` leaf, its scriptPubKey and address. */
243
+ interface SbtcV2PegOutput {
244
+ /** Sorted x-only signing keys in the script. */
245
+ signingKeys: Uint8Array[];
246
+ signaturesRequired: number;
247
+ /** `<k1> CHECKSIG <k2> CHECKSIGADD … <m> NUMEQUAL`. */
248
+ signingScript: Uint8Array;
249
+ /** `OP_1 <32-byte output key>`. */
250
+ scriptPubKey: Uint8Array;
251
+ address: string;
252
+ }
253
+ /**
254
+ * Derive the v2 peg output from the registry signer set and threshold:
255
+ * `tr(NUMS_V2, multi_a(m, signer_1/0/0, …))` with the derived keys x-only and
256
+ * sorted. Mirrors `SignerKeySet::derive` + `script_pubkey` in the sBTC signer.
257
+ */
258
+ declare function deriveSbtcV2PegOutput(signerPublicKeys: readonly Uint8Array[], signaturesRequired: number, network?: BitcoinNetwork): SbtcV2PegOutput;
154
259
  /**
155
260
  * sBTC mainnet contract identifiers.
156
261
  *
@@ -292,7 +397,6 @@ type SbtcTokenEvent = SbtcTokenTransferEvent | SbtcTokenMintEvent | SbtcTokenBur
292
397
  type SbtcEventByTopic<T extends SbtcEventTopic> = Extract<SbtcRegistryEvent, {
293
398
  topic: T
294
399
  }>;
295
- type BitcoinNetwork = "mainnet" | "testnet" | "regtest";
296
400
  /**
297
401
  * Format a `(buff 1) + (buff 32)` BTC recipient tuple into a canonical
298
402
  * Bitcoin address string. Defaults to mainnet encoding; pass `network`
@@ -426,10 +530,18 @@ type SbtcActions = {
426
530
  getSymbol: () => Promise<string>
427
531
  getDecimals: () => Promise<bigint>
428
532
  getTokenUri: () => Promise<string | null>
429
- /** Current signer-set aggregate pubkey (33B compressed) from `sbtc-registry`. */
533
+ /** Current signer set and threshold from `sbtc-registry`. */
534
+ getSignerSet: () => Promise<SbtcSignerSet>
535
+ /**
536
+ * Current signer-set aggregate pubkey (33B compressed) from `sbtc-registry`.
537
+ * Throws `SbtcV2MarkerError` once the registry holds the v2 marker.
538
+ */
430
539
  getSignersPublicKey: () => Promise<Uint8Array>
431
- /** Signers' taproot deposit address, network-aware from `client.chain`. */
432
- getSignersAddress: () => Promise<string>
540
+ /**
541
+ * Signers' peg address (v1 aggregate key or v2 `multi_a`, by Bitcoin
542
+ * height), network-aware from `client.chain`.
543
+ */
544
+ getSignersAddress: (options?: SbtcPegAddressOptions) => Promise<string>
433
545
  }
434
546
  };
435
547
  /**
@@ -448,4 +560,4 @@ type SbtcActions = {
448
560
  * const balance = await client.sbtc.getBalance("SP1...");
449
561
  */
450
562
  declare function sbtc(): (client: Client) => SbtcActions;
451
- export { CompletedDepositEvent, KeyRotationEvent, SBTC_ASSET_IDENTIFIER_MAINNET, SBTC_ASSET_IDENTIFIER_TESTNET, SBTC_BTC_ADDRESS_VERSION, SBTC_CONTRACTS, SBTC_DECIMALS, SBTC_EVENT_TOPICS, SBTC_TOKEN_ABI, SBTC_UNIT_NAME, SbtcActions, SbtcBtcRecipient, SbtcEventByTopic, SbtcEventTopic, SbtcNetwork, SbtcRegistryEvent, SbtcTokenBurnEvent, SbtcTokenEvent, SbtcTokenMintEvent, SbtcTokenTransferEvent, UpdateProtocolContractEvent, WithdrawalAcceptEvent, WithdrawalCreateEvent, WithdrawalRejectEvent, bitcoinTxidFromHex, bitcoinTxidToHex, formatBtcAddress, satsToSbtc, sbtc, sbtcContractId, sbtcToSats, validateBitcoinTxid };
563
+ export { CompletedDepositEvent, KeyRotationEvent, SBTC_ASSET_IDENTIFIER_MAINNET, SBTC_ASSET_IDENTIFIER_TESTNET, SBTC_BTC_ADDRESS_VERSION, SBTC_CONTRACTS, SBTC_DECIMALS, SBTC_EVENT_TOPICS, SBTC_TOKEN_ABI, SBTC_UNIT_NAME, SBTC_V2_INTERNAL_KEY, SBTC_V2_SIGNING_BURN_HEIGHT_MAINNET, SbtcActions, SbtcBtcRecipient, SbtcEventByTopic, SbtcEventTopic, SbtcNetwork, SbtcPegAddressOptions, SbtcRegistryEvent, SbtcSignerSet, SbtcTokenBurnEvent, SbtcTokenEvent, SbtcTokenMintEvent, SbtcTokenTransferEvent, SbtcV2MarkerError, SbtcV2PegOutput, UpdateProtocolContractEvent, WithdrawalAcceptEvent, WithdrawalCreateEvent, WithdrawalRejectEvent, assertRegistryAggregateKey, bitcoinTxidFromHex, bitcoinTxidToHex, deriveSbtcSigningKey, deriveSbtcV2PegOutput, formatBtcAddress, satsToSbtc, sbtc, sbtcContractId, sbtcToSats, validateBitcoinTxid };
@@ -151,6 +151,111 @@ type Client<TExtended extends Record<string, unknown> = Record<string, unknown>>
151
151
  nonceManager?: NonceManager
152
152
  extend: <const TNew extends Record<string, unknown>>(fn: (client: Client<TExtended>) => TNew) => Client<TExtended & TNew> & TNew
153
153
  } & TExtended;
154
+ /** The registry's current signer set (`get-current-signer-data`). */
155
+ interface SbtcSignerSet {
156
+ /** 33-byte compressed signer public keys. */
157
+ signerPublicKeys: Uint8Array[];
158
+ /** Signatures needed to spend the peg UTXO. */
159
+ signaturesRequired: number;
160
+ /**
161
+ * Raw aggregate-key field: a 33-byte public key while DKG runs, or the v2
162
+ * marker `0xFF || block hash` once DKG is disabled. Not checked here.
163
+ */
164
+ aggregatePubkey: Uint8Array;
165
+ signerPrincipal: string;
166
+ }
167
+ /** Options for {@link getSignersAddress}. */
168
+ interface SbtcPegAddressOptions {
169
+ /**
170
+ * Peg script format. Leave it out to pick the format the signers lock to
171
+ * at `burnBlockHeight`.
172
+ */
173
+ version?: "v1" | "v2";
174
+ /** Bitcoin height to resolve the format at. Defaults to the node's burn tip. */
175
+ burnBlockHeight?: number;
176
+ /**
177
+ * Height at which the signers switch to v2. Defaults to
178
+ * {@link SBTC_V2_SIGNING_BURN_HEIGHT_MAINNET} on mainnet; required on other
179
+ * networks unless `version` is given.
180
+ */
181
+ v2ActivationBurnHeight?: number;
182
+ }
183
+ type BitcoinNetwork = "mainnet" | "testnet" | "regtest";
184
+ declare class BaseError extends Error {
185
+ private;
186
+ name: string;
187
+ shortMessage: string;
188
+ details?: string;
189
+ constructor(shortMessage: string, options?: {
190
+ cause?: Error
191
+ details?: string
192
+ code?: string
193
+ });
194
+ /**
195
+ * Stable identifier for programmatic handling; survives message
196
+ * rewording and minification. An explicit `code` option wins, else it
197
+ * is derived from `name` (`TimeoutError` gives `TIMEOUT_ERROR`).
198
+ */
199
+ get code(): string;
200
+ set code(value: string);
201
+ toJSON(): {
202
+ name: string
203
+ code: string
204
+ message: string
205
+ shortMessage: string
206
+ details: string | undefined
207
+ cause: string | undefined
208
+ };
209
+ }
210
+ /**
211
+ * Bitcoin height at which mainnet sBTC signers start locking the peg UTXO to
212
+ * the v2 script (`MAINNET_V2_SIGNING_BLOCK_HEIGHT` in the sBTC signer). From
213
+ * this height the next sweep pays the v2 output; until that sweep confirms,
214
+ * the peg funds still sit at the v1 address.
215
+ */
216
+ declare const SBTC_V2_SIGNING_BURN_HEIGHT_MAINNET = 972295;
217
+ /**
218
+ * Unspendable internal key of v2 peg outputs: the `/0/0` child of the
219
+ * BIP341 NUMS point with an all-zero chain code (`V2_NUMS_X_COORDINATE`).
220
+ */
221
+ declare const SBTC_V2_INTERNAL_KEY: Uint8Array;
222
+ /**
223
+ * The registry's aggregate-key field holds the v2 marker `0xFF || block hash`
224
+ * instead of a public key. There is no aggregate key to derive an address
225
+ * from: the v2 peg is derived from the signer set and threshold.
226
+ */
227
+ declare class SbtcV2MarkerError extends BaseError {
228
+ name: string;
229
+ }
230
+ /**
231
+ * Check a registry aggregate key and return it. A key is 33 bytes starting
232
+ * with `0x02`/`0x03`. Throws {@link SbtcV2MarkerError} on the v2 marker
233
+ * (`0xFF` prefix) and a plain `Error` on anything else.
234
+ */
235
+ declare function assertRegistryAggregateKey(key: Uint8Array): Uint8Array;
236
+ /**
237
+ * The x-only Bitcoin signing key of one registry signer: the unhardened
238
+ * `/0/0` BIP32 child of its 33-byte public key, with chain code
239
+ * `SHA256("sbtc/signer/chain-code/v1" || pubkey)`.
240
+ */
241
+ declare function deriveSbtcSigningKey(registryPublicKey: Uint8Array): Uint8Array;
242
+ /** A v2 sBTC peg output: the `multi_a` leaf, its scriptPubKey and address. */
243
+ interface SbtcV2PegOutput {
244
+ /** Sorted x-only signing keys in the script. */
245
+ signingKeys: Uint8Array[];
246
+ signaturesRequired: number;
247
+ /** `<k1> CHECKSIG <k2> CHECKSIGADD … <m> NUMEQUAL`. */
248
+ signingScript: Uint8Array;
249
+ /** `OP_1 <32-byte output key>`. */
250
+ scriptPubKey: Uint8Array;
251
+ address: string;
252
+ }
253
+ /**
254
+ * Derive the v2 peg output from the registry signer set and threshold:
255
+ * `tr(NUMS_V2, multi_a(m, signer_1/0/0, …))` with the derived keys x-only and
256
+ * sorted. Mirrors `SignerKeySet::derive` + `script_pubkey` in the sBTC signer.
257
+ */
258
+ declare function deriveSbtcV2PegOutput(signerPublicKeys: readonly Uint8Array[], signaturesRequired: number, network?: BitcoinNetwork): SbtcV2PegOutput;
154
259
  /**
155
260
  * sBTC mainnet contract identifiers.
156
261
  *
@@ -292,7 +397,6 @@ type SbtcTokenEvent = SbtcTokenTransferEvent | SbtcTokenMintEvent | SbtcTokenBur
292
397
  type SbtcEventByTopic<T extends SbtcEventTopic> = Extract<SbtcRegistryEvent, {
293
398
  topic: T
294
399
  }>;
295
- type BitcoinNetwork = "mainnet" | "testnet" | "regtest";
296
400
  /**
297
401
  * Format a `(buff 1) + (buff 32)` BTC recipient tuple into a canonical
298
402
  * Bitcoin address string. Defaults to mainnet encoding; pass `network`
@@ -426,10 +530,18 @@ type SbtcActions = {
426
530
  getSymbol: () => Promise<string>
427
531
  getDecimals: () => Promise<bigint>
428
532
  getTokenUri: () => Promise<string | null>
429
- /** Current signer-set aggregate pubkey (33B compressed) from `sbtc-registry`. */
533
+ /** Current signer set and threshold from `sbtc-registry`. */
534
+ getSignerSet: () => Promise<SbtcSignerSet>
535
+ /**
536
+ * Current signer-set aggregate pubkey (33B compressed) from `sbtc-registry`.
537
+ * Throws `SbtcV2MarkerError` once the registry holds the v2 marker.
538
+ */
430
539
  getSignersPublicKey: () => Promise<Uint8Array>
431
- /** Signers' taproot deposit address, network-aware from `client.chain`. */
432
- getSignersAddress: () => Promise<string>
540
+ /**
541
+ * Signers' peg address (v1 aggregate key or v2 `multi_a`, by Bitcoin
542
+ * height), network-aware from `client.chain`.
543
+ */
544
+ getSignersAddress: (options?: SbtcPegAddressOptions) => Promise<string>
433
545
  }
434
546
  };
435
547
  /**
@@ -448,4 +560,4 @@ type SbtcActions = {
448
560
  * const balance = await client.sbtc.getBalance("SP1...");
449
561
  */
450
562
  declare function sbtc(): (client: Client) => SbtcActions;
451
- export { CompletedDepositEvent, KeyRotationEvent, SBTC_ASSET_IDENTIFIER_MAINNET, SBTC_ASSET_IDENTIFIER_TESTNET, SBTC_BTC_ADDRESS_VERSION, SBTC_CONTRACTS, SBTC_DECIMALS, SBTC_EVENT_TOPICS, SBTC_TOKEN_ABI, SBTC_UNIT_NAME, SbtcActions, SbtcBtcRecipient, SbtcEventByTopic, SbtcEventTopic, SbtcNetwork, SbtcRegistryEvent, SbtcTokenBurnEvent, SbtcTokenEvent, SbtcTokenMintEvent, SbtcTokenTransferEvent, UpdateProtocolContractEvent, WithdrawalAcceptEvent, WithdrawalCreateEvent, WithdrawalRejectEvent, bitcoinTxidFromHex, bitcoinTxidToHex, formatBtcAddress, satsToSbtc, sbtc, sbtcContractId, sbtcToSats, validateBitcoinTxid };
563
+ export { CompletedDepositEvent, KeyRotationEvent, SBTC_ASSET_IDENTIFIER_MAINNET, SBTC_ASSET_IDENTIFIER_TESTNET, SBTC_BTC_ADDRESS_VERSION, SBTC_CONTRACTS, SBTC_DECIMALS, SBTC_EVENT_TOPICS, SBTC_TOKEN_ABI, SBTC_UNIT_NAME, SBTC_V2_INTERNAL_KEY, SBTC_V2_SIGNING_BURN_HEIGHT_MAINNET, SbtcActions, SbtcBtcRecipient, SbtcEventByTopic, SbtcEventTopic, SbtcNetwork, SbtcPegAddressOptions, SbtcRegistryEvent, SbtcSignerSet, SbtcTokenBurnEvent, SbtcTokenEvent, SbtcTokenMintEvent, SbtcTokenTransferEvent, SbtcV2MarkerError, SbtcV2PegOutput, UpdateProtocolContractEvent, WithdrawalAcceptEvent, WithdrawalCreateEvent, WithdrawalRejectEvent, assertRegistryAggregateKey, bitcoinTxidFromHex, bitcoinTxidToHex, deriveSbtcSigningKey, deriveSbtcV2PegOutput, formatBtcAddress, satsToSbtc, sbtc, sbtcContractId, sbtcToSats, validateBitcoinTxid };
@@ -1,24 +1,33 @@
1
1
  import {
2
2
  bytesToHex2,
3
- hexToBytes2
3
+ hexToBytes2,
4
+ concatBytes2
4
5
  } from "../../shared/stacks-esm-7a0ehykf.js";
5
6
  import"../../shared/stacks-esm-kbz5s6v8.js";
6
7
  import"../../shared/stacks-esm-gs60rd15.js";
7
8
  import"../../shared/stacks-esm-896kv9yv.js";
8
- import"../../shared/stacks-esm-zwbhghxb.js";
9
- import"../../shared/stacks-esm-hv11fdgy.js";
9
+ import"../../shared/stacks-esm-90bwm9ng.js";
10
+ import"../../shared/stacks-esm-kd5gn8v3.js";
10
11
  import {
12
+ BITCOIN_NETWORK_PARAMS,
13
+ taprootTweakPubkey2,
11
14
  publicKeyToP2trAddress2
12
- } from "../../shared/stacks-esm-e2qhfgke.js";
15
+ } from "../../shared/stacks-esm-ph2fd7hg.js";
13
16
  import {
14
17
  stringifyBtcAddress2
15
- } from "../../shared/stacks-esm-ss9ap75h.js";
18
+ } from "../../shared/stacks-esm-47b3bb9e.js";
19
+ import {
20
+ getBurnBlockHeight2
21
+ } from "../../shared/stacks-esm-zvpv6a06.js";
16
22
  import {
17
23
  getContract2,
18
24
  resolveNetworkContract
19
- } from "../../shared/stacks-esm-w8kswk0r.js";
20
- import"../../shared/stacks-esm-hcjqgrtm.js";
25
+ } from "../../shared/stacks-esm-2g7h9sbq.js";
26
+ import"../../shared/stacks-esm-60wsk8b7.js";
21
27
  import"../../shared/stacks-esm-x8gjr2v6.js";
28
+ import {
29
+ BaseError2
30
+ } from "../../shared/stacks-esm-7v18h5dk.js";
22
31
 
23
32
  // src/sbtc/abi.ts
24
33
  var SBTC_TOKEN_ABI = {
@@ -77,6 +86,25 @@ var SBTC_REGISTRY_ABI = {
77
86
  access: "read-only",
78
87
  args: [],
79
88
  outputs: { buff: { length: 33 } }
89
+ },
90
+ {
91
+ name: "get-current-signer-data",
92
+ access: "read-only",
93
+ args: [],
94
+ outputs: {
95
+ tuple: [
96
+ {
97
+ name: "current-aggregate-pubkey",
98
+ type: { buff: { length: 33 } }
99
+ },
100
+ { name: "current-signature-threshold", type: "uint128" },
101
+ { name: "current-signer-principal", type: "principal" },
102
+ {
103
+ name: "current-signer-set",
104
+ type: { list: { type: { buff: { length: 33 } }, length: 128 } }
105
+ }
106
+ ]
107
+ }
80
108
  }
81
109
  ]
82
110
  };
@@ -122,6 +150,90 @@ function sbtcContractId(network, contract) {
122
150
  return `${cfg.address}.${cfg[contract]}`;
123
151
  }
124
152
 
153
+ // src/sbtc/peg.ts
154
+ import { schnorr } from "@noble/curves/secp256k1.js";
155
+ import { sha256 } from "@noble/hashes/sha2.js";
156
+ import { bech32m } from "@scure/base";
157
+ import { HDKey } from "@scure/bip32";
158
+ var SBTC_V2_SIGNING_BURN_HEIGHT_MAINNET = 972295;
159
+ var MAX_SIGNERS = 16;
160
+ var SBTC_V2_INTERNAL_KEY = hexToBytes2("4a30b2e461b280c0b13a03799096ab1256589153fc4b9c8cead16dc0b6420697");
161
+ var CHAIN_CODE_DOMAIN = new TextEncoder().encode("sbtc/signer/chain-code/v1");
162
+ var OP_CHECKSIG = 172;
163
+ var OP_CHECKSIGADD = 186;
164
+ var OP_NUMEQUAL = 156;
165
+ var OP_PUSHNUM_BASE = 80;
166
+ var TAPSCRIPT_LEAF_VERSION = 192;
167
+
168
+ class SbtcV2MarkerError extends BaseError2 {
169
+ name = "SbtcV2MarkerError";
170
+ }
171
+ function assertRegistryAggregateKey(key) {
172
+ if (key.length === 33 && key[0] === 255) {
173
+ throw new SbtcV2MarkerError("sbtc-registry aggregate key is the v2 marker (0xFF || block hash), not a public key", {
174
+ details: "Derive the v2 peg from the signer set: getSignersAddress(client, { version: 'v2' })."
175
+ });
176
+ }
177
+ if (key.length !== 33 || key[0] !== 2 && key[0] !== 3) {
178
+ throw new Error(`sbtc-registry aggregate key is not a compressed public key (${key.length} bytes, prefix 0x${(key[0] ?? 0).toString(16).padStart(2, "0")})`);
179
+ }
180
+ return key;
181
+ }
182
+ function deriveSbtcSigningKey(registryPublicKey) {
183
+ if (registryPublicKey.length !== 33 || registryPublicKey[0] !== 2 && registryPublicKey[0] !== 3) {
184
+ throw new Error("sBTC signer key must be a 33-byte compressed public key");
185
+ }
186
+ const master = new HDKey({
187
+ publicKey: registryPublicKey,
188
+ chainCode: sha256(concatBytes2(CHAIN_CODE_DOMAIN, registryPublicKey))
189
+ });
190
+ const child = master.deriveChild(0).deriveChild(0).publicKey;
191
+ if (!child)
192
+ throw new Error("BIP32 derivation returned no public key");
193
+ return child.slice(1);
194
+ }
195
+ function compareBytes(a, b) {
196
+ for (let i = 0;i < a.length; i++) {
197
+ const d = a[i] - b[i];
198
+ if (d !== 0)
199
+ return d;
200
+ }
201
+ return a.length - b.length;
202
+ }
203
+ function compactSize(n) {
204
+ if (n < 253)
205
+ return Uint8Array.of(n);
206
+ if (n <= 65535)
207
+ return Uint8Array.of(253, n & 255, n >> 8);
208
+ throw new Error("tapscript too long");
209
+ }
210
+ function deriveSbtcV2PegOutput(signerPublicKeys, signaturesRequired, network = "mainnet") {
211
+ const unique = new Map;
212
+ for (const key of signerPublicKeys.map(deriveSbtcSigningKey)) {
213
+ unique.set(bytesToHex2(key), key);
214
+ }
215
+ const signingKeys = [...unique.values()].sort(compareBytes);
216
+ if (signingKeys.length > MAX_SIGNERS) {
217
+ throw new Error(`sBTC v2 peg holds at most ${MAX_SIGNERS} signer keys, got ${signingKeys.length}`);
218
+ }
219
+ if (!Number.isInteger(signaturesRequired) || signaturesRequired < 1 || signaturesRequired > signingKeys.length) {
220
+ throw new Error(`sBTC v2 threshold must be between 1 and ${signingKeys.length}, got ${signaturesRequired}`);
221
+ }
222
+ const signingScript = concatBytes2(...signingKeys.map((key, i) => concatBytes2(Uint8Array.of(32), key, Uint8Array.of(i === 0 ? OP_CHECKSIG : OP_CHECKSIGADD))), Uint8Array.of(OP_PUSHNUM_BASE + signaturesRequired, OP_NUMEQUAL));
223
+ const leafHash = schnorr.utils.taggedHash("TapLeaf", Uint8Array.of(TAPSCRIPT_LEAF_VERSION), compactSize(signingScript.length), signingScript);
224
+ const outputKey = taprootTweakPubkey2(SBTC_V2_INTERNAL_KEY, leafHash);
225
+ return {
226
+ signingKeys,
227
+ signaturesRequired,
228
+ signingScript,
229
+ scriptPubKey: concatBytes2(Uint8Array.of(81, 32), outputKey),
230
+ address: bech32m.encode(BITCOIN_NETWORK_PARAMS[network].hrp, [
231
+ 1,
232
+ ...bech32m.toWords(outputKey)
233
+ ])
234
+ };
235
+ }
236
+
125
237
  // src/sbtc/actions.ts
126
238
  function getTokenContract(client) {
127
239
  const contract = resolveNetworkContract(client, SBTC_CONTRACTS);
@@ -173,17 +285,41 @@ async function getTokenUri(client) {
173
285
  const token = getTokenContract(client);
174
286
  return await token.read.getTokenUri({});
175
287
  }
288
+ async function getSignerSet(client) {
289
+ const registry = getRegistryContract(client);
290
+ const data = await registry.read.getCurrentSignerData({});
291
+ return {
292
+ signerPublicKeys: data.currentSignerSet,
293
+ signaturesRequired: Number(data.currentSignatureThreshold),
294
+ aggregatePubkey: data.currentAggregatePubkey,
295
+ signerPrincipal: data.currentSignerPrincipal
296
+ };
297
+ }
176
298
  async function getSignersPublicKey(client) {
177
299
  const registry = getRegistryContract(client);
178
300
  const pubkey = await registry.read.getCurrentAggregatePubkey({});
179
301
  if (!pubkey || pubkey.length !== 33 || pubkey.every((b) => b === 0)) {
180
302
  throw new Error("sbtc-registry returned no aggregate pubkey (signer set not yet rotated in on this network)");
181
303
  }
182
- return pubkey;
304
+ return assertRegistryAggregateKey(pubkey);
183
305
  }
184
- async function getSignersAddress(client) {
185
- const pubkey = await getSignersPublicKey(client);
186
- return publicKeyToP2trAddress2(pubkey, bitcoinNetworkFromChain(client));
306
+ async function getSignersAddress(client, options = {}) {
307
+ const network = bitcoinNetworkFromChain(client);
308
+ const version = options.version ?? await pegVersionAt(client, options);
309
+ if (version === "v1") {
310
+ const pubkey = await getSignersPublicKey(client);
311
+ return publicKeyToP2trAddress2(pubkey, network);
312
+ }
313
+ const { signerPublicKeys, signaturesRequired } = await getSignerSet(client);
314
+ return deriveSbtcV2PegOutput(signerPublicKeys, signaturesRequired, network).address;
315
+ }
316
+ async function pegVersionAt(client, options) {
317
+ const activation = options.v2ActivationBurnHeight ?? (client.chain?.network === "mainnet" ? SBTC_V2_SIGNING_BURN_HEIGHT_MAINNET : undefined);
318
+ if (activation == null) {
319
+ throw new Error(`sBTC v2 signing has no fixed activation height on ${client.chain?.network ?? "this network"}; pass { version } or { v2ActivationBurnHeight }`);
320
+ }
321
+ const height = options.burnBlockHeight ?? await getBurnBlockHeight2(client);
322
+ return height >= activation ? "v2" : "v1";
187
323
  }
188
324
  // src/sbtc/utils.ts
189
325
  function formatBtcAddress(recipient, network = "mainnet") {
@@ -241,8 +377,9 @@ function sbtc() {
241
377
  getSymbol: () => getSymbol(client),
242
378
  getDecimals: () => getDecimals(client),
243
379
  getTokenUri: () => getTokenUri(client),
380
+ getSignerSet: () => getSignerSet(client),
244
381
  getSignersPublicKey: () => getSignersPublicKey(client),
245
- getSignersAddress: () => getSignersAddress(client)
382
+ getSignersAddress: (options) => getSignersAddress(client, options)
246
383
  }
247
384
  });
248
385
  }
@@ -255,8 +392,14 @@ export {
255
392
  SBTC_EVENT_TOPICS,
256
393
  SBTC_TOKEN_ABI,
257
394
  SBTC_UNIT_NAME,
395
+ SBTC_V2_INTERNAL_KEY,
396
+ SBTC_V2_SIGNING_BURN_HEIGHT_MAINNET,
397
+ SbtcV2MarkerError,
398
+ assertRegistryAggregateKey,
258
399
  bitcoinTxidFromHex,
259
400
  bitcoinTxidToHex,
401
+ deriveSbtcSigningKey,
402
+ deriveSbtcV2PegOutput,
260
403
  formatBtcAddress,
261
404
  satsToSbtc,
262
405
  sbtc,
@@ -265,5 +408,5 @@ export {
265
408
  validateBitcoinTxid
266
409
  };
267
410
 
268
- //# debugId=38B52C86BBC6201364756E2164756E21
411
+ //# debugId=4D1E6BA701859ED164756E2164756E21
269
412
  //# sourceMappingURL=index.js.map