@bananapus/nana-sdk-core 3.5.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. package/bin/wallet-check.mjs +489 -0
  2. package/dist/cjs/actions/suckerPairs.d.ts +5 -3
  3. package/dist/cjs/actions/suckerPairs.d.ts.map +1 -1
  4. package/dist/cjs/actions/suckerPairs.js +6 -26
  5. package/dist/cjs/actions/suckerPairs.js.map +1 -1
  6. package/dist/cjs/pause.d.ts +2 -0
  7. package/dist/cjs/pause.d.ts.map +1 -1
  8. package/dist/cjs/pause.js +17 -0
  9. package/dist/cjs/pause.js.map +1 -1
  10. package/dist/cjs/review/confirm.d.ts +52 -0
  11. package/dist/cjs/review/confirm.d.ts.map +1 -0
  12. package/dist/cjs/review/confirm.js +88 -0
  13. package/dist/cjs/review/confirm.js.map +1 -0
  14. package/dist/cjs/review/contractWrite.d.ts +5 -3
  15. package/dist/cjs/review/contractWrite.d.ts.map +1 -1
  16. package/dist/cjs/review/contractWrite.js +8 -7
  17. package/dist/cjs/review/contractWrite.js.map +1 -1
  18. package/dist/cjs/review/decode.d.ts +19 -1
  19. package/dist/cjs/review/decode.d.ts.map +1 -1
  20. package/dist/cjs/review/decode.js +30 -11
  21. package/dist/cjs/review/decode.js.map +1 -1
  22. package/dist/cjs/review/decodeCall.d.ts +21 -0
  23. package/dist/cjs/review/decodeCall.d.ts.map +1 -0
  24. package/dist/cjs/review/decodeCall.js +183 -0
  25. package/dist/cjs/review/decodeCall.js.map +1 -0
  26. package/dist/cjs/review/heldWrite.d.ts.map +1 -1
  27. package/dist/cjs/review/heldWrite.js +5 -4
  28. package/dist/cjs/review/heldWrite.js.map +1 -1
  29. package/dist/cjs/review/index.d.ts +11 -0
  30. package/dist/cjs/review/index.d.ts.map +1 -1
  31. package/dist/cjs/review/index.js +24 -0
  32. package/dist/cjs/review/index.js.map +1 -1
  33. package/dist/cjs/review/intents.d.ts +10 -0
  34. package/dist/cjs/review/intents.d.ts.map +1 -1
  35. package/dist/cjs/review/intents.js +13 -0
  36. package/dist/cjs/review/intents.js.map +1 -1
  37. package/dist/cjs/review/lineError.d.ts +34 -0
  38. package/dist/cjs/review/lineError.d.ts.map +1 -0
  39. package/dist/cjs/review/lineError.js +42 -0
  40. package/dist/cjs/review/lineError.js.map +1 -0
  41. package/dist/cjs/review/messages.d.ts +15 -3
  42. package/dist/cjs/review/messages.d.ts.map +1 -1
  43. package/dist/cjs/review/messages.js +16 -4
  44. package/dist/cjs/review/messages.js.map +1 -1
  45. package/dist/cjs/review/model.d.ts +149 -0
  46. package/dist/cjs/review/model.d.ts.map +1 -0
  47. package/dist/cjs/review/model.js +750 -0
  48. package/dist/cjs/review/model.js.map +1 -0
  49. package/dist/cjs/review/plan.d.ts +63 -0
  50. package/dist/cjs/review/plan.d.ts.map +1 -0
  51. package/dist/cjs/review/plan.js +149 -0
  52. package/dist/cjs/review/plan.js.map +1 -0
  53. package/dist/cjs/review/react/index.d.ts +1 -0
  54. package/dist/cjs/review/react/index.d.ts.map +1 -1
  55. package/dist/cjs/review/react/index.js +1 -0
  56. package/dist/cjs/review/react/index.js.map +1 -1
  57. package/dist/cjs/review/react/useReviewedRun.d.ts +96 -0
  58. package/dist/cjs/review/react/useReviewedRun.d.ts.map +1 -0
  59. package/dist/cjs/review/react/useReviewedRun.js +261 -0
  60. package/dist/cjs/review/react/useReviewedRun.js.map +1 -0
  61. package/dist/cjs/review/receipt.d.ts +4 -1
  62. package/dist/cjs/review/receipt.d.ts.map +1 -1
  63. package/dist/cjs/review/receipt.js +7 -3
  64. package/dist/cjs/review/receipt.js.map +1 -1
  65. package/dist/cjs/review/relayr.d.ts +13 -4
  66. package/dist/cjs/review/relayr.d.ts.map +1 -1
  67. package/dist/cjs/review/relayr.js +51 -8
  68. package/dist/cjs/review/relayr.js.map +1 -1
  69. package/dist/cjs/review/relayrSend.d.ts +135 -0
  70. package/dist/cjs/review/relayrSend.d.ts.map +1 -0
  71. package/dist/cjs/review/relayrSend.js +943 -0
  72. package/dist/cjs/review/relayrSend.js.map +1 -0
  73. package/dist/cjs/review/reviewQueue.d.ts +10 -9
  74. package/dist/cjs/review/reviewQueue.d.ts.map +1 -1
  75. package/dist/cjs/review/reviewQueue.js +19 -29
  76. package/dist/cjs/review/reviewQueue.js.map +1 -1
  77. package/dist/cjs/review/reviewRequests.d.ts +86 -0
  78. package/dist/cjs/review/reviewRequests.d.ts.map +1 -0
  79. package/dist/cjs/review/reviewRequests.js +266 -0
  80. package/dist/cjs/review/reviewRequests.js.map +1 -0
  81. package/dist/cjs/review/safeRelayr.d.ts +3 -1
  82. package/dist/cjs/review/safeRelayr.d.ts.map +1 -1
  83. package/dist/cjs/review/safeRelayr.js +5 -1
  84. package/dist/cjs/review/safeRelayr.js.map +1 -1
  85. package/dist/cjs/review/safeSend.d.ts +69 -0
  86. package/dist/cjs/review/safeSend.d.ts.map +1 -0
  87. package/dist/cjs/review/safeSend.js +308 -0
  88. package/dist/cjs/review/safeSend.js.map +1 -0
  89. package/dist/cjs/review/send.d.ts +241 -0
  90. package/dist/cjs/review/send.d.ts.map +1 -0
  91. package/dist/cjs/review/send.js +1017 -0
  92. package/dist/cjs/review/send.js.map +1 -0
  93. package/dist/cjs/review/sequence.d.ts +77 -0
  94. package/dist/cjs/review/sequence.d.ts.map +1 -0
  95. package/dist/cjs/review/sequence.js +232 -0
  96. package/dist/cjs/review/sequence.js.map +1 -0
  97. package/dist/cjs/review/sign.d.ts +109 -0
  98. package/dist/cjs/review/sign.d.ts.map +1 -0
  99. package/dist/cjs/review/sign.js +374 -0
  100. package/dist/cjs/review/sign.js.map +1 -0
  101. package/dist/cjs/review/simulation.d.ts +41 -2
  102. package/dist/cjs/review/simulation.d.ts.map +1 -1
  103. package/dist/cjs/review/simulation.js +99 -29
  104. package/dist/cjs/review/simulation.js.map +1 -1
  105. package/dist/cjs/review/transaction-message.d.ts +13 -0
  106. package/dist/cjs/review/transaction-message.d.ts.map +1 -1
  107. package/dist/cjs/review/transaction-message.js +25 -0
  108. package/dist/cjs/review/transaction-message.js.map +1 -1
  109. package/dist/cjs/review/transactionReview.d.ts +27 -19
  110. package/dist/cjs/review/transactionReview.d.ts.map +1 -1
  111. package/dist/cjs/review/transactionReview.js +22 -63
  112. package/dist/cjs/review/transactionReview.js.map +1 -1
  113. package/dist/cjs/review/wallet.d.ts +82 -0
  114. package/dist/cjs/review/wallet.d.ts.map +1 -0
  115. package/dist/cjs/review/wallet.js +157 -0
  116. package/dist/cjs/review/wallet.js.map +1 -0
  117. package/dist/cjs/review/writeHold.d.ts +100 -12
  118. package/dist/cjs/review/writeHold.d.ts.map +1 -1
  119. package/dist/cjs/review/writeHold.js +61 -13
  120. package/dist/cjs/review/writeHold.js.map +1 -1
  121. package/dist/cjs/review/writeRecovery.d.ts +6 -1
  122. package/dist/cjs/review/writeRecovery.d.ts.map +1 -1
  123. package/dist/cjs/review/writeRecovery.js +108 -40
  124. package/dist/cjs/review/writeRecovery.js.map +1 -1
  125. package/dist/cjs/safeService.d.ts +27 -4
  126. package/dist/cjs/safeService.d.ts.map +1 -1
  127. package/dist/cjs/safeService.js +120 -3
  128. package/dist/cjs/safeService.js.map +1 -1
  129. package/dist/cjs/testing.d.ts +24 -0
  130. package/dist/cjs/testing.d.ts.map +1 -1
  131. package/dist/cjs/testing.js +26 -1
  132. package/dist/cjs/testing.js.map +1 -1
  133. package/dist/cjs/v6/defifa.d.ts.map +1 -1
  134. package/dist/cjs/v6/defifa.js +24 -23
  135. package/dist/cjs/v6/defifa.js.map +1 -1
  136. package/dist/cjs/v6/executionErrors.d.ts.map +1 -1
  137. package/dist/cjs/v6/executionErrors.js +3 -2
  138. package/dist/cjs/v6/executionErrors.js.map +1 -1
  139. package/dist/cjs/v6/pay.d.ts +25 -7
  140. package/dist/cjs/v6/pay.d.ts.map +1 -1
  141. package/dist/cjs/v6/pay.js +168 -40
  142. package/dist/cjs/v6/pay.js.map +1 -1
  143. package/dist/cjs/v6/suckers.d.ts +30 -0
  144. package/dist/cjs/v6/suckers.d.ts.map +1 -1
  145. package/dist/cjs/v6/suckers.js +69 -5
  146. package/dist/cjs/v6/suckers.js.map +1 -1
  147. package/dist/esm/actions/suckerPairs.d.ts +5 -3
  148. package/dist/esm/actions/suckerPairs.d.ts.map +1 -1
  149. package/dist/esm/actions/suckerPairs.js +7 -27
  150. package/dist/esm/actions/suckerPairs.js.map +1 -1
  151. package/dist/esm/pause.d.ts +2 -0
  152. package/dist/esm/pause.d.ts.map +1 -1
  153. package/dist/esm/pause.js +16 -0
  154. package/dist/esm/pause.js.map +1 -1
  155. package/dist/esm/review/confirm.d.ts +52 -0
  156. package/dist/esm/review/confirm.d.ts.map +1 -0
  157. package/dist/esm/review/confirm.js +83 -0
  158. package/dist/esm/review/confirm.js.map +1 -0
  159. package/dist/esm/review/contractWrite.d.ts +5 -3
  160. package/dist/esm/review/contractWrite.d.ts.map +1 -1
  161. package/dist/esm/review/contractWrite.js +8 -7
  162. package/dist/esm/review/contractWrite.js.map +1 -1
  163. package/dist/esm/review/decode.d.ts +19 -1
  164. package/dist/esm/review/decode.d.ts.map +1 -1
  165. package/dist/esm/review/decode.js +29 -14
  166. package/dist/esm/review/decode.js.map +1 -1
  167. package/dist/esm/review/decodeCall.d.ts +21 -0
  168. package/dist/esm/review/decodeCall.d.ts.map +1 -0
  169. package/dist/esm/review/decodeCall.js +180 -0
  170. package/dist/esm/review/decodeCall.js.map +1 -0
  171. package/dist/esm/review/heldWrite.d.ts.map +1 -1
  172. package/dist/esm/review/heldWrite.js +5 -4
  173. package/dist/esm/review/heldWrite.js.map +1 -1
  174. package/dist/esm/review/index.d.ts +11 -0
  175. package/dist/esm/review/index.d.ts.map +1 -1
  176. package/dist/esm/review/index.js +11 -0
  177. package/dist/esm/review/index.js.map +1 -1
  178. package/dist/esm/review/intents.d.ts +10 -0
  179. package/dist/esm/review/intents.d.ts.map +1 -1
  180. package/dist/esm/review/intents.js +12 -0
  181. package/dist/esm/review/intents.js.map +1 -1
  182. package/dist/esm/review/lineError.d.ts +34 -0
  183. package/dist/esm/review/lineError.d.ts.map +1 -0
  184. package/dist/esm/review/lineError.js +36 -0
  185. package/dist/esm/review/lineError.js.map +1 -0
  186. package/dist/esm/review/messages.d.ts +15 -3
  187. package/dist/esm/review/messages.d.ts.map +1 -1
  188. package/dist/esm/review/messages.js +15 -3
  189. package/dist/esm/review/messages.js.map +1 -1
  190. package/dist/esm/review/model.d.ts +149 -0
  191. package/dist/esm/review/model.d.ts.map +1 -0
  192. package/dist/esm/review/model.js +746 -0
  193. package/dist/esm/review/model.js.map +1 -0
  194. package/dist/esm/review/plan.d.ts +63 -0
  195. package/dist/esm/review/plan.d.ts.map +1 -0
  196. package/dist/esm/review/plan.js +141 -0
  197. package/dist/esm/review/plan.js.map +1 -0
  198. package/dist/esm/review/react/index.d.ts +1 -0
  199. package/dist/esm/review/react/index.d.ts.map +1 -1
  200. package/dist/esm/review/react/index.js +1 -0
  201. package/dist/esm/review/react/index.js.map +1 -1
  202. package/dist/esm/review/react/useReviewedRun.d.ts +96 -0
  203. package/dist/esm/review/react/useReviewedRun.d.ts.map +1 -0
  204. package/dist/esm/review/react/useReviewedRun.js +257 -0
  205. package/dist/esm/review/react/useReviewedRun.js.map +1 -0
  206. package/dist/esm/review/receipt.d.ts +4 -1
  207. package/dist/esm/review/receipt.d.ts.map +1 -1
  208. package/dist/esm/review/receipt.js +6 -2
  209. package/dist/esm/review/receipt.js.map +1 -1
  210. package/dist/esm/review/relayr.d.ts +13 -4
  211. package/dist/esm/review/relayr.d.ts.map +1 -1
  212. package/dist/esm/review/relayr.js +50 -8
  213. package/dist/esm/review/relayr.js.map +1 -1
  214. package/dist/esm/review/relayrSend.d.ts +135 -0
  215. package/dist/esm/review/relayrSend.d.ts.map +1 -0
  216. package/dist/esm/review/relayrSend.js +934 -0
  217. package/dist/esm/review/relayrSend.js.map +1 -0
  218. package/dist/esm/review/reviewQueue.d.ts +10 -9
  219. package/dist/esm/review/reviewQueue.d.ts.map +1 -1
  220. package/dist/esm/review/reviewQueue.js +17 -26
  221. package/dist/esm/review/reviewQueue.js.map +1 -1
  222. package/dist/esm/review/reviewRequests.d.ts +86 -0
  223. package/dist/esm/review/reviewRequests.d.ts.map +1 -0
  224. package/dist/esm/review/reviewRequests.js +263 -0
  225. package/dist/esm/review/reviewRequests.js.map +1 -0
  226. package/dist/esm/review/safeRelayr.d.ts +3 -1
  227. package/dist/esm/review/safeRelayr.d.ts.map +1 -1
  228. package/dist/esm/review/safeRelayr.js +5 -1
  229. package/dist/esm/review/safeRelayr.js.map +1 -1
  230. package/dist/esm/review/safeSend.d.ts +69 -0
  231. package/dist/esm/review/safeSend.d.ts.map +1 -0
  232. package/dist/esm/review/safeSend.js +303 -0
  233. package/dist/esm/review/safeSend.js.map +1 -0
  234. package/dist/esm/review/send.d.ts +241 -0
  235. package/dist/esm/review/send.d.ts.map +1 -0
  236. package/dist/esm/review/send.js +1011 -0
  237. package/dist/esm/review/send.js.map +1 -0
  238. package/dist/esm/review/sequence.d.ts +77 -0
  239. package/dist/esm/review/sequence.d.ts.map +1 -0
  240. package/dist/esm/review/sequence.js +223 -0
  241. package/dist/esm/review/sequence.js.map +1 -0
  242. package/dist/esm/review/sign.d.ts +109 -0
  243. package/dist/esm/review/sign.d.ts.map +1 -0
  244. package/dist/esm/review/sign.js +368 -0
  245. package/dist/esm/review/sign.js.map +1 -0
  246. package/dist/esm/review/simulation.d.ts +41 -2
  247. package/dist/esm/review/simulation.d.ts.map +1 -1
  248. package/dist/esm/review/simulation.js +95 -29
  249. package/dist/esm/review/simulation.js.map +1 -1
  250. package/dist/esm/review/transaction-message.d.ts +13 -0
  251. package/dist/esm/review/transaction-message.d.ts.map +1 -1
  252. package/dist/esm/review/transaction-message.js +23 -0
  253. package/dist/esm/review/transaction-message.js.map +1 -1
  254. package/dist/esm/review/transactionReview.d.ts +27 -19
  255. package/dist/esm/review/transactionReview.d.ts.map +1 -1
  256. package/dist/esm/review/transactionReview.js +19 -56
  257. package/dist/esm/review/transactionReview.js.map +1 -1
  258. package/dist/esm/review/wallet.d.ts +82 -0
  259. package/dist/esm/review/wallet.d.ts.map +1 -0
  260. package/dist/esm/review/wallet.js +150 -0
  261. package/dist/esm/review/wallet.js.map +1 -0
  262. package/dist/esm/review/writeHold.d.ts +100 -12
  263. package/dist/esm/review/writeHold.d.ts.map +1 -1
  264. package/dist/esm/review/writeHold.js +59 -13
  265. package/dist/esm/review/writeHold.js.map +1 -1
  266. package/dist/esm/review/writeRecovery.d.ts +6 -1
  267. package/dist/esm/review/writeRecovery.d.ts.map +1 -1
  268. package/dist/esm/review/writeRecovery.js +111 -43
  269. package/dist/esm/review/writeRecovery.js.map +1 -1
  270. package/dist/esm/safeService.d.ts +27 -4
  271. package/dist/esm/safeService.d.ts.map +1 -1
  272. package/dist/esm/safeService.js +119 -4
  273. package/dist/esm/safeService.js.map +1 -1
  274. package/dist/esm/testing.d.ts +24 -0
  275. package/dist/esm/testing.d.ts.map +1 -1
  276. package/dist/esm/testing.js +23 -1
  277. package/dist/esm/testing.js.map +1 -1
  278. package/dist/esm/v6/defifa.d.ts.map +1 -1
  279. package/dist/esm/v6/defifa.js +24 -23
  280. package/dist/esm/v6/defifa.js.map +1 -1
  281. package/dist/esm/v6/executionErrors.d.ts.map +1 -1
  282. package/dist/esm/v6/executionErrors.js +3 -2
  283. package/dist/esm/v6/executionErrors.js.map +1 -1
  284. package/dist/esm/v6/pay.d.ts +25 -7
  285. package/dist/esm/v6/pay.d.ts.map +1 -1
  286. package/dist/esm/v6/pay.js +166 -39
  287. package/dist/esm/v6/pay.js.map +1 -1
  288. package/dist/esm/v6/suckers.d.ts +30 -0
  289. package/dist/esm/v6/suckers.d.ts.map +1 -1
  290. package/dist/esm/v6/suckers.js +67 -5
  291. package/dist/esm/v6/suckers.js.map +1 -1
  292. package/package.json +11 -2
