@bananapus/nana-sdk-core 3.5.2 → 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 -8
  140. package/dist/cjs/v6/pay.d.ts.map +1 -1
  141. package/dist/cjs/v6/pay.js +117 -23
  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 -8
  285. package/dist/esm/v6/pay.d.ts.map +1 -1
  286. package/dist/esm/v6/pay.js +115 -22
  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
@@ -1,6 +1,7 @@
1
- import { decodeFunctionData, isAddress, keccak256, } from "viem";
2
- import { lookAtSafeProposal, readSafeAppExecution, readSafeTransaction, SAFE_EXEC_ABI, safeProposalFor, safeTransactionMatchesCall, } from "../safeService.js";
3
- import { multiSendCallsOf } from "../safe.js";
1
+ import { ReviewLineError } from "./lineError.js";
2
+ import { decodeFunctionData, isAddress, numberToHex, keccak256, } from "viem";
3
+ import { lookAtSafeProposal, readSafeAppExecution, readSafeTransaction, isSafeExecTransaction, safeExecTransactionResult, SAFE_EXEC_ABI, safeProposalFor, safeTransactionMatchesCall, } from "../safeService.js";
4
+ import { MULTI_SEND_CALL_ONLY_DEPLOYMENTS, multiSendCallsOf, readAuthorityIdentity, } from "../safe.js";
4
5
  import { TAB } from "./tabState.js";
5
6
  import { isBytes32, isHexBytes, uint256 } from "../untrusted.js";
6
7
  import { atCanonicalFinalizedBlock, } from "./relayr.js";
@@ -11,7 +12,7 @@ const TAB_SEEN = TAB.seen;
11
12
  // failed. It is visible only while the exact durable reservation still exists.
12
13
  const unpersistedSubmissions = new WeakMap();
13
14
  /** The wallet returned this identity, but storing it failed. Keep it in memory and retry submitted(hash, record). */
