stxer 0.7.0 → 0.9.0

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.
@@ -0,0 +1,121 @@
1
+ /**
2
+ * SHA-256. Pure-JS via `@noble/hashes` so this module works in
3
+ * browsers, Node, and Bun without a polyfill.
4
+ */
5
+ export declare function sha256(data: Uint8Array): Uint8Array;
6
+ /** Bitcoin-style double-sha256 used for txids, block hashes, and Merkle nodes. */
7
+ export declare function sha256d(data: Uint8Array): Uint8Array;
8
+ /** Decode a hex string (with or without `0x` prefix). */
9
+ export declare function hexToBytes(s: string): Uint8Array;
10
+ /** Lower-case hex (no `0x` prefix). */
11
+ export declare function bytesToHex(b: Uint8Array): string;
12
+ /** P2WPKH output script: `OP_0 <20-byte pubkey-hash>`. */
13
+ export declare function p2wpkhScript(pubKeyHash20: Uint8Array): Uint8Array;
14
+ /** P2PKH output script: `OP_DUP OP_HASH160 <hash> OP_EQUALVERIFY OP_CHECKSIG`. */
15
+ export declare function p2pkhScript(pubKeyHash20: Uint8Array): Uint8Array;
16
+ /**
17
+ * `OP_RETURN <data>` output. Used to embed peg-in metadata
18
+ * (recipient principal, marker bytes, etc.). Bitcoin's standard relay
19
+ * limit caps `data` at 80 bytes; this helper rejects > 75 to leave
20
+ * room for the prefix bytes.
21
+ */
22
+ export declare function opReturnScript(data: Uint8Array): Uint8Array;
23
+ export interface BitcoinTxInput {
24
+ /** 32-byte previous txid in *internal byte order* (raw `sha256d`). */
25
+ prevTxid: Uint8Array;
26
+ prevVout: number;
27
+ /** Script signature bytes. Empty for segwit-style inputs. */
28
+ scriptSig: Uint8Array;
29
+ /** Sequence number; default `0xfffffffd`. */
30
+ sequence?: number;
31
+ }
32
+ export interface BitcoinTxOutput {
33
+ /** Satoshi amount. */
34
+ value: bigint;
35
+ /** Locking script — use {@link p2wpkhScript} / {@link p2pkhScript} / {@link opReturnScript}. */
36
+ scriptPubKey: Uint8Array;
37
+ }
38
+ export interface ForgedBitcoinTx {
39
+ /** Wire-encoded non-witness tx bytes (this is what the txid is computed over). */
40
+ bytes: Uint8Array;
41
+ /** Canonical txid: `sha256d(bytes)`. Internal byte order. */
42
+ txid: Uint8Array;
43
+ /** Display-form (reversed) txid — what block explorers render. */
44
+ txidDisplay: Uint8Array;
45
+ }
46
+ /**
47
+ * Build a non-witness Bitcoin transaction (legacy serialization). The
48
+ * txid is `sha256d` of the returned `bytes`. Use this form when you
49
+ * only need to assert SPV inclusion; segwit witness data is irrelevant
50
+ * to the txid.
51
+ *
52
+ * Wire format:
53
+ * ```
54
+ * 4 version (LE)
55
+ * varint in-count
56
+ * per-input: 32 prev_txid + 4 prev_vout + varint script-len + script + 4 sequence
57
+ * varint out-count
58
+ * per-output: 8 value (LE) + varint script-len + script
59
+ * 4 locktime (LE)
60
+ * ```
61
+ */
62
+ export declare function forgeBitcoinTx(opts: {
63
+ version?: number;
64
+ inputs: BitcoinTxInput[];
65
+ outputs: BitcoinTxOutput[];
66
+ locktime?: number;
67
+ }): ForgedBitcoinTx;
68
+ export interface BitcoinHeader {
69
+ version: number;
70
+ prevHash: Uint8Array;
71
+ merkleRoot: Uint8Array;
72
+ timestamp: number;
73
+ bits: number;
74
+ nonce: number;
75
+ }
76
+ export interface BuiltBitcoinHeader {
77
+ /** Raw 80-byte serialized header. */
78
+ header: Uint8Array;
79
+ /**
80
+ * Display-form hash (`reverse(sha256d(header))`) — what the Stacks
81
+ * chainstate stores as `BurnchainHeaderHash`. Pass this as the
82
+ * `burn_header_hashes[i]` override on `addAdvanceBlocks`.
83
+ */
84
+ hash: Uint8Array;
85
+ /** Raw `sha256d(header)` (internal byte order). */
86
+ rawHash: Uint8Array;
87
+ }
88
+ /**
89
+ * Build an 80-byte Bitcoin block header. `prevHash` and `merkleRoot`
90
+ * are written in internal byte order (raw `sha256d` output) — matching
91
+ * the on-chain `clarity-bitcoin-v1-07` parser convention.
92
+ */
93
+ export declare function buildBitcoinHeader(h: Partial<BitcoinHeader> & {
94
+ merkleRoot: Uint8Array;
95
+ }): BuiltBitcoinHeader;
96
+ /**
97
+ * Single-tx Merkle root — the txid itself. Bitcoin's Merkle tree
98
+ * convention does NOT pre-hash the leaves; for a one-tx block the
99
+ * root equals the txid.
100
+ */
101
+ export declare function singleTxMerkleRoot(txid: Uint8Array): Uint8Array;
102
+ /**
103
+ * Compute a Bitcoin Merkle proof for `txid` at `index` in `txids`
104
+ * (transaction order within the block). Returns the sibling hashes
105
+ * from leaf to root.
106
+ *
107
+ * Bitcoin convention:
108
+ * - Leaves are the txids themselves (no pre-hashing).
109
+ * - Inner nodes are `sha256d(left || right)`.
110
+ * - Odd levels duplicate the last entry to pair.
111
+ */
112
+ export declare function merkleProof(txids: Uint8Array[], index: number): {
113
+ proof: Uint8Array[];
114
+ root: Uint8Array;
115
+ };
116
+ /**
117
+ * Verify a Bitcoin Merkle proof against `root`. Returns `true` iff the
118
+ * proof reconstructs the root from `txid` at `index`. Matches the
119
+ * on-chain `verify-merkle-proof` semantic.
120
+ */
121
+ export declare function verifyMerkleProof(txid: Uint8Array, index: number, proof: Uint8Array[], root: Uint8Array): boolean;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  export * from './ast';
2
2
  export * from './batch-api';
