@secondlayer/stacks 6.1.0 → 6.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/dist/shared/stacks-esm-0pc6tmf0.js +50 -0
  2. package/dist/shared/{stacks-esm-743jfh10.js.map → stacks-esm-0pc6tmf0.js.map} +2 -2
  3. package/dist/shared/{stacks-esm-0rdxcta7.js → stacks-esm-16d82wyc.js} +10 -10
  4. package/dist/shared/{stacks-esm-0rdxcta7.js.map → stacks-esm-16d82wyc.js.map} +2 -2
  5. package/dist/shared/{stacks-esm-cvhazvhd.js → stacks-esm-7a0ehykf.js} +43 -43
  6. package/dist/shared/{stacks-esm-cvhazvhd.js.map → stacks-esm-7a0ehykf.js.map} +2 -2
  7. package/dist/shared/{stacks-esm-1jae0a3r.js → stacks-esm-7v18h5dk.js} +4 -4
  8. package/dist/shared/{stacks-esm-1jae0a3r.js.map → stacks-esm-7v18h5dk.js.map} +2 -2
  9. package/dist/shared/{stacks-esm-9rnx0zxr.js → stacks-esm-8f5catbf.js} +126 -126
  10. package/dist/shared/{stacks-esm-9rnx0zxr.js.map → stacks-esm-8f5catbf.js.map} +2 -2
  11. package/dist/shared/{stacks-esm-7fpqgtyx.js → stacks-esm-8jt6k8p3.js} +13 -13
  12. package/dist/shared/{stacks-esm-7fpqgtyx.js.map → stacks-esm-8jt6k8p3.js.map} +2 -2
  13. package/dist/shared/{stacks-esm-hr7fpxtj.js → stacks-esm-a20wyky3.js} +92 -92
  14. package/dist/shared/{stacks-esm-hr7fpxtj.js.map → stacks-esm-a20wyky3.js.map} +2 -2
  15. package/dist/shared/{stacks-esm-3pv5avgr.js → stacks-esm-b54n1jdx.js} +54 -54
  16. package/dist/shared/{stacks-esm-3pv5avgr.js.map → stacks-esm-b54n1jdx.js.map} +2 -2
  17. package/dist/shared/{stacks-esm-r9q4wnyw.js → stacks-esm-cmtj5vky.js} +162 -162
  18. package/dist/shared/{stacks-esm-r9q4wnyw.js.map → stacks-esm-cmtj5vky.js.map} +2 -2
  19. package/dist/shared/{stacks-esm-wv67m4g6.js → stacks-esm-e2qhfgke.js} +36 -36
  20. package/dist/shared/{stacks-esm-wv67m4g6.js.map → stacks-esm-e2qhfgke.js.map} +2 -2
  21. package/dist/shared/{stacks-esm-qk0p9fr6.js → stacks-esm-ea4m4bk7.js} +117 -117
  22. package/dist/shared/{stacks-esm-qk0p9fr6.js.map → stacks-esm-ea4m4bk7.js.map} +2 -2
  23. package/dist/shared/{stacks-esm-fcfdn2zx.js → stacks-esm-hkw1kvd4.js} +140 -140
  24. package/dist/shared/{stacks-esm-fcfdn2zx.js.map → stacks-esm-hkw1kvd4.js.map} +2 -2
  25. package/dist/shared/{stacks-esm-qkj67g80.js → stacks-esm-k108pemv.js} +4 -4
  26. package/dist/shared/{stacks-esm-qkj67g80.js.map → stacks-esm-k108pemv.js.map} +2 -2
  27. package/dist/shared/stacks-esm-kbz5s6v8.js +84 -0
  28. package/dist/shared/{stacks-esm-2mc7ebrm.js.map → stacks-esm-kbz5s6v8.js.map} +2 -2
  29. package/dist/shared/{stacks-esm-n53kvwmt.js → stacks-esm-mt1thm7k.js} +9 -9
  30. package/dist/shared/{stacks-esm-n53kvwmt.js.map → stacks-esm-mt1thm7k.js.map} +2 -2
  31. package/dist/shared/{stacks-esm-v45990hx.js → stacks-esm-n1mekwnb.js} +9 -9
  32. package/dist/shared/{stacks-esm-v45990hx.js.map → stacks-esm-n1mekwnb.js.map} +2 -2
  33. package/dist/shared/{stacks-esm-r6dejrgr.js → stacks-esm-nt5hf8ht.js} +34 -34
  34. package/dist/shared/{stacks-esm-r6dejrgr.js.map → stacks-esm-nt5hf8ht.js.map} +2 -2
  35. package/dist/shared/{stacks-esm-skmcf5n2.js → stacks-esm-phgy8yqf.js} +210 -210
  36. package/dist/shared/{stacks-esm-skmcf5n2.js.map → stacks-esm-phgy8yqf.js.map} +2 -2
  37. package/dist/shared/{stacks-esm-kds4n82p.js → stacks-esm-pxv6ny92.js} +116 -116
  38. package/dist/shared/{stacks-esm-kds4n82p.js.map → stacks-esm-pxv6ny92.js.map} +2 -2
  39. package/dist/shared/{stacks-esm-3g33bqsm.js → stacks-esm-qfzxhdqz.js} +19 -19
  40. package/dist/shared/{stacks-esm-3g33bqsm.js.map → stacks-esm-qfzxhdqz.js.map} +2 -2
  41. package/dist/shared/{stacks-esm-aw2mj3sj.js → stacks-esm-snj9s2q8.js} +43 -43
  42. package/dist/shared/{stacks-esm-aw2mj3sj.js.map → stacks-esm-snj9s2q8.js.map} +2 -2
  43. package/dist/shared/{stacks-esm-q19a17fd.js → stacks-esm-ss9ap75h.js} +28 -28
  44. package/dist/shared/{stacks-esm-q19a17fd.js.map → stacks-esm-ss9ap75h.js.map} +2 -2
  45. package/dist/shared/{stacks-esm-x1r01353.js → stacks-esm-t88hc019.js} +18 -18
  46. package/dist/shared/{stacks-esm-x1r01353.js.map → stacks-esm-t88hc019.js.map} +2 -2
  47. package/dist/shared/stacks-esm-tdrdye4y.js +48 -0
  48. package/dist/shared/{stacks-esm-pxhfqfff.js.map → stacks-esm-tdrdye4y.js.map} +2 -2
  49. package/dist/src/accounts/index.cjs +15 -13
  50. package/dist/src/accounts/index.cjs.map +2 -2
  51. package/dist/src/accounts/index.d.cts +1 -1
  52. package/dist/src/accounts/index.d.ts +1 -1
  53. package/dist/src/accounts/index.js +26 -26
  54. package/dist/src/accounts/index.js.map +2 -2
  55. package/dist/src/actions/index.cjs +83 -81
  56. package/dist/src/actions/index.cjs.map +2 -2
  57. package/dist/src/actions/index.d.cts +1 -1
  58. package/dist/src/actions/index.d.ts +1 -1
  59. package/dist/src/actions/index.js +102 -103
  60. package/dist/src/actions/index.js.map +1 -1
  61. package/dist/src/bitcoin/index.cjs +2035 -2036
  62. package/dist/src/bitcoin/index.cjs.map +8 -8
  63. package/dist/src/bitcoin/index.d.cts +92 -92
  64. package/dist/src/bitcoin/index.d.ts +92 -92
  65. package/dist/src/bitcoin/index.js +88 -90
  66. package/dist/src/bitcoin/index.js.map +2 -2
  67. package/dist/src/bns/index.cjs +3313 -3310
  68. package/dist/src/bns/index.cjs.map +13 -13
  69. package/dist/src/bns/index.d.cts +1 -1
  70. package/dist/src/bns/index.d.ts +1 -1
  71. package/dist/src/bns/index.js +39 -41
  72. package/dist/src/bns/index.js.map +2 -2
  73. package/dist/src/chains/index.cjs +14 -12
  74. package/dist/src/chains/index.cjs.map +2 -2
  75. package/dist/src/chains/index.d.cts +1 -1
  76. package/dist/src/chains/index.d.ts +1 -1
  77. package/dist/src/chains/index.js +12 -12
  78. package/dist/src/chains/index.js.map +1 -1
  79. package/dist/src/clarity/index.cjs +98 -96
  80. package/dist/src/clarity/index.cjs.map +2 -2
  81. package/dist/src/clarity/index.d.cts +1 -1
  82. package/dist/src/clarity/index.d.ts +1 -1
  83. package/dist/src/clarity/index.js +170 -171
  84. package/dist/src/clarity/index.js.map +1 -1
  85. package/dist/src/connect/index.cjs +27 -20
  86. package/dist/src/connect/index.cjs.map +3 -3
  87. package/dist/src/connect/index.d.cts +1 -1
  88. package/dist/src/connect/index.d.ts +1 -1
  89. package/dist/src/connect/index.js +27 -20
  90. package/dist/src/connect/index.js.map +3 -3
  91. package/dist/src/connect/walletconnect/index.cjs +6 -46
  92. package/dist/src/connect/walletconnect/index.cjs.map +3 -4
  93. package/dist/src/connect/walletconnect/index.d.cts +1 -1
  94. package/dist/src/connect/walletconnect/index.d.ts +1 -1
  95. package/dist/src/connect/walletconnect/index.js +6 -46
  96. package/dist/src/connect/walletconnect/index.js.map +3 -4
  97. package/dist/src/filters/index.cjs +22 -20
  98. package/dist/src/filters/index.cjs.map +2 -2
  99. package/dist/src/filters/index.d.cts +1 -1
  100. package/dist/src/filters/index.d.ts +1 -1
  101. package/dist/src/filters/index.js +30 -30
  102. package/dist/src/filters/index.js.map +1 -1
  103. package/dist/src/index.cjs +1411 -1410
  104. package/dist/src/index.cjs.map +11 -11
  105. package/dist/src/index.d.cts +724 -724
  106. package/dist/src/index.d.ts +724 -724
  107. package/dist/src/index.js +219 -219
  108. package/dist/src/index.js.map +2 -2
  109. package/dist/src/postconditions/index.cjs +26 -24
  110. package/dist/src/postconditions/index.cjs.map +2 -2
  111. package/dist/src/postconditions/index.d.cts +1 -1
  112. package/dist/src/postconditions/index.d.ts +1 -1
  113. package/dist/src/postconditions/index.js +16 -17
  114. package/dist/src/postconditions/index.js.map +1 -1
  115. package/dist/src/pox/index.cjs +722 -721
  116. package/dist/src/pox/index.cjs.map +9 -9
  117. package/dist/src/pox/index.d.cts +1 -1
  118. package/dist/src/pox/index.d.ts +1 -1
  119. package/dist/src/pox/index.js +40 -41
  120. package/dist/src/pox/index.js.map +2 -2
  121. package/dist/src/pox5/index.cjs +141 -137
  122. package/dist/src/pox5/index.cjs.map +3 -3
  123. package/dist/src/pox5/index.d.cts +9 -1
  124. package/dist/src/pox5/index.d.ts +9 -1
  125. package/dist/src/pox5/index.js +210 -209
  126. package/dist/src/pox5/index.js.map +3 -3
  127. package/dist/src/sbtc/index.cjs +71 -69
  128. package/dist/src/sbtc/index.cjs.map +2 -2
  129. package/dist/src/sbtc/index.d.cts +1 -1
  130. package/dist/src/sbtc/index.d.ts +1 -1
  131. package/dist/src/sbtc/index.js +39 -40
  132. package/dist/src/sbtc/index.js.map +2 -2
  133. package/dist/src/simnet/index.cjs +16 -16
  134. package/dist/src/simnet/index.cjs.map +2 -2
  135. package/dist/src/simnet/index.d.cts +1 -1
  136. package/dist/src/simnet/index.d.ts +1 -1
  137. package/dist/src/simnet/index.js +16 -16
  138. package/dist/src/simnet/index.js.map +2 -2
  139. package/dist/src/stackingdao/index.cjs +716 -715
  140. package/dist/src/stackingdao/index.cjs.map +9 -9
  141. package/dist/src/stackingdao/index.d.cts +1 -1
  142. package/dist/src/stackingdao/index.d.ts +1 -1
  143. package/dist/src/stackingdao/index.js +26 -27
  144. package/dist/src/stackingdao/index.js.map +2 -2
  145. package/dist/src/subscriptions/index.cjs +15 -13
  146. package/dist/src/subscriptions/index.cjs.map +2 -2
  147. package/dist/src/subscriptions/index.d.cts +1 -1
  148. package/dist/src/subscriptions/index.d.ts +1 -1
  149. package/dist/src/subscriptions/index.js +14 -15
  150. package/dist/src/subscriptions/index.js.map +1 -1
  151. package/dist/src/transactions/index.cjs +79 -77
  152. package/dist/src/transactions/index.cjs.map +2 -2
  153. package/dist/src/transactions/index.d.cts +1 -1
  154. package/dist/src/transactions/index.d.ts +1 -1
  155. package/dist/src/transactions/index.js +104 -105
  156. package/dist/src/transactions/index.js.map +1 -1
  157. package/dist/src/utils/index.cjs +76 -74
  158. package/dist/src/utils/index.cjs.map +2 -2
  159. package/dist/src/utils/index.d.cts +1 -1
  160. package/dist/src/utils/index.d.ts +1 -1
  161. package/dist/src/utils/index.js +131 -131
  162. package/dist/src/utils/index.js.map +2 -2
  163. package/package.json +1 -1
  164. package/dist/shared/stacks-esm-2mc7ebrm.js +0 -84
  165. package/dist/shared/stacks-esm-743jfh10.js +0 -50
  166. package/dist/shared/stacks-esm-pxhfqfff.js +0 -48
@@ -19,13 +19,15 @@ var __toESM = (mod, isNodeMode, target) => {
19
19
  return cached;
20
20
  }
21
21
  target = mod != null ? __create(__getProtoOf(mod)) : {};
22
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
23
- for (let key of __getOwnPropNames(mod))
24
- if (!__hasOwnProp.call(to, key))
25
- __defProp(to, key, {
26
- get: __accessProp.bind(mod, key),
27
- enumerable: true
28
- });
22
+ const to = isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
23
+ if (mod && typeof mod === "object" || typeof mod === "function") {
24
+ for (let key of __getOwnPropNames(mod))
25
+ if (!__hasOwnProp.call(to, key))
26
+ __defProp(to, key, {
27
+ get: __accessProp.bind(mod, key),
28
+ enumerable: true
29
+ });
30
+ }
29
31
  if (canCache)
30
32
  cache.set(mod, to);
31
33
  return to;
@@ -61,78 +63,156 @@ var __export = (target, all) => {
61
63
  });
62
64
  };
63
65
 