14
- export class SubmittedWritePersistenceError extends Error {
15
+ export class SubmittedWritePersistenceError extends ReviewLineError {
15
16
  constructor(record, cause) {
16
17
  super("The wallet returned a transaction identity, but recovery storage is unavailable. Keep this transaction pending.");
17
18
  this.name = "SubmittedWritePersistenceError";
@@ -23,7 +24,7 @@ function normalizedIdentity(input) {
23
24
  if (!Number.isSafeInteger(input?.chainId) ||
24
25
  input.chainId <= 0 ||
25
26
  !isAddress(input?.account, { strict: false }))
26
- throw new Error("Invalid reviewed write recovery evidence.");
27
+ throw new ReviewLineError("Invalid reviewed write recovery evidence.");
27
28
  return {
28
29
  chainId: input.chainId,
29
30
  account: input.account.toLowerCase(),
@@ -36,7 +37,7 @@ function normalized(input) {
36
37
  !isAddress(input?.call?.to, { strict: false }) ||
37
38
  !isHexBytes(input?.call?.data) ||
38
39
  value === null)
39
- throw new Error("Invalid reviewed write recovery evidence.");
40
+ throw new ReviewLineError("Invalid reviewed write recovery evidence.");
40
41
  return {
41
42
  ...normalizedIdentity(input),
42
43
  safe: input.safe,
@@ -80,7 +81,7 @@ function recordOf(value) {
80
81
  (record.executed !== undefined && record.executed !== true) ||
81
82
  (record.executionHash !== undefined &&
82
83
  (record.executed !== true || !isBytes32(record.executionHash))))
83
- throw new Error("Invalid saved write recovery record. Keep this action pending.");
84
+ throw new ReviewLineError("Invalid saved write recovery record. Keep this action pending.");
84
85
  return {
85
86
  version: 1,
86
87
  id: record.id,
@@ -157,7 +158,7 @@ function namespaceOf(value) {
157
158
  return undefined;
158
159
  if (typeof value !== "string" ||
159
160
  !/^[a-z0-9][a-z0-9:._/-]{0,127}$/.test(value))
160
- throw new Error("Invalid write recovery namespace.");
161
+ throw new ReviewLineError("Invalid write recovery namespace.");
161
162
  return value;
162
163
  }
163
164
  function namespaceScope(input) {
@@ -171,7 +172,7 @@ function scope(input) {
171
172
  function recoveryStorage(store) {
172
173
  const result = store ?? globalThis.localStorage;
173
174
  if (!result)
174
- throw new Error("Write recovery storage is unavailable.");
175
+ throw new ReviewLineError("Write recovery storage is unavailable.");
175
176
  return result;
176
177
  }
177
178
  /** Every key `store` holds: its own `keys()`, or Web Storage's `length` and `key()`. */
@@ -363,7 +364,7 @@ export function findReviewedWrites(input, options = {}) {
363
364
  const identity = normalizedIdentity(input);
364
365
  if (!isAddress(input.to, { strict: false }) ||
365
366
  !/^0x[0-9a-fA-F]{8}$/.test(input.selector))
366
- throw new Error("Invalid write hold match.");
367
+ throw new ReviewLineError("Invalid write hold match.");
367
368
  const to = input.to.toLowerCase();
368
369
  const selector = input.selector.toLowerCase();
369
370
  const store = recoveryStorage(options.storage);
@@ -401,7 +402,7 @@ function foundAt(input, at) {
401
402
  (at.startsWith(prefix) &&
402
403
  /^\d+:0x[0-9a-f]{64}$/.test(at.slice(prefix.length)))))
403
404
  return at;
404
- throw new Error("Invalid write recovery key.");
405
+ throw new ReviewLineError("Invalid write recovery key.");
405
406
  }
406
407
  /**
407
408
  * Every unresolved write saved for `account` on `chainId`, with the key it
@@ -449,7 +450,7 @@ export function readBrowserWriteRecovery(input, options = {}) {
449
450
  const identity = normalizedIdentity(input);
450
451
  const namespace = namespaceOf(input?.namespace);
451
452
  if (namespace === undefined)
452
- throw new Error("Provide a write recovery namespace.");
453
+ throw new ReviewLineError("Provide a write recovery namespace.");
453
454
  return readRecovery(recoveryStorage(options.storage), namespaceScope({ ...identity, namespace }));
454
455
  }
455
456
  /**
@@ -460,12 +461,20 @@ export function readBrowserWriteRecovery(input, options = {}) {
460
461
  function releasedKey(key, id) {
461
462
  return `${key}:released:${id}`;
462
463
  }
464
+ /**
465
+ * The key that marks the record `id` saved at `key` as ended by the user's
466
+ * exit or as never sent, never by a settlement's cleanup: only it lets a
467
+ * saved sequence send that step again.
468
+ */
469
+ function exitedKey(key, id) {
470
+ return `${key}:exited:${id}`;
471
+ }
463
472
  function readStored(raw, key, scopeOf = scope, store) {
464
473
  if (raw === null)
465
474
  return null;
466
475
  const record = recordOf(JSON.parse(raw));
467
476
  if (scopeOf(record) !== key)
468
- throw new Error("Saved write recovery scope does not match.");
477
+ throw new ReviewLineError("Saved write recovery scope does not match.");
469
478
  if (store && store.getItem(releasedKey(key, record.id)) !== null)
470
479
  return null;
471
480
  return record;
@@ -690,7 +699,7 @@ export function createBrowserWriteRecovery(input, options = {}) {
690
699
  }
691
700
  function requireLock() {
692
701
  if (!locked)
693
- throw new Error("Write recovery changes require the browser lock.");
702
+ throw new ReviewLineError("Write recovery changes require the browser lock.");
694
703
  }
695
704
  function read() {
696
705
  const store = storage();
@@ -702,7 +711,7 @@ export function createBrowserWriteRecovery(input, options = {}) {
702
711
  const store = storage();
703
712
  store.setItem(at, raw);
704
713
  if (store.getItem(at) !== raw)
705
- throw new Error("Write recovery storage did not retain the action.");
714
+ throw new ReviewLineError("Write recovery storage did not retain the action.");
706
715
  }
707
716
  function clear(expected) {
708
717
  requireLock();
@@ -718,7 +727,7 @@ export function createBrowserWriteRecovery(input, options = {}) {
718
727
  if (!current)
719
728
  return;
720
729
  if (JSON.stringify(current) !== JSON.stringify(recordOf(expected))) {
721
- throw new Error("Write recovery changed. Keep the current action pending.");
730
+ throw new ReviewLineError("Write recovery changed. Keep the current action pending.");
722
731
  }
723
732
  // The last record of an attempt goes only once its generation is the
724
733
  // committed latest marker; otherwise it stays, released, and carries it.
@@ -726,13 +735,13 @@ export function createBrowserWriteRecovery(input, options = {}) {
726
735
  const marker = releasedKey(at, current.id);
727
736
  store.setItem(marker, "1");
728
737
  if (store.getItem(marker) !== "1")
729
- throw new Error("Write recovery storage did not clear the action.");
738
+ throw new ReviewLineError("Write recovery storage did not clear the action.");
730
739
  unpersistedSubmissions.get(store)?.delete(at);
731
740
  return;
732
741
  }
733
742
  store.removeItem(at);
734
743
  if (store.getItem(at) !== null)
735
- throw new Error("Write recovery storage did not clear the action.");
744
+ throw new ReviewLineError("Write recovery storage did not clear the action.");
736
745
  unpersistedSubmissions.get(store)?.delete(at);
737
746
  }
738
747
  /** Add `fields` to exactly `expected`, a hashed record `when` allows; extra evidence only. */
@@ -760,6 +769,12 @@ export function createBrowserWriteRecovery(input, options = {}) {
760
769
  const current = read();
761
770
  if (current?.id === owned.id && current.hash)
762
771
  return;
772
+ try {
773
+ storage().setItem(exitedKey(locate(storage()).at, owned.id), "1");
774
+ }
775
+ catch {
776
+ /* Unsaved, a sequence resumed over it asks for the user's check. */
777
+ }
763
778
  // Removing the record must not uncover a settlement of an earlier
764
779
  // attempt: unless this reservation is the verified latest, it stays as
765
780
  // released instead, which still invalidates that settlement.
@@ -815,13 +830,13 @@ export function createBrowserWriteRecovery(input, options = {}) {
815
830
  function record(hash, expected, replace) {
816
831
  requireLock();
817
832
  if (!isBytes32(hash))
818
- throw new Error("The wallet returned an invalid transaction identity.");
833
+ throw new ReviewLineError("The wallet returned an invalid transaction identity.");
819
834
  const previous = expected && recordOf(expected);
820
835
  const submittedHash = hash.toLowerCase();
821
836
  if (!previous ||
822
837
  keyOf(previous) !== key ||
823
838
  (!replace && previous.hash && previous.hash !== submittedHash)) {
824
- throw new Error("Write recovery changed before submission was recorded.");
839
+ throw new ReviewLineError("Write recovery changed before submission was recorded.");
825
840
  }
826
841
  // A hash the wallet returns now starts its clock; a speed-up found at its nonce keeps it.
827
842
  const submittedAt = replace || previous.hash === submittedHash
@@ -858,7 +873,7 @@ export function createBrowserWriteRecovery(input, options = {}) {
858
873
  submittedAt: undefined,
859
874
  }) ||
860
875
  (!replace && current.hash && current.hash !== submittedHash)) {
861
- throw new Error("Write recovery changed before submission was recorded.");
876
+ throw new ReviewLineError("Write recovery changed before submission was recorded.");
862
877
  }
863
878
  owned = recordOf(submitted);
864
879
  if (current.hash !== submittedHash) {
@@ -892,15 +907,15 @@ export function createBrowserWriteRecovery(input, options = {}) {
892
907
  ? normalized({ ...reviewed, call: actualCall })
893
908
  : reviewed;
894
909
  if (legacyScope(actual) !== legacyScope(reviewed))
895
- throw new Error("The adopted write has a different recovery scope.");
910
+ throw new ReviewLineError("The adopted write has a different recovery scope.");
896
911
  const nonce = evidence && uint256(evidence.nonce);
897
912
  const fromBlock = evidence && uint256(evidence.blockNumber);
898
913
  if (evidence && (nonce === null || fromBlock === null))
899
- throw new Error("Invalid write recovery nonce evidence.");
914
+ throw new ReviewLineError("Invalid write recovery nonce evidence.");
900
915
  const store = storage();
901
916
  const { at, raw } = locate(store);
902
917
  if (readRecovery(store, at, raw, scopeAt(at)))
903
- throw new Error("An earlier wallet write is still unresolved. Check it before trying again.");
918
+ throw new ReviewLineError("An earlier wallet write is still unresolved. Check it before trying again.");
904
919
  // The record this one replaces, if the user released it: its marker goes too.
905
920
  let replaced;
906
921
  try {
@@ -939,6 +954,7 @@ export function createBrowserWriteRecovery(input, options = {}) {
939
954
  if (typeof replaced === "string" && replaced !== record.id)
940
955
  try {
941
956
  store.removeItem(releasedKey(key, replaced));
957
+ store.removeItem(exitedKey(key, replaced));
942
958
  }
943
959
  catch {
944
960
  /* A leftover marker names only the old record. */
@@ -971,7 +987,7 @@ export function createBrowserWriteRecovery(input, options = {}) {
971
987
  requireLock();
972
988
  const current = read();
973
989
  if (current && current.mirrorOf !== of)
974
- throw new Error("An earlier wallet write is still unresolved. Check it before trying again.");
990
+ throw new ReviewLineError("An earlier wallet write is still unresolved. Check it before trying again.");
975
991
  const mirrored = recordOf({
976
992
  version: 1,
977
993
  id: source.id,
@@ -1011,6 +1027,16 @@ export function createBrowserWriteRecovery(input, options = {}) {
1011
1027
  return undefined;
1012
1028
  }
1013
1029
  },
1030
+ /** Whether the record `id` ended by the user's exit, or because nothing was sent. */
1031
+ released(id) {
1032
+ try {
1033
+ const store = storage();
1034
+ return store.getItem(exitedKey(locate(store).at, id)) !== null;
1035
+ }
1036
+ catch {
1037
+ return false;
1038
+ }
1039
+ },
1014
1040
  /**
1015
1041
  * The call's latest reservation id: the record saved at the key (held,
1016
1042
  * or released by its exit), or else the saved latest marker.
@@ -1271,7 +1297,7 @@ export function createBrowserWriteRecovery(input, options = {}) {
1271
1297
  executed(expected, executionHash) {
1272
1298
  requireLock();
1273
1299
  if (executionHash !== undefined && !isBytes32(executionHash))
1274
- throw new Error("Invalid execution transaction identity.");
1300
+ throw new ReviewLineError("Invalid execution transaction identity.");
1275
1301
  const store = storage();
1276
1302
  const { at, raw } = locate(store);
1277
1303
  const current = readRecovery(store, at, raw, scopeAt(at));
@@ -1279,7 +1305,7 @@ export function createBrowserWriteRecovery(input, options = {}) {
1279
1305
  if (!current?.hash ||
1280
1306
  current.id !== wanted.id ||
1281
1307
  current.hash !== wanted.hash)
1282
- throw new Error("Write recovery changed. Keep the current action pending.");
1308
+ throw new ReviewLineError("Write recovery changed. Keep the current action pending.");
1283
1309
  const next = recordOf({
1284
1310
  ...current,
1285
1311
  executed: true,
@@ -1318,7 +1344,7 @@ export function createBrowserWriteRecovery(input, options = {}) {
1318
1344
  */
1319
1345
  abandon(expected, acknowledgement) {
1320
1346
  if (acknowledgement?.checkedWallet !== true)
1321
- throw new Error("Release a held write only after the user confirms they checked their wallet.");
1347
+ throw new ReviewLineError("Release a held write only after the user confirms they checked their wallet.");
1322
1348
  const wanted = JSON.stringify(recordOf(expected));
1323
1349
  const store = storage();
1324
1350
  const { at, raw } = locate(store);
@@ -1326,15 +1352,21 @@ export function createBrowserWriteRecovery(input, options = {}) {
1326
1352
  if (!durable)
1327
1353
  return;
1328
1354
  if (durable.executed)
1329
- throw new Error("This write ran onchain. Keep it held until its result is known.");
1355
+ throw new ReviewLineError("This write ran onchain. Keep it held until its result is known.");
1330
1356
  const shown = readRecovery(store, at, raw, scopeAt(at));
1331
1357
  if (JSON.stringify(durable) !== wanted &&
1332
1358
  JSON.stringify(shown) !== wanted)
1333
- throw new Error("Write recovery changed. Keep the current action pending.");
1359
+ throw new ReviewLineError("Write recovery changed. Keep the current action pending.");
1334
1360
  const marker = releasedKey(at, durable.id);
1361
+ try {
1362
+ store.setItem(exitedKey(at, durable.id), "1");
1363
+ }
1364
+ catch {
1365
+ /* Unsaved, a sequence resumed over it asks for the user's check. */
1366
+ }
1335
1367
  store.setItem(marker, "1");
1336
1368
  if (store.getItem(marker) !== "1")
1337
- throw new Error("Write recovery storage did not release the action.");
1369
+ throw new ReviewLineError("Write recovery storage did not release the action.");
1338
1370
  const memory = unpersistedSubmissions.get(store);
1339
1371
  if (memory?.get(at)?.id === durable.id)
1340
1372
  memory.delete(at);
@@ -1345,7 +1377,7 @@ export function createBrowserWriteRecovery(input, options = {}) {
1345
1377
  const locks = options.locks ?? browserLocks();
1346
1378
  return locks.request(key, { mode: "exclusive", ...(!wait && { ifAvailable: true }) }, async (lock) => {
1347
1379
  if (!lock)
1348
- throw new Error("This wallet action is already open in another tab.");
1380
+ throw new ReviewLineError("This wallet action is already open in another tab.");
1349
1381
  locked = true;
1350
1382
  try {
1351
1383
  return await work();
@@ -1503,7 +1535,13 @@ function heldBatch(record) {
1503
1535
  : null;
1504
1536
  return inner && inner.map((call) => normalized({ ...record, call }).call);
1505
1537
  }
1506
- /** Whether `transaction` is the Safe's execTransaction of exactly the held batch: its MultiSend target, calldata, zero value and DELEGATECALL. */
1538
+ /**
1539
+ * The MultiSend targets a held batch may run through: a Safe app folds the
1540
+ * same calls into its own version's MultiSendCallOnly, so any recognized
1541
+ * deployment carries exactly the held calldata.
1542
+ */
1543
+ const BATCH_TARGETS = MULTI_SEND_CALL_ONLY_DEPLOYMENTS.map((to) => to.toLowerCase());
1544
+ /** Whether `transaction` is the Safe's execTransaction of exactly the held batch: a recognized MultiSendCallOnly, its calldata, zero value and DELEGATECALL. */
1507
1545
  function runsHeldBatch(transaction, record) {
1508
1546
  try {
1509
1547
  const { functionName, args } = decodeFunctionData({
@@ -1513,7 +1551,7 @@ function runsHeldBatch(transaction, record) {
1513
1551
  if (functionName !== "execTransaction")
1514
1552
  return false;
1515
1553
  const [to, value, data, operation] = args;
1516
- return (to.toLowerCase() === record.call.to &&
1554
+ return (BATCH_TARGETS.includes(to.toLowerCase()) &&
1517
1555
  value === 0n &&
1518
1556
  data.toLowerCase() === record.call.data &&
1519
1557
  operation === 1);
@@ -1539,13 +1577,14 @@ export function heldSafeProposal(input, nonce) {
1539
1577
  */
1540
1578
  export function safeProposalIsHeldCall(proposal, input) {
1541
1579
  const record = normalized(input);
1542
- return safeTransactionMatchesCall(proposal, {
1543
- ...record.call,
1544
- value: BigInt(record.call.value),
1545
- ...(heldBatch({ ...record, version: 1, id: "" })
1546
- ? { operation: 1 }
1547
- : {}),
1548
- });
1580
+ const call = { ...record.call, value: BigInt(record.call.value) };
1581
+ return heldBatch({ ...record, version: 1, id: "" })
1582
+ ? BATCH_TARGETS.some((to) => safeTransactionMatchesCall(proposal, {
1583
+ ...call,
1584
+ to: to,
1585
+ operation: 1,
1586
+ }))
1587
+ : safeTransactionMatchesCall(proposal, call);
1549
1588
  }
1550
1589
  /**
1551
1590
  * Authenticate the saved wallet identity, canonical inclusion and Safe effect.
@@ -1559,7 +1598,7 @@ export function safeProposalIsHeldCall(proposal, input) {
1559
1598
  */
1560
1599
  export async function verifyReviewedWriteReceipt(client, saved, receipt, proof, { finality = true } = {}) {
1561
1600
  const record = recordOf(saved);
1562
- const pending = () => new Error("The saved wallet write is not yet proven. Keep this action pending.");
1601
+ const pending = () => new ReviewLineError("The saved wallet write is not yet proven. Keep this action pending.");
1563
1602
  // A batch hold's call is its MultiSend: its proof is the calls it encodes.
1564
1603
  const batch = heldBatch(record);
1565
1604
  let calls = batch ?? [record.call];
@@ -1646,6 +1685,35 @@ export async function verifyReviewedWriteReceipt(client, saved, receipt, proof,
1646
1685
  throw pending();
1647
1686
  status = result.status;
1648
1687
  }
1688
+ else if (status === "success" && isSafeExecTransaction(record.call.data)) {
1689
+ // A Safe's execTransaction succeeds only with the Safe's own
1690
+ // ExecutionSuccess for its exact hash: an ExecutionFailure, or no event
1691
+ // for it, is a failure whatever the receipt's status. A call that only
1692
+ // shares the selector, to anything but a Safe, is decided as any other.
1693
+ if (!client.request)
1694
+ throw pending();
1695
+ const { request } = client;
1696
+ const at = (blockNumber) => blockNumber === undefined ? "latest" : numberToHex(blockNumber);
1697
+ // Every read through the one `request` the receipt client has.
1698
+ const identity = await readAuthorityIdentity({
1699
+ request,
1700
+ getCode: ({ address, blockNumber }) => request({
1701
+ method: "eth_getCode",
1702
+ params: [address, at(blockNumber)],
1703
+ }),
1704
+ getStorageAt: ({ address, slot, blockNumber }) => request({
1705
+ method: "eth_getStorageAt",
1706
+ params: [address, slot, at(blockNumber)],
1707
+ }),
1708
+ }, record.call.to, { blockNumber: canonical.blockNumber });
1709
+ if (!identity)
1710
+ throw pending();
1711
+ if (identity.kind === "safe") {
1712
+ const execution = await safeExecTransactionResult({ request: client.request }, record.chainId, record.call.to, record.call.data, canonical);
1713
+ if (execution?.status !== "success")
1714
+ status = "failed";
1715
+ }
1716
+ }
1649
1717
  const isCanonical = async () => {
1650
1718
  const block = await client.getBlock({ blockNumber: canonical.blockNumber });
1651
1719
  return (block.number === canonical.blockNumber &&
@@ -1666,7 +1734,7 @@ export async function verifyReviewedWriteReceipt(client, saved, receipt, proof,
1666
1734
  */
1667
1735
  export async function verifyReviewedWriteExpiry(client, saved, service) {
1668
1736
  const record = recordOf(saved);
1669
- const pending = () => new Error("The saved Safe proposal is not proven expired. Keep this action pending.");
1737
+ const pending = () => new ReviewLineError("The saved Safe proposal is not proven expired. Keep this action pending.");
1670
1738
  if (!record.safe ||
1671
1739
  !record.hash ||
1672
1740
  (await client.getChainId()) !== record.chainId)