3
+ export * from './bitcoin';
3
4
  export * from './clarity-api';
4
5
  export * from './constants';
5
6
  export * from './simulation';
6
7
  export * from './simulation-api';
7
8
  export * from './tip';
9
+ export * from './transaction';
8
10
  export * from './types';
@@ -4,7 +4,30 @@
4
4
  * These functions provide direct access to the stxer V2 simulation endpoints
5
5
  * for programmatic use cases where you need more control than SimulationBuilder provides.
6
6
  */
7
- import type { InstantSimulationRequest, InstantSimulationResponse, SimulationBatchReadsRequest, SimulationBatchReadsResponse, SimulationResult, SubmitSimulationStepsRequest, SubmitSimulationStepsResponse } from './types';
7
+ import type { InstantSimulationRequest, InstantSimulationResponse, SimulationBatchReadsRequest, SimulationBatchReadsResponse, SimulationResult, SimulationTipResponse, SubmitSimulationStepsRequest, SubmitSimulationStepsResponse, U64 } from './types';
8
+ /**
9
+ * Server-side error markers. `simulation_busy` ↔ HTTP 409,
10
+ * `simulation_outdated` ↔ HTTP 410. Other errors keep `marker = null`.
11
+ */
12
+ export type SimulationErrorMarker = 'simulation_busy' | 'simulation_outdated' | null;
13
+ /**
14
+ * Thrown by the simulation-api fetch wrappers when the API responds
15
+ * with a non-2xx status. `status` carries the wire HTTP code so
16
+ * callers can branch on 409 (busy) / 410 (outdated) without parsing
17
+ * the message string. `marker` is the server-side classification
18
+ * extracted from the body prefix (`simulation_busy:` /
19
+ * `simulation_outdated:`).
20
+ *
21
+ * Pre-0.8.0 SDKs threw a plain `Error` whose message embedded the body
22
+ * text; that lossy form is still used for the message field here so
23
+ * existing log scrapers keep working.
24
+ */
25
+ export declare class SimulationError extends Error {
26
+ readonly status: number;
27
+ readonly marker: SimulationErrorMarker;
28
+ readonly body: string;
29
+ constructor(operation: string, status: number, body: string);
30
+ }
8
31
  /**
9
32
  * Options for API calls
10
33
  */