@@ -0,0 +1,368 @@
1
+ import { ReviewLineError } from "./lineError.js";
2
+ import { encodeFunctionData, getAddress, hashTypedData, isAddress, } from "viem";
3
+ import { multiSendCallsOf } from "../safe.js";
4
+ import { isHexBytes, uint256 } from "../untrusted.js";
5
+ import { SAFE_EXEC_ABI, SAFE_TX_TYPES, safeTransactionMessage, } from "../safeService.js";
6
+ import { permit2TypedData, } from "../v6/permit2.js";
7
+ import { promptReview } from "./confirm.js";
8
+ import { isDefiniteWalletRejection, submitReviewedContractWrite, } from "./contractWrite.js";
9
+ import { permit2Rows } from "./decode.js";
10
+ import { decodeReviewCall } from "./decodeCall.js";
11
+ import { buildReviewModel } from "./model.js";
12
+ import { REVIEWED_PLAN_REFUSED_LINE, spendPlan, } from "./plan.js";
13
+ import { FORWARD_REQUEST_TYPES, relayrForwarder, relayrForwarderDeadline, } from "./relayr.js";
14
+ import { TransactionReviewCancelledError } from "./reviewQueue.js";
15
+ import { unsupportedWalletRequest, walletReady, } from "./wallet.js";
16
+ const REJECTED = "You rejected the signature. Nothing was sent.";
17
+ function requireChainId(chainId) {
18
+ if (typeof chainId !== "number" ||
19
+ !Number.isSafeInteger(chainId) ||
20
+ chainId <= 0) {
21
+ throw new ReviewLineError("Invalid chain ID.");
22
+ }
23
+ return chainId;
24
+ }
25
+ function requireAddress(name, value) {
26
+ if (typeof value !== "string" || !isAddress(value)) {
27
+ throw new ReviewLineError(`Invalid ${name} address.`);
28
+ }
29
+ return getAddress(value);
30
+ }
31
+ /** An unsigned integer as a primitive, so nothing can change it after review. */
32
+ function requireUint(name, value) {
33
+ const parsed = uint256(value);
34
+ if (parsed === null)
35
+ throw new ReviewLineError(`Invalid ${name}.`);
36
+ return parsed;
37
+ }
38
+ /** `value` and everything in it frozen. */
39
+ function frozen(value) {
40
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
41
+ Object.freeze(value);
42
+ for (const inner of Object.values(value))
43
+ frozen(inner);
44
+ }
45
+ return value;
46
+ }
47
+ /**
48
+ * The prepared signature: `payload` is what the wallet signs and what the
49
+ * review shows, one frozen copy, so neither the inputs nor the shared type
50
+ * constants changing after review changes what is signed. Typed data must
51
+ * encode first, so viem checks every address and integer before the review
52
+ * opens.
53
+ */
54
+ function prepared(kind, chainId, payload, shown = {}) {
55
+ const copy = frozen(structuredClone(payload));
56
+ const typedData = "typedData" in copy ? copy.typedData : null;
57
+ if (typedData)
58
+ hashTypedData(typedData);
59
+ return Object.freeze({
60
+ chainId,
61
+ typedData,
62
+ message: "message" in copy ? copy.message : null,
63
+ review: { kind, chainId, ...copy, ...shown },
64
+ });
65
+ }
66
+ /**
67
+ * `signature` as core signs and shows it, each field read once. Refuses any
68
+ * kind core does not know, a Safe transaction that DELEGATECALLs anything
69
+ * but a recognized MultiSendCallOnly, a forward request not from `account`,
70
+ * on a chain with no forwarder, or executable past
71
+ * {@link relayrForwarderDeadline}, and a message that is not text.
72
+ */
73
+ export function prepareSignature(signature, account) {
74
+ const kind = signature?.kind;
75
+ switch (kind) {
76
+ case "safe-tx": {
77
+ const { chainId, safe, tx } = signature;
78
+ const id = requireChainId(chainId);
79
+ const verifyingContract = requireAddress("Safe", safe);
80
+ const given = tx?.safeTxHash;
81
+ const message = safeTransactionMessage(tx);
82
+ // A hash the caller holds for it must be the one signed.
83
+ if (given != null &&
84
+ (typeof given !== "string" ||
85
+ given.toLowerCase() !==
86
+ hashTypedData({
87
+ domain: { chainId: id, verifyingContract },
88
+ types: SAFE_TX_TYPES,
89
+ primaryType: "SafeTx",
90
+ message,
91
+ })))
92
+ throw new ReviewLineError("This Safe transaction does not match its hash. Nothing was signed.");
93
+ const inner = multiSendCallsOf(message);
94
+ if (message.operation === 1 && !inner) {
95
+ throw new ReviewLineError("This Safe transaction DELEGATECALLs a contract other than MultiSendCallOnly. Nothing was signed.");
96
+ }
97
+ const args = [
98
+ message.to,
99
+ message.value,
100
+ message.data,
101
+ message.operation,
102
+ message.safeTxGas,
103
+ message.baseGas,
104
+ message.gasPrice,
105
+ message.gasToken,
106
+ message.refundReceiver,
107
+ "0x",
108
+ ];
109
+ return prepared(kind, id, {
110
+ typedData: {
111
+ domain: { chainId: id, verifyingContract },
112
+ types: SAFE_TX_TYPES,
113
+ primaryType: "SafeTx",
114
+ message,
115
+ },
116
+ }, {
117
+ // The Safe's own execution of it, with the MultiSend's calls inside.
118
+ calls: [
119
+ {
120
+ chainId: id,
121
+ to: verifyingContract,
122
+ data: encodeFunctionData({
123
+ abi: SAFE_EXEC_ABI,
124
+ functionName: "execTransaction",
125
+ args,
126
+ }),
127
+ abi: SAFE_EXEC_ABI,
128
+ functionName: "execTransaction",
129
+ args,
130
+ safeTxGas: message.safeTxGas,
131
+ contractName: "Safe",
132
+ ...(inner
133
+ ? {
134
+ calls: inner.map((call) => decodeReviewCall({
135
+ chainId: id,
136
+ from: verifyingContract,
137
+ ...call,
138
+ })),
139
+ }
140
+ : {}),
141
+ },
142
+ ],
143
+ });
144
+ }
145
+ case "forward-request": {
146
+ const { chainId, request } = signature;
147
+ const id = requireChainId(chainId);
148
+ const verifyingContract = relayrForwarder(id);
149
+ if (!verifyingContract) {
150
+ throw new ReviewLineError(`There is no Juicebox forwarder on chain ${id}. Nothing was signed.`);
151
+ }
152
+ const { from, to, value, gas, nonce, deadline, data } = request;
153
+ if (typeof from !== "string" ||
154
+ from.toLowerCase() !== account.toLowerCase()) {
155
+ throw new ReviewLineError("This request is not from the connected account. Nothing was signed.");
156
+ }
157
+ if (!Number.isSafeInteger(deadline) ||
158
+ deadline > relayrForwarderDeadline()) {
159
+ throw new ReviewLineError("This request stays executable longer than allowed. Nothing was signed.");
160
+ }
161
+ if (!isHexBytes(data))
162
+ throw new ReviewLineError("Invalid forwarded calldata.");
163
+ const message = {
164
+ from: requireAddress("sender", from),
165
+ to: requireAddress("destination", to),
166
+ value: requireUint("value", value),
167
+ gas: requireUint("gas", gas),
168
+ nonce: requireUint("nonce", nonce),
169
+ deadline,
170
+ data,
171
+ };
172
+ return prepared(kind, id, {
173
+ typedData: {
174
+ domain: {
175
+ name: "Juicebox",
176
+ version: "1",
177
+ chainId: id,
178
+ verifyingContract,
179
+ },
180
+ types: FORWARD_REQUEST_TYPES,
181
+ primaryType: "ForwardRequest",
182
+ message,
183
+ },
184
+ }, {
185
+ calls: [
186
+ decodeReviewCall({
187
+ chainId: id,
188
+ from: message.from,
189
+ to: message.to,
190
+ data,
191
+ value: message.value,
192
+ gas: message.gas,
193
+ }),
194
+ ],
195
+ });
196
+ }
197
+ case "permit2": {
198
+ const { chainId, token, spender, amount, expiration, nonce, sigDeadline, } = signature.authorization;
199
+ const id = requireChainId(chainId);
200
+ const authorization = {
201
+ chainId: id,
202
+ token: requireAddress("token", token),
203
+ spender: requireAddress("spender", spender),
204
+ amount: requireUint("amount", amount),
205
+ expiration: Number(requireUint("expiration", expiration)),
206
+ nonce: Number(requireUint("nonce", nonce)),
207
+ sigDeadline: requireUint("signature deadline", sigDeadline),
208
+ };
209
+ return prepared(kind, id, { typedData: permit2TypedData(authorization) }, {
210
+ steps: [
211
+ {
212
+ title: "Permit2 allowance",
213
+ rows: permit2Rows(id, authorization),
214
+ },
215
+ ],
216
+ });
217
+ }
218
+ case "message": {
219
+ const { chainId, message, calls } = signature;
220
+ const id = requireChainId(chainId);
221
+ if (typeof message !== "string") {
222
+ throw new ReviewLineError("A message to sign must be text. Nothing was signed.");
223
+ }
224
+ if (calls === undefined)
225
+ return prepared(kind, id, { message });
226
+ return prepared(kind, id, { message }, {
227
+ calls: [...calls].map((call) => {
228
+ const { chainId, to, data, value } = call;
229
+ if (!isHexBytes(data))
230
+ throw new ReviewLineError("Invalid call data.");
231
+ return decodeReviewCall({
232
+ chainId: requireChainId(chainId),
233
+ to: requireAddress("call target", to),
234
+ data,
235
+ value: requireUint("call value", value ?? 0n),
236
+ });
237
+ }),
238
+ });
239
+ }
240
+ }
241
+ throw new ReviewLineError("This signature is not one the app can review. Nothing was signed.");
242
+ }
243
+ /**
244
+ * Signs each prepared signature in order through the adapter, after the same
245
+ * account and chain checks as {@link submitReviewedContractWrite}: the
246
+ * connected account must stay `account`, and typed data is signed on its
247
+ * domain's chain. A message is chain-free, so the wallet is not asked to
248
+ * switch for one. A definite wallet rejection (EIP-1193 4001) returns no
249
+ * signature and throws {@link TransactionReviewCancelledError}.
250
+ */
251
+ export async function signPrepared(prepared, account, adapter,
252
+ /** The caller's final gate before each signature; it throws to stop. */
253
+ beforeSign,
254
+ /** The caller's async recheck before each signature, ahead of `beforeSign`. */
255
+ reverify) {
256
+ const signatures = [];
257
+ for (const { chainId, typedData, message } of prepared) {
258
+ signatures.push(await submitReviewedContractWrite({
259
+ request: { chainId },
260
+ expectedAccount: account,
261
+ review: () => Promise.resolve(),
262
+ switchChain: async (id) => {
263
+ if (typedData && adapter.chainId() !== id) {
264
+ await adapter.switchChain(id);
265
+ }
266
+ },
267
+ currentAccount: () => adapter.account(),
268
+ ...(reverify ? { reverify } : {}),
269
+ simulate: async () => undefined,
270
+ beforeSend: () => {
271
+ beforeSign?.();
272
+ if (typedData && adapter.chainId() !== chainId) {
273
+ throw new ReviewLineError("Your wallet changed networks. Review the signature again.");
274
+ }
275
+ // Last, after every callback above could have run.
276
+ if (adapter.account()?.toLowerCase() !== account.toLowerCase()) {
277
+ throw new ReviewLineError("The connected account changed. Review again.");
278
+ }
279
+ },
280
+ // Only the wallet's own answer can read as a rejection.
281
+ write: async () => {
282
+ try {
283
+ return await (typedData
284
+ ? adapter.signTypedData(typedData)
285
+ : adapter.signMessage(message));
286
+ }
287
+ catch (error) {
288
+ if (isDefiniteWalletRejection(error)) {
289
+ throw new TransactionReviewCancelledError(REJECTED);
290
+ }
291
+ throw error;
292
+ }
293
+ },
294
+ }));
295
+ }
296
+ return signatures;
297
+ }
298
+ /**
299
+ * The calls a prepared signature lets someone run, as a plan matches them,
300
+ * read from the exact payload signed: a Safe transaction's CALL or
301
+ * MultiSendCallOnly calls, from the Safe, when it pays no refund and its
302
+ * safeTxGas is 0 (so a failed call reverts, not spends the nonce), or a
303
+ * forward request's call, from its signer. Any other signature is refused
304
+ * under a plan.
305
+ */
306
+ export function plannedCallsOf({ chainId, typedData, }) {
307
+ const message = typedData?.message;
308
+ if (typedData?.primaryType === "SafeTx" && message) {
309
+ const { to, data, value, operation, safeTxGas, gasPrice } = message;
310
+ const safe = typedData.domain?.verifyingContract;
311
+ const inner = operation === 1
312
+ ? multiSendCallsOf({ to, data, operation })
313
+ : [{ to, data, value }];
314
+ if (safe && inner && safeTxGas === 0n && gasPrice === 0n)
315
+ return inner.map((call) => ({
316
+ chainId,
317
+ from: safe,
318
+ to: call.to,
319
+ data: call.data,
320
+ value: call.value,
321
+ }));
322
+ }
323
+ else if (typedData?.primaryType === "ForwardRequest" && message) {
324
+ const { from, to, data, value, gas } = message;
325
+ return [{ chainId, from, to, data, value, gas }];
326
+ }
327
+ throw new ReviewLineError(REVIEWED_PLAN_REFUSED_LINE);
328
+ }
329
+ /**
330
+ * Signs only what the person reviewed: one prompt for every signature, with
331
+ * the exact typed data or text and the calls each lets someone run, decoded.
332
+ * Nothing is signed unless the review handler returns core's confirmation
333
+ * ({@link registerReviewHandler}). The signatures come back in order.
334
+ *
335
+ * A self-reviewing adapter (Signa) is refused with EIP-1193 4200: it has no
336
+ * reviewed-signature path yet.
337
+ */
338
+ export async function signReviewed(signatures, action, deps) {
339
+ const { adapter } = deps;
340
+ const { account } = action;
341
+ await walletReady(adapter);
342
+ if (adapter.kind === "self-reviewing")
343
+ throw unsupportedWalletRequest();
344
+ const connected = adapter.account();
345
+ if (!connected)
346
+ throw new ReviewLineError("Connect a wallet first.");
347
+ if (connected.toLowerCase() !== account.toLowerCase()) {
348
+ throw new ReviewLineError("The connected account changed. Review again.");
349
+ }
350
+ const prepared = [...signatures].map((signature) => prepareSignature(signature, account));
351
+ if (!prepared.length)
352
+ throw new ReviewLineError("There is nothing to sign.");
353
+ if (action.plan) {
354
+ spendPlan(action.plan, account, prepared.flatMap(plannedCallsOf));
355
+ return signPrepared(prepared, account, adapter, undefined, action.reverify);
356
+ }
357
+ const model = buildReviewModel({
358
+ calls: [],
359
+ signatures: prepared.map(({ review }) => review),
360
+ ...(action.title ? { title: action.title } : {}),
361
+ ...(action.description ? { description: action.description } : {}),
362
+ ...(action.context ? { context: action.context } : {}),
363
+ });
364
+ // Nothing is sent, so there is nothing to simulate.
365
+ await promptReview(model, Promise.resolve({ status: "passed" }), Promise.resolve(model), action.signal);
366
+ return signPrepared(prepared, account, adapter, undefined, action.reverify);
367
+ }
368
+ //# sourceMappingURL=sign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign.js","sourceRoot":"","sources":["../../../src/review/sign.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,7 @@ export declare const TRANSACTION_SIMULATION_MAX_RETURN_BYTES = 4096;
13
13
  * `blockNumber` to simulate on the block a prerequisite (an approval, say) was