64
- // src/filters/index.ts
65
- var exports_filters = {};
66
- __export(exports_filters, {
66
+ // src/index.ts
67
+ var exports_src = {};
68
+ __export(exports_src, {
69
+ AddressVersion: () => AddressVersion,
70
+ BaseError: () => BaseError,
71
+ BroadcastError: () => BroadcastError,
72
+ HttpRequestError: () => HttpRequestError,
73
+ IndexSourceConfigError: () => IndexSourceConfigError,
74
+ MICROSTX_PER_STX: () => MICROSTX_PER_STX,
75
+ MalformedResponseError: () => MalformedResponseError,
76
+ ReadContractError: () => ReadContractError,
77
+ SerializationError: () => SerializationError,
78
+ SigningError: () => SigningError,
79
+ SimulationError: () => SimulationError,
80
+ TESTNET_ZERO_ADDRESS: () => TESTNET_ZERO_ADDRESS,
81
+ TimeoutError: () => TimeoutError,
82
+ TransactionAbortedError: () => TransactionAbortedError,
83
+ TransactionDroppedError: () => TransactionDroppedError,
84
+ TransactionError: () => TransactionError,
85
+ WaitForTransactionTimeoutError: () => WaitForTransactionTimeoutError,
86
+ WebSocketError: () => WebSocketError,
87
+ ZERO_ADDRESS: () => ZERO_ADDRESS,
88
+ broadcastWithNonceReset: () => broadcastWithNonceReset,
89
+ createClient: () => createClient,
90
+ createMultiSigClient: () => createMultiSigClient,
91
+ createNonceManager: () => createNonceManager,
92
+ createPublicClient: () => createPublicClient,
93
+ createWalletClient: () => createWalletClient,
94
+ custom: () => custom,
95
+ defineChain: () => defineChain,
96
+ devnet: () => devnet,
97
+ extendedApiSource: () => extendedApiSource,
98
+ fallback: () => fallback,
99
+ formatStx: () => formatStx,
100
+ getContractAddress: () => getContractAddress,
101
+ getTransaction: () => getTransaction,
102
+ hiroNonceSource: () => hiroNonceSource,
103
+ http: () => http,
104
+ indexSource: () => indexSource,
105
+ indexTxSource: () => indexTxSource,
106
+ isAddressEqual: () => isAddressEqual,
107
+ isNonceConflictError: () => isNonceConflictError,
108
+ isValidAddress: () => isValidAddress,
109
+ jsonRpcSource: () => jsonRpcSource,
110
+ mainnet: () => mainnet,
111
+ memoryStore: () => memoryStore,
112
+ mempoolAwareSource: () => mempoolAwareSource,
113
+ mocknet: () => mocknet,
114
+ multisigActions: () => multisigActions,
115
+ nextFreeNonce: () => nextFreeNonce,
67
116
  on: () => on,
68
- makeChainEventFilter: () => makeChainEventFilter,
69
- isPrincipal: () => isPrincipal,
70
- hasWildcard: () => hasWildcard,
71
- fromSubgraphSource: () => fromSubgraphSource,
72
- assetId: () => assetId,
73
- assertPrincipalish: () => assertPrincipalish,
74
- assertContractId: () => assertContractId,
75
- assertAssetIdentifier: () => assertAssetIdentifier,
76
- VM_NODE_TO_STORED_TYPE: () => VM_NODE_TO_STORED_TYPE,
77
- VM_EVENT_TYPES: () => VM_EVENT_TYPES,
78
- DECODED_EVENT_TYPES: () => DECODED_EVENT_TYPES,
79
- CHAIN_EVENT_FILTER_TYPES: () => CHAIN_EVENT_FILTER_TYPES
117
+ parseStx: () => parseStx,
118
+ postgresStore: () => postgresStore,
119
+ providerToAccount: () => providerToAccount,
120
+ publicActions: () => publicActions,
121
+ reconcileNonce: () => reconcileNonce,
122
+ redisStore: () => redisStore,
123
+ resolveNonce: () => resolveNonce,
124
+ startNonceReconciler: () => startNonceReconciler,
125
+ testnet: () => testnet,
126
+ waitForTransactionReceipt: () => waitForTransactionReceipt,
127
+ walletActions: () => walletActions,
128
+ webSocket: () => webSocket
80
129
  });
81
- module.exports = __toCommonJS(exports_filters);
130
+ module.exports = __toCommonJS(exports_src);
131
+
132
+ // src/clients/createClient.ts
133
+ var BASE_KEYS = new Set([
134
+ "chain",
135
+ "account",
136
+ "transport",
137
+ "request",
138
+ "nonceManager",
139
+ "extend"
140
+ ]);
141
+ function bindExtend(base) {
142
+ return (fn) => {
143
+ const extensions = fn(base);
144
+ const next = { ...base };
145
+ for (const [key, value] of Object.entries(extensions)) {
146
+ if (BASE_KEYS.has(key))
147
+ continue;
148
+ next[key] = value;
149
+ }
150
+ next.extend = bindExtend(next);
151
+ return next;
152
+ };
153
+ }
154
+ function createClient(config) {
155
+ const transport = config.transport({ chain: config.chain });
156
+ const client = {
157
+ chain: config.chain,
158
+ account: config.account,
159
+ transport,
160
+ request: transport.request,
161
+ nonceManager: config.nonceManager,
162
+ extend: null
163
+ };
164
+ client.extend = bindExtend(client);
165
+ return client;
166
+ }
167
+ // src/errors/base.ts
168
+ function codeFromName(name) {
169
+ return name.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").toUpperCase();
170
+ }
171
+
172
+ class BaseError extends Error {
173
+ name = "StacksError";
174
+ #code;
175
+ shortMessage;
176
+ details;
177
+ constructor(shortMessage, options) {
178
+ const message = [
179
+ shortMessage,
180
+ options?.details ? `
181
+ ${options.details}` : ""
182
+ ].join("");
183
+ super(message, { cause: options?.cause });
184
+ if (options?.code !== undefined)
185
+ this.#code = options.code;
186
+ this.shortMessage = shortMessage;
187
+ this.details = options?.details;
188
+ }
189
+ get code() {
190
+ return this.#code ?? codeFromName(this.name);
191
+ }
192
+ set code(value) {
193
+ this.#code = value;
194
+ }
195
+ toJSON() {
196
+ return {
197
+ name: this.name,
198
+ code: this.code,
199
+ message: this.message,
200
+ shortMessage: this.shortMessage,
201
+ details: this.details,
202
+ cause: this.cause instanceof Error ? this.cause.message : undefined
203
+ };
204
+ }
205
+ }
206
+
207
+ // src/errors/response.ts
208
+ class MalformedResponseError extends BaseError {
209
+ name = "MalformedResponseError";
210
+ }
211
+
212
+ class ReadContractError extends BaseError {
213
+ name = "ReadContractError";
214
+ }
82
215
 
83
- // src/filters/event-types.ts
84
- var DECODED_EVENT_TYPES = [
85
- "stx_transfer",
86
- "stx_mint",
87
- "stx_burn",
88
- "stx_lock",
89
- "ft_transfer",
90
- "ft_mint",
91
- "ft_burn",
92
- "nft_transfer",
93
- "nft_mint",
94
- "nft_burn",
95
- "print"
96
- ];
97
- var VM_EVENT_TYPES = [
98
- "nested_contract_call",
99
- "var_set",
100
- "map_set",
101
- "map_insert",
102
- "map_delete"
103
- ];
104
- var VM_NODE_TO_STORED_TYPE = {
105
- contract_call_event: "nested_contract_call",
106
- var_set_event: "var_set",
107
- map_set_event: "map_set",
108
- map_insert_event: "map_insert",
109
- map_delete_event: "map_delete"
110
- };
111
- var CHAIN_EVENT_FILTER_TYPES = [
112
- "stx_transfer",
113
- "stx_mint",
114
- "stx_burn",
115
- "stx_lock",
116
- "ft_transfer",
117
- "ft_mint",
118
- "ft_burn",
119
- "nft_transfer",
120
- "nft_mint",
121
- "nft_burn",
122
- "contract_call",
123
- "contract_deploy",
124
- "print_event",
125
- "nested_contract_call",
126
- "var_set",
127
- "map_set",
128
- "map_insert",
129
- "map_delete",
130
- "sbtc_deposit",
131
- "sbtc_withdrawal_create",
132
- "sbtc_withdrawal_accept",
133
- "sbtc_withdrawal_reject",
134
- "sbtc_withdrawal_swept_confirmed"
135
- ];
136
216
  // src/utils/c32.ts
137
217
  var import_sha2 = require("@noble/hashes/sha2.js");
138
218
 
@@ -380,600 +460,108 @@ function c32addressDecode(c32addr) {
380
460
  return c32checkDecode(c32addr.slice(1));
381
461
  }
382
462
 
383
- // src/utils/constants.ts
384
- var MAX_U128 = (1n << 128n) - 1n;
385
- var MAX_I128 = (1n << 127n) - 1n;
386
- var MIN_I128 = -(1n << 127n);
387
- var AddressVersion = {
388
- MainnetSingleSig: 22,
389
- MainnetMultiSig: 20,
390
- TestnetSingleSig: 26,
391
- TestnetMultiSig: 21
463
+ // src/clarity/types.ts
464
+ var ClarityWireType = {
465
+ int: 0,
466
+ uint: 1,
467
+ buffer: 2,
468
+ true: 3,
469
+ false: 4,
470
+ address: 5,
471
+ contract: 6,
472
+ ok: 7,
473
+ err: 8,
474
+ none: 9,
475
+ some: 10,
476
+ list: 11,
477
+ tuple: 12,
478
+ ascii: 13,
479
+ utf8: 14
392
480
  };
393
- var ZERO_ADDRESS = "SP000000000000000000002Q6VF78";
394
- var TESTNET_ZERO_ADDRESS = "ST000000000000000000002AMW42H";
395
- var MICROSTX_PER_STX = 1000000n;
481
+ var wireTypeToClarity = Object.fromEntries(Object.entries(ClarityWireType).map(([k, v]) => [v, k]));
482
+ function clarityTypeFromByte(byte) {
483
+ const type = wireTypeToClarity[byte];
484
+ if (!type)
485
+ throw new Error(`Unknown clarity wire type: ${byte}`);
486
+ return type;
487
+ }
396
488
 
397
- // src/utils/hash.ts
398
- var import_legacy = require("@noble/hashes/legacy.js");
399
- var import_sha22 = require("@noble/hashes/sha2.js");
400
- var import_sha23 = require("@noble/hashes/sha2.js");
401
- function hash160(input) {
402
- return import_legacy.ripemd160(import_sha22.sha256(input));
403
- }
404
- function txidFromBytes(data) {
405
- return bytesToHex(import_sha23.sha512_256(data));
406
- }
407
- function hashP2PKH(input) {
408
- return bytesToHex(hash160(input));
409
- }
410
-
411
- // src/utils/address.ts
412
- function publicKeyToAddress(publicKey, network = "mainnet") {
413
- const bytes = typeof publicKey === "string" ? hexToBytes(without0x(publicKey)) : publicKey;
414
- const version = network === "mainnet" ? AddressVersion.MainnetSingleSig : AddressVersion.TestnetSingleSig;
415
- return c32address(version, bytesToHex(hash160(bytes)));
416
- }
417
- var CONTRACT_NAME_REGEX = /^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/;
418
- function validateStacksAddress(address) {
419
- try {
420
- c32addressDecode(address);
421
- return true;
422
- } catch {
423
- return false;
424
- }
425
- }
426
- var isValidAddress = validateStacksAddress;
427
- function parsePrincipal(value) {
428
- const parts = value.split(".");
429
- if (parts.length > 2)
430
- return null;
431
- const [address, contractName] = parts;
432
- if (!validateStacksAddress(address))
433
- return null;
434
- if (contractName === undefined)
435
- return { address };
436
- if (!CONTRACT_NAME_REGEX.test(contractName))
437
- return null;
438
- return { address, contractName };
439
- }
440
- function parseContractId(contractId) {
441
- const parsed = parsePrincipal(contractId);
442
- if (!parsed?.contractName)
443
- throw new Error(`Invalid contract identifier: ${contractId}`);
444
- return [parsed.address, parsed.contractName];
445
- }
446
- function isClarityName(name) {
447
- const regex = /^[a-zA-Z]([a-zA-Z0-9]|[-_!?+<>=/*])*$|^[-+=/*]$|^[<>]=?$/;
448
- return regex.test(name) && name.length < 128;
449
- }
450
- function isAddressEqual(a, b) {
451
- const [versionA, hashA] = c32addressDecode(a);
452
- const [versionB, hashB] = c32addressDecode(b);
453
- return versionA === versionB && hashA.toLowerCase() === hashB.toLowerCase();
454
- }
455
- function addressToVersion(address) {
456
- return c32addressDecode(address)[0];
457
- }
458
- function getContractAddress(deployer, contractName) {
459
- if (!validateStacksAddress(deployer)) {
460
- throw new Error(`Invalid deployer address: ${deployer}`);
461
- }
462
- if (!isClarityName(contractName)) {
463
- throw new Error(`Invalid contract name: ${contractName}`);
464
- }
465
- return `${deployer}.${contractName}`;
466
- }
467
-
468
- // src/filters/validate.ts
469
- function assetId(value) {
470
- assertAssetIdentifier("assetIdentifier", value);
471
- return value;
472
- }
473
- function isPrincipal(value) {
474
- return parsePrincipal(value) !== null;
475
- }
476
- function hasWildcard(value) {
477
- return value.includes("*");
478
- }
479
- function assertPrincipalish(field, value) {
480
- if (hasWildcard(value))
481
- return;
482
- if (!isPrincipal(value)) {
483
- throw new Error(`${field} "${value}" is not a valid Stacks principal (SP…/ST…, optionally .contract-name).`);
484
- }
485
- }
486
- function assertAssetIdentifier(field, value) {
487
- if (hasWildcard(value))
488
- return;
489
- const [contractId, assetName, ...rest] = value.split("::");
490
- if (!contractId || !assetName || rest.length > 0 || !contractId.includes(".") || !isPrincipal(contractId)) {
491
- throw new Error(`${field} "${value}" is not a valid asset identifier (SP….contract-name::asset-name). Passing a bare contract id here matches zero rows — use contractId for that.`);
492
- }
493
- }
494
- function assertContractId(field, value) {
495
- if (hasWildcard(value))
496
- return;
497
- if (value.includes("::")) {
498
- throw new Error(`${field} "${value}" is an asset identifier, not a contract id — use assetIdentifier for that.`);
499
- }
500
- if (!value.includes(".") || !isPrincipal(value)) {
501
- throw new Error(`${field} "${value}" is not a valid contract id (SP….contract-name).`);
502
- }
489
+ // src/clarity/serialize.ts
490
+ var CLARITY_INT_SIZE = 128n;
491
+ var CLARITY_INT_BYTE_SIZE = 16;
492
+ function typeIdByte(type) {
493
+ return ClarityWireType[type];
503
494
  }
504
-
505
- // src/filters/factories.ts
506
- var PRINCIPAL_FIELDS = new Set([
507
- "sender",
508
- "recipient",
509
- "caller",
510
- "deployer",
511
- "lockedAddress"
512
- ]);
513
- var AMOUNT_FIELDS = new Set(["minAmount", "maxAmount"]);
514
- var DECORATIVE_FIELDS = new Set(["abi", "prints"]);
515
- function specEntries(spec) {
516
- return Object.entries(spec).filter(([key, value]) => key !== "type" && value !== undefined);
495
+ function withTypeId(type, bytes) {
496
+ return concatBytes(new Uint8Array([typeIdByte(type)]), bytes);
517
497
  }
518
- function validateSpec(spec) {
519
- for (const [key, value] of specEntries(spec)) {
520
- if (PRINCIPAL_FIELDS.has(key)) {
521
- assertPrincipalish(key, value);
522
- } else if (key === "assetIdentifier") {
523
- assertAssetIdentifier(key, value);
524
- } else if (key === "contractId") {
525
- for (const id of Array.isArray(value) ? value : [value]) {
526
- assertContractId(key, id);
527
- }
528
- }
529
- }
498
+ function serializeAddress(c32Address) {
499
+ const [version, hash160] = c32addressDecode(c32Address);
500
+ return concatBytes(new Uint8Array([version]), hexToBytes(hash160));
530
501
  }
531
- function unsupported(surface, field, hint) {
532
- throw new Error(`${field} cannot be expressed on ${surface} — ${hint}. Drop the field from the filter or use the surface that supports it.`);
502
+ function serializeLPString(str, prefixBytes = 1) {
503
+ const content = utf8ToBytes(str);
504
+ const lengthPrefix = hexToBytes(intToHex(content.byteLength, prefixBytes));
505
+ return concatBytes(lengthPrefix, content);
533
506
  }
534
- function assertNoWildcards(surface, spec) {
535
- for (const [key, value] of specEntries(spec)) {
536
- const candidates = Array.isArray(value) ? value : [value];
537
- for (const candidate of candidates) {
538
- if (typeof candidate === "string" && hasWildcard(candidate)) {
539
- unsupported(surface, `${key} wildcard "${candidate}"`, "wildcard patterns are Webhooks/Subgraphs-only");
540
- }
507
+ function serializeCVBytes(value) {
508
+ switch (value.type) {
509
+ case "true":
510
+ case "false":
511
+ return new Uint8Array([typeIdByte(value.type)]);
512
+ case "int": {
513
+ const bytes = bigIntToBytes(toTwos(BigInt(value.value), CLARITY_INT_SIZE), CLARITY_INT_BYTE_SIZE);
514
+ return withTypeId(value.type, bytes);
541
515
  }
542
- }
543
- }
544
- function assertNotTraitAndContract(surface, spec) {
545
- const trait = "trait" in spec ? spec.trait : undefined;
546
- const contract = "contractId" in spec ? spec.contractId : undefined;
547
- if (trait !== undefined && contract !== undefined) {
548
- unsupported(surface, "trait with contractId", "the Index treats them as mutually exclusive — drop one, or use a subgraph source, which ANDs the pair");
549
- }
550
- }
551
- function toChainTrigger(spec) {
552
- const out = {};
553
- for (const [key, value] of specEntries(spec)) {
554
- if (DECORATIVE_FIELDS.has(key))
555
- continue;
556
- if (key === "factory") {
557
- unsupported("Webhooks", "factory", "dynamic factory discovery is a Subgraphs-only concept — a trigger targets addresses known when it is created");
516
+ case "uint": {
517
+ const bytes = bigIntToBytes(BigInt(value.value), CLARITY_INT_BYTE_SIZE);
518
+ return withTypeId(value.type, bytes);
558
519
  }
559
- if (Array.isArray(value)) {
560
- unsupported("Webhooks", `${key} set`, "a chain trigger targets ONE contract — create one subscription per contract, or use Index/Subgraphs which accept the set");
520
+ case "buffer": {
521
+ const bufBytes = hexToBytes(value.value);
522
+ return withTypeId(value.type, concatBytes(writeUInt32BE(bufBytes.length), bufBytes));
561
523
  }
562
- out[key] = typeof value === "bigint" ? value.toString() : value;
563
- }
564
- return { type: spec.type, ...out };
565
- }
566
- function toIndexParams(spec, extra = {}) {
567
- assertNoWildcards("Index events", spec);
568
- assertNotTraitAndContract("Index events", spec);
569
- const out = {
570
- eventType: spec.type === "print_event" ? "print" : spec.type
571
- };
572
- for (const [key, value] of specEntries(spec)) {
573
- if (DECORATIVE_FIELDS.has(key))
574
- continue;
575
- if (key === "factory") {
576
- unsupported("Index events", "factory", "dynamic factory discovery is a Subgraphs-only concept");
524
+ case "none":
525
+ return new Uint8Array([typeIdByte(value.type)]);
526
+ case "some":
527
+ return withTypeId(value.type, serializeCVBytes(value.value));
528
+ case "ok":
529
+ case "err":
530
+ return withTypeId(value.type, serializeCVBytes(value.value));
531
+ case "address":
532
+ return withTypeId(value.type, serializeAddress(value.value));
533
+ case "contract": {
534
+ const [addr, name] = value.value.split(".");
535
+ if (!addr || !name)
536
+ throw new Error(`Invalid contract principal: ${value.value}`);
537
+ return withTypeId(value.type, concatBytes(serializeAddress(addr), serializeLPString(name)));
577
538
  }
578
- if (AMOUNT_FIELDS.has(key)) {
579
- unsupported("Index events", key, "amount predicates are Webhooks/Subgraphs-only; filter client-side on the decoded rows");
539
+ case "list": {
540
+ const parts = [writeUInt32BE(value.value.length)];
541
+ for (const item of value.value) {
542
+ parts.push(serializeCVBytes(item));
543
+ }
544
+ return withTypeId(value.type, concatBytes(...parts));
580
545
  }
581
- if (key === "topic") {
582
- unsupported("Index events", "topic", "per-topic reads are Subgraphs/Webhooks-only (or read the contract's print feed and switch on topic)");
546
+ case "tuple": {
547
+ const keys = Object.keys(value.value).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
548
+ const parts = [writeUInt32BE(keys.length)];
549
+ for (const key of keys) {
550
+ parts.push(serializeLPString(key));
551
+ parts.push(serializeCVBytes(value.value[key]));
552
+ }
553
+ return withTypeId(value.type, concatBytes(...parts));
583
554
  }
584
- if (key === "lockedAddress") {
585
- out.sender = value;
586
- continue;
555
+ case "ascii": {
556
+ const strBytes = asciiToBytes(value.value);
557
+ return withTypeId(value.type, concatBytes(writeUInt32BE(strBytes.length), strBytes));
587
558
  }
588
- if (key === "caller" && spec.type !== "nested_contract_call") {
589
- unsupported("Index events", "caller", "outer contract-call fields live on index.contractCalls");
559
+ case "utf8": {
560
+ const strBytes = utf8ToBytes(value.value);
561
+ return withTypeId(value.type, concatBytes(writeUInt32BE(strBytes.length), strBytes));
590
562
  }
591
- out[key] = value;
592
- }
593
- return { ...out, ...extra };
594
- }
595
- var VM_MEMBERS = new Set([
596
- "nested_contract_call",
597
- "var_set",
598
- "map_set",
599
- "map_insert",
600
- "map_delete"
601
- ]);
602
- var VM_INDEX_ONLY_FIELDS = new Set([
603
- "functionName",
604
- "caller",
605
- "sender",
606
- "map",
607
- "varName"
608
- ]);
609
- function toStreamsParams(spec, extra = {}) {
610
- assertNoWildcards("Streams", spec);
611
- const out = {
612
- types: [spec.type === "print_event" ? "print" : spec.type]
613
- };
614
- const isVm = VM_MEMBERS.has(spec.type);
615
- if (isVm)
616
- out.clock = "vm";
617
- for (const [key, value] of specEntries(spec)) {
618
- if (DECORATIVE_FIELDS.has(key))
619
- continue;
620
- if (isVm && VM_INDEX_ONLY_FIELDS.has(key)) {
621
- unsupported("Streams", key, "vm payload predicates are Index/Subgraphs/Subscriptions-only; Streams clock=vm narrows by types and contractId");
622
- }
623
- if (key === "factory") {
624
- unsupported("Streams", "factory", "dynamic factory discovery is a Subgraphs-only concept");
625
- }
626
- if (AMOUNT_FIELDS.has(key)) {
627
- unsupported("Streams", key, "amount predicates are Webhooks/Subgraphs-only");
628
- }
629
- if (key === "trait") {
630
- unsupported("Streams", "trait", "Streams has no trait resolution — Index and Subgraphs do");
631
- }
632
- if (key === "topic") {
633
- unsupported("Streams", "topic", "per-topic filtering is Subgraphs/Webhooks-only");
634
- }
635
- if (key === "lockedAddress") {
636
- unsupported("Streams", "lockedAddress", "stx_lock address filtering is Webhooks/Subgraphs-only");
637
- }
638
- out[key] = value;
639
- }
640
- return { ...out, ...extra };
641
- }
642
- function toContractCallsParams(spec, extra = {}) {
643
- assertNoWildcards("Index contract-calls", spec);
644
- assertNotTraitAndContract("Index contract-calls", spec);
645
- const out = {};
646
- for (const [key, value] of specEntries(spec)) {
647
- if (DECORATIVE_FIELDS.has(key))
648
- continue;
649
- if (key === "factory") {
650
- unsupported("Index contract-calls", "factory", "dynamic factory discovery is a Subgraphs-only concept");
651
- }
652
- if (key === "caller") {
653
- out.sender = value;
654
- continue;
655
- }
656
- out[key] = value;
657
- }
658
- return { ...out, ...extra };
659
- }
660
- function toSubgraphSource(spec) {
661
- return Object.fromEntries([
662
- ["type", spec.type],
663
- ...specEntries(spec)
664
- ]);
665
- }
666
- var DECODED_MEMBERS = new Set([
667
- "stx_transfer",
668
- "stx_mint",
669
- "stx_burn",
670
- "stx_lock",
671
- "ft_transfer",
672
- "ft_mint",
673
- "ft_burn",
674
- "nft_transfer",
675
- "nft_mint",
676
- "nft_burn",
677
- "print_event"
678
- ]);
679
- function makeChainEventFilter(type, fields) {
680
- const spec = { type, ...fields };
681
- validateSpec(spec);
682
- const filter = { ...spec };
683
- filter.toChainTrigger = () => toChainTrigger(spec);
684
- if (DECODED_MEMBERS.has(type) || VM_MEMBERS.has(type)) {
685
- filter.toIndexParams = (extra) => toIndexParams(spec, extra);
686
- filter.toStreamsParams = (extra) => toStreamsParams(spec, extra);
687
- }
688
- if (type === "contract_call") {
689
- filter.toContractCallsParams = (extra) => toContractCallsParams(spec, extra);
690
- }
691
- if (!type.startsWith("sbtc_")) {
692
- filter.toSubgraphSource = () => toSubgraphSource(spec);
693
- }
694
- return filter;
695
- }
696
- function fromSubgraphSource(source) {
697
- const { type, ...fields } = source;
698
- return makeChainEventFilter(type, fields);
699
- }
700
- var on = {
701
- stxTransfer: (fields = {}) => makeChainEventFilter("stx_transfer", fields),
702
- stxMint: (fields = {}) => makeChainEventFilter("stx_mint", fields),
703
- stxBurn: (fields = {}) => makeChainEventFilter("stx_burn", fields),
704
- stxLock: (fields = {}) => makeChainEventFilter("stx_lock", fields),
705
- ftTransfer: (fields = {}) => makeChainEventFilter("ft_transfer", fields),
706
- ftMint: (fields = {}) => makeChainEventFilter("ft_mint", fields),
707
- ftBurn: (fields = {}) => makeChainEventFilter("ft_burn", fields),
708
- nftTransfer: (fields = {}) => makeChainEventFilter("nft_transfer", fields),
709
- nftMint: (fields = {}) => makeChainEventFilter("nft_mint", fields),
710
- nftBurn: (fields = {}) => makeChainEventFilter("nft_burn", fields),
711
- contractCall: (fields = {}) => makeChainEventFilter("contract_call", fields),
712
- contractDeploy: (fields = {}) => makeChainEventFilter("contract_deploy", fields),
713
- print: (fields = {}) => makeChainEventFilter("print_event", fields),
714
- nestedCall: (fields = {}) => makeChainEventFilter("nested_contract_call", fields),
715
- varSet: (fields = {}) => makeChainEventFilter("var_set", fields),
716
- mapSet: (fields = {}) => makeChainEventFilter("map_set", fields),
717
- mapInsert: (fields = {}) => makeChainEventFilter("map_insert", fields),
718
- mapDelete: (fields = {}) => makeChainEventFilter("map_delete", fields),
719
- sbtcDeposit: (fields = {}) => makeChainEventFilter("sbtc_deposit", fields),
720
- sbtcWithdrawalCreate: (fields = {}) => makeChainEventFilter("sbtc_withdrawal_create", fields),
721
- sbtcWithdrawalAccept: (fields = {}) => makeChainEventFilter("sbtc_withdrawal_accept", fields),
722
- sbtcWithdrawalReject: (fields = {}) => makeChainEventFilter("sbtc_withdrawal_reject", fields),
723
- sbtcWithdrawalSweptConfirmed: (fields = {}) => makeChainEventFilter("sbtc_withdrawal_swept_confirmed", fields)
724
- };
725
- // src/index.ts
726
- var exports_src = {};
727
- __export(exports_src, {
728
- webSocket: () => webSocket,
729
- walletActions: () => walletActions,
730
- waitForTransactionReceipt: () => waitForTransactionReceipt,
731
- testnet: () => testnet,
732
- startNonceReconciler: () => startNonceReconciler,
733
- resolveNonce: () => resolveNonce,
734
- redisStore: () => redisStore,
735
- reconcileNonce: () => reconcileNonce,
736
- publicActions: () => publicActions,
737
- providerToAccount: () => providerToAccount,
738
- postgresStore: () => postgresStore,
739
- parseStx: () => parseStx,
740
- on: () => on,
741
- nextFreeNonce: () => nextFreeNonce,
742
- multisigActions: () => multisigActions,
743
- mocknet: () => mocknet,
744
- mempoolAwareSource: () => mempoolAwareSource,
745
- memoryStore: () => memoryStore,
746
- mainnet: () => mainnet,
747
- jsonRpcSource: () => jsonRpcSource,
748
- isValidAddress: () => isValidAddress,
749
- isNonceConflictError: () => isNonceConflictError,
750
- isAddressEqual: () => isAddressEqual,
751
- indexTxSource: () => indexTxSource,
752
- indexSource: () => indexSource,
753
- http: () => http,
754
- hiroNonceSource: () => hiroNonceSource,
755
- getTransaction: () => getTransaction,
756
- getContractAddress: () => getContractAddress,
757
- formatStx: () => formatStx,
758
- fallback: () => fallback,
759
- extendedApiSource: () => extendedApiSource,
760
- devnet: () => devnet,
761
- defineChain: () => defineChain,
762
- custom: () => custom,
763
- createWalletClient: () => createWalletClient,
764
- createPublicClient: () => createPublicClient,
765
- createNonceManager: () => createNonceManager,
766
- createMultiSigClient: () => createMultiSigClient,
767
- createClient: () => createClient,
768
- broadcastWithNonceReset: () => broadcastWithNonceReset,
769
- ZERO_ADDRESS: () => ZERO_ADDRESS,
770
- WebSocketError: () => WebSocketError,
771
- WaitForTransactionTimeoutError: () => WaitForTransactionTimeoutError,
772
- TransactionError: () => TransactionError,
773
- TransactionDroppedError: () => TransactionDroppedError,
774
- TransactionAbortedError: () => TransactionAbortedError,
775
- TimeoutError: () => TimeoutError,
776
- TESTNET_ZERO_ADDRESS: () => TESTNET_ZERO_ADDRESS,
777
- SimulationError: () => SimulationError,
778
- SigningError: () => SigningError,
779
- SerializationError: () => SerializationError,
780
- ReadContractError: () => ReadContractError,
781
- MalformedResponseError: () => MalformedResponseError,
782
- MICROSTX_PER_STX: () => MICROSTX_PER_STX,
783
- IndexSourceConfigError: () => IndexSourceConfigError,
784
- HttpRequestError: () => HttpRequestError,
785
- BroadcastError: () => BroadcastError,
786
- BaseError: () => BaseError,
787
- AddressVersion: () => AddressVersion
788
- });
789
- module.exports = __toCommonJS(exports_src);
790
-
791
- // src/clients/createClient.ts
792
- var BASE_KEYS = new Set([
793
- "chain",
794
- "account",
795
- "transport",
796
- "request",
797
- "nonceManager",
798
- "extend"
799
- ]);
800
- function bindExtend(base) {
801
- return (fn) => {
802
- const extensions = fn(base);
803
- const next = { ...base };
804
- for (const [key, value] of Object.entries(extensions)) {
805
- if (BASE_KEYS.has(key))
806
- continue;
807
- next[key] = value;
808
- }
809
- next.extend = bindExtend(next);
810
- return next;
811
- };
812
- }
813
- function createClient(config) {
814
- const transport = config.transport({ chain: config.chain });
815
- const client = {
816
- chain: config.chain,
817
- account: config.account,
818
- transport,
819
- request: transport.request,
820
- nonceManager: config.nonceManager,
821
- extend: null
822
- };
823
- client.extend = bindExtend(client);
824
- return client;
825
- }
826
- // src/errors/base.ts
827
- function codeFromName(name) {
828
- return name.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").toUpperCase();
829
- }
830
-
831
- class BaseError extends Error {
832
- name = "StacksError";
833
- #code;
834
- shortMessage;
835
- details;
836
- constructor(shortMessage, options) {
837
- const message = [
838
- shortMessage,
839
- options?.details ? `
840
- ${options.details}` : ""
841
- ].join("");
842
- super(message, { cause: options?.cause });
843
- if (options?.code !== undefined)
844
- this.#code = options.code;
845
- this.shortMessage = shortMessage;
846
- this.details = options?.details;
847
- }
848
- get code() {
849
- return this.#code ?? codeFromName(this.name);
850
- }
851
- set code(value) {
852
- this.#code = value;
853
- }
854
- toJSON() {
855
- return {
856
- name: this.name,
857
- code: this.code,
858
- message: this.message,
859
- shortMessage: this.shortMessage,
860
- details: this.details,
861
- cause: this.cause instanceof Error ? this.cause.message : undefined
862
- };
863
- }
864
- }
865
-
866
- // src/errors/response.ts
867
- class MalformedResponseError extends BaseError {
868
- name = "MalformedResponseError";
869
- }
870
-
871
- class ReadContractError extends BaseError {
872
- name = "ReadContractError";
873
- }
874
-
875
- // src/clarity/types.ts
876
- var ClarityWireType = {
877
- int: 0,
878
- uint: 1,
879
- buffer: 2,
880
- true: 3,
881
- false: 4,
882
- address: 5,
883
- contract: 6,
884
- ok: 7,
885
- err: 8,
886
- none: 9,
887
- some: 10,
888
- list: 11,
889
- tuple: 12,
890
- ascii: 13,
891
- utf8: 14
892
- };
893
- var wireTypeToClarity = Object.fromEntries(Object.entries(ClarityWireType).map(([k, v]) => [v, k]));
894
- function clarityTypeFromByte(byte) {
895
- const type = wireTypeToClarity[byte];
896
- if (!type)
897
- throw new Error(`Unknown clarity wire type: ${byte}`);
898
- return type;
899
- }
900
-
901
- // src/clarity/serialize.ts
902
- var CLARITY_INT_SIZE = 128n;
903
- var CLARITY_INT_BYTE_SIZE = 16;
904
- function typeIdByte(type) {
905
- return ClarityWireType[type];
906
- }
907
- function withTypeId(type, bytes) {
908
- return concatBytes(new Uint8Array([typeIdByte(type)]), bytes);
909
- }
910
- function serializeAddress(c32Address) {
911
- const [version, hash1602] = c32addressDecode(c32Address);
912
- return concatBytes(new Uint8Array([version]), hexToBytes(hash1602));
913
- }
914
- function serializeLPString(str, prefixBytes = 1) {
915
- const content = utf8ToBytes(str);
916
- const lengthPrefix = hexToBytes(intToHex(content.byteLength, prefixBytes));
917
- return concatBytes(lengthPrefix, content);
918
- }
919
- function serializeCVBytes(value) {
920
- switch (value.type) {
921
- case "true":
922
- case "false":
923
- return new Uint8Array([typeIdByte(value.type)]);
924
- case "int": {
925
- const bytes = bigIntToBytes(toTwos(BigInt(value.value), CLARITY_INT_SIZE), CLARITY_INT_BYTE_SIZE);
926
- return withTypeId(value.type, bytes);
927
- }
928
- case "uint": {
929
- const bytes = bigIntToBytes(BigInt(value.value), CLARITY_INT_BYTE_SIZE);
930
- return withTypeId(value.type, bytes);
931
- }
932
- case "buffer": {
933
- const bufBytes = hexToBytes(value.value);
934
- return withTypeId(value.type, concatBytes(writeUInt32BE(bufBytes.length), bufBytes));
935
- }
936
- case "none":
937
- return new Uint8Array([typeIdByte(value.type)]);
938
- case "some":
939
- return withTypeId(value.type, serializeCVBytes(value.value));
940
- case "ok":
941
- case "err":
942
- return withTypeId(value.type, serializeCVBytes(value.value));
943
- case "address":
944
- return withTypeId(value.type, serializeAddress(value.value));
945
- case "contract": {
946
- const [addr, name] = value.value.split(".");
947
- if (!addr || !name)
948
- throw new Error(`Invalid contract principal: ${value.value}`);
949
- return withTypeId(value.type, concatBytes(serializeAddress(addr), serializeLPString(name)));
950
- }
951
- case "list": {
952
- const parts = [writeUInt32BE(value.value.length)];
953
- for (const item of value.value) {
954
- parts.push(serializeCVBytes(item));
955
- }
956
- return withTypeId(value.type, concatBytes(...parts));
957
- }
958
- case "tuple": {
959
- const keys = Object.keys(value.value).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
960
- const parts = [writeUInt32BE(keys.length)];
961
- for (const key of keys) {
962
- parts.push(serializeLPString(key));
963
- parts.push(serializeCVBytes(value.value[key]));
964
- }
965
- return withTypeId(value.type, concatBytes(...parts));
966
- }
967
- case "ascii": {
968
- const strBytes = asciiToBytes(value.value);
969
- return withTypeId(value.type, concatBytes(writeUInt32BE(strBytes.length), strBytes));
970
- }
971
- case "utf8": {
972
- const strBytes = utf8ToBytes(value.value);
973
- return withTypeId(value.type, concatBytes(writeUInt32BE(strBytes.length), strBytes));
974
- }
975
- default:
976
- throw new Error("Cannot serialize unknown clarity type");
563
+ default:
564
+ throw new Error("Cannot serialize unknown clarity type");
977
565
  }
978
566
  }
979
567
  function serializeCV(value) {
@@ -1079,8 +667,8 @@ var TenureChangeCause = {
1079
667
 
1080
668
  // src/transactions/wire/serialize.ts
1081
669
  function serializeAddress2(c32Address) {
1082
- const [version, hash1602] = c32addressDecode(c32Address);
1083
- return concatBytes(new Uint8Array([version]), hexToBytes(hash1602));
670
+ const [version, hash160] = c32addressDecode(c32Address);
671
+ return concatBytes(new Uint8Array([version]), hexToBytes(hash160));
1084
672
  }
1085
673
  function serializeLPString2(str, prefixBytes = 1) {
1086
674
  const content = utf8ToBytes(str);
@@ -1119,8 +707,8 @@ function serializeSpendingCondition(condition) {
1119
707
  }
1120
708
  function serializeAuthField(field) {
1121
709
  if (field.type === "publicKey") {
1122
- const typeId2 = field.pubKeyEncoding === 0 ? 0 : 1;
1123
- return concatBytes(writeUInt8(typeId2), hexToBytes(field.data));
710
+ const typeId = field.pubKeyEncoding === 0 ? 0 : 1;
711
+ return concatBytes(writeUInt8(typeId), hexToBytes(field.data));
1124
712
  }
1125
713
  const typeId = field.pubKeyEncoding === 0 ? 2 : 3;
1126
714
  return concatBytes(writeUInt8(typeId), hexToBytes(field.data));
@@ -1319,40 +907,125 @@ async function getAccountInfo(client, params) {
1319
907
  };
1320
908
  }
1321
909
 
1322
- // src/actions/public/getBalance.ts
1323
- async function getBalance(client, params) {
1324
- const data = await client.request(`/v2/accounts/${encodeURIComponent(params.address)}`, {
1325
- method: "GET"
1326
- });
1327
- const balance = data?.balance;
1328
- if (typeof balance !== "string" && typeof balance !== "number") {
1329
- throw new MalformedResponseError(`getBalance: /v2/accounts/${params.address} response is missing "balance"`);
1330
- }
1331
- return BigInt(balance);
910
+ // src/actions/public/getBalance.ts
911
+ async function getBalance(client, params) {
912
+ const data = await client.request(`/v2/accounts/${encodeURIComponent(params.address)}`, {
913
+ method: "GET"
914
+ });
915
+ const balance = data?.balance;
916
+ if (typeof balance !== "string" && typeof balance !== "number") {
917
+ throw new MalformedResponseError(`getBalance: /v2/accounts/${params.address} response is missing "balance"`);
918
+ }
919
+ return BigInt(balance);
920
+ }
921
+
922
+ // src/actions/public/getBlock.ts
923
+ async function getBlock(client, params) {
924
+ if (params?.hash) {
925
+ return client.request(`/extended/v2/blocks/${encodeURIComponent(params.hash)}`, { method: "GET" });
926
+ }
927
+ if (params?.height !== undefined) {
928
+ return client.request(`/extended/v2/blocks/${encodeURIComponent(String(params.height))}`, { method: "GET" });
929
+ }
930
+ const data = await client.request("/extended/v2/blocks?limit=1", {
931
+ method: "GET"
932
+ });
933
+ const results = data?.results;
934
+ return Array.isArray(results) ? results[0] ?? null : data;
935
+ }
936
+
937
+ // src/actions/public/getBlockHeight.ts
938
+ async function getBlockHeight(client) {
939
+ const data = await client.request("/v2/info", { method: "GET" });
940
+ if (typeof data?.stacks_tip_height !== "number") {
941
+ throw new MalformedResponseError('getBlockHeight: /v2/info response is missing "stacks_tip_height"');
942
+ }
943
+ return data.stacks_tip_height;
944
+ }
945
+
946
+ // src/utils/constants.ts
947
+ var MAX_U128 = (1n << 128n) - 1n;
948
+ var MAX_I128 = (1n << 127n) - 1n;
949
+ var MIN_I128 = -(1n << 127n);
950
+ var AddressVersion = {
951
+ MainnetSingleSig: 22,
952
+ MainnetMultiSig: 20,
953
+ TestnetSingleSig: 26,
954
+ TestnetMultiSig: 21
955
+ };
956
+ var ZERO_ADDRESS = "SP000000000000000000002Q6VF78";
957
+ var TESTNET_ZERO_ADDRESS = "ST000000000000000000002AMW42H";
958
+ var MICROSTX_PER_STX = 1000000n;
959
+
960
+ // src/utils/hash.ts
961
+ var import_legacy = require("@noble/hashes/legacy.js");
962
+ var import_sha22 = require("@noble/hashes/sha2.js");
963
+ var import_sha23 = require("@noble/hashes/sha2.js");
964
+ function hash160(input) {
965
+ return import_legacy.ripemd160(import_sha22.sha256(input));
966
+ }
967
+ function txidFromBytes(data) {
968
+ return bytesToHex(import_sha23.sha512_256(data));
969
+ }
970
+ function hashP2PKH(input) {
971
+ return bytesToHex(hash160(input));
972
+ }
973
+
974
+ // src/utils/address.ts
975
+ function publicKeyToAddress(publicKey, network = "mainnet") {
976
+ const bytes = typeof publicKey === "string" ? hexToBytes(without0x(publicKey)) : publicKey;
977
+ const version = network === "mainnet" ? AddressVersion.MainnetSingleSig : AddressVersion.TestnetSingleSig;
978
+ return c32address(version, bytesToHex(hash160(bytes)));
1332
979
  }
1333
-
1334
- // src/actions/public/getBlock.ts
1335
- async function getBlock(client, params) {
1336
- if (params?.hash) {
1337
- return client.request(`/extended/v2/blocks/${encodeURIComponent(params.hash)}`, { method: "GET" });
1338
- }
1339
- if (params?.height !== undefined) {
1340
- return client.request(`/extended/v2/blocks/${encodeURIComponent(String(params.height))}`, { method: "GET" });
980
+ var CONTRACT_NAME_REGEX = /^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/;
981
+ function validateStacksAddress(address) {
982
+ try {
983
+ c32addressDecode(address);
984
+ return true;
985
+ } catch {
986
+ return false;
1341
987
  }
1342
- const data = await client.request("/extended/v2/blocks?limit=1", {
1343
- method: "GET"
1344
- });
1345
- const results = data?.results;
1346
- return Array.isArray(results) ? results[0] ?? null : data;
1347
988
  }
1348
-
1349
- // src/actions/public/getBlockHeight.ts
1350
- async function getBlockHeight(client) {
1351
- const data = await client.request("/v2/info", { method: "GET" });
1352
- if (typeof data?.stacks_tip_height !== "number") {
1353
- throw new MalformedResponseError('getBlockHeight: /v2/info response is missing "stacks_tip_height"');
989
+ var isValidAddress = validateStacksAddress;
990
+ function parsePrincipal(value) {
991
+ const parts = value.split(".");
992
+ if (parts.length > 2)
993
+ return null;
994
+ const [address, contractName] = parts;
995
+ if (!validateStacksAddress(address))
996
+ return null;
997
+ if (contractName === undefined)
998
+ return { address };
999
+ if (!CONTRACT_NAME_REGEX.test(contractName))
1000
+ return null;
1001
+ return { address, contractName };
1002
+ }
1003
+ function parseContractId(contractId) {
1004
+ const parsed = parsePrincipal(contractId);
1005
+ if (!parsed?.contractName)
1006
+ throw new Error(`Invalid contract identifier: ${contractId}`);
1007
+ return [parsed.address, parsed.contractName];
1008
+ }
1009
+ function isClarityName(name) {
1010
+ const regex = /^[a-zA-Z]([a-zA-Z0-9]|[-_!?+<>=/*])*$|^[-+=/*]$|^[<>]=?$/;
1011
+ return regex.test(name) && name.length < 128;
1012
+ }
1013
+ function isAddressEqual(a, b) {
1014
+ const [versionA, hashA] = c32addressDecode(a);
1015
+ const [versionB, hashB] = c32addressDecode(b);
1016
+ return versionA === versionB && hashA.toLowerCase() === hashB.toLowerCase();
1017
+ }
1018
+ function addressToVersion(address) {
1019
+ return c32addressDecode(address)[0];
1020
+ }
1021
+ function getContractAddress(deployer, contractName) {
1022
+ if (!validateStacksAddress(deployer)) {
1023
+ throw new Error(`Invalid deployer address: ${deployer}`);
1354
1024
  }
1355
- return data.stacks_tip_height;
1025
+ if (!isClarityName(contractName)) {
1026
+ throw new Error(`Invalid contract name: ${contractName}`);
1027
+ }
1028
+ return `${deployer}.${contractName}`;
1356
1029
  }
1357
1030
 
1358
1031
  // src/actions/public/getContractAbi.ts
@@ -1523,13 +1196,13 @@ function bufferCV(buffer) {
1523
1196
  return { type: "buffer", value: bytesToHex(buffer) };
1524
1197
  }
1525
1198
  function standardPrincipalCV(address) {
1526
- const [version, hash1602] = c32addressDecode(address);
1527
- const normalized = c32address(version, hash1602);
1199
+ const [version, hash160] = c32addressDecode(address);
1200
+ const normalized = c32address(version, hash160);
1528
1201
  return { type: "address", value: normalized };
1529
1202
  }
1530
1203
  function contractPrincipalCV(address, contractName) {
1531
- const [version, hash1602] = c32addressDecode(address);
1532
- const normalized = c32address(version, hash1602);
1204
+ const [version, hash160] = c32addressDecode(address);
1205
+ const normalized = c32address(version, hash160);
1533
1206
  if (utf8ToBytes(contractName).byteLength >= 128) {
1534
1207
  throw new Error("Contract name must be less than 128 bytes");
1535
1208
  }
@@ -1600,8 +1273,8 @@ var Cl = {
1600
1273
  // src/clarity/deserialize.ts
1601
1274
  function readAddress(reader) {
1602
1275
  const version = reader.readUInt8();
1603
- const hash1602 = bytesToHex(reader.readBytes(20));
1604
- return c32address(version, hash1602);
1276
+ const hash160 = bytesToHex(reader.readBytes(20));
1277
+ return c32address(version, hash160);
1605
1278
  }
1606
1279
  function readLPString(reader, prefixBytes = 1) {
1607
1280
  let length = 0;
@@ -2212,7 +1885,7 @@ async function simulateTransaction(client, params) {
2212
1885
  if (payload.payloadType === PayloadType.ContractCall) {
2213
1886
  const sender = params.sender ?? extractSender(transaction, client);
2214
1887
  const contract = `${payload.contractAddress}.${payload.contractName}`;
2215
- const [execution, fees2] = await Promise.all([
1888
+ const [execution, fees] = await Promise.all([
2216
1889
  simulateCall(client, {
2217
1890
  contract,
2218
1891
  functionName: payload.functionName,
@@ -2222,7 +1895,7 @@ async function simulateTransaction(client, params) {
2222
1895
  }),
2223
1896
  estimateFee(client, { transaction })
2224
1897
  ]);
2225
- return { type: "contract-call", execution, fees: fees2 };
1898
+ return { type: "contract-call", execution, fees };
2226
1899
  }
2227
1900
  const fees = await estimateFee(client, { transaction });
2228
1901
  if (payload.payloadType === PayloadType.SmartContract || payload.payloadType === PayloadType.VersionedSmartContract) {
@@ -2952,11 +2625,11 @@ function replayMultiSigSigHash(tx) {
2952
2625
  const condition = tx.auth.spendingCondition;
2953
2626
  if (isNonSequential(condition.hashMode)) {
2954
2627
  const preSign = nonSequentialPreSignHash(tx);
2955
- let curSigHash2 = preSign;
2628
+ let curSigHash = preSign;
2956
2629
  for (const field of condition.fields) {
2957
- curSigHash2 = sigHashPostSign(curSigHash2, field.pubKeyEncoding, field.data);
2630
+ curSigHash = sigHashPostSign(curSigHash, field.pubKeyEncoding, field.data);
2958
2631
  }
2959
- return curSigHash2;
2632
+ return curSigHash;
2960
2633
  }
2961
2634
  let curSigHash = initialSigHash(tx);
2962
2635
  for (const field of condition.fields) {
@@ -3077,8 +2750,8 @@ async function signSequentialWithAccount(tx, condition, account, publicKeys, sig
3077
2750
  const fields = [...condition.fields];
3078
2751
  let curSigHash = initialSigHash(tx);
3079
2752
  for (const field of fields) {
3080
- const preSign2 = sigHashPreSign(curSigHash, AuthType.Standard, condition.fee, condition.nonce);
3081
- curSigHash = sigHashPostSign(preSign2, field.pubKeyEncoding, field.data);
2753
+ const preSign = sigHashPreSign(curSigHash, AuthType.Standard, condition.fee, condition.nonce);
2754
+ curSigHash = sigHashPostSign(preSign, field.pubKeyEncoding, field.data);
3082
2755
  }
3083
2756
  for (let i = fields.length;i < signerIndex; i++) {
3084
2757
  const pubKeyField = {
@@ -3087,8 +2760,8 @@ async function signSequentialWithAccount(tx, condition, account, publicKeys, sig
3087
2760
  data: publicKeys[i]
3088
2761
  };
3089
2762
  fields.push(pubKeyField);
3090
- const preSign2 = sigHashPreSign(curSigHash, AuthType.Standard, condition.fee, condition.nonce);
3091
- curSigHash = sigHashPostSign(preSign2, pubKeyField.pubKeyEncoding, pubKeyField.data);
2763
+ const preSign = sigHashPreSign(curSigHash, AuthType.Standard, condition.fee, condition.nonce);
2764
+ curSigHash = sigHashPostSign(preSign, pubKeyField.pubKeyEncoding, pubKeyField.data);
3092
2765
  }
3093
2766
  const preSign = sigHashPreSign(curSigHash, AuthType.Standard, condition.fee, condition.nonce);
3094
2767
  const sigBytes = await account.sign(hexToBytes(preSign));
@@ -3327,9 +3000,9 @@ function getOriginSigHash(tx) {
3327
3000
  if ("fields" in condition) {
3328
3001
  return replayMultiSigSigHash(tx);
3329
3002
  }
3330
- const initialSigHash2 = signBegin(tx);
3003
+ const initialSigHash = signBegin(tx);
3331
3004
  const sc = condition;
3332
- const preSign = sigHashPreSign(initialSigHash2, AuthType.Standard, sc.fee, sc.nonce);
3005
+ const preSign = sigHashPreSign(initialSigHash, AuthType.Standard, sc.fee, sc.nonce);
3333
3006
  return sigHashPostSign(preSign, sc.keyEncoding, sc.signature);
3334
3007
  }
3335
3008
  function signSponsor(tx, privateKey) {
@@ -3395,11 +3068,11 @@ async function sendTransaction(client, params) {
3395
3068
  throw error;
3396
3069
  }
3397
3070
  } else if (error instanceof TimeoutError) {
3398
- const txid3 = getTransactionId(params.transaction);
3399
- const receipt = await getTransaction(client, { txid: txid3 }).catch(() => null);
3071
+ const txid = getTransactionId(params.transaction);
3072
+ const receipt = await getTransaction(client, { txid }).catch(() => null);
3400
3073
  if (receipt === null)
3401
3074
  throw error;
3402
- data = { txid: txid3 };
3075
+ data = { txid };
3403
3076
  } else {
3404
3077
  throw error;
3405
3078
  }
@@ -3411,16 +3084,16 @@ async function sendTransaction(client, params) {
3411
3084
  txid: data.txid ?? getTransactionId(params.transaction)
3412
3085
  });
3413
3086
  }
3414
- const txid2 = typeof data === "string" ? data.replace(/"/g, "") : data.txid ?? getTransactionId(params.transaction);
3087
+ const txid = typeof data === "string" ? data.replace(/"/g, "") : data.txid ?? getTransactionId(params.transaction);
3415
3088
  if (params.wait) {
3416
3089
  const confirmations = params.wait === true ? 1 : params.wait;
3417
3090
  const receipt = await waitForTransactionReceipt(client, {
3418
- txid: txid2,
3091
+ txid,
3419
3092
  confirmations
3420
3093
  });
3421
- return { txid: txid2, receipt };
3094
+ return { txid, receipt };
3422
3095
  }
3423
- return { txid: txid2 };
3096
+ return { txid };
3424
3097
  }
3425
3098
 
3426
3099
  // src/actions/wallet/nonceManager.ts
@@ -3674,10 +3347,180 @@ async function deployContract(client, params) {
3674
3347
  throw new Error(`Invalid contract name: ${params.contractName}`);
3675
3348
  if (isProviderAccount(account)) {
3676
3349
  assertNoFeeTierForProvider(params.fee);
3677
- const result = await account.provider.request("stx_deployContract", {
3678
- contractName: params.contractName,
3679
- codeBody: params.codeBody,
3680
- clarityVersion: params.clarityVersion
3350
+ const result = await account.provider.request("stx_deployContract", {
3351
+ contractName: params.contractName,
3352
+ codeBody: params.codeBody,
3353
+ clarityVersion: params.clarityVersion
3354
+ });
3355
+ return result.txid;
3356
+ }
3357
+ const managed = params.nonce === undefined && client.nonceManager !== undefined;
3358
+ const nonce = params.nonce ?? await resolveNonce(client, account.address);
3359
+ try {
3360
+ const needsFeeResolution = params.fee === undefined || isFeeTier(params.fee);
3361
+ const unsigned = buildContractDeploy({
3362
+ contractName: params.contractName,
3363
+ codeBody: params.codeBody,
3364
+ clarityVersion: params.clarityVersion,
3365
+ fee: needsFeeResolution ? 0n : params.fee,
3366
+ nonce,
3367
+ publicKey: account.publicKey,
3368
+ chain: client.chain,
3369
+ postConditionMode: params.postConditionMode,
3370
+ postConditions: params.postConditions
3371
+ });
3372
+ if (needsFeeResolution) {
3373
+ const { fee } = await resolveFee(client, unsigned, params.fee);
3374
+ setUnsignedFee(unsigned, fee);
3375
+ }
3376
+ const signed = await signTransactionWithAccount(unsigned, account);
3377
+ return await broadcastWithNonceReset(client, {
3378
+ transaction: signed,
3379
+ address: account.address
3380
+ });
3381
+ } catch (error) {
3382
+ if (managed)
3383
+ await releaseNonce(client, account.address, nonce);
3384
+ throw error;
3385
+ }
3386
+ }
3387
+
3388
+ // src/actions/wallet/signMessage.ts
3389
+ var import_sha26 = require("@noble/hashes/sha2.js");
3390
+
3391
+ // src/clarity/structuredData.ts
3392
+ var import_sha25 = require("@noble/hashes/sha2.js");
3393
+ var SIP018_PREFIX = new Uint8Array([
3394
+ 83,
3395
+ 73,
3396
+ 80,
3397
+ 48,
3398
+ 49,
3399
+ 56
3400
+ ]);
3401
+ function hashStructuredData(structuredData) {
3402
+ return import_sha25.sha256(serializeCVBytes(structuredData));
3403
+ }
3404
+ function isDomain(value) {
3405
+ if (value.type !== "tuple")
3406
+ return false;
3407
+ const { name, version, "chain-id": chainId } = value.value;
3408
+ return name?.type === "ascii" && version?.type === "ascii" && chainId?.type === "uint";
3409
+ }
3410
+ function encodeStructuredData(opts) {
3411
+ if (!isDomain(opts.domain)) {
3412
+ throw new Error("domain must be a tuple { name: ascii, version: ascii, chain-id: uint }");
3413
+ }
3414
+ return concatBytes(SIP018_PREFIX, hashStructuredData(opts.domain), hashStructuredData(opts.message));
3415
+ }
3416
+ function structuredDataHash(opts) {
3417
+ return import_sha25.sha256(encodeStructuredData(opts));
3418
+ }
3419
+ async function signStructuredData(account, opts) {
3420
+ const vrs = await account.sign(structuredDataHash(opts));
3421
+ if (vrs.length !== 65) {
3422
+ throw new Error(`Expected 65-byte recoverable signature, got ${vrs.length}`);
3423
+ }
3424
+ return bytesToHex(concatBytes(vrs.slice(1), vrs.slice(0, 1)));
3425
+ }
3426
+
3427
+ // src/actions/wallet/signMessage.ts
3428
+ async function signMessage(client, params) {
3429
+ const account = client.account;
3430
+ if (!account)
3431
+ throw new Error("Account required");
3432
+ if (isProviderAccount(account)) {
3433
+ const method = params.domain ? "stx_signStructuredMessage" : "stx_signMessage";
3434
+ const result = await account.provider.request(method, {
3435
+ message: params.message,
3436
+ domain: params.domain
3437
+ });
3438
+ return result.signature;
3439
+ }
3440
+ const cv = typeof params.message === "string" ? Cl.stringAscii(params.message) : params.message;
3441
+ const hash = params.domain ? structuredDataHash({
3442
+ message: cv,
3443
+ domain: Cl.tuple({
3444
+ name: Cl.stringAscii(params.domain.name),
3445
+ version: Cl.stringAscii(params.domain.version),
3446
+ "chain-id": Cl.uint(params.domain.chainId)
3447
+ })
3448
+ }) : import_sha26.sha256(serializeCVBytes(cv));
3449
+ const sigBytes = await account.sign(hash);
3450
+ return bytesToHex(sigBytes);
3451
+ }
3452
+
3453
+ // src/actions/wallet/signTransaction.ts
3454
+ async function signTransactionAction(client, params) {
3455
+ const account = client.account;
3456
+ if (!account)
3457
+ throw new Error("Account required");
3458
+ if (isProviderAccount(account)) {
3459
+ const hex = serializeTransactionHex(params.transaction);
3460
+ const result = await account.provider.request("stx_signTransaction", {
3461
+ transaction: hex
3462
+ });
3463
+ return deserializeTransaction(result.transaction, {
3464
+ _multisig: params.transaction._multisig
3465
+ });
3466
+ }
3467
+ const condition = params.transaction.auth.spendingCondition;
3468
+ if ("fields" in condition) {
3469
+ const publicKeys = params.signers ?? params.transaction._multisig?.publicKeys;
3470
+ if (!publicKeys)
3471
+ throw new Error("Multi-sig signing requires signers (publicKeys)");
3472
+ return signMultiSigWithAccount(params.transaction, account, publicKeys);
3473
+ }
3474
+ return signTransactionWithAccount(params.transaction, account);
3475
+ }
3476
+
3477
+ // src/actions/wallet/sponsorTransaction.ts
3478
+ async function sponsorTransaction(client, params) {
3479
+ const { transaction } = params;
3480
+ if (transaction.auth.authType !== AuthType.Sponsored) {
3481
+ throw new Error("Transaction must have sponsored authorization");
3482
+ }
3483
+ const account = client.account;
3484
+ if (!account)
3485
+ throw new Error("Account required");
3486
+ if (isProviderAccount(account)) {
3487
+ throw new Error("Provider accounts cannot sponsor transactions");
3488
+ }
3489
+ const managed = params.nonce == null && client.nonceManager !== undefined;
3490
+ const nonce = params.nonce != null ? intToBigInt(params.nonce) : await resolveNonce(client, account.address);
3491
+ let fee;
3492
+ try {
3493
+ ({ fee } = await resolveFee(client, transaction, params.fee));
3494
+ } catch (error) {
3495
+ if (managed)
3496
+ await releaseNonce(client, account.address, nonce);
3497
+ throw error;
3498
+ }
3499
+ const sponsorCondition = createSingleSigSpendingCondition(account.publicKey, nonce, fee);
3500
+ const auth = transaction.auth;
3501
+ const sponsored = {
3502
+ ...transaction,
3503
+ auth: {
3504
+ ...auth,
3505
+ sponsorSpendingCondition: sponsorCondition
3506
+ }
3507
+ };
3508
+ return signSponsorWithAccount(sponsored, account);
3509
+ }
3510
+
3511
+ // src/actions/wallet/transferStx.ts
3512
+ async function transferStx(client, params) {
3513
+ const account = client.account;
3514
+ if (!account)
3515
+ throw new Error("Account required");
3516
+ if (!validateStacksAddress(params.to))
3517
+ throw new Error(`Invalid recipient address: ${params.to}`);
3518
+ if (isProviderAccount(account)) {
3519
+ assertNoFeeTierForProvider(params.fee);
3520
+ const result = await account.provider.request("stx_transferStx", {
3521
+ recipient: params.to,
3522
+ amount: String(params.amount),
3523
+ memo: params.memo
3681
3524
  });
3682
3525
  return result.txid;
3683
3526
  }
@@ -3685,10 +3528,10 @@ async function deployContract(client, params) {
3685
3528
  const nonce = params.nonce ?? await resolveNonce(client, account.address);
3686
3529
  try {
3687
3530
  const needsFeeResolution = params.fee === undefined || isFeeTier(params.fee);
3688
- const unsigned = buildContractDeploy({
3689
- contractName: params.contractName,
3690
- codeBody: params.codeBody,
3691
- clarityVersion: params.clarityVersion,
3531
+ const unsigned = buildTokenTransfer({
3532
+ recipient: params.to,
3533
+ amount: params.amount,
3534
+ memo: params.memo,
3692
3535
  fee: needsFeeResolution ? 0n : params.fee,
3693
3536
  nonce,
3694
3537
  publicKey: account.publicKey,
@@ -3712,755 +3555,913 @@ async function deployContract(client, params) {
3712
3555
  }
3713
3556
  }
3714
3557
 
3715
- // src/actions/wallet/signMessage.ts
3716
- var import_sha26 = require("@noble/hashes/sha2.js");
3717
-
3718
- // src/clarity/structuredData.ts
3719
- var import_sha25 = require("@noble/hashes/sha2.js");
3720
- var SIP018_PREFIX = new Uint8Array([
3721
- 83,
3722
- 73,
3723
- 80,
3724
- 48,
3725
- 49,
3726
- 56
3727
- ]);
3728
- function hashStructuredData(structuredData) {
3729
- return import_sha25.sha256(serializeCVBytes(structuredData));
3558
+ // src/clients/decorators/wallet.ts
3559
+ function walletActions(client) {
3560
+ return {
3561
+ sendTransaction: (params) => sendTransaction(client, params),
3562
+ signTransaction: (params) => signTransactionAction(client, params),
3563
+ transferStx: (params) => transferStx(client, params),
3564
+ callContract: (params) => callContract(client, params),
3565
+ deployContract: (params) => deployContract(client, params),
3566
+ signMessage: (params) => signMessage(client, params),
3567
+ sponsorTransaction: (params) => sponsorTransaction(client, params)
3568
+ };
3730
3569
  }
3731
- function isDomain(value) {
3732
- if (value.type !== "tuple")
3733
- return false;
3734
- const { name, version, "chain-id": chainId } = value.value;
3735
- return name?.type === "ascii" && version?.type === "ascii" && chainId?.type === "uint";
3570
+
3571
+ // src/clients/createWalletClient.ts
3572
+ function createWalletClient(config) {
3573
+ return createClient(config).extend(walletActions);
3736
3574
  }
3737
- function encodeStructuredData(opts) {
3738
- if (!isDomain(opts.domain)) {
3739
- throw new Error("domain must be a tuple { name: ascii, version: ascii, chain-id: uint }");
3575
+ // src/clients/decorators/multisig.ts
3576
+ function multisigActions(client) {
3577
+ const msConfig = client._multisigConfig;
3578
+ if (!msConfig)
3579
+ throw new Error("multisigActions requires a multi-sig client");
3580
+ const { signers, requiredSignatures, hashMode } = msConfig;
3581
+ async function resolveNonce(nonce) {
3582
+ if (nonce !== undefined)
3583
+ return nonce;
3584
+ const address = makeMultiSigAddress(signers, requiredSignatures, client.chain);
3585
+ if (client.nonceManager)
3586
+ return client.nonceManager.consume({ client, address });
3587
+ return getNonce(client, { address });
3740
3588
  }
3741
- return concatBytes(SIP018_PREFIX, hashStructuredData(opts.domain), hashStructuredData(opts.message));
3589
+ return {
3590
+ async transferStx(params) {
3591
+ const nonce = await resolveNonce(params.nonce);
3592
+ const unsigned = buildTokenTransfer({
3593
+ recipient: params.to,
3594
+ amount: params.amount,
3595
+ memo: params.memo,
3596
+ fee: params.fee ?? 0n,
3597
+ nonce,
3598
+ publicKeys: signers,
3599
+ signaturesRequired: requiredSignatures,
3600
+ hashMode,
3601
+ chain: client.chain,
3602
+ postConditionMode: params.postConditionMode,
3603
+ postConditions: params.postConditions
3604
+ });
3605
+ if (params.fee === undefined) {
3606
+ const estimates = await estimateFee(client, { transaction: unsigned });
3607
+ const mid = estimates[1] ?? estimates[0];
3608
+ if (mid) {
3609
+ setUnsignedFee(unsigned, BigInt(mid.fee));
3610
+ }
3611
+ }
3612
+ return unsigned;
3613
+ },
3614
+ async callContract(params) {
3615
+ const [contractAddress, contractName] = parseContractId(params.contract);
3616
+ const nonce = await resolveNonce(params.nonce);
3617
+ const unsigned = buildContractCall({
3618
+ contractAddress,
3619
+ contractName,
3620
+ functionName: params.functionName,
3621
+ functionArgs: params.functionArgs ?? [],
3622
+ fee: params.fee ?? 0n,
3623
+ nonce,
3624
+ publicKeys: signers,
3625
+ signaturesRequired: requiredSignatures,
3626
+ hashMode,
3627
+ chain: client.chain,
3628
+ postConditionMode: params.postConditionMode,
3629
+ postConditions: params.postConditions
3630
+ });
3631
+ if (params.fee === undefined) {
3632
+ const estimates = await estimateFee(client, { transaction: unsigned });
3633
+ const mid = estimates[1] ?? estimates[0];
3634
+ if (mid) {
3635
+ setUnsignedFee(unsigned, BigInt(mid.fee));
3636
+ }
3637
+ }
3638
+ return unsigned;
3639
+ },
3640
+ async deployContract(params) {
3641
+ const nonce = await resolveNonce(params.nonce);
3642
+ const unsigned = buildContractDeploy({
3643
+ contractName: params.contractName,
3644
+ codeBody: params.codeBody,
3645
+ clarityVersion: params.clarityVersion,
3646
+ fee: params.fee ?? 0n,
3647
+ nonce,
3648
+ publicKeys: signers,
3649
+ signaturesRequired: requiredSignatures,
3650
+ hashMode,
3651
+ chain: client.chain,
3652
+ postConditionMode: params.postConditionMode,
3653
+ postConditions: params.postConditions
3654
+ });
3655
+ if (params.fee === undefined) {
3656
+ const estimates = await estimateFee(client, { transaction: unsigned });
3657
+ const mid = estimates[1] ?? estimates[0];
3658
+ if (mid) {
3659
+ setUnsignedFee(unsigned, BigInt(mid.fee));
3660
+ }
3661
+ }
3662
+ return unsigned;
3663
+ },
3664
+ async sendTransaction(params) {
3665
+ const finalized = finalizeMultiSig(params.transaction, signers);
3666
+ return sendTransaction(client, {
3667
+ transaction: finalized,
3668
+ attachment: params.attachment
3669
+ });
3670
+ }
3671
+ };
3742
3672
  }
3743
- function structuredDataHash(opts) {
3744
- return import_sha25.sha256(encodeStructuredData(opts));
3673
+
3674
+ // src/clients/createMultiSigClient.ts
3675
+ function createMultiSigClient(config) {
3676
+ const client = createClient(config);
3677
+ client._multisigConfig = {
3678
+ signers: config.signers,
3679
+ requiredSignatures: config.requiredSignatures,
3680
+ hashMode: config.hashMode
3681
+ };
3682
+ return client.extend(multisigActions);
3745
3683
  }
3746
- async function signStructuredData(account, opts) {
3747
- const vrs = await account.sign(structuredDataHash(opts));
3748
- if (vrs.length !== 65) {
3749
- throw new Error(`Expected 65-byte recoverable signature, got ${vrs.length}`);
3684
+ // src/actions/wallet/nonceStores.ts
3685
+ var TAKE_IF_PRESENT = `local v = redis.call('GET', KEYS[1])
3686
+ if v == false then return false end
3687
+ redis.call('INCR', KEYS[1])
3688
+ return v`;
3689
+ var SEED_OR_TAKE = `local v = redis.call('GET', KEYS[1])
3690
+ if v == false then redis.call('SET', KEYS[1], ARGV[1]); v = ARGV[1] end
3691
+ redis.call('INCR', KEYS[1])
3692
+ return v`;
3693
+ var RELEASE_IF_LATEST = `local v = redis.call('GET', KEYS[1])
3694
+ if v ~= false and v == ARGV[1] then redis.call('SET', KEYS[1], ARGV[2]) end
3695
+ return v`;
3696
+ function redisStore(params) {
3697
+ const { redis } = params;
3698
+ const prefix = params.prefix ?? "stacks:nonce:";
3699
+ return {
3700
+ async reserve(key, getFloor) {
3701
+ const k = prefix + key;
3702
+ const present = await redis.send("EVAL", [TAKE_IF_PRESENT, "1", k]);
3703
+ if (present != null)
3704
+ return BigInt(present);
3705
+ const floor = await getFloor();
3706
+ const seeded = await redis.send("EVAL", [
3707
+ SEED_OR_TAKE,
3708
+ "1",
3709
+ k,
3710
+ floor.toString()
3711
+ ]);
3712
+ return BigInt(seeded);
3713
+ },
3714
+ async reset(key) {
3715
+ await redis.send("DEL", [prefix + key]);
3716
+ },
3717
+ async release(key, nonce) {
3718
+ await redis.send("EVAL", [
3719
+ RELEASE_IF_LATEST,
3720
+ "1",
3721
+ prefix + key,
3722
+ (nonce + 1n).toString(),
3723
+ nonce.toString()
3724
+ ]);
3725
+ },
3726
+ async peek(key) {
3727
+ const v = await redis.send("GET", [prefix + key]);
3728
+ return v == null ? undefined : BigInt(v);
3729
+ }
3730
+ };
3731
+ }
3732
+ function postgresStore(params) {
3733
+ const { sql } = params;
3734
+ const shouldEnsure = params.ensureTable ?? true;
3735
+ let ensured = false;
3736
+ async function ensureTable() {
3737
+ if (!shouldEnsure || ensured)
3738
+ return;
3739
+ await sql`CREATE TABLE IF NOT EXISTS stacks_nonce_state (key text PRIMARY KEY, next numeric NOT NULL)`;
3740
+ ensured = true;
3750
3741
  }
3751
- return bytesToHex(concatBytes(vrs.slice(1), vrs.slice(0, 1)));
3742
+ return {
3743
+ async reserve(key, getFloor) {
3744
+ await ensureTable();
3745
+ const updated = await sql`UPDATE stacks_nonce_state SET next = next + 1 WHERE key = ${key} RETURNING next - 1 AS nonce`;
3746
+ const warm = updated[0];
3747
+ if (warm)
3748
+ return BigInt(String(warm.nonce));
3749
+ const floor = await getFloor();
3750
+ const seeded = await sql`INSERT INTO stacks_nonce_state (key, next) VALUES (${key}, ${(floor + 1n).toString()}) ON CONFLICT (key) DO UPDATE SET next = stacks_nonce_state.next + 1 RETURNING next - 1 AS nonce`;
3751
+ const cold = seeded[0];
3752
+ if (!cold)
3753
+ throw new Error("postgresStore: insert returned no row");
3754
+ return BigInt(String(cold.nonce));
3755
+ },
3756
+ async reset(key) {
3757
+ await ensureTable();
3758
+ await sql`DELETE FROM stacks_nonce_state WHERE key = ${key}`;
3759
+ },
3760
+ async release(key, nonce) {
3761
+ await ensureTable();
3762
+ await sql`UPDATE stacks_nonce_state SET next = ${nonce.toString()} WHERE key = ${key} AND next = ${(nonce + 1n).toString()}`;
3763
+ },
3764
+ async peek(key) {
3765
+ await ensureTable();
3766
+ const rows = await sql`SELECT next FROM stacks_nonce_state WHERE key = ${key}`;
3767
+ const row = rows[0];
3768
+ return row ? BigInt(String(row.next)) : undefined;
3769
+ }
3770
+ };
3771
+ }
3772
+ // src/actions/wallet/nonceSources.ts
3773
+ function resolveFetch(fetchImpl) {
3774
+ const f = fetchImpl ?? globalThis.fetch;
3775
+ if (!f)
3776
+ throw new Error("No fetch implementation available; pass `fetchImpl`");
3777
+ return f;
3752
3778
  }
3753
-
3754
- // src/actions/wallet/signMessage.ts
3755
- async function signMessage(client, params) {
3756
- const account = client.account;
3757
- if (!account)
3758
- throw new Error("Account required");
3759
- if (isProviderAccount(account)) {
3760
- const method = params.domain ? "stx_signStructuredMessage" : "stx_signMessage";
3761
- const result = await account.provider.request(method, {
3762
- message: params.message,
3763
- domain: params.domain
3764
- });
3765
- return result.signature;
3766
- }
3767
- const cv = typeof params.message === "string" ? Cl.stringAscii(params.message) : params.message;
3768
- const hash = params.domain ? structuredDataHash({
3769
- message: cv,
3770
- domain: Cl.tuple({
3771
- name: Cl.stringAscii(params.domain.name),
3772
- version: Cl.stringAscii(params.domain.version),
3773
- "chain-id": Cl.uint(params.domain.chainId)
3774
- })
3775
- }) : import_sha26.sha256(serializeCVBytes(cv));
3776
- const sigBytes = await account.sign(hash);
3777
- return bytesToHex(sigBytes);
3779
+ function nextFreeNonce(confirmed, pending) {
3780
+ const taken = new Set(pending.filter((n) => n >= confirmed).map((n) => n.toString()));
3781
+ let n = confirmed;
3782
+ while (taken.has(n.toString()))
3783
+ n += 1n;
3784
+ return n;
3778
3785
  }
3779
-
3780
- // src/actions/wallet/signTransaction.ts
3781
- async function signTransactionAction(client, params) {
3782
- const account = client.account;
3783
- if (!account)
3784
- throw new Error("Account required");
3785
- if (isProviderAccount(account)) {
3786
- const hex = serializeTransactionHex(params.transaction);
3787
- const result = await account.provider.request("stx_signTransaction", {
3788
- transaction: hex
3789
- });
3790
- return deserializeTransaction(result.transaction, {
3791
- _multisig: params.transaction._multisig
3792
- });
3793
- }
3794
- const condition = params.transaction.auth.spendingCondition;
3795
- if ("fields" in condition) {
3796
- const publicKeys = params.signers ?? params.transaction._multisig?.publicKeys;
3797
- if (!publicKeys)
3798
- throw new Error("Multi-sig signing requires signers (publicKeys)");
3799
- return signMultiSigWithAccount(params.transaction, account, publicKeys);
3800
- }
3801
- return signTransactionWithAccount(params.transaction, account);
3786
+ function mempoolAwareSource(params) {
3787
+ const getConfirmed = params.getConfirmed ?? (({ client, address }) => getNonce(client, { address }));
3788
+ return {
3789
+ async get({ client, address }) {
3790
+ const confirmed = await getConfirmed({ client, address });
3791
+ let pending = [];
3792
+ try {
3793
+ pending = await params.getPending({ client, address });
3794
+ } catch (error) {
3795
+ if (error instanceof IndexSourceConfigError)
3796
+ throw error;
3797
+ return confirmed;
3798
+ }
3799
+ return nextFreeNonce(confirmed, pending);
3800
+ }
3801
+ };
3802
3802
  }
3803
-
3804
- // src/actions/wallet/sponsorTransaction.ts
3805
- async function sponsorTransaction(client, params) {
3806
- const { transaction } = params;
3807
- if (transaction.auth.authType !== AuthType.Sponsored) {
3808
- throw new Error("Transaction must have sponsored authorization");
3809
- }
3810
- const account = client.account;
3811
- if (!account)
3812
- throw new Error("Account required");
3813
- if (isProviderAccount(account)) {
3814
- throw new Error("Provider accounts cannot sponsor transactions");
3815
- }
3816
- const managed = params.nonce == null && client.nonceManager !== undefined;
3817
- const nonce = params.nonce != null ? intToBigInt(params.nonce) : await resolveNonce(client, account.address);
3818
- let fee;
3819
- try {
3820
- ({ fee } = await resolveFee(client, transaction, params.fee));
3821
- } catch (error) {
3822
- if (managed)
3823
- await releaseNonce(client, account.address, nonce);
3824
- throw error;
3825
- }
3826
- const sponsorCondition = createSingleSigSpendingCondition(account.publicKey, nonce, fee);
3827
- const auth = transaction.auth;
3828
- const sponsored = {
3829
- ...transaction,
3830
- auth: {
3831
- ...auth,
3832
- sponsorSpendingCondition: sponsorCondition
3803
+ function indexSource(params = {}) {
3804
+ const maxPages = params.maxPages ?? 10;
3805
+ const headers = params.apiKey ? { authorization: `Bearer ${params.apiKey}` } : undefined;
3806
+ const source = mempoolAwareSource({
3807
+ getConfirmed: params.getConfirmed,
3808
+ async getPending({ client, address }) {
3809
+ const request = indexRequestFn(client, params.baseUrl, "indexSource");
3810
+ const out = [];
3811
+ let cursor;
3812
+ let pages = 0;
3813
+ do {
3814
+ const query = new URLSearchParams({
3815
+ sender: address,
3816
+ limit: "200"
3817
+ });
3818
+ if (cursor)
3819
+ query.set("from_cursor", cursor);
3820
+ let data;
3821
+ try {
3822
+ data = await request(`/v1/index/mempool?${query}`, {
3823
+ method: "GET",
3824
+ headers
3825
+ });
3826
+ } catch (error) {
3827
+ if (indexNotFound(error, "indexSource"))
3828
+ break;
3829
+ throw error;
3830
+ }
3831
+ for (const tx of data.mempool ?? []) {
3832
+ if (tx.nonce != null)
3833
+ out.push(BigInt(tx.nonce));
3834
+ }
3835
+ cursor = data.next_cursor ?? undefined;
3836
+ pages += 1;
3837
+ } while (cursor && pages < maxPages);
3838
+ return out;
3839
+ }
3840
+ });
3841
+ return {
3842
+ async get(args) {
3843
+ indexRequestFn(args.client, params.baseUrl, "indexSource");
3844
+ return source.get(args);
3833
3845
  }
3834
3846
  };
3835
- return signSponsorWithAccount(sponsored, account);
3836
3847
  }
3837
-
3838
- // src/actions/wallet/transferStx.ts
3839
- async function transferStx(client, params) {
3840
- const account = client.account;
3841
- if (!account)
3842
- throw new Error("Account required");
3843
- if (!validateStacksAddress(params.to))
3844
- throw new Error(`Invalid recipient address: ${params.to}`);
3845
- if (isProviderAccount(account)) {
3846
- assertNoFeeTierForProvider(params.fee);
3847
- const result = await account.provider.request("stx_transferStx", {
3848
- recipient: params.to,
3849
- amount: String(params.amount),
3850
- memo: params.memo
3851
- });
3852
- return result.txid;
3853
- }
3854
- const managed = params.nonce === undefined && client.nonceManager !== undefined;
3855
- const nonce = params.nonce ?? await resolveNonce(client, account.address);
3856
- try {
3857
- const needsFeeResolution = params.fee === undefined || isFeeTier(params.fee);
3858
- const unsigned = buildTokenTransfer({
3859
- recipient: params.to,
3860
- amount: params.amount,
3861
- memo: params.memo,
3862
- fee: needsFeeResolution ? 0n : params.fee,
3863
- nonce,
3864
- publicKey: account.publicKey,
3865
- chain: client.chain,
3866
- postConditionMode: params.postConditionMode,
3867
- postConditions: params.postConditions
3868
- });
3869
- if (needsFeeResolution) {
3870
- const { fee } = await resolveFee(client, unsigned, params.fee);
3871
- setUnsignedFee(unsigned, fee);
3848
+ function hiroNonceSource(params) {
3849
+ const baseUrl = params.baseUrl.replace(/\/$/, "");
3850
+ const fetchImpl = resolveFetch(params.fetchImpl);
3851
+ return {
3852
+ async get({ address }) {
3853
+ const res = await fetchImpl(`${baseUrl}/extended/v1/address/${address}/nonces`, {
3854
+ headers: params.apiKey ? { "x-api-key": params.apiKey } : undefined
3855
+ });
3856
+ if (!res.ok) {
3857
+ throw new Error(`hiroNonceSource: /nonces ${res.status}`);
3858
+ }
3859
+ const data = await res.json();
3860
+ const missing = (data.detected_missing_nonces ?? []).map((n) => BigInt(n)).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
3861
+ if (missing[0] !== undefined)
3862
+ return missing[0];
3863
+ return BigInt(data.possible_next_nonce ?? 0);
3872
3864
  }
3873
- const signed = await signTransactionWithAccount(unsigned, account);
3874
- return await broadcastWithNonceReset(client, {
3875
- transaction: signed,
3876
- address: account.address
3865
+ };
3866
+ }
3867
+ // src/transports/http.ts
3868
+ function http(url, config) {
3869
+ return (params) => {
3870
+ const resolvedUrl = url ?? params?.chain?.rpcUrls.default.http[0] ?? "http://localhost:3999";
3871
+ const mergedConfig = {
3872
+ ...config,
3873
+ url: resolvedUrl
3874
+ };
3875
+ return createTransport("http", {
3876
+ ...mergedConfig,
3877
+ request: buildRequestFn(resolvedUrl, mergedConfig)
3877
3878
  });
3878
- } catch (error) {
3879
- if (managed)
3880
- await releaseNonce(client, account.address, nonce);
3881
- throw error;
3882
- }
3879
+ };
3883
3880
  }
3884
-
3885
- // src/clients/decorators/wallet.ts
3886
- function walletActions(client) {
3887
- return {
3888
- sendTransaction: (params) => sendTransaction(client, params),
3889
- signTransaction: (params) => signTransactionAction(client, params),
3890
- transferStx: (params) => transferStx(client, params),
3891
- callContract: (params) => callContract(client, params),
3892
- deployContract: (params) => deployContract(client, params),
3893
- signMessage: (params) => signMessage(client, params),
3894
- sponsorTransaction: (params) => sponsorTransaction(client, params)
3881
+ // src/transports/custom.ts
3882
+ function custom(params) {
3883
+ return () => createTransport("custom", { request: params.request });
3884
+ }
3885
+ // src/transports/fallback.ts
3886
+ function fallback(transports) {
3887
+ return (params) => {
3888
+ const resolved = transports.map((t) => t(params));
3889
+ return createTransport("fallback", {
3890
+ request: async (path, options) => {
3891
+ let lastError;
3892
+ for (const transport of resolved) {
3893
+ try {
3894
+ return await transport.request(path, options);
3895
+ } catch (error) {
3896
+ lastError = error instanceof Error ? error : new Error(String(error));
3897
+ }
3898
+ }
3899
+ throw lastError ?? new Error("All transports failed");
3900
+ }
3901
+ });
3895
3902
  };
3896
3903
  }
3904
+ // src/transports/webSocket.ts
3905
+ function subKey(params) {
3906
+ const parts = [params.event];
3907
+ if (params.tx_id)
3908
+ parts.push(`tx_id:${params.tx_id}`);
3909
+ if (params.address)
3910
+ parts.push(`address:${params.address}`);
3911
+ if (params.asset_identifier)
3912
+ parts.push(`asset:${params.asset_identifier}`);
3913
+ if (params.value)
3914
+ parts.push(`value:${params.value}`);
3915
+ return parts.join("|");
3916
+ }
3897
3917
 
3898
- // src/clients/createWalletClient.ts
3899
- function createWalletClient(config) {
3900
- return createClient(config).extend(walletActions);
3901
- }
3902
- // src/clients/decorators/multisig.ts
3903
- function multisigActions(client) {
3904
- const msConfig = client._multisigConfig;
3905
- if (!msConfig)
3906
- throw new Error("multisigActions requires a multi-sig client");
3907
- const { signers, requiredSignatures, hashMode } = msConfig;
3908
- async function resolveNonce2(nonce) {
3909
- if (nonce !== undefined)
3910
- return nonce;
3911
- const address = makeMultiSigAddress(signers, requiredSignatures, client.chain);
3912
- if (client.nonceManager)
3913
- return client.nonceManager.consume({ client, address });
3914
- return getNonce(client, { address });
3918
+ class WebSocketChannel {
3919
+ ws = null;
3920
+ url;
3921
+ nextId = 1;
3922
+ pending = new Map;
3923
+ subs = new Map;
3924
+ destroyed = false;
3925
+ reconnecting = false;
3926
+ reconnectAttempt = 0;
3927
+ reconnectTimer = null;
3928
+ reconnect;
3929
+ reconnectMaxAttempts;
3930
+ reconnectBaseDelay;
3931
+ constructor(url, config) {
3932
+ this.url = url;
3933
+ this.reconnect = config?.reconnect ?? true;
3934
+ this.reconnectMaxAttempts = config?.reconnectMaxAttempts ?? 10;
3935
+ this.reconnectBaseDelay = config?.reconnectBaseDelay ?? 1000;
3915
3936
  }
3916
- return {
3917
- async transferStx(params) {
3918
- const nonce = await resolveNonce2(params.nonce);
3919
- const unsigned = buildTokenTransfer({
3920
- recipient: params.to,
3921
- amount: params.amount,
3922
- memo: params.memo,
3923
- fee: params.fee ?? 0n,
3924
- nonce,
3925
- publicKeys: signers,
3926
- signaturesRequired: requiredSignatures,
3927
- hashMode,
3928
- chain: client.chain,
3929
- postConditionMode: params.postConditionMode,
3930
- postConditions: params.postConditions
3937
+ connect() {
3938
+ if (this.ws?.readyState === WebSocket.OPEN)
3939
+ return Promise.resolve();
3940
+ if (this.ws?.readyState === WebSocket.CONNECTING) {
3941
+ return new Promise((resolve, reject) => {
3942
+ const onOpen = () => {
3943
+ this.ws?.removeEventListener("error", onError);
3944
+ resolve();
3945
+ };
3946
+ const onError = (e) => {
3947
+ this.ws?.removeEventListener("open", onOpen);
3948
+ reject(new WebSocketError("WebSocket connection failed", {
3949
+ details: String(e)
3950
+ }));
3951
+ };
3952
+ this.ws?.addEventListener("open", onOpen, { once: true });
3953
+ this.ws?.addEventListener("error", onError, { once: true });
3931
3954
  });
3932
- if (params.fee === undefined) {
3933
- const estimates = await estimateFee(client, { transaction: unsigned });
3934
- const mid = estimates[1] ?? estimates[0];
3935
- if (mid) {
3936
- setUnsignedFee(unsigned, BigInt(mid.fee));
3937
- }
3938
- }
3939
- return unsigned;
3940
- },
3941
- async callContract(params) {
3942
- const [contractAddress, contractName] = parseContractId(params.contract);
3943
- const nonce = await resolveNonce2(params.nonce);
3944
- const unsigned = buildContractCall({
3945
- contractAddress,
3946
- contractName,
3947
- functionName: params.functionName,
3948
- functionArgs: params.functionArgs ?? [],
3949
- fee: params.fee ?? 0n,
3950
- nonce,
3951
- publicKeys: signers,
3952
- signaturesRequired: requiredSignatures,
3953
- hashMode,
3954
- chain: client.chain,
3955
- postConditionMode: params.postConditionMode,
3956
- postConditions: params.postConditions
3955
+ }
3956
+ return new Promise((resolve, reject) => {
3957
+ this.ws = new WebSocket(this.url);
3958
+ this.ws.addEventListener("open", () => {
3959
+ this.reconnectAttempt = 0;
3960
+ this.reconnecting = false;
3961
+ resolve();
3962
+ }, { once: true });
3963
+ this.ws.addEventListener("error", (e) => {
3964
+ reject(new WebSocketError("WebSocket connection failed", {
3965
+ details: String(e)
3966
+ }));
3967
+ }, { once: true });
3968
+ this.ws.addEventListener("message", (event) => {
3969
+ this.handleMessage(event.data);
3957
3970
  });
3958
- if (params.fee === undefined) {
3959
- const estimates = await estimateFee(client, { transaction: unsigned });
3960
- const mid = estimates[1] ?? estimates[0];
3961
- if (mid) {
3962
- setUnsignedFee(unsigned, BigInt(mid.fee));
3963
- }
3964
- }
3965
- return unsigned;
3966
- },
3967
- async deployContract(params) {
3968
- const nonce = await resolveNonce2(params.nonce);
3969
- const unsigned = buildContractDeploy({
3970
- contractName: params.contractName,
3971
- codeBody: params.codeBody,
3972
- clarityVersion: params.clarityVersion,
3973
- fee: params.fee ?? 0n,
3974
- nonce,
3975
- publicKeys: signers,
3976
- signaturesRequired: requiredSignatures,
3977
- hashMode,
3978
- chain: client.chain,
3979
- postConditionMode: params.postConditionMode,
3980
- postConditions: params.postConditions
3971
+ this.ws.addEventListener("close", () => {
3972
+ if (!this.destroyed)
3973
+ this.handleDisconnect();
3981
3974
  });
3982
- if (params.fee === undefined) {
3983
- const estimates = await estimateFee(client, { transaction: unsigned });
3984
- const mid = estimates[1] ?? estimates[0];
3985
- if (mid) {
3986
- setUnsignedFee(unsigned, BigInt(mid.fee));
3975
+ });
3976
+ }
3977
+ handleMessage(raw) {
3978
+ const data = typeof raw === "string" ? raw : new TextDecoder().decode(raw);
3979
+ let msg;
3980
+ try {
3981
+ msg = JSON.parse(data);
3982
+ } catch {
3983
+ return;
3984
+ }
3985
+ if ("id" in msg && msg.id != null) {
3986
+ const rpc = msg;
3987
+ const p = this.pending.get(rpc.id);
3988
+ if (!p)
3989
+ return;
3990
+ this.pending.delete(rpc.id);
3991
+ if (rpc.error) {
3992
+ p.reject(new WebSocketError(rpc.error.message, {
3993
+ details: `JSON-RPC error ${rpc.error.code}`
3994
+ }));
3995
+ } else {
3996
+ p.resolve(rpc.result);
3997
+ }
3998
+ return;
3999
+ }
4000
+ const notif = msg;
4001
+ if (!notif.method)
4002
+ return;
4003
+ for (const [, entry] of this.subs) {
4004
+ if (entry.params.event === notif.method) {
4005
+ for (const cb of entry.callbacks) {
4006
+ try {
4007
+ cb(notif.params);
4008
+ } catch {}
3987
4009
  }
3988
4010
  }
3989
- return unsigned;
3990
- },
3991
- async sendTransaction(params) {
3992
- const finalized = finalizeMultiSig(params.transaction, signers);
3993
- return sendTransaction(client, {
3994
- transaction: finalized,
3995
- attachment: params.attachment
3996
- });
3997
4011
  }
3998
- };
3999
- }
4000
-
4001
- // src/clients/createMultiSigClient.ts
4002
- function createMultiSigClient(config) {
4003
- const client = createClient(config);
4004
- client._multisigConfig = {
4005
- signers: config.signers,
4006
- requiredSignatures: config.requiredSignatures,
4007
- hashMode: config.hashMode
4008
- };
4009
- return client.extend(multisigActions);
4010
- }
4011
- // src/actions/wallet/nonceStores.ts
4012
- var TAKE_IF_PRESENT = `local v = redis.call('GET', KEYS[1])
4013
- if v == false then return false end
4014
- redis.call('INCR', KEYS[1])
4015
- return v`;
4016
- var SEED_OR_TAKE = `local v = redis.call('GET', KEYS[1])
4017
- if v == false then redis.call('SET', KEYS[1], ARGV[1]); v = ARGV[1] end
4018
- redis.call('INCR', KEYS[1])
4019
- return v`;
4020
- var RELEASE_IF_LATEST = `local v = redis.call('GET', KEYS[1])
4021
- if v ~= false and v == ARGV[1] then redis.call('SET', KEYS[1], ARGV[2]) end
4022
- return v`;
4023
- function redisStore(params) {
4024
- const { redis } = params;
4025
- const prefix = params.prefix ?? "stacks:nonce:";
4026
- return {
4027
- async reserve(key, getFloor) {
4028
- const k = prefix + key;
4029
- const present = await redis.send("EVAL", [TAKE_IF_PRESENT, "1", k]);
4030
- if (present != null)
4031
- return BigInt(present);
4032
- const floor = await getFloor();
4033
- const seeded = await redis.send("EVAL", [
4034
- SEED_OR_TAKE,
4035
- "1",
4036
- k,
4037
- floor.toString()
4038
- ]);
4039
- return BigInt(seeded);
4040
- },
4041
- async reset(key) {
4042
- await redis.send("DEL", [prefix + key]);
4043
- },
4044
- async release(key, nonce) {
4045
- await redis.send("EVAL", [
4046
- RELEASE_IF_LATEST,
4047
- "1",
4048
- prefix + key,
4049
- (nonce + 1n).toString(),
4050
- nonce.toString()
4051
- ]);
4052
- },
4053
- async peek(key) {
4054
- const v = await redis.send("GET", [prefix + key]);
4055
- return v == null ? undefined : BigInt(v);
4012
+ }
4013
+ handleDisconnect() {
4014
+ this.ws = null;
4015
+ for (const [, p] of this.pending) {
4016
+ p.reject(new WebSocketError("WebSocket disconnected"));
4056
4017
  }
4057
- };
4058
- }
4059
- function postgresStore(params) {
4060
- const { sql } = params;
4061
- const shouldEnsure = params.ensureTable ?? true;
4062
- let ensured = false;
4063
- async function ensureTable() {
4064
- if (!shouldEnsure || ensured)
4018
+ this.pending.clear();
4019
+ if (this.reconnect && this.subs.size > 0 && this.reconnectAttempt < this.reconnectMaxAttempts) {
4020
+ this.scheduleReconnect();
4021
+ }
4022
+ }
4023
+ scheduleReconnect() {
4024
+ if (this.destroyed || this.reconnecting)
4065
4025
  return;
4066
- await sql`CREATE TABLE IF NOT EXISTS stacks_nonce_state (key text PRIMARY KEY, next numeric NOT NULL)`;
4067
- ensured = true;
4026
+ this.reconnecting = true;
4027
+ const delay = this.reconnectBaseDelay * 2 ** this.reconnectAttempt;
4028
+ this.reconnectAttempt++;
4029
+ this.reconnectTimer = setTimeout(async () => {
4030
+ this.reconnecting = false;
4031
+ try {
4032
+ await this.connect();
4033
+ await this.resubscribeAll();
4034
+ } catch {
4035
+ if (!this.destroyed && this.subs.size > 0) {
4036
+ this.handleDisconnect();
4037
+ }
4038
+ }
4039
+ }, delay);
4068
4040
  }
4069
- return {
4070
- async reserve(key, getFloor) {
4071
- await ensureTable();
4072
- const updated = await sql`UPDATE stacks_nonce_state SET next = next + 1 WHERE key = ${key} RETURNING next - 1 AS nonce`;
4073
- const warm = updated[0];
4074
- if (warm)
4075
- return BigInt(String(warm.nonce));
4076
- const floor = await getFloor();
4077
- const seeded = await sql`INSERT INTO stacks_nonce_state (key, next) VALUES (${key}, ${(floor + 1n).toString()}) ON CONFLICT (key) DO UPDATE SET next = stacks_nonce_state.next + 1 RETURNING next - 1 AS nonce`;
4078
- const cold = seeded[0];
4079
- if (!cold)
4080
- throw new Error("postgresStore: insert returned no row");
4081
- return BigInt(String(cold.nonce));
4082
- },
4083
- async reset(key) {
4084
- await ensureTable();
4085
- await sql`DELETE FROM stacks_nonce_state WHERE key = ${key}`;
4086
- },
4087
- async release(key, nonce) {
4088
- await ensureTable();
4089
- await sql`UPDATE stacks_nonce_state SET next = ${nonce.toString()} WHERE key = ${key} AND next = ${(nonce + 1n).toString()}`;
4090
- },
4091
- async peek(key) {
4092
- await ensureTable();
4093
- const rows = await sql`SELECT next FROM stacks_nonce_state WHERE key = ${key}`;
4094
- const row = rows[0];
4095
- return row ? BigInt(String(row.next)) : undefined;
4041
+ async resubscribeAll() {
4042
+ for (const [, entry] of this.subs) {
4043
+ await this.sendRpc("subscribe", entry.params);
4096
4044
  }
4097
- };
4098
- }
4099
- // src/actions/wallet/nonceSources.ts
4100
- function resolveFetch(fetchImpl) {
4101
- const f = fetchImpl ?? globalThis.fetch;
4102
- if (!f)
4103
- throw new Error("No fetch implementation available; pass `fetchImpl`");
4104
- return f;
4105
- }
4106
- function nextFreeNonce(confirmed, pending) {
4107
- const taken = new Set(pending.filter((n2) => n2 >= confirmed).map((n2) => n2.toString()));
4108
- let n = confirmed;
4109
- while (taken.has(n.toString()))
4110
- n += 1n;
4111
- return n;
4112
- }
4113
- function mempoolAwareSource(params) {
4114
- const getConfirmed = params.getConfirmed ?? (({ client, address }) => getNonce(client, { address }));
4115
- return {
4116
- async get({ client, address }) {
4117
- const confirmed = await getConfirmed({ client, address });
4118
- let pending = [];
4119
- try {
4120
- pending = await params.getPending({ client, address });
4121
- } catch (error) {
4122
- if (error instanceof IndexSourceConfigError)
4123
- throw error;
4124
- return confirmed;
4045
+ }
4046
+ sendRpc(method, params) {
4047
+ return new Promise((resolve, reject) => {
4048
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
4049
+ return reject(new WebSocketError("WebSocket not connected"));
4125
4050
  }
4126
- return nextFreeNonce(confirmed, pending);
4051
+ const id = this.nextId++;
4052
+ const msg = {
4053
+ jsonrpc: "2.0",
4054
+ id,
4055
+ method,
4056
+ params
4057
+ };
4058
+ this.pending.set(id, { resolve, reject });
4059
+ this.ws.send(JSON.stringify(msg));
4060
+ });
4061
+ }
4062
+ async subscribe(params, callback) {
4063
+ if (this.destroyed) {
4064
+ throw new WebSocketError("WebSocket channel has been destroyed");
4127
4065
  }
4128
- };
4129
- }
4130
- function indexSource(params = {}) {
4131
- const maxPages = params.maxPages ?? 10;
4132
- const headers = params.apiKey ? { authorization: `Bearer ${params.apiKey}` } : undefined;
4133
- const source = mempoolAwareSource({
4134
- getConfirmed: params.getConfirmed,
4135
- async getPending({ client, address }) {
4136
- const request = indexRequestFn(client, params.baseUrl, "indexSource");
4137
- const out = [];
4138
- let cursor;
4139
- let pages = 0;
4140
- do {
4141
- const query = new URLSearchParams({
4142
- sender: address,
4143
- limit: "200"
4144
- });
4145
- if (cursor)
4146
- query.set("from_cursor", cursor);
4147
- let data;
4148
- try {
4149
- data = await request(`/v1/index/mempool?${query}`, {
4150
- method: "GET",
4151
- headers
4152
- });
4153
- } catch (error) {
4154
- if (indexNotFound(error, "indexSource"))
4155
- break;
4156
- throw error;
4157
- }
4158
- for (const tx of data.mempool ?? []) {
4159
- if (tx.nonce != null)
4160
- out.push(BigInt(tx.nonce));
4066
+ await this.connect();
4067
+ const key = subKey(params);
4068
+ let entry = this.subs.get(key);
4069
+ if (entry) {
4070
+ entry.callbacks.add(callback);
4071
+ } else {
4072
+ entry = { params, callbacks: new Set([callback]) };
4073
+ this.subs.set(key, entry);
4074
+ await this.sendRpc("subscribe", params);
4075
+ }
4076
+ return {
4077
+ unsubscribe: () => {
4078
+ const e = this.subs.get(key);
4079
+ if (!e)
4080
+ return;
4081
+ e.callbacks.delete(callback);
4082
+ if (e.callbacks.size === 0) {
4083
+ this.subs.delete(key);
4084
+ if (this.ws?.readyState === WebSocket.OPEN) {
4085
+ this.sendRpc("unsubscribe", params).catch(() => {});
4086
+ }
4087
+ if (this.subs.size === 0)
4088
+ this.closeQuietly();
4161
4089
  }
4162
- cursor = data.next_cursor ?? undefined;
4163
- pages += 1;
4164
- } while (cursor && pages < maxPages);
4165
- return out;
4090
+ }
4091
+ };
4092
+ }
4093
+ closeQuietly() {
4094
+ if (this.ws) {
4095
+ this.ws.close();
4096
+ this.ws = null;
4166
4097
  }
4167
- });
4168
- return {
4169
- async get(args) {
4170
- indexRequestFn(args.client, params.baseUrl, "indexSource");
4171
- return source.get(args);
4098
+ }
4099
+ destroy() {
4100
+ this.destroyed = true;
4101
+ if (this.reconnectTimer)
4102
+ clearTimeout(this.reconnectTimer);
4103
+ for (const [, p] of this.pending) {
4104
+ p.reject(new WebSocketError("WebSocket channel destroyed"));
4172
4105
  }
4106
+ this.pending.clear();
4107
+ this.subs.clear();
4108
+ if (this.ws) {
4109
+ this.ws.close();
4110
+ this.ws = null;
4111
+ }
4112
+ }
4113
+ }
4114
+ function deriveWsUrl(httpUrl) {
4115
+ return `${httpUrl.replace(/^http/, "ws").replace(/\/$/, "")}/extended/v1/ws`;
4116
+ }
4117
+ function webSocket(url, config) {
4118
+ return (params) => {
4119
+ const httpUrl = config?.url ?? params?.chain?.rpcUrls.default.http[0] ?? "http://localhost:3999";
4120
+ const wsUrl = url ?? params?.chain?.rpcUrls.default.ws?.[0] ?? deriveWsUrl(httpUrl);
4121
+ const resolvedHttpConfig = {
4122
+ ...config,
4123
+ url: httpUrl
4124
+ };
4125
+ const channel = new WebSocketChannel(wsUrl, config);
4126
+ const { apiKey: _apiKey, ...exposedConfig } = resolvedHttpConfig;
4127
+ const transport = {
4128
+ type: "webSocket",
4129
+ request: buildRequestFn(httpUrl, resolvedHttpConfig),
4130
+ config: exposedConfig,
4131
+ subscribe: (subParams, callback) => channel.subscribe(subParams, callback),
4132
+ destroy: () => channel.destroy()
4133
+ };
4134
+ return transport;
4173
4135
  };
4174
4136
  }
4175
- function hiroNonceSource(params) {
4176
- const baseUrl = params.baseUrl.replace(/\/$/, "");
4177
- const fetchImpl = resolveFetch(params.fetchImpl);
4178
- return {
4179
- async get({ address }) {
4180
- const res = await fetchImpl(`${baseUrl}/extended/v1/address/${address}/nonces`, {
4181
- headers: params.apiKey ? { "x-api-key": params.apiKey } : undefined
4182
- });
4183
- if (!res.ok) {
4184
- throw new Error(`hiroNonceSource: /nonces ${res.status}`);
4185
- }
4186
- const data = await res.json();
4187
- const missing = (data.detected_missing_nonces ?? []).map((n) => BigInt(n)).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
4188
- if (missing[0] !== undefined)
4189
- return missing[0];
4190
- return BigInt(data.possible_next_nonce ?? 0);
4191
- }
4192
- };
4137
+ // src/filters/index.ts
4138
+ var exports_filters = {};
4139
+ __export(exports_filters, {
4140
+ CHAIN_EVENT_FILTER_TYPES: () => CHAIN_EVENT_FILTER_TYPES,
4141
+ DECODED_EVENT_TYPES: () => DECODED_EVENT_TYPES,
4142
+ VM_EVENT_TYPES: () => VM_EVENT_TYPES,
4143
+ VM_NODE_TO_STORED_TYPE: () => VM_NODE_TO_STORED_TYPE,
4144
+ assertAssetIdentifier: () => assertAssetIdentifier,
4145
+ assertContractId: () => assertContractId,
4146
+ assertPrincipalish: () => assertPrincipalish,
4147
+ assetId: () => assetId,
4148
+ fromSubgraphSource: () => fromSubgraphSource,
4149
+ hasWildcard: () => hasWildcard,
4150
+ isPrincipal: () => isPrincipal,
4151
+ makeChainEventFilter: () => makeChainEventFilter,
4152
+ on: () => on
4153
+ });
4154
+
4155
+ // src/filters/event-types.ts
4156
+ var DECODED_EVENT_TYPES = [
4157
+ "stx_transfer",
4158
+ "stx_mint",
4159
+ "stx_burn",
4160
+ "stx_lock",
4161
+ "ft_transfer",
4162
+ "ft_mint",
4163
+ "ft_burn",
4164
+ "nft_transfer",
4165
+ "nft_mint",
4166
+ "nft_burn",
4167
+ "print"
4168
+ ];
4169
+ var VM_EVENT_TYPES = [
4170
+ "nested_contract_call",
4171
+ "var_set",
4172
+ "map_set",
4173
+ "map_insert",
4174
+ "map_delete"
4175
+ ];
4176
+ var VM_NODE_TO_STORED_TYPE = {
4177
+ contract_call_event: "nested_contract_call",
4178
+ var_set_event: "var_set",
4179
+ map_set_event: "map_set",
4180
+ map_insert_event: "map_insert",
4181
+ map_delete_event: "map_delete"
4182
+ };
4183
+ var CHAIN_EVENT_FILTER_TYPES = [
4184
+ "stx_transfer",
4185
+ "stx_mint",
4186
+ "stx_burn",
4187
+ "stx_lock",
4188
+ "ft_transfer",
4189
+ "ft_mint",
4190
+ "ft_burn",
4191
+ "nft_transfer",
4192
+ "nft_mint",
4193
+ "nft_burn",
4194
+ "contract_call",
4195
+ "contract_deploy",
4196
+ "print_event",
4197
+ "nested_contract_call",
4198
+ "var_set",
4199
+ "map_set",
4200
+ "map_insert",
4201
+ "map_delete",
4202
+ "sbtc_deposit",
4203
+ "sbtc_withdrawal_create",
4204
+ "sbtc_withdrawal_accept",
4205
+ "sbtc_withdrawal_reject",
4206
+ "sbtc_withdrawal_swept_confirmed"
4207
+ ];
4208
+ // src/filters/validate.ts
4209
+ function assetId(value) {
4210
+ assertAssetIdentifier("assetIdentifier", value);
4211
+ return value;
4212
+ }
4213
+ function isPrincipal(value) {
4214
+ return parsePrincipal(value) !== null;
4193
4215
  }
4194
- // src/transports/http.ts
4195
- function http(url, config) {
4196
- return (params) => {
4197
- const resolvedUrl = url ?? params?.chain?.rpcUrls.default.http[0] ?? "http://localhost:3999";
4198
- const mergedConfig = {
4199
- ...config,
4200
- url: resolvedUrl
4201
- };
4202
- return createTransport("http", {
4203
- ...mergedConfig,
4204
- request: buildRequestFn(resolvedUrl, mergedConfig)
4205
- });
4206
- };
4216
+ function hasWildcard(value) {
4217
+ return value.includes("*");
4207
4218
  }
4208
- // src/transports/custom.ts
4209
- function custom(params) {
4210
- return () => createTransport("custom", { request: params.request });
4219
+ function assertPrincipalish(field, value) {
4220
+ if (hasWildcard(value))
4221
+ return;
4222
+ if (!isPrincipal(value)) {
4223
+ throw new Error(`${field} "${value}" is not a valid Stacks principal (SP…/ST…, optionally .contract-name).`);
4224
+ }
4211
4225
  }
4212
- // src/transports/fallback.ts
4213
- function fallback(transports) {
4214
- return (params) => {
4215
- const resolved = transports.map((t) => t(params));
4216
- return createTransport("fallback", {
4217
- request: async (path, options) => {
4218
- let lastError;
4219
- for (const transport of resolved) {
4220
- try {
4221
- return await transport.request(path, options);
4222
- } catch (error) {
4223
- lastError = error instanceof Error ? error : new Error(String(error));
4224
- }
4225
- }
4226
- throw lastError ?? new Error("All transports failed");
4227
- }
4228
- });
4229
- };
4226
+ function assertAssetIdentifier(field, value) {
4227
+ if (hasWildcard(value))
4228
+ return;
4229
+ const [contractId, assetName, ...rest] = value.split("::");
4230
+ if (!contractId || !assetName || rest.length > 0 || !contractId.includes(".") || !isPrincipal(contractId)) {
4231
+ throw new Error(`${field} "${value}" is not a valid asset identifier (SP….contract-name::asset-name). Passing a bare contract id here matches zero rows — use contractId for that.`);
4232
+ }
4230
4233
  }
4231
- // src/transports/webSocket.ts
4232
- function subKey(params) {
4233
- const parts = [params.event];
4234
- if (params.tx_id)
4235
- parts.push(`tx_id:${params.tx_id}`);
4236
- if (params.address)
4237
- parts.push(`address:${params.address}`);
4238
- if (params.asset_identifier)
4239
- parts.push(`asset:${params.asset_identifier}`);
4240
- if (params.value)
4241
- parts.push(`value:${params.value}`);
4242
- return parts.join("|");
4234
+ function assertContractId(field, value) {
4235
+ if (hasWildcard(value))
4236
+ return;
4237
+ if (value.includes("::")) {
4238
+ throw new Error(`${field} "${value}" is an asset identifier, not a contract id — use assetIdentifier for that.`);
4239
+ }
4240
+ if (!value.includes(".") || !isPrincipal(value)) {
4241
+ throw new Error(`${field} "${value}" is not a valid contract id (SP….contract-name).`);
4242
+ }
4243
4243
  }
4244
4244
 
4245
- class WebSocketChannel {
4246
- ws = null;
4247
- url;
4248
- nextId = 1;
4249
- pending = new Map;
4250
- subs = new Map;
4251
- destroyed = false;
4252
- reconnecting = false;
4253
- reconnectAttempt = 0;
4254
- reconnectTimer = null;
4255
- reconnect;
4256
- reconnectMaxAttempts;
4257
- reconnectBaseDelay;
4258
- constructor(url, config) {
4259
- this.url = url;
4260
- this.reconnect = config?.reconnect ?? true;
4261
- this.reconnectMaxAttempts = config?.reconnectMaxAttempts ?? 10;
4262
- this.reconnectBaseDelay = config?.reconnectBaseDelay ?? 1000;
4245
+ // src/filters/factories.ts
4246
+ var PRINCIPAL_FIELDS = new Set([
4247
+ "sender",
4248
+ "recipient",
4249
+ "caller",
4250
+ "deployer",
4251
+ "lockedAddress"
4252
+ ]);
4253
+ var AMOUNT_FIELDS = new Set(["minAmount", "maxAmount"]);
4254
+ var DECORATIVE_FIELDS = new Set(["abi", "prints"]);
4255
+ function specEntries(spec) {
4256
+ return Object.entries(spec).filter(([key, value]) => key !== "type" && value !== undefined);
4257
+ }
4258
+ function validateSpec(spec) {
4259
+ for (const [key, value] of specEntries(spec)) {
4260
+ if (PRINCIPAL_FIELDS.has(key)) {
4261
+ assertPrincipalish(key, value);
4262
+ } else if (key === "assetIdentifier") {
4263
+ assertAssetIdentifier(key, value);
4264
+ } else if (key === "contractId") {
4265
+ for (const id of Array.isArray(value) ? value : [value]) {
4266
+ assertContractId(key, id);
4267
+ }
4268
+ }
4263
4269
  }
4264
- connect() {
4265
- if (this.ws?.readyState === WebSocket.OPEN)
4266
- return Promise.resolve();
4267
- if (this.ws?.readyState === WebSocket.CONNECTING) {
4268
- return new Promise((resolve, reject) => {
4269
- const onOpen = () => {
4270
- this.ws?.removeEventListener("error", onError);
4271
- resolve();
4272
- };
4273
- const onError = (e) => {
4274
- this.ws?.removeEventListener("open", onOpen);
4275
- reject(new WebSocketError("WebSocket connection failed", {
4276
- details: String(e)
4277
- }));
4278
- };
4279
- this.ws?.addEventListener("open", onOpen, { once: true });
4280
- this.ws?.addEventListener("error", onError, { once: true });
4281
- });
4270
+ }
4271
+ function unsupported(surface, field, hint) {
4272
+ throw new Error(`${field} cannot be expressed on ${surface} — ${hint}. Drop the field from the filter or use the surface that supports it.`);
4273
+ }
4274
+ function assertNoWildcards(surface, spec) {
4275
+ for (const [key, value] of specEntries(spec)) {
4276
+ const candidates = Array.isArray(value) ? value : [value];
4277
+ for (const candidate of candidates) {
4278
+ if (typeof candidate === "string" && hasWildcard(candidate)) {
4279
+ unsupported(surface, `${key} wildcard "${candidate}"`, "wildcard patterns are Webhooks/Subgraphs-only");
4280
+ }
4282
4281
  }
4283
- return new Promise((resolve, reject) => {
4284
- this.ws = new WebSocket(this.url);
4285
- this.ws.addEventListener("open", () => {
4286
- this.reconnectAttempt = 0;
4287
- this.reconnecting = false;
4288
- resolve();
4289
- }, { once: true });
4290
- this.ws.addEventListener("error", (e) => {
4291
- reject(new WebSocketError("WebSocket connection failed", {
4292
- details: String(e)
4293
- }));
4294
- }, { once: true });
4295
- this.ws.addEventListener("message", (event) => {
4296
- this.handleMessage(event.data);
4297
- });
4298
- this.ws.addEventListener("close", () => {
4299
- if (!this.destroyed)
4300
- this.handleDisconnect();
4301
- });
4302
- });
4303
4282
  }
4304
- handleMessage(raw) {
4305
- const data = typeof raw === "string" ? raw : new TextDecoder().decode(raw);
4306
- let msg;
4307
- try {
4308
- msg = JSON.parse(data);
4309
- } catch {
4310
- return;
4283
+ }
4284
+ function assertNotTraitAndContract(surface, spec) {
4285
+ const trait = "trait" in spec ? spec.trait : undefined;
4286
+ const contract = "contractId" in spec ? spec.contractId : undefined;
4287
+ if (trait !== undefined && contract !== undefined) {
4288
+ unsupported(surface, "trait with contractId", "the Index treats them as mutually exclusive — drop one, or use a subgraph source, which ANDs the pair");
4289
+ }
4290
+ }
4291
+ function toChainTrigger(spec) {
4292
+ const out = {};
4293
+ for (const [key, value] of specEntries(spec)) {
4294
+ if (DECORATIVE_FIELDS.has(key))
4295
+ continue;
4296
+ if (key === "factory") {
4297
+ unsupported("Webhooks", "factory", "dynamic factory discovery is a Subgraphs-only concept — a trigger targets addresses known when it is created");
4311
4298
  }
4312
- if ("id" in msg && msg.id != null) {
4313
- const rpc = msg;
4314
- const p = this.pending.get(rpc.id);
4315
- if (!p)
4316
- return;
4317
- this.pending.delete(rpc.id);
4318
- if (rpc.error) {
4319
- p.reject(new WebSocketError(rpc.error.message, {
4320
- details: `JSON-RPC error ${rpc.error.code}`
4321
- }));
4322
- } else {
4323
- p.resolve(rpc.result);
4324
- }
4325
- return;
4299
+ if (Array.isArray(value)) {
4300
+ unsupported("Webhooks", `${key} set`, "a chain trigger targets ONE contract — create one subscription per contract, or use Index/Subgraphs which accept the set");
4301
+ }
4302
+ out[key] = typeof value === "bigint" ? value.toString() : value;
4303
+ }
4304
+ return { type: spec.type, ...out };
4305
+ }
4306
+ function toIndexParams(spec, extra = {}) {
4307
+ assertNoWildcards("Index events", spec);
4308
+ assertNotTraitAndContract("Index events", spec);
4309
+ const out = {
4310
+ eventType: spec.type === "print_event" ? "print" : spec.type
4311
+ };
4312
+ for (const [key, value] of specEntries(spec)) {
4313
+ if (DECORATIVE_FIELDS.has(key))
4314
+ continue;
4315
+ if (key === "factory") {
4316
+ unsupported("Index events", "factory", "dynamic factory discovery is a Subgraphs-only concept");
4326
4317
  }
4327
- const notif = msg;
4328
- if (!notif.method)
4329
- return;
4330
- for (const [, entry] of this.subs) {
4331
- if (entry.params.event === notif.method) {
4332
- for (const cb of entry.callbacks) {
4333
- try {
4334
- cb(notif.params);
4335
- } catch {}
4336
- }
4337
- }
4318
+ if (AMOUNT_FIELDS.has(key)) {
4319
+ unsupported("Index events", key, "amount predicates are Webhooks/Subgraphs-only; filter client-side on the decoded rows");
4338
4320
  }
4339
- }
4340
- handleDisconnect() {
4341
- this.ws = null;
4342
- for (const [, p] of this.pending) {
4343
- p.reject(new WebSocketError("WebSocket disconnected"));
4321
+ if (key === "topic") {
4322
+ unsupported("Index events", "topic", "per-topic reads are Subgraphs/Webhooks-only (or read the contract's print feed and switch on topic)");
4344
4323
  }
4345
- this.pending.clear();
4346
- if (this.reconnect && this.subs.size > 0 && this.reconnectAttempt < this.reconnectMaxAttempts) {
4347
- this.scheduleReconnect();
4324
+ if (key === "lockedAddress") {
4325
+ out.sender = value;
4326
+ continue;
4348
4327
  }
4349
- }
4350
- scheduleReconnect() {
4351
- if (this.destroyed || this.reconnecting)
4352
- return;
4353
- this.reconnecting = true;
4354
- const delay = this.reconnectBaseDelay * 2 ** this.reconnectAttempt;
4355
- this.reconnectAttempt++;
4356
- this.reconnectTimer = setTimeout(async () => {
4357
- this.reconnecting = false;
4358
- try {
4359
- await this.connect();
4360
- await this.resubscribeAll();
4361
- } catch {
4362
- if (!this.destroyed && this.subs.size > 0) {
4363
- this.handleDisconnect();
4364
- }
4365
- }
4366
- }, delay);
4367
- }
4368
- async resubscribeAll() {
4369
- for (const [, entry] of this.subs) {
4370
- await this.sendRpc("subscribe", entry.params);
4328
+ if (key === "caller" && spec.type !== "nested_contract_call") {
4329
+ unsupported("Index events", "caller", "outer contract-call fields live on index.contractCalls");
4371
4330
  }
4331
+ out[key] = value;
4372
4332
  }
4373
- sendRpc(method, params) {
4374
- return new Promise((resolve, reject) => {
4375
- if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
4376
- return reject(new WebSocketError("WebSocket not connected"));
4377
- }
4378
- const id = this.nextId++;
4379
- const msg = {
4380
- jsonrpc: "2.0",
4381
- id,
4382
- method,
4383
- params
4384
- };
4385
- this.pending.set(id, { resolve, reject });
4386
- this.ws.send(JSON.stringify(msg));
4387
- });
4388
- }
4389
- async subscribe(params, callback) {
4390
- if (this.destroyed) {
4391
- throw new WebSocketError("WebSocket channel has been destroyed");
4333
+ return { ...out, ...extra };
4334
+ }
4335
+ var VM_MEMBERS = new Set([
4336
+ "nested_contract_call",
4337
+ "var_set",
4338
+ "map_set",
4339
+ "map_insert",
4340
+ "map_delete"
4341
+ ]);
4342
+ var VM_INDEX_ONLY_FIELDS = new Set([
4343
+ "functionName",
4344
+ "caller",
4345
+ "sender",
4346
+ "map",
4347
+ "varName"
4348
+ ]);
4349
+ function toStreamsParams(spec, extra = {}) {
4350
+ assertNoWildcards("Streams", spec);
4351
+ const out = {
4352
+ types: [spec.type === "print_event" ? "print" : spec.type]
4353
+ };
4354
+ const isVm = VM_MEMBERS.has(spec.type);
4355
+ if (isVm)
4356
+ out.clock = "vm";
4357
+ for (const [key, value] of specEntries(spec)) {
4358
+ if (DECORATIVE_FIELDS.has(key))
4359
+ continue;
4360
+ if (isVm && VM_INDEX_ONLY_FIELDS.has(key)) {
4361
+ unsupported("Streams", key, "vm payload predicates are Index/Subgraphs/Subscriptions-only; Streams clock=vm narrows by types and contractId");
4392
4362
  }
4393
- await this.connect();
4394
- const key = subKey(params);
4395
- let entry = this.subs.get(key);
4396
- if (entry) {
4397
- entry.callbacks.add(callback);
4398
- } else {
4399
- entry = { params, callbacks: new Set([callback]) };
4400
- this.subs.set(key, entry);
4401
- await this.sendRpc("subscribe", params);
4363
+ if (key === "factory") {
4364
+ unsupported("Streams", "factory", "dynamic factory discovery is a Subgraphs-only concept");
4402
4365
  }
4403
- return {
4404
- unsubscribe: () => {
4405
- const e = this.subs.get(key);
4406
- if (!e)
4407
- return;
4408
- e.callbacks.delete(callback);
4409
- if (e.callbacks.size === 0) {
4410
- this.subs.delete(key);
4411
- if (this.ws?.readyState === WebSocket.OPEN) {
4412
- this.sendRpc("unsubscribe", params).catch(() => {});
4413
- }
4414
- if (this.subs.size === 0)
4415
- this.closeQuietly();
4416
- }
4417
- }
4418
- };
4419
- }
4420
- closeQuietly() {
4421
- if (this.ws) {
4422
- this.ws.close();
4423
- this.ws = null;
4366
+ if (AMOUNT_FIELDS.has(key)) {
4367
+ unsupported("Streams", key, "amount predicates are Webhooks/Subgraphs-only");
4368
+ }
4369
+ if (key === "trait") {
4370
+ unsupported("Streams", "trait", "Streams has no trait resolution — Index and Subgraphs do");
4371
+ }
4372
+ if (key === "topic") {
4373
+ unsupported("Streams", "topic", "per-topic filtering is Subgraphs/Webhooks-only");
4374
+ }
4375
+ if (key === "lockedAddress") {
4376
+ unsupported("Streams", "lockedAddress", "stx_lock address filtering is Webhooks/Subgraphs-only");
4424
4377
  }
4378
+ out[key] = value;
4425
4379
  }
4426
- destroy() {
4427
- this.destroyed = true;
4428
- if (this.reconnectTimer)
4429
- clearTimeout(this.reconnectTimer);
4430
- for (const [, p] of this.pending) {
4431
- p.reject(new WebSocketError("WebSocket channel destroyed"));
4380
+ return { ...out, ...extra };
4381
+ }
4382
+ function toContractCallsParams(spec, extra = {}) {
4383
+ assertNoWildcards("Index contract-calls", spec);
4384
+ assertNotTraitAndContract("Index contract-calls", spec);
4385
+ const out = {};
4386
+ for (const [key, value] of specEntries(spec)) {
4387
+ if (DECORATIVE_FIELDS.has(key))
4388
+ continue;
4389
+ if (key === "factory") {
4390
+ unsupported("Index contract-calls", "factory", "dynamic factory discovery is a Subgraphs-only concept");
4432
4391
  }
4433
- this.pending.clear();
4434
- this.subs.clear();
4435
- if (this.ws) {
4436
- this.ws.close();
4437
- this.ws = null;
4392
+ if (key === "caller") {
4393
+ out.sender = value;
4394
+ continue;
4438
4395
  }
4396
+ out[key] = value;
4439
4397
  }
4398
+ return { ...out, ...extra };
4440
4399
  }
4441
- function deriveWsUrl(httpUrl) {
4442
- return `${httpUrl.replace(/^http/, "ws").replace(/\/$/, "")}/extended/v1/ws`;
4400
+ function toSubgraphSource(spec) {
4401
+ return Object.fromEntries([
4402
+ ["type", spec.type],
4403
+ ...specEntries(spec)
4404
+ ]);
4443
4405
  }
4444
- function webSocket(url, config) {
4445
- return (params) => {
4446
- const httpUrl = config?.url ?? params?.chain?.rpcUrls.default.http[0] ?? "http://localhost:3999";
4447
- const wsUrl = url ?? params?.chain?.rpcUrls.default.ws?.[0] ?? deriveWsUrl(httpUrl);
4448
- const resolvedHttpConfig = {
4449
- ...config,
4450
- url: httpUrl
4451
- };
4452
- const channel = new WebSocketChannel(wsUrl, config);
4453
- const { apiKey: _apiKey, ...exposedConfig } = resolvedHttpConfig;
4454
- const transport = {
4455
- type: "webSocket",
4456
- request: buildRequestFn(httpUrl, resolvedHttpConfig),
4457
- config: exposedConfig,
4458
- subscribe: (subParams, callback) => channel.subscribe(subParams, callback),
4459
- destroy: () => channel.destroy()
4460
- };
4461
- return transport;
4462
- };
4406
+ var DECODED_MEMBERS = new Set([
4407
+ "stx_transfer",
4408
+ "stx_mint",
4409
+ "stx_burn",
4410
+ "stx_lock",
4411
+ "ft_transfer",
4412
+ "ft_mint",
4413
+ "ft_burn",
4414
+ "nft_transfer",
4415
+ "nft_mint",
4416
+ "nft_burn",
4417
+ "print_event"
4418
+ ]);
4419
+ function makeChainEventFilter(type, fields) {
4420
+ const spec = { type, ...fields };
4421
+ validateSpec(spec);
4422
+ const filter = { ...spec };
4423
+ filter.toChainTrigger = () => toChainTrigger(spec);
4424
+ if (DECODED_MEMBERS.has(type) || VM_MEMBERS.has(type)) {
4425
+ filter.toIndexParams = (extra) => toIndexParams(spec, extra);
4426
+ filter.toStreamsParams = (extra) => toStreamsParams(spec, extra);
4427
+ }
4428
+ if (type === "contract_call") {
4429
+ filter.toContractCallsParams = (extra) => toContractCallsParams(spec, extra);
4430
+ }
4431
+ if (!type.startsWith("sbtc_")) {
4432
+ filter.toSubgraphSource = () => toSubgraphSource(spec);
4433
+ }
4434
+ return filter;
4435
+ }
4436
+ function fromSubgraphSource(source) {
4437
+ const { type, ...fields } = source;
4438
+ return makeChainEventFilter(type, fields);
4463
4439
  }
4440
+ var on = {
4441
+ stxTransfer: (fields = {}) => makeChainEventFilter("stx_transfer", fields),
4442
+ stxMint: (fields = {}) => makeChainEventFilter("stx_mint", fields),
4443
+ stxBurn: (fields = {}) => makeChainEventFilter("stx_burn", fields),
4444
+ stxLock: (fields = {}) => makeChainEventFilter("stx_lock", fields),
4445
+ ftTransfer: (fields = {}) => makeChainEventFilter("ft_transfer", fields),
4446
+ ftMint: (fields = {}) => makeChainEventFilter("ft_mint", fields),
4447
+ ftBurn: (fields = {}) => makeChainEventFilter("ft_burn", fields),
4448
+ nftTransfer: (fields = {}) => makeChainEventFilter("nft_transfer", fields),
4449
+ nftMint: (fields = {}) => makeChainEventFilter("nft_mint", fields),
4450
+ nftBurn: (fields = {}) => makeChainEventFilter("nft_burn", fields),
4451
+ contractCall: (fields = {}) => makeChainEventFilter("contract_call", fields),
4452
+ contractDeploy: (fields = {}) => makeChainEventFilter("contract_deploy", fields),
4453
+ print: (fields = {}) => makeChainEventFilter("print_event", fields),
4454
+ nestedCall: (fields = {}) => makeChainEventFilter("nested_contract_call", fields),
4455
+ varSet: (fields = {}) => makeChainEventFilter("var_set", fields),
4456
+ mapSet: (fields = {}) => makeChainEventFilter("map_set", fields),
4457
+ mapInsert: (fields = {}) => makeChainEventFilter("map_insert", fields),
4458
+ mapDelete: (fields = {}) => makeChainEventFilter("map_delete", fields),
4459
+ sbtcDeposit: (fields = {}) => makeChainEventFilter("sbtc_deposit", fields),
4460
+ sbtcWithdrawalCreate: (fields = {}) => makeChainEventFilter("sbtc_withdrawal_create", fields),
4461
+ sbtcWithdrawalAccept: (fields = {}) => makeChainEventFilter("sbtc_withdrawal_accept", fields),
4462
+ sbtcWithdrawalReject: (fields = {}) => makeChainEventFilter("sbtc_withdrawal_reject", fields),
4463
+ sbtcWithdrawalSweptConfirmed: (fields = {}) => makeChainEventFilter("sbtc_withdrawal_swept_confirmed", fields)
4464
+ };
4464
4465
  // src/accounts/providerToAccount.ts
4465
4466
  async function providerToAccount(provider) {
4466
4467
  const result = await provider.request("stx_getAddresses");
@@ -4588,5 +4589,5 @@ function parseStx(stx) {
4588
4589
  return parseUnits(stx, 6);
4589
4590
  }
4590
4591
 
4591
- //# debugId=3FA35CAE5C34437464756E2164756E21
4592
+ //# debugId=BBEDE03C59EADB7164756E2164756E21
4592
4593
  //# sourceMappingURL=index.cjs.map