@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.
- package/dist/shared/{stacks-esm-w8kswk0r.js → stacks-esm-2g7h9sbq.js} +3 -3
- package/dist/shared/{stacks-esm-ss9ap75h.js → stacks-esm-47b3bb9e.js} +2 -2
- package/dist/shared/stacks-esm-51sysw9g.js +7 -0
- package/dist/shared/stacks-esm-51sysw9g.js.map +10 -0
- package/dist/shared/{stacks-esm-w36fvdxx.js → stacks-esm-5w6zn26c.js} +2 -2
- package/dist/shared/{stacks-esm-hcjqgrtm.js → stacks-esm-60wsk8b7.js} +3 -3
- package/dist/shared/{stacks-esm-zwbhghxb.js → stacks-esm-90bwm9ng.js} +3 -4
- package/dist/shared/{stacks-esm-zwbhghxb.js.map → stacks-esm-90bwm9ng.js.map} +3 -3
- package/dist/shared/{stacks-esm-z0rq3ejt.js → stacks-esm-fb1gh99a.js} +4 -7
- package/dist/shared/{stacks-esm-z0rq3ejt.js.map → stacks-esm-fb1gh99a.js.map} +4 -5
- package/dist/shared/{stacks-esm-hv11fdgy.js → stacks-esm-kd5gn8v3.js} +2 -2
- package/dist/shared/{stacks-esm-e2qhfgke.js → stacks-esm-ph2fd7hg.js} +8 -4
- package/dist/shared/{stacks-esm-e2qhfgke.js.map → stacks-esm-ph2fd7hg.js.map} +3 -3
- package/dist/shared/{stacks-esm-bragecm9.js → stacks-esm-s6tybkrn.js} +4 -4
- package/dist/shared/stacks-esm-zvpv6a06.js +28 -0
- package/dist/shared/stacks-esm-zvpv6a06.js.map +10 -0
- package/dist/src/accounts/index.cjs +7 -3
- package/dist/src/accounts/index.cjs.map +3 -3
- package/dist/src/accounts/index.js +1 -1
- package/dist/src/actions/index.cjs +2 -3
- package/dist/src/actions/index.cjs.map +3 -3
- package/dist/src/actions/index.js +5 -5
- package/dist/src/bitcoin/index.cjs +7 -3
- package/dist/src/bitcoin/index.cjs.map +3 -3
- package/dist/src/bitcoin/index.d.cts +6 -5
- package/dist/src/bitcoin/index.d.ts +6 -5
- package/dist/src/bitcoin/index.js +12 -23
- package/dist/src/bitcoin/index.js.map +3 -4
- package/dist/src/bns/index.cjs +2 -3
- package/dist/src/bns/index.cjs.map +3 -3
- package/dist/src/bns/index.js +5 -5
- package/dist/src/index.cjs +2 -3
- package/dist/src/index.cjs.map +3 -3
- package/dist/src/index.js +4 -4
- package/dist/src/postconditions/index.cjs +2 -3
- package/dist/src/postconditions/index.cjs.map +3 -3
- package/dist/src/postconditions/index.js +2 -2
- package/dist/src/pox/index.cjs +8 -5
- package/dist/src/pox/index.cjs.map +4 -4
- package/dist/src/pox/index.js +7 -7
- package/dist/src/pox5/index.cjs +8 -5
- package/dist/src/pox5/index.cjs.map +4 -4
- package/dist/src/pox5/index.js +11 -9
- package/dist/src/pox5/index.js.map +2 -2
- package/dist/src/sbtc/index.cjs +174 -17
- package/dist/src/sbtc/index.cjs.map +11 -8
- package/dist/src/sbtc/index.d.cts +117 -5
- package/dist/src/sbtc/index.d.ts +117 -5
- package/dist/src/sbtc/index.js +156 -13
- package/dist/src/sbtc/index.js.map +7 -6
- package/dist/src/simnet/index.cjs +2 -3
- package/dist/src/simnet/index.cjs.map +3 -3
- package/dist/src/simnet/index.js +2 -3
- package/dist/src/simnet/index.js.map +3 -3
- package/dist/src/stackingdao/index.cjs +2 -3
- package/dist/src/stackingdao/index.cjs.map +3 -3
- package/dist/src/stackingdao/index.js +5 -5
- package/dist/src/transactions/index.cjs +2 -3
- package/dist/src/transactions/index.cjs.map +3 -3
- package/dist/src/transactions/index.js +2 -2
- package/package.json +1 -1
- /package/dist/shared/{stacks-esm-w8kswk0r.js.map → stacks-esm-2g7h9sbq.js.map} +0 -0
- /package/dist/shared/{stacks-esm-ss9ap75h.js.map → stacks-esm-47b3bb9e.js.map} +0 -0
- /package/dist/shared/{stacks-esm-w36fvdxx.js.map → stacks-esm-5w6zn26c.js.map} +0 -0
- /package/dist/shared/{stacks-esm-hcjqgrtm.js.map → stacks-esm-60wsk8b7.js.map} +0 -0
- /package/dist/shared/{stacks-esm-hv11fdgy.js.map → stacks-esm-kd5gn8v3.js.map} +0 -0
- /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
|
|
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
|
-
/**
|
|
432
|
-
|
|
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 };
|
package/dist/src/sbtc/index.d.ts
CHANGED
|
@@ -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
|
|
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
|
-
/**
|
|
432
|
-
|
|
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 };
|
package/dist/src/sbtc/index.js
CHANGED
|
@@ -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-
|
|
9
|
-
import"../../shared/stacks-esm-
|
|
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-
|
|
15
|
+
} from "../../shared/stacks-esm-ph2fd7hg.js";
|
|
13
16
|
import {
|
|
14
17
|
stringifyBtcAddress2
|
|
15
|
-
} from "../../shared/stacks-esm-
|
|
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-
|
|
20
|
-
import"../../shared/stacks-esm-
|
|
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
|
|
186
|
-
|
|
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=
|
|
411
|
+
//# debugId=4D1E6BA701859ED164756E2164756E21
|
|
269
412
|
//# sourceMappingURL=index.js.map
|