14
14
  * mined in, instead of `latest` on a node that may lag behind it.
15
15
  */
16
- export declare function simulateStateChangingTransaction(client: Pick<PublicClient, "request">, { from, to, data, value, gas, blockNumber, maxReturnBytes, }: {
16
+ export declare function simulateStateChangingTransaction(client: Pick<PublicClient, "request">, { from, to, data, value, gas, blockNumber, maxReturnBytes, balance, }: {
17
17
  from: Address;
18
18
  to: Address;
19
19
  data: Hex;
@@ -21,17 +21,54 @@ export declare function simulateStateChangingTransaction(client: Pick<PublicClie
21
21
  gas?: bigint;
22
22
  blockNumber?: bigint;
23
23
  maxReturnBytes?: number;
24
+ /** `from`'s balance for the simulation, in place of its own. */
25
+ balance?: bigint;
24
26
  }): Promise<Hex>;
25
27
  /** One call of an ordered sequence, such as a Safe MultiSend batch. */
26
28
  export type SimulatedSequenceCall = {
27
29
  to: Address;
28
30
  data: Hex;
29
31
  value?: bigint;
32
+ /** The exact gas limit the call is sent with, when the app fixed it. */
33
+ gas?: bigint;
30
34
  /** Names the call in a failure message. */
31
35
  label: string;
32
36
  /** Needs an earlier call's effect (an allowance, a hook), so it cannot run alone. */
33
37
  dependsOnPrior?: boolean;
38
+ /** Its value is paid for the sender (by Relayr): run alone, it gets the sequence's `balance`. */
39
+ funded?: boolean;
34
40
  };
41
+ /** The line for a revert whose reason the SDK does not know. */
42
+ export declare const REVERT_UNKNOWN_LINE = "This transaction would fail. Check the amounts and try again.";
43
+ /** The line for a simulation the node did not answer. */
44
+ export declare const SIMULATION_NO_ANSWER_LINE = "The node did not answer the simulation.";
45
+ /**
46
+ * Why a call reverted, when the SDK knows the revert: a payment revert's
47
+ * plain line ({@link decodePayFailure}). Null otherwise. Error text (viem's
48
+ * `shortMessage`, a node's message) is never read: it can quote a request or
49
+ * its URL.
50
+ */
51
+ export declare function revertReason(error: unknown): string | null;
52
+ /**
53
+ * A failed simulation's one-line reason: {@link revertReason}, or a fixed
54
+ * line, {@link REVERT_UNKNOWN_LINE} for a revert and
55
+ * {@link SIMULATION_NO_ANSWER_LINE} otherwise. Never the error's own text.
56
+ */
57
+ export declare function revertDetail(error: unknown): string;
58
+ /**
59
+ * Whether a failed simulation is the call reverting, not the node failing:
60
+ * EIP-1474 code 3, viem's contract-revert errors, or the node's own text
61
+ * saying it reverted, in the error's first eight causes. A viem error is read
62
+ * by its `details`, since its `message` quotes the request.
63
+ */
64
+ export declare function isRevert(error: unknown): boolean;
65
+ /**
66
+ * The error a failed simulation throws, with the answer as its cause: the
67
+ * SDK's own line (a {@link ReviewLineError}) for a revert, decoded or not; a
68
+ * plain error, which `errorLine` shows as the network line, for a node that
69
+ * did not answer.
70
+ */
71
+ export declare function simulationFailure(text: string, cause: unknown): Error;
35
72
  /**
36
73
  * Prove a whole sequence from `from` before anything is signed. `eth_simulateV1`
37
74
  * runs the calls in order against one state. Where a node lacks it, each call
@@ -39,9 +76,11 @@ export type SimulatedSequenceCall = {
39
76
  * {@link simulateStateChangingTransaction}; the dependent ones are left to the
40
77
  * executing wallet's own simulation. `chainName` names the chain in errors.
41
78
  */
42
- export declare function simulateCallSequence(client: Pick<PublicClient, "request" | "simulateCalls">, { from, calls, chainName, }: {
79
+ export declare function simulateCallSequence(client: Pick<PublicClient, "request" | "simulateCalls">, { from, calls, chainName, balance, }: {
43
80
  from: Address;
44
81
  calls: readonly SimulatedSequenceCall[];
45
82
  chainName: string;
83
+ /** `from`'s balance for the sequence, in place of its own; a call run alone gets it only when `funded`. */
84
+ balance?: bigint;
46
85
  }): Promise<void>;
47
86
  //# sourceMappingURL=simulation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"simulation.d.ts","sourceRoot":"","sources":["../../../src/review/simulation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,YAAY,EAAE,MAAM,MAAM,CAAC;AAE9E,+EAA+E;AAC/E,eAAO,MAAM,0BAA0B,YAAc,CAAC;AAEtD,+EAA+E;AAC/E,eAAO,MAAM,uCAAuC,OAAQ,CAAC;AAE7D;;;;;;;;;GASG;AACH,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,EACrC,EACE,IAAI,EACJ,EAAE,EACF,IAAI,EACJ,KAAU,EACV,GAAgC,EAChC,WAAW,EACX,cAAwD,GACzD,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,GAAG,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACA,OAAO,CAAC,GAAG,CAAC,CA6Bd;AAED,uEAAuE;AACvE,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,GAAG,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,qFAAqF;IACrF,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AA+DF;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,eAAe,CAAC,EACvD,EACE,IAAI,EACJ,KAAK,EACL,SAAS,GACV,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;CACnB,GACA,OAAO,CAAC,IAAI,CAAC,CA8Cf"}
1
+ {"version":3,"file":"simulation.d.ts","sourceRoot":"","sources":["../../../src/review/simulation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,YAAY,EAAE,MAAM,MAAM,CAAC;AAI9E,+EAA+E;AAC/E,eAAO,MAAM,0BAA0B,YAAc,CAAC;AAEtD,+EAA+E;AAC/E,eAAO,MAAM,uCAAuC,OAAQ,CAAC;AAE7D;;;;;;;;;GASG;AACH,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,EACrC,EACE,IAAI,EACJ,EAAE,EACF,IAAI,EACJ,KAAU,EACV,GAAgC,EAChC,WAAW,EACX,cAAwD,EACxD,OAAO,GACR,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,GAAG,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACA,OAAO,CAAC,GAAG,CAAC,CAmCd;AAED,uEAAuE;AACvE,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,GAAG,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,qFAAqF;IACrF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iGAAiG;IACjG,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,mBAAmB,kEACiC,CAAC;AAElE,yDAAyD;AACzD,eAAO,MAAM,yBAAyB,4CACK,CAAC;AAE5C;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAE1D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKnD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAsChD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,CAMrE;AAkDD;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,eAAe,CAAC,EACvD,EACE,IAAI,EACJ,KAAK,EACL,SAAS,EACT,OAAO,GACR,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,2GAA2G;IAC3G,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACA,OAAO,CAAC,IAAI,CAAC,CA2Df"}
@@ -1,4 +1,6 @@
1
1
  import { numberToHex } from "viem";
2
+ import { decodePayFailure } from "../v6/executionErrors.js";
3
+ import { ReviewLineError } from "./lineError.js";
2
4
  /** A generous explicit gas ceiling for a reviewed state-changing preflight. */
3
5
  export const TRANSACTION_SIMULATION_GAS = 10000000n;
4
6
  /** The most return data a preflight hands back to a caller that decodes it. */
@@ -13,45 +15,99 @@ export const TRANSACTION_SIMULATION_MAX_RETURN_BYTES = 4_096;
13
15
  * `blockNumber` to simulate on the block a prerequisite (an approval, say) was
14
16
  * mined in, instead of `latest` on a node that may lag behind it.
15
17
  */
16
- export async function simulateStateChangingTransaction(client, { from, to, data, value = 0n, gas = TRANSACTION_SIMULATION_GAS, blockNumber, maxReturnBytes = TRANSACTION_SIMULATION_MAX_RETURN_BYTES, }) {
18
+ export async function simulateStateChangingTransaction(client, { from, to, data, value = 0n, gas = TRANSACTION_SIMULATION_GAS, blockNumber, maxReturnBytes = TRANSACTION_SIMULATION_MAX_RETURN_BYTES, balance, }) {
17
19
  if (gas <= 0n) {
18
- throw new Error("Transaction simulation gas must be positive.");
20
+ throw new ReviewLineError("Transaction simulation gas must be positive.");
19
21
  }
20
22
  if (!Number.isSafeInteger(maxReturnBytes) || maxReturnBytes < 0) {
21
- throw new Error("Transaction simulation needs a return data limit.");
23
+ throw new ReviewLineError("Transaction simulation needs a return data limit.");
22
24
  }
23
25
  // A raw request bypasses call()/simulateContract(), whose behavior can
24
26
  // inherit a client-level CCIP-read policy.
27
+ const call = {
28
+ from,
29
+ to,
30
+ data,
31
+ value: numberToHex(value),
32
+ gas: numberToHex(gas),
33
+ };
34
+ const block = blockNumber === undefined ? "latest" : numberToHex(blockNumber);
25
35
  const result = await client.request({
26
36
  method: "eth_call",
27
- params: [
28
- {
29
- from,
30
- to,
31
- data,
32
- value: numberToHex(value),
33
- gas: numberToHex(gas),
34
- },
35
- blockNumber === undefined ? "latest" : numberToHex(blockNumber),
36
- ],
37
+ params: balance === undefined
38
+ ? [call, block]
39
+ : [call, block, { [from]: { balance: numberToHex(balance) } }],
37
40
  });
38
41
  if (typeof result !== "string" || !/^0x(?:[0-9a-f]{2})*$/iu.test(result)) {
39
- throw new Error("Transaction simulation returned malformed data.");
42
+ throw new ReviewLineError("Transaction simulation returned malformed data.");
40
43
  }
41
44
  if ((result.length - 2) / 2 > maxReturnBytes) {
42
- throw new Error("Transaction simulation returned too much data.");
45
+ throw new ReviewLineError("Transaction simulation returned too much data.");
43
46
  }
44
47
  return result;
45
48
  }
46
- function revertDetail(error) {
47
- if (error instanceof Error &&
48
- "shortMessage" in error &&
49
- typeof error.shortMessage === "string") {
50
- return error.shortMessage;
49
+ /** The line for a revert whose reason the SDK does not know. */
50
+ export const REVERT_UNKNOWN_LINE = "This transaction would fail. Check the amounts and try again.";
51
+ /** The line for a simulation the node did not answer. */
52
+ export const SIMULATION_NO_ANSWER_LINE = "The node did not answer the simulation.";
53
+ /**
54
+ * Why a call reverted, when the SDK knows the revert: a payment revert's
55
+ * plain line ({@link decodePayFailure}). Null otherwise. Error text (viem's
56
+ * `shortMessage`, a node's message) is never read: it can quote a request or
57
+ * its URL.
58
+ */
59
+ export function revertReason(error) {
60
+ return decodePayFailure(error)?.message ?? null;
61
+ }
62
+ /**
63
+ * A failed simulation's one-line reason: {@link revertReason}, or a fixed
64
+ * line, {@link REVERT_UNKNOWN_LINE} for a revert and
65
+ * {@link SIMULATION_NO_ANSWER_LINE} otherwise. Never the error's own text.
66
+ */
67
+ export function revertDetail(error) {
68
+ return (revertReason(error) ??
69
+ (isRevert(error) ? REVERT_UNKNOWN_LINE : SIMULATION_NO_ANSWER_LINE));
70
+ }
71
+ /**
72
+ * Whether a failed simulation is the call reverting, not the node failing:
73
+ * EIP-1474 code 3, viem's contract-revert errors, or the node's own text
74
+ * saying it reverted, in the error's first eight causes. A viem error is read
75
+ * by its `details`, since its `message` quotes the request.
76
+ */
77
+ export function isRevert(error) {
78
+ let current = error;
79
+ for (let depth = 0; depth < 8 && current && typeof current === "object"; depth += 1) {
80
+ const item = current;
81
+ if (item.code === 3 ||
82
+ item.name === "ContractFunctionRevertedError" ||
83
+ item.name === "RawContractError" ||
84
+ item.name === "ExecutionRevertedError" ||
85
+ // A failed call that returned no revert data.
86
+ item.name === "ContractFunctionZeroDataError" ||
87
+ item.name === "AbiDecodingZeroDataError") {
88
+ return true;
89
+ }
90
+ // A wrapper that carries its cause (simulateCallSequence's, which names
91
+ // the call) is read through that cause, never by its own text.
92
+ const text = typeof item.details === "string"
93
+ ? item.details
94
+ : typeof item.shortMessage === "string" || "cause" in item
95
+ ? undefined
96
+ : item.message;
97
+ if (typeof text === "string" && /revert/i.test(text))
98
+ return true;
99
+ current = item.cause;
51
100
  }
52
- return error instanceof Error
53
- ? error.message.split("\n")[0]
54
- : "The call would revert.";
101
+ return false;
102
+ }
103
+ /**
104
+ * The error a failed simulation throws, with the answer as its cause: the
105
+ * SDK's own line (a {@link ReviewLineError}) for a revert, decoded or not; a
106
+ * plain error, which `errorLine` shows as the network line, for a node that
107
+ * did not answer.
108
+ */
109
+ export function simulationFailure(text, cause) {
110
+ return Object.defineProperty(isRevert(cause) ? new ReviewLineError(text) : new Error(text), "cause", { value: cause, configurable: true, writable: true });
55
111
  }
56
112
  /** Node text saying the method itself is missing: "method not found", "Unsupported method: eth_simulateV1". */
57
113
  function namesMissingMethod(text) {
@@ -93,12 +149,20 @@ function simulationUnsupported(error) {
93
149
  * {@link simulateStateChangingTransaction}; the dependent ones are left to the
94
150
  * executing wallet's own simulation. `chainName` names the chain in errors.
95
151
  */
96
- export async function simulateCallSequence(client, { from, calls, chainName, }) {
152
+ export async function simulateCallSequence(client, { from, calls, chainName, balance, }) {
97
153
  let sequence;
98
154
  try {
99
155
  const simulated = await client.simulateCalls({
100
156
  account: from,
101
- calls: calls.map(({ to, data, value }) => ({ to, data, value })),
157
+ calls: calls.map(({ to, data, value, gas }) => ({
158
+ to,
159
+ data,
160
+ value,
161
+ ...(gas === undefined ? {} : { gas }),
162
+ })),
163
+ ...(balance === undefined
164
+ ? {}
165
+ : { stateOverrides: [{ address: from, balance }] }),
102
166
  });
103
167
  sequence = simulated.results.map((result) => result.status === "failure"
104
168
  ? { status: "failure", error: result.error }
@@ -106,7 +170,7 @@ export async function simulateCallSequence(client, { from, calls, chainName, })
106
170
  }
107
171
  catch (error) {
108
172
  if (!simulationUnsupported(error)) {
109
- throw new Error(`The batch could not be simulated on ${chainName}: ${revertDetail(error)}`);
173
+ throw simulationFailure(`The batch could not be simulated on ${chainName}: ${revertDetail(error)}`, error);
110
174
  }
111
175
  sequence = null;
112
176
  }
@@ -115,9 +179,9 @@ export async function simulateCallSequence(client, { from, calls, chainName, })
115
179
  const result = sequence[index];
116
180
  if (result?.status === "success")
117
181
  continue;
118
- throw new Error(`${call.label} cannot run on ${chainName}: ${result?.status === "failure"
182
+ throw simulationFailure(`${call.label} cannot run on ${chainName}: ${result?.status === "failure"
119
183
  ? revertDetail(result.error)
120
- : "The call would revert."}`);
184
+ : SIMULATION_NO_ANSWER_LINE}`, result?.error);
121
185
  }
122
186
  if (call.dependsOnPrior)
123
187
  continue;
@@ -127,10 +191,12 @@ export async function simulateCallSequence(client, { from, calls, chainName, })
127
191
  to: call.to,
128
192
  data: call.data,
129
193
  value: call.value,
194
+ gas: call.gas,
195
+ ...(balance === undefined || !call.funded ? {} : { balance }),
130
196
  });
131
197
  }
132
198
  catch (error) {
133
- throw new Error(`${call.label} cannot run on ${chainName}: ${revertDetail(error)}`);
199
+ throw simulationFailure(`${call.label} cannot run on ${chainName}: ${revertDetail(error)}`, error);
134
200
  }
135
201
  }
136
202
  }