@@ -16,8 +39,11 @@ export interface SimulationApiOptions {
16
39
  * Create simulation session options
17
40
  */
18
41
  export interface CreateSessionOptions {
19
- /** Block height for simulation (optional, uses tip if not provided) */
20
- block_height?: number;
42
+ /**
43
+ * Block height for simulation (optional, uses tip if not provided).
44
+ * u64 — `number | string`; see {@link U64}.
45
+ */
46
+ block_height?: U64;
21
47
  /** Block hash corresponding to block_height */
22
48
  block_hash?: string;
23
49
  /** Skip debug tracing for faster simulations */
@@ -113,6 +139,29 @@ export declare function submitSimulationSteps(sessionId: string, request: Submit
113
139
  * ```
114
140
  */
115
141
  export declare function getSimulationResult(sessionId: string, options?: SimulationApiOptions): Promise<SimulationResult>;
142
+ /**
143
+ * Get the current tip of a simulation session.
144
+ *
145
+ * Returns the latest synthetic tip when at least one `AdvanceBlocks`
146
+ * step has run (`synthetic: true`, includes `vrf_seed` and
147
+ * `tenure_change`). Returns the parent metadata pinned at session
148
+ * start otherwise (`synthetic: false`, `vrf_seed` and `tenure_change`
149
+ * omitted).
150
+ *
151
+ * Backed by `GET /devtools/v2/simulations/{id}/tip`. Older simulator
152
+ * builds that predate this route respond 404.
153
+ *
154
+ * @example
155
+ * ```typescript
156
+ * import { getSimulationTip } from 'stxer';
157
+ *
158
+ * const tip = await getSimulationTip(sessionId);
159
+ * if (tip.synthetic) {
160
+ * console.log('synthetic tip vrf_seed:', tip.vrf_seed);
161
+ * }
162
+ * ```
163
+ */
164
+ export declare function getSimulationTip(sessionId: string, options?: SimulationApiOptions): Promise<SimulationTipResponse>;
116
165
  /**
117
166
  * Batch reads from a simulation session
118
167
  *
@@ -1,6 +1,8 @@
1
1
  import { type StacksNetworkName } from '@stacks/network';
2
- import { type ClarityValue, ClarityVersion } from '@stacks/transactions';
3
- import type { ReadStep } from './types';
2
+ import { type ClarityValue, ClarityVersion, PostConditionMode } from '@stacks/transactions';
3
+ import { type SimulationApiOptions } from './simulation-api';
4
+ import { type ContractCallTxArgs } from './transaction';
5
+ import type { AdvanceBlocksRequest, ReadStep, TenureExtendCause, TransactionReceipt } from './types';
4
6
  export interface SimulationEval {
5
7
  contract_id: string;
6
8
  code: string;
@@ -53,9 +55,74 @@ export declare class SimulationBuilder {
53
55
  clarity_version?: ClarityVersion;
54
56
  }): this;
55
57
  addReads(reads: ReadStep[]): this;
56
- addTenureExtend(): this;
58
+ /**
59
+ * Add a `TenureExtend` step. Defaults to `cause: 'Extended'` (full
60
+ * cost reset) — equivalent in server-side behavior to the legacy
61
+ * zero-arg call.
62
+ *
63
+ * Pass an explicit `TenureExtendCause` to reset only one SIP-034
64
+ * dimension (`ExtendedRuntime` / `ExtendedReadCount` / etc.).
65
+ *
66
+ * On the wire SDK 0.8.0 emits the modern `{ TenureExtend: { cause } }`
67
+ * shape. The server still parses the legacy `[]` shape for any
68
+ * caller emitting raw step objects.
69
+ */
70
+ addTenureExtend(cause?: TenureExtendCause): this;
71
+ /**
72
+ * Synthesize bitcoin and stacks blocks on top of the simulation's
73
+ * pinned parent tip. Used to model burn-block / tenure boundaries
74
+ * (bridge contracts, time-locked redemptions, locked-STX unlock).
75
+ *
76
+ * The simulator validates the request shape; older simulator builds
77
+ * that don't yet support `AdvanceBlocks` reject this variant with
78
+ * HTTP 400.
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * builder.addAdvanceBlocks({
83
+ * bitcoin_blocks: 1,
84
+ * stacks_blocks_per_bitcoin: 1,
85
+ * });
86
+ * ```
87
+ */
88
+ addAdvanceBlocks(request: AdvanceBlocksRequest): this;
57
89
  private getBlockInfo;
58
90
  run(): Promise<string>;
59
91
  pipe(transform: (builder: SimulationBuilder) => SimulationBuilder): SimulationBuilder;
60
92
  }
93
+ export interface CallContractResult {
94
+ /** Decoded Clarity result (e.g. `(ok true)`, `(err u100)`, `u5`). */
95
+ result: string;
96
+ /** Hex-encoded raw Clarity result (SIP-005). */
97
+ resultHex: string;
98
+ /** VM-level error message, if any (e.g. arithmetic overflow). */
99
+ vmError: string | null;
100
+ /** True when one or more post-conditions tripped. */
101
+ pcAborted: boolean;
102
+ /** Full upstream receipt for callers that need more detail. */
103
+ receipt: TransactionReceipt;
104
+ }
105
+ /**
106
+ * Build, submit, and decode a contract-call transaction. The caller
107
+ * supplies the principal to use as `tx-sender`; nonce is auto-fetched
108
+ * via {@link getNonce} unless `nonce` is explicitly provided.
109
+ */
110
+ export declare function callContract(sessionId: string, args: Omit<ContractCallTxArgs, 'nonce'> & {
111
+ nonce?: number;
112
+ postConditionMode?: PostConditionMode;
113
+ }, options?: SimulationApiOptions): Promise<CallContractResult>;
114
+ /**
115
+ * Read the SIP-010 / hBTC-style `(get-balance principal)` value.
116
+ * Returns 0n if the read returns `(err …)`. Throws on infra failures.
117
+ */
118
+ export declare function getFtBalance(sessionId: string, contractId: string, principal: string, options?: SimulationApiOptions): Promise<bigint>;
119
+ /** Read a principal's STX balance (uSTX) from a simulation session. */
120
+ export declare function getStxBalance(sessionId: string, principal: string, options?: SimulationApiOptions): Promise<bigint>;
121
+ /** Read a principal's current nonce. Returns 0n if never seen. */
122
+ export declare function getNonce(sessionId: string, principal: string, options?: SimulationApiOptions): Promise<bigint>;
123
+ /**
124
+ * Read a Clarity data variable. Returns the decoded `ClarityValue`,
125
+ * or throws if the read failed.
126
+ */
127
+ export declare function readDataVar(sessionId: string, contractId: string, varName: string, options?: SimulationApiOptions): Promise<ClarityValue>;
61
128
  export type { CreateSimulationRequest, ExecutionCost, InstantSimulationRequest, InstantSimulationResponse, ReadResult, ReadStep, SimulationMetadata, SimulationResult, SimulationStepInput, TransactionReceipt, } from './types';