@secondlayer/stacks 4.3.1 → 5.0.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.
- package/README.md +27 -11
- package/dist/shared/{stacks-gxq2pbky.js → stacks-2as26bcg.js} +10 -7
- package/dist/shared/stacks-2as26bcg.js.map +13 -0
- package/dist/shared/{stacks-bfan7ex7.js → stacks-4d7c3x27.js} +5 -5
- package/dist/shared/{stacks-bfan7ex7.js.map → stacks-4d7c3x27.js.map} +3 -3
- package/dist/shared/{stacks-709tra19.js → stacks-4hs8r4q2.js} +16 -2
- package/dist/shared/stacks-4hs8r4q2.js.map +10 -0
- package/dist/shared/{stacks-w23294am.js → stacks-51ybf135.js} +3 -3
- package/dist/shared/{stacks-0jk7vd8r.cjs → stacks-69nq48jp.js} +120 -17
- package/dist/shared/stacks-69nq48jp.js.map +15 -0
- package/dist/shared/{stacks-8pfdscq6.js → stacks-6gavarmy.js} +37 -9
- package/dist/shared/stacks-6gavarmy.js.map +12 -0
- package/dist/shared/{stacks-7wkf2rph.js → stacks-7bqkf3b0.js} +86 -71
- package/dist/shared/{stacks-7wkf2rph.js.map → stacks-7bqkf3b0.js.map} +9 -10
- package/dist/shared/{stacks-zcpvzbr0.js → stacks-8brgfvqx.js} +3 -3
- package/dist/shared/{stacks-4vzmhw3q.cjs → stacks-8vzxax5e.cjs} +13 -3
- package/dist/shared/stacks-8vzxax5e.cjs.map +10 -0
- package/dist/shared/{stacks-hnqt5rz4.js → stacks-9c1yam8b.js} +3 -3
- package/dist/shared/{stacks-bnbdqznq.cjs → stacks-bdgh9n83.cjs} +11 -10
- package/dist/shared/{stacks-bnbdqznq.cjs.map → stacks-bdgh9n83.cjs.map} +3 -3
- package/dist/shared/{stacks-fb75yew8.js → stacks-db3kwavg.cjs} +346 -138
- package/dist/shared/stacks-db3kwavg.cjs.map +23 -0
- package/dist/shared/{stacks-jpt52csy.js → stacks-e3nwm1dz.js} +14 -17
- package/dist/shared/stacks-e3nwm1dz.js.map +10 -0
- package/dist/shared/{stacks-27fmgajb.js → stacks-ga026yxz.js} +9 -9
- package/dist/shared/{stacks-27fmgajb.js.map → stacks-ga026yxz.js.map} +3 -3
- package/dist/shared/{stacks-nyaw1z2a.cjs → stacks-ggdz96r1.cjs} +4 -4
- package/dist/shared/{stacks-nyaw1z2a.cjs.map → stacks-ggdz96r1.cjs.map} +3 -3
- package/dist/shared/{stacks-08y0y0t7.js → stacks-gjz26k6b.js} +2 -2
- package/dist/shared/{stacks-x5386y2y.cjs → stacks-gza2n1zs.cjs} +5 -5
- package/dist/shared/{stacks-x5386y2y.cjs.map → stacks-gza2n1zs.cjs.map} +3 -3
- package/dist/shared/{stacks-ta1gar0b.cjs → stacks-kqn4y8kq.cjs} +7 -5
- package/dist/shared/{stacks-ta1gar0b.cjs.map → stacks-kqn4y8kq.cjs.map} +3 -3
- package/dist/shared/{stacks-ztzygy90.js → stacks-mftyrc60.js} +2 -2
- package/dist/shared/stacks-n4d8j8q3.js +801 -0
- package/dist/shared/stacks-n4d8j8q3.js.map +23 -0
- package/dist/shared/{stacks-ycbq8pf7.cjs → stacks-p337hp6m.cjs} +74 -59
- package/dist/shared/{stacks-ycbq8pf7.cjs.map → stacks-p337hp6m.cjs.map} +9 -10
- package/dist/shared/{stacks-ttdk2g2f.js → stacks-s5vej5z6.cjs} +92 -41
- package/dist/shared/stacks-s5vej5z6.cjs.map +15 -0
- package/dist/shared/stacks-sdqkapct.cjs +67 -0
- package/dist/shared/stacks-sdqkapct.cjs.map +12 -0
- package/dist/shared/{stacks-1arrcd11.js → stacks-v2rfr46a.js} +2 -2
- package/dist/shared/{stacks-9mqveyjv.cjs → stacks-w9t61fra.cjs} +7 -10
- package/dist/shared/stacks-w9t61fra.cjs.map +10 -0
- package/dist/shared/{stacks-tjjnkt3r.js → stacks-wxfd6r4b.js} +2 -2
- package/dist/shared/{stacks-4z72akdf.js → stacks-x0qqwrev.js} +3 -3
- package/dist/shared/{stacks-gck1sq7h.cjs → stacks-xjkn3en1.cjs} +16 -2
- package/dist/shared/stacks-xjkn3en1.cjs.map +10 -0
- package/dist/shared/stacks-xnrywjf1.cjs +131 -0
- package/dist/shared/stacks-xnrywjf1.cjs.map +11 -0
- package/dist/shared/stacks-yajyej2y.js +139 -0
- package/dist/shared/stacks-yajyej2y.js.map +11 -0
- package/dist/shared/{stacks-913a2rx7.js → stacks-yvb7rvwk.js} +13 -3
- package/dist/shared/stacks-yvb7rvwk.js.map +10 -0
- package/dist/shared/{stacks-0cdm20eh.js → stacks-z90xdr1x.js} +7 -11
- package/dist/shared/{stacks-0cdm20eh.js.map → stacks-z90xdr1x.js.map} +3 -3
- package/dist/src/accounts/index.js +2 -3
- package/dist/src/accounts/index.js.map +2 -2
- package/dist/src/actions/index.cjs +2 -1
- package/dist/src/actions/index.cjs.map +1 -1
- package/dist/src/actions/index.d.cts +108 -20
- package/dist/src/actions/index.d.ts +108 -20
- package/dist/src/actions/index.js +17 -15
- package/dist/src/actions/index.js.map +1 -1
- package/dist/src/bitcoin/index.d.cts +27 -0
- package/dist/src/bitcoin/index.d.ts +27 -0
- package/dist/src/bitcoin/index.js +10 -11
- package/dist/src/bitcoin/index.js.map +2 -2
- package/dist/src/bns/index.d.cts +27 -0
- package/dist/src/bns/index.d.ts +27 -0
- package/dist/src/bns/index.js +13 -13
- package/dist/src/bns/index.js.map +1 -1
- package/dist/src/clarity/index.js +7 -6
- package/dist/src/clarity/index.js.map +1 -1
- package/dist/src/connect/index.cjs +44 -30
- package/dist/src/connect/index.cjs.map +7 -7
- package/dist/src/connect/index.d.cts +16 -1
- package/dist/src/connect/index.d.ts +16 -1
- package/dist/src/connect/index.js +44 -30
- package/dist/src/connect/index.js.map +7 -7
- package/dist/src/connect/walletconnect/index.cjs +49 -413
- package/dist/src/connect/walletconnect/index.cjs.map +4 -4
- package/dist/src/connect/walletconnect/index.js +47 -411
- package/dist/src/connect/walletconnect/index.js.map +4 -4
- package/dist/src/filters/index.js +2 -2
- package/dist/src/index.cjs +49 -124
- package/dist/src/index.cjs.map +6 -8
- package/dist/src/index.d.cts +163 -54
- package/dist/src/index.d.ts +163 -54
- package/dist/src/index.js +79 -147
- package/dist/src/index.js.map +6 -8
- package/dist/src/postconditions/index.js +6 -5
- package/dist/src/postconditions/index.js.map +1 -1
- package/dist/src/pox/index.cjs +7 -83
- package/dist/src/pox/index.cjs.map +3 -3
- package/dist/src/pox/index.d.cts +32 -1
- package/dist/src/pox/index.d.ts +32 -1
- package/dist/src/pox/index.js +22 -102
- package/dist/src/pox/index.js.map +3 -3
- package/dist/src/pox5/index.cjs +4 -129
- package/dist/src/pox5/index.cjs.map +3 -4
- package/dist/src/pox5/index.d.cts +27 -0
- package/dist/src/pox5/index.d.ts +27 -0
- package/dist/src/pox5/index.js +20 -148
- package/dist/src/pox5/index.js.map +3 -4
- package/dist/src/sbtc/index.cjs +2 -59
- package/dist/src/sbtc/index.cjs.map +3 -3
- package/dist/src/sbtc/index.d.cts +30 -2
- package/dist/src/sbtc/index.d.ts +30 -2
- package/dist/src/sbtc/index.js +15 -74
- package/dist/src/sbtc/index.js.map +3 -3
- package/dist/src/stackingdao/index.d.cts +27 -0
- package/dist/src/stackingdao/index.d.ts +27 -0
- package/dist/src/stackingdao/index.js +11 -11
- package/dist/src/stackingdao/index.js.map +1 -1
- package/dist/src/subscriptions/index.d.cts +27 -0
- package/dist/src/subscriptions/index.d.ts +27 -0
- package/dist/src/subscriptions/index.js +2 -2
- package/dist/src/tools/btc/index.cjs.map +2 -2
- package/dist/src/tools/btc/index.js.map +2 -2
- package/dist/src/tools/index.cjs +629 -392
- package/dist/src/tools/index.cjs.map +30 -28
- package/dist/src/tools/index.d.cts +44 -0
- package/dist/src/tools/index.d.ts +44 -0
- package/dist/src/tools/index.js +628 -391
- package/dist/src/tools/index.js.map +30 -28
- package/dist/src/transactions/index.js +6 -5
- package/dist/src/transactions/index.js.map +1 -1
- package/dist/src/utils/index.d.cts +2 -5
- package/dist/src/utils/index.d.ts +2 -5
- package/dist/src/utils/index.js +2 -2
- package/package.json +18 -7
- package/dist/shared/stacks-0eatsx6d.cjs +0 -25
- package/dist/shared/stacks-0eatsx6d.cjs.map +0 -10
- package/dist/shared/stacks-0jk7vd8r.cjs.map +0 -14
- package/dist/shared/stacks-4vzmhw3q.cjs.map +0 -10
- package/dist/shared/stacks-5nmz5ad9.js +0 -409
- package/dist/shared/stacks-5nmz5ad9.js.map +0 -10
- package/dist/shared/stacks-709tra19.js.map +0 -10
- package/dist/shared/stacks-8pfdscq6.js.map +0 -12
- package/dist/shared/stacks-913a2rx7.js.map +0 -10
- package/dist/shared/stacks-9mqveyjv.cjs.map +0 -10
- package/dist/shared/stacks-e4xn4m7j.js +0 -27
- package/dist/shared/stacks-e4xn4m7j.js.map +0 -10
- package/dist/shared/stacks-fb75yew8.js.map +0 -21
- package/dist/shared/stacks-gck1sq7h.cjs.map +0 -10
- package/dist/shared/stacks-gxq2pbky.js.map +0 -13
- package/dist/shared/stacks-jpt52csy.js.map +0 -10
- package/dist/shared/stacks-mnnhpex3.cjs +0 -407
- package/dist/shared/stacks-mnnhpex3.cjs.map +0 -10
- package/dist/shared/stacks-tdsp5gsb.cjs +0 -527
- package/dist/shared/stacks-tdsp5gsb.cjs.map +0 -21
- package/dist/shared/stacks-ttdk2g2f.js.map +0 -14
- package/dist/shared/stacks-wdp5yr8n.cjs +0 -39
- package/dist/shared/stacks-wdp5yr8n.cjs.map +0 -12
- /package/dist/shared/{stacks-w23294am.js.map → stacks-51ybf135.js.map} +0 -0
- /package/dist/shared/{stacks-zcpvzbr0.js.map → stacks-8brgfvqx.js.map} +0 -0
- /package/dist/shared/{stacks-hnqt5rz4.js.map → stacks-9c1yam8b.js.map} +0 -0
- /package/dist/shared/{stacks-08y0y0t7.js.map → stacks-gjz26k6b.js.map} +0 -0
- /package/dist/shared/{stacks-ztzygy90.js.map → stacks-mftyrc60.js.map} +0 -0
- /package/dist/shared/{stacks-1arrcd11.js.map → stacks-v2rfr46a.js.map} +0 -0
- /package/dist/shared/{stacks-tjjnkt3r.js.map → stacks-wxfd6r4b.js.map} +0 -0
- /package/dist/shared/{stacks-4z72akdf.js.map → stacks-x0qqwrev.js.map} +0 -0
|
@@ -1,527 +0,0 @@
|
|
|
1
|
-
// src/actions/public/estimateFee.ts
|
|
2
|
-
function isValidEstimation(e) {
|
|
3
|
-
return typeof e === "object" && e !== null && "fee_rate" in e && "fee" in e && (typeof e.fee_rate === "number" || typeof e.fee_rate === "string") && (typeof e.fee === "number" || typeof e.fee === "string");
|
|
4
|
-
}
|
|
5
|
-
async function estimateFee(client, params) {
|
|
6
|
-
const payloadHex = bytesToHex(serializePayload(params.transaction.payload));
|
|
7
|
-
const txHex = bytesToHex(serializeTransaction(params.transaction));
|
|
8
|
-
const data = await client.request("/v2/fees/transaction", {
|
|
9
|
-
method: "POST",
|
|
10
|
-
body: {
|
|
11
|
-
estimated_len: Math.ceil(txHex.length / 2),
|
|
12
|
-
transaction_payload: `0x${payloadHex}`
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
const raw = data?.estimations ?? [];
|
|
16
|
-
return raw.map((e) => {
|
|
17
|
-
if (!isValidEstimation(e)) {
|
|
18
|
-
throw new MalformedResponseError("estimateFee: node response contains invalid fee estimation entry");
|
|
19
|
-
}
|
|
20
|
-
return {
|
|
21
|
-
feeRate: Number(e.fee_rate),
|
|
22
|
-
fee: Number(e.fee)
|
|
23
|
-
};
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// src/actions/public/getBlockHeight.ts
|
|
28
|
-
async function getBlockHeight(client) {
|
|
29
|
-
const data = await client.request("/v2/info", { method: "GET" });
|
|
30
|
-
if (typeof data?.stacks_tip_height !== "number") {
|
|
31
|
-
throw new MalformedResponseError('getBlockHeight: /v2/info response is missing "stacks_tip_height"');
|
|
32
|
-
}
|
|
33
|
-
return data.stacks_tip_height;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// src/errors/http.ts
|
|
37
|
-
class HttpRequestError extends BaseError {
|
|
38
|
-
name = "HttpRequestError";
|
|
39
|
-
status;
|
|
40
|
-
constructor(status, options) {
|
|
41
|
-
super(`HTTP request failed with status ${status}`, options);
|
|
42
|
-
this.status = status;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// src/actions/public/getMapEntry.ts
|
|
47
|
-
async function getMapEntry(client, params) {
|
|
48
|
-
const [address, name] = parseContractId(params.contract);
|
|
49
|
-
const serializedKey = with0x(bytesToHex(serializeCVBytes(params.key)));
|
|
50
|
-
const data = await client.request(`/v2/map_entry/${address}/${name}/${params.mapName}`, {
|
|
51
|
-
method: "POST",
|
|
52
|
-
body: serializedKey
|
|
53
|
-
});
|
|
54
|
-
if (typeof data?.data !== "string") {
|
|
55
|
-
throw new MalformedResponseError(`getMapEntry: /v2/map_entry/${address}/${name}/${params.mapName} response is missing "data"`);
|
|
56
|
-
}
|
|
57
|
-
return deserializeCVBytes(data.data);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// src/actions/public/getNonce.ts
|
|
61
|
-
async function getNonce(client, params) {
|
|
62
|
-
const data = await client.request(`/v2/accounts/${params.address}`, {
|
|
63
|
-
method: "GET"
|
|
64
|
-
});
|
|
65
|
-
const nonce = data?.nonce;
|
|
66
|
-
if (typeof nonce !== "number" && typeof nonce !== "string") {
|
|
67
|
-
throw new Error(`getNonce: unexpected /v2/accounts response for ${params.address} (missing numeric nonce)`);
|
|
68
|
-
}
|
|
69
|
-
return BigInt(nonce);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// src/actions/public/txSources.ts
|
|
73
|
-
function resolveFetch(fetchImpl) {
|
|
74
|
-
const f = fetchImpl ?? globalThis.fetch;
|
|
75
|
-
if (!f)
|
|
76
|
-
throw new Error("No fetch implementation available; pass `fetchImpl`");
|
|
77
|
-
return f;
|
|
78
|
-
}
|
|
79
|
-
function normalizeTxid(txid) {
|
|
80
|
-
return txid.startsWith("0x") ? txid : `0x${txid}`;
|
|
81
|
-
}
|
|
82
|
-
function decodeResultHex(hex) {
|
|
83
|
-
if (!hex)
|
|
84
|
-
return {};
|
|
85
|
-
try {
|
|
86
|
-
return { result: deserializeCVBytes(hex), resultHex: hex };
|
|
87
|
-
} catch {
|
|
88
|
-
return { resultHex: hex };
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
function normalizeStatus(txStatus) {
|
|
92
|
-
switch (txStatus) {
|
|
93
|
-
case "pending":
|
|
94
|
-
case "success":
|
|
95
|
-
case "abort_by_response":
|
|
96
|
-
case "abort_by_post_condition":
|
|
97
|
-
return txStatus;
|
|
98
|
-
default:
|
|
99
|
-
return txStatus.startsWith("dropped") ? "dropped" : undefined;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
function extendedApiSource() {
|
|
103
|
-
return {
|
|
104
|
-
async get({ client, txid }) {
|
|
105
|
-
let data;
|
|
106
|
-
try {
|
|
107
|
-
data = await client.request(`/extended/v1/tx/${normalizeTxid(txid)}`, {
|
|
108
|
-
method: "GET"
|
|
109
|
-
});
|
|
110
|
-
} catch (error) {
|
|
111
|
-
if (error instanceof HttpRequestError && error.status === 404) {
|
|
112
|
-
return { receipt: null };
|
|
113
|
-
}
|
|
114
|
-
throw error;
|
|
115
|
-
}
|
|
116
|
-
const txStatus = typeof data?.tx_status === "string" ? data.tx_status : undefined;
|
|
117
|
-
if (!txStatus)
|
|
118
|
-
return { receipt: null };
|
|
119
|
-
const status = normalizeStatus(txStatus);
|
|
120
|
-
if (!status)
|
|
121
|
-
return { receipt: null };
|
|
122
|
-
return {
|
|
123
|
-
receipt: {
|
|
124
|
-
txid: normalizeTxid(txid),
|
|
125
|
-
status,
|
|
126
|
-
blockHeight: typeof data.block_height === "number" && data.block_height > 0 ? data.block_height : undefined,
|
|
127
|
-
blockHash: data.block_hash ?? undefined,
|
|
128
|
-
...decodeResultHex(data.tx_result?.hex),
|
|
129
|
-
events: Array.isArray(data.events) ? data.events : [],
|
|
130
|
-
raw: data
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
function indexTxSource(params = {}) {
|
|
137
|
-
const baseUrl = (params.baseUrl ?? "https://api.secondlayer.tools").replace(/\/$/, "");
|
|
138
|
-
const fetchImpl = resolveFetch(params.fetchImpl);
|
|
139
|
-
return {
|
|
140
|
-
async get({ txid }) {
|
|
141
|
-
const res = await fetchImpl(`${baseUrl}/v1/index/transactions/${normalizeTxid(txid)}`, {
|
|
142
|
-
headers: params.apiKey ? { "x-api-key": params.apiKey } : undefined
|
|
143
|
-
});
|
|
144
|
-
if (res.status === 404) {
|
|
145
|
-
return { receipt: null };
|
|
146
|
-
}
|
|
147
|
-
if (!res.ok) {
|
|
148
|
-
throw new Error(`indexTxSource: /v1/index/transactions ${res.status}`);
|
|
149
|
-
}
|
|
150
|
-
const data = await res.json();
|
|
151
|
-
const tx = data.transaction;
|
|
152
|
-
const tip = data.tip?.block_height;
|
|
153
|
-
if (!tx)
|
|
154
|
-
return { receipt: null, tip };
|
|
155
|
-
const status = normalizeStatus(tx.status) ?? "success";
|
|
156
|
-
return {
|
|
157
|
-
receipt: {
|
|
158
|
-
txid: normalizeTxid(tx.tx_id),
|
|
159
|
-
status,
|
|
160
|
-
blockHeight: tx.block_height,
|
|
161
|
-
...decodeResultHex(tx.contract_call?.result_hex),
|
|
162
|
-
events: [],
|
|
163
|
-
raw: data
|
|
164
|
-
},
|
|
165
|
-
tip
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// src/errors/transaction.ts
|
|
172
|
-
class TransactionError extends BaseError {
|
|
173
|
-
name = "TransactionError";
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
class BroadcastError extends BaseError {
|
|
177
|
-
name = "BroadcastError";
|
|
178
|
-
txid;
|
|
179
|
-
reason;
|
|
180
|
-
reasonData;
|
|
181
|
-
constructor(message, options) {
|
|
182
|
-
super(message, options);
|
|
183
|
-
this.txid = options?.txid;
|
|
184
|
-
this.reason = options?.reason;
|
|
185
|
-
this.reasonData = options?.reasonData;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
class TransactionAbortedError extends BaseError {
|
|
190
|
-
name = "TransactionAbortedError";
|
|
191
|
-
receipt;
|
|
192
|
-
constructor(message, options) {
|
|
193
|
-
super(message, options);
|
|
194
|
-
this.receipt = options.receipt;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
class TransactionDroppedError extends BaseError {
|
|
199
|
-
name = "TransactionDroppedError";
|
|
200
|
-
txid;
|
|
201
|
-
constructor(message, options) {
|
|
202
|
-
super(message, options);
|
|
203
|
-
this.txid = options.txid;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
class WaitForTransactionTimeoutError extends BaseError {
|
|
208
|
-
name = "WaitForTransactionTimeoutError";
|
|
209
|
-
txid;
|
|
210
|
-
constructor(message, options) {
|
|
211
|
-
super(message, options);
|
|
212
|
-
this.txid = options.txid;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
class SerializationError extends BaseError {
|
|
217
|
-
name = "SerializationError";
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
class SigningError extends BaseError {
|
|
221
|
-
name = "SigningError";
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// src/actions/public/waitForTransactionReceipt.ts
|
|
225
|
-
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
226
|
-
async function waitForTransactionReceipt(client, params) {
|
|
227
|
-
const {
|
|
228
|
-
txid,
|
|
229
|
-
confirmations = 1,
|
|
230
|
-
timeout = 180000,
|
|
231
|
-
pollingInterval = 3000,
|
|
232
|
-
droppedGracePeriod = 30000
|
|
233
|
-
} = params;
|
|
234
|
-
const source = params.source ?? extendedApiSource();
|
|
235
|
-
const startedAt = Date.now();
|
|
236
|
-
let unknownSince = null;
|
|
237
|
-
let everPending = false;
|
|
238
|
-
while (true) {
|
|
239
|
-
const snapshot = await source.get({ client, txid });
|
|
240
|
-
const receipt = snapshot.receipt;
|
|
241
|
-
if (receipt === null) {
|
|
242
|
-
unknownSince ??= Date.now();
|
|
243
|
-
if (Date.now() - unknownSince >= droppedGracePeriod) {
|
|
244
|
-
throw new TransactionDroppedError(everPending ? `Transaction ${txid} left the mempool without being mined` : `Transaction ${txid} was never observed by the status source`, { txid });
|
|
245
|
-
}
|
|
246
|
-
} else {
|
|
247
|
-
unknownSince = null;
|
|
248
|
-
switch (receipt.status) {
|
|
249
|
-
case "dropped":
|
|
250
|
-
throw new TransactionDroppedError(`Transaction ${txid} was dropped from the mempool`, { txid });
|
|
251
|
-
case "abort_by_response":
|
|
252
|
-
case "abort_by_post_condition":
|
|
253
|
-
throw new TransactionAbortedError(`Transaction ${txid} aborted (${receipt.status})`, { receipt });
|
|
254
|
-
case "pending":
|
|
255
|
-
everPending = true;
|
|
256
|
-
break;
|
|
257
|
-
case "success": {
|
|
258
|
-
if (confirmations <= 1)
|
|
259
|
-
return receipt;
|
|
260
|
-
if (receipt.blockHeight !== undefined) {
|
|
261
|
-
const tip = snapshot.tip ?? await getBlockHeight(client);
|
|
262
|
-
if (tip - receipt.blockHeight + 1 >= confirmations)
|
|
263
|
-
return receipt;
|
|
264
|
-
}
|
|
265
|
-
break;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
if (Date.now() - startedAt >= timeout) {
|
|
270
|
-
throw new WaitForTransactionTimeoutError(`Timed out after ${timeout}ms waiting for transaction ${txid}`, { txid });
|
|
271
|
-
}
|
|
272
|
-
await sleep(pollingInterval);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// src/actions/wallet/sendTransaction.ts
|
|
277
|
-
async function sendTransaction(client, params) {
|
|
278
|
-
const hex = bytesToHex(serializeTransaction(params.transaction));
|
|
279
|
-
const body = { tx: hex };
|
|
280
|
-
if (params.attachment) {
|
|
281
|
-
body.attachment = typeof params.attachment === "string" ? params.attachment : bytesToHex(params.attachment);
|
|
282
|
-
}
|
|
283
|
-
let data;
|
|
284
|
-
try {
|
|
285
|
-
data = await client.request("/v2/transactions", { method: "POST", body });
|
|
286
|
-
} catch (error) {
|
|
287
|
-
if (error instanceof HttpRequestError && error.details) {
|
|
288
|
-
try {
|
|
289
|
-
data = JSON.parse(error.details);
|
|
290
|
-
} catch {
|
|
291
|
-
throw error;
|
|
292
|
-
}
|
|
293
|
-
} else {
|
|
294
|
-
throw error;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
if (data.error) {
|
|
298
|
-
throw new BroadcastError(data.reason ?? data.error, {
|
|
299
|
-
reason: data.reason,
|
|
300
|
-
reasonData: data.reason_data,
|
|
301
|
-
txid: data.txid ?? getTransactionId(params.transaction)
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
const txid = typeof data === "string" ? data.replace(/"/g, "") : data.txid ?? getTransactionId(params.transaction);
|
|
305
|
-
if (params.wait) {
|
|
306
|
-
const confirmations = params.wait === true ? 1 : params.wait;
|
|
307
|
-
const receipt = await waitForTransactionReceipt(client, {
|
|
308
|
-
txid,
|
|
309
|
-
confirmations
|
|
310
|
-
});
|
|
311
|
-
return { txid, receipt };
|
|
312
|
-
}
|
|
313
|
-
return { txid };
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
// src/actions/wallet/nonceManager.ts
|
|
317
|
-
function jsonRpcSource() {
|
|
318
|
-
return {
|
|
319
|
-
get: ({ client, address }) => getNonce(client, { address })
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
function memoryStore() {
|
|
323
|
-
const next = new Map;
|
|
324
|
-
const locks = new Map;
|
|
325
|
-
function withLock(key, fn) {
|
|
326
|
-
const prev = locks.get(key) ?? Promise.resolve();
|
|
327
|
-
const run = prev.then(fn, fn);
|
|
328
|
-
locks.set(key, run.catch(() => {}));
|
|
329
|
-
return run;
|
|
330
|
-
}
|
|
331
|
-
return {
|
|
332
|
-
reserve(key, getFloor) {
|
|
333
|
-
return withLock(key, async () => {
|
|
334
|
-
let current = next.get(key);
|
|
335
|
-
if (current === undefined)
|
|
336
|
-
current = await getFloor();
|
|
337
|
-
next.set(key, current + 1n);
|
|
338
|
-
return current;
|
|
339
|
-
});
|
|
340
|
-
},
|
|
341
|
-
reset(key) {
|
|
342
|
-
next.delete(key);
|
|
343
|
-
},
|
|
344
|
-
peek(key) {
|
|
345
|
-
return next.get(key);
|
|
346
|
-
}
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
function nonceKey(client, address) {
|
|
350
|
-
return `${client.chain?.id ?? "stacks"}:${address}`;
|
|
351
|
-
}
|
|
352
|
-
function createNonceManager(params = {}) {
|
|
353
|
-
const source = params.source ?? jsonRpcSource();
|
|
354
|
-
const store = params.store ?? memoryStore();
|
|
355
|
-
return {
|
|
356
|
-
consume({ client, address }) {
|
|
357
|
-
return store.reserve(nonceKey(client, address), () => source.get({ client, address }));
|
|
358
|
-
},
|
|
359
|
-
reset({ client, address }) {
|
|
360
|
-
return store.reset(nonceKey(client, address));
|
|
361
|
-
},
|
|
362
|
-
async peek({ client, address }) {
|
|
363
|
-
return store.peek?.(nonceKey(client, address));
|
|
364
|
-
}
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
async function resolveNonce(client, address) {
|
|
368
|
-
if (client.nonceManager)
|
|
369
|
-
return client.nonceManager.consume({ client, address });
|
|
370
|
-
return getNonce(client, { address });
|
|
371
|
-
}
|
|
372
|
-
async function reconcileNonce(manager, params) {
|
|
373
|
-
const { client, address, source } = params;
|
|
374
|
-
const downward = params.downward ?? true;
|
|
375
|
-
const authoritative = await source.get({ client, address });
|
|
376
|
-
const tracked = await manager.peek({ client, address });
|
|
377
|
-
if (tracked === undefined || authoritative === tracked) {
|
|
378
|
-
return { reset: false, authoritative, tracked };
|
|
379
|
-
}
|
|
380
|
-
if (authoritative < tracked && !downward) {
|
|
381
|
-
return { reset: false, authoritative, tracked };
|
|
382
|
-
}
|
|
383
|
-
await manager.reset({ client, address });
|
|
384
|
-
return { reset: true, authoritative, tracked };
|
|
385
|
-
}
|
|
386
|
-
function startNonceReconciler(manager, params) {
|
|
387
|
-
const { client, addresses, source, clock } = params;
|
|
388
|
-
const intervalMs = params.intervalMs ?? 60000;
|
|
389
|
-
let running = true;
|
|
390
|
-
const tick = async () => {
|
|
391
|
-
if (!running)
|
|
392
|
-
return;
|
|
393
|
-
for (const address of addresses) {
|
|
394
|
-
try {
|
|
395
|
-
const result = await reconcileNonce(manager, {
|
|
396
|
-
client,
|
|
397
|
-
address,
|
|
398
|
-
source,
|
|
399
|
-
downward: params.downward
|
|
400
|
-
});
|
|
401
|
-
params.onReconcile?.(address, result);
|
|
402
|
-
} catch (error) {
|
|
403
|
-
try {
|
|
404
|
-
params.onError?.(address, error);
|
|
405
|
-
} catch {}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
if (running && clock) {
|
|
409
|
-
await clock.advance(intervalMs);
|
|
410
|
-
tick();
|
|
411
|
-
}
|
|
412
|
-
};
|
|
413
|
-
if (clock) {
|
|
414
|
-
tick();
|
|
415
|
-
return {
|
|
416
|
-
stop: () => {
|
|
417
|
-
running = false;
|
|
418
|
-
}
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
const timer = setInterval(tick, intervalMs);
|
|
422
|
-
timer.unref?.();
|
|
423
|
-
return {
|
|
424
|
-
stop: () => clearInterval(timer)
|
|
425
|
-
};
|
|
426
|
-
}
|
|
427
|
-
function isNonceConflictError(error) {
|
|
428
|
-
if (!(error instanceof BroadcastError))
|
|
429
|
-
return false;
|
|
430
|
-
if (error.reason === "ConflictingNonceInMempool" || error.reason === "BadNonce") {
|
|
431
|
-
return true;
|
|
432
|
-
}
|
|
433
|
-
if (error.reason !== undefined)
|
|
434
|
-
return false;
|
|
435
|
-
return error.message.toLowerCase().includes("nonce");
|
|
436
|
-
}
|
|
437
|
-
async function broadcastWithNonceReset(client, params) {
|
|
438
|
-
try {
|
|
439
|
-
const result = await sendTransaction(client, {
|
|
440
|
-
transaction: params.transaction
|
|
441
|
-
});
|
|
442
|
-
return result.txid;
|
|
443
|
-
} catch (error) {
|
|
444
|
-
if (client.nonceManager && isNonceConflictError(error)) {
|
|
445
|
-
await client.nonceManager.reset({ client, address: params.address });
|
|
446
|
-
}
|
|
447
|
-
throw error;
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// src/actions/wallet/utils.ts
|
|
452
|
-
function isProviderAccount(account) {
|
|
453
|
-
return account.type === "provider";
|
|
454
|
-
}
|
|
455
|
-
var FEE_TIERS = ["min", "low", "mid", "high"];
|
|
456
|
-
var TIER_INDEX = { low: 0, mid: 1, high: 2 };
|
|
457
|
-
function isFeeTier(fee) {
|
|
458
|
-
return typeof fee === "string" && FEE_TIERS.includes(fee);
|
|
459
|
-
}
|
|
460
|
-
function minimumFee(transaction) {
|
|
461
|
-
return BigInt(serializeTransaction(transaction).length);
|
|
462
|
-
}
|
|
463
|
-
async function resolveFee(client, transaction, fee) {
|
|
464
|
-
if (fee !== undefined && !isFeeTier(fee))
|
|
465
|
-
return intToBigInt(fee);
|
|
466
|
-
const tier = fee ?? "mid";
|
|
467
|
-
if (tier === "min")
|
|
468
|
-
return minimumFee(transaction);
|
|
469
|
-
try {
|
|
470
|
-
const estimates = await estimateFee(client, { transaction });
|
|
471
|
-
const pick = estimates[TIER_INDEX[tier]] ?? estimates[estimates.length - 1];
|
|
472
|
-
if (pick)
|
|
473
|
-
return BigInt(pick.fee);
|
|
474
|
-
} catch {}
|
|
475
|
-
return minimumFee(transaction);
|
|
476
|
-
}
|
|
477
|
-
function setUnsignedFee(transaction, fee) {
|
|
478
|
-
transaction.auth.spendingCondition.fee = fee;
|
|
479
|
-
clearTxCache(transaction);
|
|
480
|
-
}
|
|
481
|
-
function assertNoFeeTierForProvider(fee) {
|
|
482
|
-
if (isFeeTier(fee)) {
|
|
483
|
-
throw new Error(`Fee tier '${fee}' requires local signing; provider (wallet) accounts set their own fee`);
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// src/actions/wallet/callContract.ts
|
|
488
|
-
async function callContract(client, params) {
|
|
489
|
-
const account = client.account;
|
|
490
|
-
if (!account)
|
|
491
|
-
throw new Error("Account required");
|
|
492
|
-
const [contractAddress, contractName] = parseContractId(params.contract);
|
|
493
|
-
if (isProviderAccount(account)) {
|
|
494
|
-
assertNoFeeTierForProvider(params.fee);
|
|
495
|
-
const result = await account.provider.request("stx_callContract", {
|
|
496
|
-
contract: params.contract,
|
|
497
|
-
functionName: params.functionName,
|
|
498
|
-
functionArgs: params.functionArgs ?? []
|
|
499
|
-
});
|
|
500
|
-
return result.txid;
|
|
501
|
-
}
|
|
502
|
-
const nonce = params.nonce ?? await resolveNonce(client, account.address);
|
|
503
|
-
const needsFeeResolution = params.fee === undefined || isFeeTier(params.fee);
|
|
504
|
-
const unsigned = buildContractCall({
|
|
505
|
-
contractAddress,
|
|
506
|
-
contractName,
|
|
507
|
-
functionName: params.functionName,
|
|
508
|
-
functionArgs: params.functionArgs ?? [],
|
|
509
|
-
fee: needsFeeResolution ? 0n : params.fee,
|
|
510
|
-
nonce,
|
|
511
|
-
publicKey: account.publicKey,
|
|
512
|
-
chain: client.chain,
|
|
513
|
-
postConditionMode: params.postConditionMode,
|
|
514
|
-
postConditions: params.postConditions
|
|
515
|
-
});
|
|
516
|
-
if (needsFeeResolution) {
|
|
517
|
-
setUnsignedFee(unsigned, await resolveFee(client, unsigned, params.fee));
|
|
518
|
-
}
|
|
519
|
-
const signed = await signTransactionWithAccount(unsigned, account);
|
|
520
|
-
return broadcastWithNonceReset(client, {
|
|
521
|
-
transaction: signed,
|
|
522
|
-
address: account.address
|
|
523
|
-
});
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
//# debugId=B1D5C24E13F4B8DE64756E2164756E21
|
|
527
|
-
//# sourceMappingURL=stacks-tdsp5gsb.cjs.map
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/actions/public/estimateFee.ts", "../src/actions/public/getBlockHeight.ts", "../src/errors/http.ts", "../src/actions/public/getMapEntry.ts", "../src/actions/public/getNonce.ts", "../src/actions/public/txSources.ts", "../src/errors/transaction.ts", "../src/actions/public/waitForTransactionReceipt.ts", "../src/actions/wallet/sendTransaction.ts", "../src/actions/wallet/nonceManager.ts", "../src/actions/wallet/utils.ts", "../src/actions/wallet/callContract.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import type { Client } from \"../../clients/types.ts\";\nimport { MalformedResponseError } from \"../../errors/response.ts\";\nimport type { StacksTransaction } from \"../../transactions/types.ts\";\nimport {\n\tserializePayload,\n\tserializeTransaction,\n} from \"../../transactions/wire/serialize.ts\";\nimport { bytesToHex } from \"../../utils/encoding.ts\";\n\nexport type EstimateFeeParams = {\n\ttransaction: StacksTransaction;\n};\n\nexport type FeeEstimation = {\n\tfeeRate: number;\n\tfee: number;\n};\n\nfunction isValidEstimation(\n\te: unknown,\n): e is { fee_rate: number | string; fee: number | string } {\n\treturn (\n\t\ttypeof e === \"object\" &&\n\t\te !== null &&\n\t\t\"fee_rate\" in e &&\n\t\t\"fee\" in e &&\n\t\t(typeof (e as Record<string, unknown>).fee_rate === \"number\" ||\n\t\t\ttypeof (e as Record<string, unknown>).fee_rate === \"string\") &&\n\t\t(typeof (e as Record<string, unknown>).fee === \"number\" ||\n\t\t\ttypeof (e as Record<string, unknown>).fee === \"string\")\n\t);\n}\n\nexport async function estimateFee(\n\tclient: Client,\n\tparams: EstimateFeeParams,\n): Promise<FeeEstimation[]> {\n\tconst payloadHex = bytesToHex(serializePayload(params.transaction.payload));\n\tconst txHex = bytesToHex(serializeTransaction(params.transaction));\n\n\tconst data = await client.request(\"/v2/fees/transaction\", {\n\t\tmethod: \"POST\",\n\t\tbody: {\n\t\t\testimated_len: Math.ceil(txHex.length / 2),\n\t\t\ttransaction_payload: `0x${payloadHex}`,\n\t\t},\n\t});\n\n\tconst raw = (data as { estimations?: unknown[] })?.estimations ?? [];\n\treturn raw.map((e) => {\n\t\tif (!isValidEstimation(e)) {\n\t\t\tthrow new MalformedResponseError(\n\t\t\t\t\"estimateFee: node response contains invalid fee estimation entry\",\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\tfeeRate: Number(e.fee_rate),\n\t\t\tfee: Number(e.fee),\n\t\t};\n\t});\n}\n",
|
|
6
|
-
"import type { Client } from \"../../clients/types.ts\";\nimport { MalformedResponseError } from \"../../errors/response.ts\";\n\nexport async function getBlockHeight(client: Client): Promise<number> {\n\tconst data = await client.request(\"/v2/info\", { method: \"GET\" });\n\tif (typeof data?.stacks_tip_height !== \"number\") {\n\t\tthrow new MalformedResponseError(\n\t\t\t'getBlockHeight: /v2/info response is missing \"stacks_tip_height\"',\n\t\t);\n\t}\n\treturn data.stacks_tip_height;\n}\n",
|
|
7
|
-
"import { BaseError } from \"./base.ts\";\n\n/** Thrown by the HTTP transport when a response's status isn't 2xx. */\nexport class HttpRequestError extends BaseError {\n\toverride name = \"HttpRequestError\";\n\tstatus: number;\n\n\tconstructor(status: number, options?: { cause?: Error; details?: string }) {\n\t\tsuper(`HTTP request failed with status ${status}`, options);\n\t\tthis.status = status;\n\t}\n}\n",
|
|
8
|
-
"import { deserializeCVBytes } from \"../../clarity/deserialize.ts\";\nimport { serializeCVBytes } from \"../../clarity/serialize.ts\";\nimport type { ClarityValue } from \"../../clarity/types.ts\";\nimport type { Client } from \"../../clients/types.ts\";\nimport { MalformedResponseError } from \"../../errors/response.ts\";\nimport { parseContractId } from \"../../utils/address.ts\";\nimport { bytesToHex, with0x } from \"../../utils/encoding.ts\";\n\nexport type GetMapEntryParams = {\n\tcontract: string; // \"address.name\"\n\tmapName: string;\n\tkey: ClarityValue;\n};\n\nexport async function getMapEntry<T extends ClarityValue = ClarityValue>(\n\tclient: Client,\n\tparams: GetMapEntryParams,\n): Promise<T> {\n\tconst [address, name] = parseContractId(params.contract);\n\tconst serializedKey = with0x(bytesToHex(serializeCVBytes(params.key)));\n\n\tconst data = await client.request(\n\t\t`/v2/map_entry/${address}/${name}/${params.mapName}`,\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\tbody: serializedKey,\n\t\t},\n\t);\n\n\tif (typeof data?.data !== \"string\") {\n\t\tthrow new MalformedResponseError(\n\t\t\t`getMapEntry: /v2/map_entry/${address}/${name}/${params.mapName} response is missing \"data\"`,\n\t\t);\n\t}\n\treturn deserializeCVBytes<T>(data.data);\n}\n",
|
|
9
|
-
"import type { Client } from \"../../clients/types.ts\";\n\nexport type GetNonceParams = {\n\taddress: string;\n};\n\nexport type GetNonceResult = {\n\tnonce: bigint;\n\tpossibleNextNonce: bigint;\n};\n\nexport async function getNonce(\n\tclient: Client,\n\tparams: GetNonceParams,\n): Promise<bigint> {\n\tconst data = await client.request(`/v2/accounts/${params.address}`, {\n\t\tmethod: \"GET\",\n\t});\n\tconst nonce = (data as { nonce?: unknown })?.nonce;\n\tif (typeof nonce !== \"number\" && typeof nonce !== \"string\") {\n\t\tthrow new Error(\n\t\t\t`getNonce: unexpected /v2/accounts response for ${params.address} (missing numeric nonce)`,\n\t\t);\n\t}\n\treturn BigInt(nonce);\n}\n",
|
|
10
|
-
"import { deserializeCVBytes } from \"../../clarity/deserialize.ts\";\nimport type { ClarityValue } from \"../../clarity/types.ts\";\nimport type { Client } from \"../../clients/types.ts\";\nimport { HttpRequestError } from \"../../errors/http.ts\";\n\n/**\n * Pluggable transaction-status sources for {@link getTransaction} /\n * `waitForTransactionReceipt`.\n *\n * A bare stacks-node has no confirmed-transaction endpoint, so status reads\n * need a host that indexes transactions. Where that data comes from is\n * pluggable, mirroring the nonce sources:\n *\n * - {@link extendedApiSource} — default; `/extended/v1/tx/{txid}` on the\n * client's transport host (Hiro API or any extended-API-compatible host).\n * - {@link indexTxSource} — Secondlayer's `/v1/index/transactions/{txid}`;\n * returns the chain tip in the same response, so N-confirmation waits\n * need no second request.\n */\n\nexport type TransactionStatus =\n\t| \"pending\"\n\t| \"success\"\n\t| \"abort_by_response\"\n\t| \"abort_by_post_condition\"\n\t| \"dropped\";\n\nexport type TransactionReceipt = {\n\ttxid: string;\n\tstatus: TransactionStatus;\n\t/** Anchor block height; absent while pending. */\n\tblockHeight?: number;\n\tblockHash?: string;\n\t/** Decoded Clarity result; absent while pending or when the source omits it. */\n\tresult?: ClarityValue;\n\tresultHex?: string;\n\tevents: unknown[];\n\t/** The source's unnormalized response, for fields the receipt doesn't model. */\n\traw: unknown;\n};\n\nexport type TransactionSnapshot = {\n\t/** `null` when the source has no record of the tx (mempool + chain). */\n\treceipt: TransactionReceipt | null;\n\t/** Chain tip height, when the source knows it (saves a round-trip). */\n\ttip?: number;\n};\n\nexport type TransactionStatusSource = {\n\tget(args: { client: Client; txid: string }): Promise<TransactionSnapshot>;\n};\n\ntype FetchImpl = typeof globalThis.fetch;\n\nfunction resolveFetch(fetchImpl?: FetchImpl): FetchImpl {\n\tconst f = fetchImpl ?? globalThis.fetch;\n\tif (!f)\n\t\tthrow new Error(\"No fetch implementation available; pass `fetchImpl`\");\n\treturn f;\n}\n\nfunction normalizeTxid(txid: string): string {\n\treturn txid.startsWith(\"0x\") ? txid : `0x${txid}`;\n}\n\nfunction decodeResultHex(hex: string | null | undefined): {\n\tresult?: ClarityValue;\n\tresultHex?: string;\n} {\n\tif (!hex) return {};\n\ttry {\n\t\treturn { result: deserializeCVBytes(hex), resultHex: hex };\n\t} catch {\n\t\treturn { resultHex: hex };\n\t}\n}\n\n/** Map a Hiro `tx_status` string onto the receipt vocabulary. */\nfunction normalizeStatus(txStatus: string): TransactionStatus | undefined {\n\tswitch (txStatus) {\n\t\tcase \"pending\":\n\t\tcase \"success\":\n\t\tcase \"abort_by_response\":\n\t\tcase \"abort_by_post_condition\":\n\t\t\treturn txStatus;\n\t\tdefault:\n\t\t\treturn txStatus.startsWith(\"dropped\") ? \"dropped\" : undefined;\n\t}\n}\n\n/**\n * Default source: `GET /extended/v1/tx/{txid}` via the client's transport.\n * Requires a host that serves Hiro's extended API (a bare stacks-node does\n * not). Does not report the chain tip — the wait action fetches it separately\n * when `confirmations > 1`.\n */\nexport function extendedApiSource(): TransactionStatusSource {\n\treturn {\n\t\tasync get({ client, txid }) {\n\t\t\tlet data: Awaited<ReturnType<Client[\"request\"]>>;\n\t\t\ttry {\n\t\t\t\tdata = await client.request(`/extended/v1/tx/${normalizeTxid(txid)}`, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof HttpRequestError && error.status === 404) {\n\t\t\t\t\treturn { receipt: null };\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tconst txStatus =\n\t\t\t\ttypeof data?.tx_status === \"string\" ? data.tx_status : undefined;\n\t\t\tif (!txStatus) return { receipt: null }; // unexpected shape\n\n\t\t\tconst status = normalizeStatus(txStatus);\n\t\t\tif (!status) return { receipt: null };\n\n\t\t\treturn {\n\t\t\t\treceipt: {\n\t\t\t\t\ttxid: normalizeTxid(txid),\n\t\t\t\t\tstatus,\n\t\t\t\t\tblockHeight:\n\t\t\t\t\t\ttypeof data.block_height === \"number\" && data.block_height > 0\n\t\t\t\t\t\t\t? data.block_height\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\tblockHash: data.block_hash ?? undefined,\n\t\t\t\t\t...decodeResultHex(data.tx_result?.hex),\n\t\t\t\t\tevents: Array.isArray(data.events) ? data.events : [],\n\t\t\t\t\traw: data,\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t};\n}\n\nexport type IndexTxSourceParams = {\n\t/** Base URL of a Secondlayer-shaped index API. */\n\tbaseUrl?: string;\n\tapiKey?: string;\n\tfetchImpl?: FetchImpl;\n};\n\n/**\n * Source backed by Secondlayer's `/v1/index/transactions/{txid}`. The response\n * embeds the chain tip, so N-confirmation math needs no extra request. The\n * index only returns canonical (mined) transactions — while a tx is in the\n * mempool this source reports `receipt: null`, and the wait action's grace\n * window carries it until inclusion.\n */\nexport function indexTxSource(\n\tparams: IndexTxSourceParams = {},\n): TransactionStatusSource {\n\tconst baseUrl = (params.baseUrl ?? \"https://api.secondlayer.tools\").replace(\n\t\t/\\/$/,\n\t\t\"\",\n\t);\n\tconst fetchImpl = resolveFetch(params.fetchImpl);\n\n\treturn {\n\t\tasync get({ txid }) {\n\t\t\tconst res = await fetchImpl(\n\t\t\t\t`${baseUrl}/v1/index/transactions/${normalizeTxid(txid)}`,\n\t\t\t\t{\n\t\t\t\t\theaders: params.apiKey ? { \"x-api-key\": params.apiKey } : undefined,\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (res.status === 404) {\n\t\t\t\treturn { receipt: null };\n\t\t\t}\n\t\t\tif (!res.ok) {\n\t\t\t\tthrow new Error(`indexTxSource: /v1/index/transactions ${res.status}`);\n\t\t\t}\n\n\t\t\tconst data = (await res.json()) as {\n\t\t\t\ttransaction?: {\n\t\t\t\t\ttx_id: string;\n\t\t\t\t\tblock_height: number;\n\t\t\t\t\tstatus: string;\n\t\t\t\t\tcontract_call?: { result_hex: string | null };\n\t\t\t\t};\n\t\t\t\ttip?: { block_height: number };\n\t\t\t};\n\t\t\tconst tx = data.transaction;\n\t\t\tconst tip = data.tip?.block_height;\n\t\t\tif (!tx) return { receipt: null, tip };\n\n\t\t\tconst status = normalizeStatus(tx.status) ?? \"success\";\n\t\t\treturn {\n\t\t\t\treceipt: {\n\t\t\t\t\ttxid: normalizeTxid(tx.tx_id),\n\t\t\t\t\tstatus,\n\t\t\t\t\tblockHeight: tx.block_height,\n\t\t\t\t\t...decodeResultHex(tx.contract_call?.result_hex),\n\t\t\t\t\tevents: [],\n\t\t\t\t\traw: data,\n\t\t\t\t},\n\t\t\t\ttip,\n\t\t\t};\n\t\t},\n\t};\n}\n",
|
|
11
|
-
"import { BaseError } from \"./base.ts\";\n\nexport class TransactionError extends BaseError {\n\toverride name = \"TransactionError\";\n}\n\n/**\n * Rejection reasons a stacks-node returns from `POST /v2/transactions`.\n * Wire strings from stacks-core `MemPoolRejection::into_json`\n * (`stackslib/src/chainstate/stacks/db/blocks.rs`).\n */\nexport type TxRejectionReason =\n\t| \"Serialization\"\n\t| \"Deserialization\"\n\t| \"SignatureValidation\"\n\t| \"BadNonce\"\n\t| \"ConflictingNonceInMempool\"\n\t| \"TooMuchChaining\"\n\t| \"FeeTooLow\"\n\t| \"NotEnoughFunds\"\n\t| \"NoSuchContract\"\n\t| \"NoSuchPublicFunction\"\n\t| \"BadFunctionArgument\"\n\t| \"ContractAlreadyExists\"\n\t| \"BadTransactionVersion\"\n\t| \"TransferRecipientCannotEqualSender\"\n\t| \"TransferAmountMustBePositive\"\n\t| \"PoisonMicroblocksDoNotConflict\"\n\t| \"PoisonMicroblockHasUnknownPubKeyHash\"\n\t| \"PoisonMicroblockIsInvalid\"\n\t| \"BadAddressVersionByte\"\n\t| \"NoCoinbaseViaMempool\"\n\t| \"NoTenureChangeViaMempool\"\n\t| \"EstimatorError\"\n\t| \"TemporarilyBlacklisted\"\n\t| \"ServerFailureNoSuchChainTip\"\n\t| \"ServerFailureDatabase\"\n\t| \"ServerFailureOther\";\n\nexport class BroadcastError extends BaseError {\n\toverride name = \"BroadcastError\";\n\ttxid?: string;\n\t// `(string & {})` keeps forward-compat with reasons newer nodes may add\n\t// while preserving literal-union completions.\n\treason?: TxRejectionReason | (string & {});\n\t/** Node-provided detail; shape varies per reason (see stacks-core RPC docs). */\n\treasonData?: unknown;\n\n\tconstructor(\n\t\tmessage: string,\n\t\toptions?: {\n\t\t\tcause?: Error;\n\t\t\ttxid?: string;\n\t\t\treason?: string;\n\t\t\treasonData?: unknown;\n\t\t},\n\t) {\n\t\tsuper(message, options);\n\t\tthis.txid = options?.txid;\n\t\tthis.reason = options?.reason;\n\t\tthis.reasonData = options?.reasonData;\n\t}\n}\n\n/** The transaction was mined but its execution aborted (runtime error or failed post-condition). */\nexport class TransactionAbortedError extends BaseError {\n\toverride name = \"TransactionAbortedError\";\n\t/** The abort receipt (status, block info, raw source response). */\n\treceipt: unknown;\n\n\tconstructor(message: string, options: { receipt: unknown; cause?: Error }) {\n\t\tsuper(message, options);\n\t\tthis.receipt = options.receipt;\n\t}\n}\n\n/** The transaction left the mempool without being mined (dropped/replaced). */\nexport class TransactionDroppedError extends BaseError {\n\toverride name = \"TransactionDroppedError\";\n\ttxid: string;\n\n\tconstructor(message: string, options: { txid: string; cause?: Error }) {\n\t\tsuper(message, options);\n\t\tthis.txid = options.txid;\n\t}\n}\n\n/** waitForTransactionReceipt gave up before the tx reached the requested state. */\nexport class WaitForTransactionTimeoutError extends BaseError {\n\toverride name = \"WaitForTransactionTimeoutError\";\n\ttxid: string;\n\n\tconstructor(message: string, options: { txid: string; cause?: Error }) {\n\t\tsuper(message, options);\n\t\tthis.txid = options.txid;\n\t}\n}\n\nexport class SerializationError extends BaseError {\n\toverride name = \"SerializationError\";\n}\n\nexport class SigningError extends BaseError {\n\toverride name = \"SigningError\";\n}\n",
|
|
12
|
-
"import type { Client } from \"../../clients/types.ts\";\nimport {\n\tTransactionAbortedError,\n\tTransactionDroppedError,\n\tWaitForTransactionTimeoutError,\n} from \"../../errors/transaction.ts\";\nimport { getBlockHeight } from \"./getBlockHeight.ts\";\nimport {\n\ttype TransactionReceipt,\n\ttype TransactionStatusSource,\n\textendedApiSource,\n} from \"./txSources.ts\";\n\nexport type WaitForTransactionReceiptParams = {\n\ttxid: string;\n\t/** Anchor-block confirmations to wait for. Default 1 (mined). */\n\tconfirmations?: number;\n\t/** Give up after this many ms. Default 180_000 (3 min). */\n\ttimeout?: number;\n\t/** Delay between status polls, ms. Default 3_000. */\n\tpollingInterval?: number;\n\t/**\n\t * How long a tx may be unknown to the source before it counts as dropped,\n\t * ms. Covers broadcast propagation lag and canonical-only sources that\n\t * can't see the mempool. Default 30_000.\n\t */\n\tdroppedGracePeriod?: number;\n\t/** Where to read status from. Defaults to {@link extendedApiSource}. */\n\tsource?: TransactionStatusSource;\n};\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\n/**\n * Poll until a transaction is mined with N confirmations, then return its\n * receipt.\n *\n * Rejects with {@link TransactionAbortedError} when the tx mines but aborts\n * (`abort_by_response` / `abort_by_post_condition`) — the receipt is attached.\n * Rejects with {@link TransactionDroppedError} when the tx leaves the mempool\n * unmined or stays unknown past `droppedGracePeriod`, and\n * {@link WaitForTransactionTimeoutError} at `timeout`.\n *\n * Reorg-tolerant: every cycle re-reads the receipt (block height may change)\n * and recomputes confirmations from the current tip.\n */\nexport async function waitForTransactionReceipt(\n\tclient: Client,\n\tparams: WaitForTransactionReceiptParams,\n): Promise<TransactionReceipt> {\n\tconst {\n\t\ttxid,\n\t\tconfirmations = 1,\n\t\ttimeout = 180_000,\n\t\tpollingInterval = 3_000,\n\t\tdroppedGracePeriod = 30_000,\n\t} = params;\n\tconst source = params.source ?? extendedApiSource();\n\n\tconst startedAt = Date.now();\n\tlet unknownSince: number | null = null;\n\tlet everPending = false;\n\n\twhile (true) {\n\t\tconst snapshot = await source.get({ client, txid });\n\t\tconst receipt = snapshot.receipt;\n\n\t\tif (receipt === null) {\n\t\t\t// Unknown to the source: propagation lag, a canonical-only source\n\t\t\t// looking at a mempool tx, or a genuine drop. Only the grace clock\n\t\t\t// distinguishes them.\n\t\t\tunknownSince ??= Date.now();\n\t\t\tif (Date.now() - unknownSince >= droppedGracePeriod) {\n\t\t\t\tthrow new TransactionDroppedError(\n\t\t\t\t\teverPending\n\t\t\t\t\t\t? `Transaction ${txid} left the mempool without being mined`\n\t\t\t\t\t\t: `Transaction ${txid} was never observed by the status source`,\n\t\t\t\t\t{ txid },\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tunknownSince = null;\n\n\t\t\tswitch (receipt.status) {\n\t\t\t\tcase \"dropped\":\n\t\t\t\t\tthrow new TransactionDroppedError(\n\t\t\t\t\t\t`Transaction ${txid} was dropped from the mempool`,\n\t\t\t\t\t\t{ txid },\n\t\t\t\t\t);\n\t\t\t\tcase \"abort_by_response\":\n\t\t\t\tcase \"abort_by_post_condition\":\n\t\t\t\t\tthrow new TransactionAbortedError(\n\t\t\t\t\t\t`Transaction ${txid} aborted (${receipt.status})`,\n\t\t\t\t\t\t{ receipt },\n\t\t\t\t\t);\n\t\t\t\tcase \"pending\":\n\t\t\t\t\teverPending = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"success\": {\n\t\t\t\t\tif (confirmations <= 1) return receipt;\n\t\t\t\t\tif (receipt.blockHeight !== undefined) {\n\t\t\t\t\t\tconst tip = snapshot.tip ?? (await getBlockHeight(client));\n\t\t\t\t\t\tif (tip - receipt.blockHeight + 1 >= confirmations) return receipt;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (Date.now() - startedAt >= timeout) {\n\t\t\tthrow new WaitForTransactionTimeoutError(\n\t\t\t\t`Timed out after ${timeout}ms waiting for transaction ${txid}`,\n\t\t\t\t{ txid },\n\t\t\t);\n\t\t}\n\t\tawait sleep(pollingInterval);\n\t}\n}\n",
|
|
13
|
-
"import type { TransactionReceipt } from \"../../actions/public/txSources.ts\";\nimport { waitForTransactionReceipt } from \"../../actions/public/waitForTransactionReceipt.ts\";\nimport type { Client } from \"../../clients/types.ts\";\nimport { HttpRequestError } from \"../../errors/http.ts\";\nimport { BroadcastError } from \"../../errors/transaction.ts\";\nimport { getTransactionId } from \"../../transactions/signer.ts\";\nimport type { StacksTransaction } from \"../../transactions/types.ts\";\nimport { serializeTransaction } from \"../../transactions/wire/serialize.ts\";\nimport { bytesToHex } from \"../../utils/encoding.ts\";\n\nexport type SendTransactionParams = {\n\ttransaction: StacksTransaction;\n\tattachment?: Uint8Array | string;\n\t/**\n\t * Wait for the transaction to be mined before returning. `true` waits for\n\t * 1 confirmation; a number waits for that many. The receipt lands on the\n\t * result. Rejects if the tx aborts, is dropped, or the wait times out.\n\t */\n\twait?: boolean | number;\n};\n\nexport type SendTransactionResult = {\n\ttxid: string;\n\t/** Present when `wait` was requested. */\n\treceipt?: TransactionReceipt;\n};\n\n/** Broadcast a signed transaction to the network */\nexport async function sendTransaction(\n\tclient: Client,\n\tparams: SendTransactionParams,\n): Promise<SendTransactionResult> {\n\tconst hex = bytesToHex(serializeTransaction(params.transaction));\n\n\tconst body: Record<string, string> = { tx: hex };\n\tif (params.attachment) {\n\t\tbody.attachment =\n\t\t\ttypeof params.attachment === \"string\"\n\t\t\t\t? params.attachment\n\t\t\t\t: bytesToHex(params.attachment);\n\t}\n\n\t// A stacks-node responds to a rejected broadcast with a non-2xx status\n\t// (the transport now throws for that) but the rejection JSON — the thing\n\t// this function actually needs — rides along as the error body.\n\tlet data: Awaited<ReturnType<Client[\"request\"]>>;\n\ttry {\n\t\tdata = await client.request(\"/v2/transactions\", { method: \"POST\", body });\n\t} catch (error) {\n\t\tif (error instanceof HttpRequestError && error.details) {\n\t\t\ttry {\n\t\t\t\tdata = JSON.parse(error.details);\n\t\t\t} catch {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t} else {\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tif (data.error) {\n\t\tthrow new BroadcastError(data.reason ?? data.error, {\n\t\t\treason: data.reason,\n\t\t\treasonData: data.reason_data,\n\t\t\ttxid: data.txid ?? getTransactionId(params.transaction),\n\t\t});\n\t}\n\n\tconst txid =\n\t\ttypeof data === \"string\"\n\t\t\t? data.replace(/\"/g, \"\")\n\t\t\t: (data.txid ?? getTransactionId(params.transaction));\n\n\tif (params.wait) {\n\t\tconst confirmations = params.wait === true ? 1 : params.wait;\n\t\tconst receipt = await waitForTransactionReceipt(client, {\n\t\t\ttxid,\n\t\t\tconfirmations,\n\t\t});\n\t\treturn { txid, receipt };\n\t}\n\n\treturn { txid };\n}\n",
|
|
14
|
-
"import type { Client } from \"../../clients/types.ts\";\nimport { BroadcastError } from \"../../errors/transaction.ts\";\nimport type { StacksTransaction } from \"../../transactions/types.ts\";\nimport { getNonce } from \"../public/getNonce.ts\";\nimport { sendTransaction } from \"./sendTransaction.ts\";\n\n/**\n * Provides the confirmed on-chain nonce floor for an address.\n *\n * The default {@link jsonRpcSource} reads the configured node's `/v2/accounts`\n * endpoint — node-agnostic, no Hiro dependency. Other sources (mempool-aware,\n * first-party Index) can be swapped in without touching the manager.\n */\nexport type NonceManagerSource = {\n\tget(params: { client: Client; address: string }): Promise<bigint>;\n};\n\n/**\n * Holds per-address allocation state and hands out the next nonce.\n *\n * `reserve` MUST be atomic per `key`: two concurrent reservations for the same\n * key must never return the same value. The in-memory {@link memoryStore}\n * serializes with a per-key promise chain; a persisted store (Redis `INCR`,\n * Postgres `SELECT ... FOR UPDATE`) becomes the cross-process lock for the\n * multi-builder / smart-wallet-as-a-service case.\n */\nexport type NonceStore = {\n\t/**\n\t * Reserve the next nonce for `key`. `getFloor` reads the confirmed on-chain\n\t * nonce; it is only invoked when the store has no tracked value (cold start\n\t * or after {@link NonceStore.reset}).\n\t */\n\treserve(key: string, getFloor: () => Promise<bigint>): Promise<bigint>;\n\t/** Forget tracked state for `key` so the next reserve re-syncs from the floor. */\n\treset(key: string): void | Promise<void>;\n\t/**\n\t * Return the next nonce that {@link NonceStore.reserve} would hand out for\n\t * `key` WITHOUT consuming it, or `undefined` if `key` is untracked. Used by\n\t * {@link reconcileNonce} to detect drift. Optional — stores that omit it\n\t * simply opt out of reconciliation.\n\t */\n\tpeek?(key: string): Promise<bigint | undefined> | bigint | undefined;\n};\n\n/** Allocates mempool-safe sequential nonces across rapid broadcasts from one account. */\nexport type NonceManager = {\n\tconsume(params: { client: Client; address: string }): Promise<bigint>;\n\treset(params: { client: Client; address: string }): void | Promise<void>;\n\t/** Next nonce that {@link NonceManager.consume} would return without consuming it, or `undefined` if untracked. */\n\tpeek(params: {\n\t\tclient: Client;\n\t\taddress: string;\n\t}): Promise<bigint | undefined>;\n};\n\nexport type CreateNonceManagerParams = {\n\tsource?: NonceManagerSource;\n\tstore?: NonceStore;\n};\n\n/** Confirmed-nonce source backed by the configured node's `/v2/accounts` RPC (no Hiro dependency). */\nexport function jsonRpcSource(): NonceManagerSource {\n\treturn {\n\t\tget: ({ client, address }) => getNonce(client, { address }),\n\t};\n}\n\n/**\n * In-memory, single-process store. Tracks the next nonce per key and serializes\n * concurrent reservations with a per-key promise chain.\n *\n * Correct only within one process — swap in a persisted store for multi-process\n * deployments that share a signing key.\n */\nexport function memoryStore(): NonceStore {\n\tconst next = new Map<string, bigint>();\n\tconst locks = new Map<string, Promise<unknown>>();\n\n\tfunction withLock<T>(key: string, fn: () => Promise<T>): Promise<T> {\n\t\tconst prev = locks.get(key) ?? Promise.resolve();\n\t\t// Chain onto the prior reservation regardless of how it settled, so a\n\t\t// rejected reserve never wedges the key.\n\t\tconst run = prev.then(fn, fn);\n\t\tlocks.set(\n\t\t\tkey,\n\t\t\trun.catch(() => {}),\n\t\t);\n\t\treturn run;\n\t}\n\n\treturn {\n\t\treserve(key, getFloor) {\n\t\t\treturn withLock(key, async () => {\n\t\t\t\tlet current = next.get(key);\n\t\t\t\tif (current === undefined) current = await getFloor();\n\t\t\t\tnext.set(key, current + 1n);\n\t\t\t\treturn current;\n\t\t\t});\n\t\t},\n\t\treset(key) {\n\t\t\tnext.delete(key);\n\t\t},\n\t\tpeek(key) {\n\t\t\treturn next.get(key);\n\t\t},\n\t};\n}\n\nfunction nonceKey(client: Client, address: string): string {\n\treturn `${client.chain?.id ?? \"stacks\"}:${address}`;\n}\n\n/**\n * Create a nonce manager that floors on a confirmed-nonce {@link NonceManagerSource}\n * and increments a {@link NonceStore} on every {@link NonceManager.consume}.\n *\n * Defaults to {@link jsonRpcSource} + {@link memoryStore} — node-agnostic,\n * single-process, zero external dependencies.\n */\nexport function createNonceManager(\n\tparams: CreateNonceManagerParams = {},\n): NonceManager {\n\tconst source = params.source ?? jsonRpcSource();\n\tconst store = params.store ?? memoryStore();\n\n\treturn {\n\t\tconsume({ client, address }) {\n\t\t\treturn store.reserve(nonceKey(client, address), () =>\n\t\t\t\tsource.get({ client, address }),\n\t\t\t);\n\t\t},\n\t\treset({ client, address }) {\n\t\t\treturn store.reset(nonceKey(client, address));\n\t\t},\n\t\tasync peek({ client, address }) {\n\t\t\treturn store.peek?.(nonceKey(client, address));\n\t\t},\n\t};\n}\n\n/** Resolve the next nonce via the client's nonce manager, falling back to a confirmed read. */\nexport async function resolveNonce(\n\tclient: Client,\n\taddress: string,\n): Promise<bigint> {\n\tif (client.nonceManager)\n\t\treturn client.nonceManager.consume({ client, address });\n\treturn getNonce(client, { address });\n}\n\nexport type ReconcileNonceParams = {\n\tclient: Client;\n\taddress: string;\n\t/** Authoritative (ideally mempool-aware) source to reconcile against. */\n\tsource: NonceManagerSource;\n\t/**\n\t * Allow resetting DOWNWARD when the source's next nonce is below what the\n\t * store tracks — i.e. a previously-allocated tx is no longer pending or\n\t * confirmed (dropped/GC'd), so its nonce should be reused. Default `true`.\n\t *\n\t * Downward resets rely on `source` being current: with a go-forward mempool\n\t * source that lags broadcast, run reconciliation on an interval comfortably\n\t * longer than mempool propagation so a still-missing tx is genuinely dropped.\n\t * Set `false` for upward-only reconciliation (always safe).\n\t */\n\tdownward?: boolean;\n};\n\nexport type ReconcileNonceResult = {\n\t/** Whether the manager was reset (drift detected). */\n\treset: boolean;\n\t/** Authoritative next nonce from `source`. */\n\tauthoritative: bigint;\n\t/** Next nonce the store tracked, or `undefined` if untracked. */\n\ttracked: bigint | undefined;\n};\n\n/**\n * Reconcile a tracked nonce against an authoritative source, healing silent\n * drift that produces no broadcast error (a dropped/GC'd mempool tx leaving the\n * counter overshot, or the chain advancing past the local view).\n *\n * When the source's next nonce differs from the tracked value, the manager is\n * {@link NonceManager.reset}; the next `consume` re-seeds from `source`. A no-op\n * if the store is untracked or does not implement `peek`.\n */\nexport async function reconcileNonce(\n\tmanager: NonceManager,\n\tparams: ReconcileNonceParams,\n): Promise<ReconcileNonceResult> {\n\tconst { client, address, source } = params;\n\tconst downward = params.downward ?? true;\n\n\tconst authoritative = await source.get({ client, address });\n\tconst tracked = await manager.peek({ client, address });\n\n\tif (tracked === undefined || authoritative === tracked) {\n\t\treturn { reset: false, authoritative, tracked };\n\t}\n\tif (authoritative < tracked && !downward) {\n\t\treturn { reset: false, authoritative, tracked };\n\t}\n\n\tawait manager.reset({ client, address });\n\treturn { reset: true, authoritative, tracked };\n}\n\nexport type StartNonceReconcilerParams = {\n\tclient: Client;\n\taddresses: string[];\n\tsource: NonceManagerSource;\n\t/** Reconcile interval in ms. Default 60_000. Keep well above mempool propagation. */\n\tintervalMs?: number;\n\tdownward?: boolean;\n\t/** Per-address callback after each reconcile (observability). */\n\tonReconcile?: (address: string, result: ReconcileNonceResult) => void;\n\t/** Per-address error callback; reconciliation continues on the next tick. */\n\tonError?: (address: string, error: unknown) => void;\n\t/** Optional test clock. If provided, the reconciler advances time via\n\t * `clock.advance(ms)` instead of real `setInterval`. */\n\tclock?: {\n\t\tadvance: (ms: number) => Promise<void>;\n\t\tnow: () => number;\n\t};\n};\n\n/**\n * Run {@link reconcileNonce} on a timer for a set of addresses.\n *\n * SINGLE-WRITER: run this in exactly ONE process. With a shared persisted store,\n * a reconciler resetting the counter while other workers allocate is racy — keep\n * reconciliation on one designated process and let the others only allocate.\n *\n * Returns a handle; call `stop()` to clear the timer.\n */\nexport function startNonceReconciler(\n\tmanager: NonceManager,\n\tparams: StartNonceReconcilerParams,\n): { stop: () => void } {\n\tconst { client, addresses, source, clock } = params;\n\tconst intervalMs = params.intervalMs ?? 60_000;\n\tlet running = true;\n\n\tconst tick = async () => {\n\t\tif (!running) return;\n\t\tfor (const address of addresses) {\n\t\t\ttry {\n\t\t\t\tconst result = await reconcileNonce(manager, {\n\t\t\t\t\tclient,\n\t\t\t\t\taddress,\n\t\t\t\t\tsource,\n\t\t\t\t\tdownward: params.downward,\n\t\t\t\t});\n\t\t\t\tparams.onReconcile?.(address, result);\n\t\t\t} catch (error) {\n\t\t\t\ttry {\n\t\t\t\t\tparams.onError?.(address, error);\n\t\t\t\t} catch {\n\t\t\t\t\t// A throwing onError callback must not abort the reconcile loop\n\t\t\t\t\t// or surface as an unhandled rejection on the interval timer.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (running && clock) {\n\t\t\tawait clock.advance(intervalMs);\n\t\t\ttick();\n\t\t}\n\t};\n\n\tif (clock) {\n\t\ttick();\n\t\treturn {\n\t\t\tstop: () => {\n\t\t\t\trunning = false;\n\t\t\t},\n\t\t};\n\t}\n\n\tconst timer = setInterval(tick, intervalMs);\n\t// Don't keep the event loop alive solely for reconciliation (Node/Bun).\n\t(timer as { unref?: () => void }).unref?.();\n\n\treturn {\n\t\tstop: () => clearInterval(timer),\n\t};\n}\n\n/** True when a broadcast was rejected for a nonce conflict (`ConflictingNonceInMempool`, `BadNonce`). */\nexport function isNonceConflictError(error: unknown): boolean {\n\tif (!(error instanceof BroadcastError)) return false;\n\tif (\n\t\terror.reason === \"ConflictingNonceInMempool\" ||\n\t\terror.reason === \"BadNonce\"\n\t) {\n\t\treturn true;\n\t}\n\t// Typed reason present but not nonce-related — trust it over the message\n\t// (e.g. a FeeTooLow message mentioning \"nonce\" must not trigger a reset).\n\tif (error.reason !== undefined) return false;\n\t// No structured reason (older nodes/proxies) — fall back to message match.\n\treturn error.message.toLowerCase().includes(\"nonce\");\n}\n\n/**\n * Broadcast a signed transaction; on a nonce-conflict rejection, reset the\n * manager so the next build re-syncs to the confirmed floor.\n */\nexport async function broadcastWithNonceReset(\n\tclient: Client,\n\tparams: { transaction: StacksTransaction; address: string },\n): Promise<string> {\n\ttry {\n\t\tconst result = await sendTransaction(client, {\n\t\t\ttransaction: params.transaction,\n\t\t});\n\t\treturn result.txid;\n\t} catch (error) {\n\t\tif (client.nonceManager && isNonceConflictError(error)) {\n\t\t\tawait client.nonceManager.reset({ client, address: params.address });\n\t\t}\n\t\tthrow error;\n\t}\n}\n",
|
|
15
|
-
"import type { ProviderAccount } from \"../../accounts/types.ts\";\nimport type { Account, Client } from \"../../clients/types.ts\";\nimport type { StacksTransaction } from \"../../transactions/types.ts\";\nimport {\n\tclearTxCache,\n\tserializeTransaction,\n} from \"../../transactions/wire/serialize.ts\";\nimport type { IntegerType } from \"../../utils/encoding.ts\";\nimport { intToBigInt } from \"../../utils/encoding.ts\";\nimport { estimateFee } from \"../public/estimateFee.ts\";\n\nexport function isProviderAccount(\n\taccount: Account,\n): account is ProviderAccount {\n\treturn account.type === \"provider\";\n}\n\n/**\n * Named fee tiers. `'low' | 'mid' | 'high'` map to the node's three fee\n * estimations; `'min'` is the node's minimum relay fee — 1 uSTX per byte of\n * the serialized transaction, computable offline.\n */\nexport type FeeTier = \"min\" | \"low\" | \"mid\" | \"high\";\n\n/** Fee input accepted by wallet actions: an explicit amount or a named tier. */\nexport type FeeParam = IntegerType | FeeTier;\n\nconst FEE_TIERS: readonly FeeTier[] = [\"min\", \"low\", \"mid\", \"high\"];\nconst TIER_INDEX = { low: 0, mid: 1, high: 2 } as const;\n\nexport function isFeeTier(fee: FeeParam | undefined): fee is FeeTier {\n\treturn typeof fee === \"string\" && FEE_TIERS.includes(fee as FeeTier);\n}\n\n/**\n * Minimum relay fee: 1 uSTX per byte of the serialized transaction. The fee\n * field is fixed-width (8 bytes), so the size — and therefore this floor — is\n * stable regardless of the fee value later set on the spending condition.\n */\nexport function minimumFee(transaction: StacksTransaction): bigint {\n\treturn BigInt(serializeTransaction(transaction).length);\n}\n\n/**\n * Resolve a fee param to a concrete amount. Numeric input passes through.\n * Tiers `'low' | 'mid' | 'high'` index the node's estimations (nearest\n * available when fewer than three are returned); `'min'` — and any estimation\n * failure (e.g. NoEstimateAvailable) — resolves to {@link minimumFee}, which\n * needs no network round-trip.\n */\nexport async function resolveFee(\n\tclient: Client,\n\ttransaction: StacksTransaction,\n\tfee: FeeParam | undefined,\n): Promise<bigint> {\n\tif (fee !== undefined && !isFeeTier(fee)) return intToBigInt(fee);\n\n\tconst tier = fee ?? \"mid\";\n\tif (tier === \"min\") return minimumFee(transaction);\n\n\ttry {\n\t\tconst estimates = await estimateFee(client, { transaction });\n\t\tconst pick = estimates[TIER_INDEX[tier]] ?? estimates[estimates.length - 1];\n\t\tif (pick) return BigInt(pick.fee);\n\t} catch {\n\t\t// Node could not produce an estimate — fall through to the relay floor.\n\t}\n\treturn minimumFee(transaction);\n}\n\n/** Set the resolved fee on an unsigned transaction's origin spending condition. */\nexport function setUnsignedFee(\n\ttransaction: StacksTransaction,\n\tfee: bigint,\n): void {\n\t// biome-ignore lint/suspicious/noExplicitAny: interop boundary or dynamic-shape value where typing adds friction without runtime safety\n\t(transaction.auth.spendingCondition as any).fee = fee;\n\t// In-place mutation: invalidate the memoized serialization (resolveFee may\n\t// have already serialized this object via minimumFee/estimateFee).\n\tclearTxCache(transaction);\n}\n\n/** Throw when a named fee tier is used with a provider (wallet) account. */\nexport function assertNoFeeTierForProvider(fee: FeeParam | undefined): void {\n\tif (isFeeTier(fee)) {\n\t\tthrow new Error(\n\t\t\t`Fee tier '${fee}' requires local signing; provider (wallet) accounts set their own fee`,\n\t\t);\n\t}\n}\n",
|
|
16
|
-
"import type { ClarityValue } from \"../../clarity/types.ts\";\nimport type { Client } from \"../../clients/types.ts\";\nimport type {\n\tPostConditionInput,\n\tPostConditionMode,\n} from \"../../postconditions/types.ts\";\nimport { buildContractCall } from \"../../transactions/build.ts\";\nimport { signTransactionWithAccount } from \"../../transactions/signer.ts\";\nimport { parseContractId } from \"../../utils/address.ts\";\nimport type { IntegerType } from \"../../utils/encoding.ts\";\nimport { broadcastWithNonceReset, resolveNonce } from \"./nonceManager.ts\";\nimport {\n\ttype FeeParam,\n\tassertNoFeeTierForProvider,\n\tisFeeTier,\n\tisProviderAccount,\n\tresolveFee,\n\tsetUnsignedFee,\n} from \"./utils.ts\";\n\nexport type CallContractParams = {\n\tcontract: string; // \"address.name\"\n\tfunctionName: string;\n\tfunctionArgs?: ClarityValue[];\n\tfee?: FeeParam;\n\tnonce?: IntegerType;\n\tpostConditionMode?: PostConditionMode;\n\tpostConditions?: PostConditionInput[];\n};\n\n/** Build, sign, and broadcast a contract call */\nexport async function callContract(\n\tclient: Client,\n\tparams: CallContractParams,\n): Promise<string> {\n\tconst account = client.account;\n\tif (!account) throw new Error(\"Account required\");\n\n\t// Validate the contract id up front so both the provider and local paths\n\t// reject malformed input instead of forwarding it to the wallet.\n\tconst [contractAddress, contractName] = parseContractId(params.contract);\n\n\t// Provider: delegate to wallet\n\tif (isProviderAccount(account)) {\n\t\tassertNoFeeTierForProvider(params.fee);\n\t\tconst result = await account.provider.request(\"stx_callContract\", {\n\t\t\tcontract: params.contract,\n\t\t\tfunctionName: params.functionName,\n\t\t\tfunctionArgs: params.functionArgs ?? [],\n\t\t});\n\t\treturn result.txid;\n\t}\n\n\t// Local/Custom: build → sign → broadcast\n\tconst nonce = params.nonce ?? (await resolveNonce(client, account.address));\n\n\tconst needsFeeResolution = params.fee === undefined || isFeeTier(params.fee);\n\n\tconst unsigned = buildContractCall({\n\t\tcontractAddress,\n\t\tcontractName,\n\t\tfunctionName: params.functionName,\n\t\tfunctionArgs: params.functionArgs ?? [],\n\t\tfee: needsFeeResolution ? 0n : (params.fee as IntegerType),\n\t\tnonce,\n\t\tpublicKey: account.publicKey,\n\t\tchain: client.chain,\n\t\tpostConditionMode: params.postConditionMode,\n\t\tpostConditions: params.postConditions,\n\t});\n\n\tif (needsFeeResolution) {\n\t\tsetUnsignedFee(unsigned, await resolveFee(client, unsigned, params.fee));\n\t}\n\n\tconst signed = await signTransactionWithAccount(unsigned, account);\n\treturn broadcastWithNonceReset(client, {\n\t\ttransaction: signed,\n\t\taddress: account.address,\n\t});\n}\n"
|
|
17
|
-
],
|
|
18
|
-
"mappings": "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",
|
|
19
|
-
"debugId": "B1D5C24E13F4B8DE64756E2164756E21",
|
|
20
|
-
"names": []
|
|
21
|
-
}
|