@bananapus/nana-sdk-core 3.5.2 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/wallet-check.mjs +495 -0
- package/dist/cjs/actions/suckerPairs.d.ts +5 -3
- package/dist/cjs/actions/suckerPairs.d.ts.map +1 -1
- package/dist/cjs/actions/suckerPairs.js +6 -26
- package/dist/cjs/actions/suckerPairs.js.map +1 -1
- package/dist/cjs/pause.d.ts +2 -0
- package/dist/cjs/pause.d.ts.map +1 -1
- package/dist/cjs/pause.js +17 -0
- package/dist/cjs/pause.js.map +1 -1
- package/dist/cjs/review/confirm.d.ts +56 -0
- package/dist/cjs/review/confirm.d.ts.map +1 -0
- package/dist/cjs/review/confirm.js +99 -0
- package/dist/cjs/review/confirm.js.map +1 -0
- package/dist/cjs/review/contractWrite.d.ts +5 -3
- package/dist/cjs/review/contractWrite.d.ts.map +1 -1
- package/dist/cjs/review/contractWrite.js +10 -8
- package/dist/cjs/review/contractWrite.js.map +1 -1
- package/dist/cjs/review/decode.d.ts +19 -1
- package/dist/cjs/review/decode.d.ts.map +1 -1
- package/dist/cjs/review/decode.js +30 -11
- package/dist/cjs/review/decode.js.map +1 -1
- package/dist/cjs/review/decodeCall.d.ts +21 -0
- package/dist/cjs/review/decodeCall.d.ts.map +1 -0
- package/dist/cjs/review/decodeCall.js +183 -0
- package/dist/cjs/review/decodeCall.js.map +1 -0
- package/dist/cjs/review/heldWrite.d.ts +4 -0
- package/dist/cjs/review/heldWrite.d.ts.map +1 -1
- package/dist/cjs/review/heldWrite.js +35 -31
- package/dist/cjs/review/heldWrite.js.map +1 -1
- package/dist/cjs/review/index.d.ts +12 -1
- package/dist/cjs/review/index.d.ts.map +1 -1
- package/dist/cjs/review/index.js +29 -1
- package/dist/cjs/review/index.js.map +1 -1
- package/dist/cjs/review/intents.d.ts +10 -0
- package/dist/cjs/review/intents.d.ts.map +1 -1
- package/dist/cjs/review/intents.js +13 -0
- package/dist/cjs/review/intents.js.map +1 -1
- package/dist/cjs/review/lineError.d.ts +72 -0
- package/dist/cjs/review/lineError.d.ts.map +1 -0
- package/dist/cjs/review/lineError.js +76 -0
- package/dist/cjs/review/lineError.js.map +1 -0
- package/dist/cjs/review/messages.d.ts +15 -3
- package/dist/cjs/review/messages.d.ts.map +1 -1
- package/dist/cjs/review/messages.js +16 -4
- package/dist/cjs/review/messages.js.map +1 -1
- package/dist/cjs/review/model.d.ts +149 -0
- package/dist/cjs/review/model.d.ts.map +1 -0
- package/dist/cjs/review/model.js +750 -0
- package/dist/cjs/review/model.js.map +1 -0
- package/dist/cjs/review/plan.d.ts +61 -0
- package/dist/cjs/review/plan.d.ts.map +1 -0
- package/dist/cjs/review/plan.js +143 -0
- package/dist/cjs/review/plan.js.map +1 -0
- package/dist/cjs/review/react/index.d.ts +1 -0
- package/dist/cjs/review/react/index.d.ts.map +1 -1
- package/dist/cjs/review/react/index.js +1 -0
- package/dist/cjs/review/react/index.js.map +1 -1
- package/dist/cjs/review/react/useHeldSend.js +3 -4
- package/dist/cjs/review/react/useHeldSend.js.map +1 -1
- package/dist/cjs/review/react/useHeldWrite.d.ts.map +1 -1
- package/dist/cjs/review/react/useHeldWrite.js +2 -1
- package/dist/cjs/review/react/useHeldWrite.js.map +1 -1
- package/dist/cjs/review/react/useReviewedRun.d.ts +122 -0
- package/dist/cjs/review/react/useReviewedRun.d.ts.map +1 -0
- package/dist/cjs/review/react/useReviewedRun.js +443 -0
- package/dist/cjs/review/react/useReviewedRun.js.map +1 -0
- package/dist/cjs/review/receipt.d.ts +37 -1
- package/dist/cjs/review/receipt.d.ts.map +1 -1
- package/dist/cjs/review/receipt.js +76 -3
- package/dist/cjs/review/receipt.js.map +1 -1
- package/dist/cjs/review/relayr.d.ts +13 -4
- package/dist/cjs/review/relayr.d.ts.map +1 -1
- package/dist/cjs/review/relayr.js +52 -8
- package/dist/cjs/review/relayr.js.map +1 -1
- package/dist/cjs/review/relayrSend.d.ts +106 -0
- package/dist/cjs/review/relayrSend.d.ts.map +1 -0
- package/dist/cjs/review/relayrSend.js +795 -0
- package/dist/cjs/review/relayrSend.js.map +1 -0
- package/dist/cjs/review/reviewQueue.d.ts +10 -9
- package/dist/cjs/review/reviewQueue.d.ts.map +1 -1
- package/dist/cjs/review/reviewQueue.js +19 -29
- package/dist/cjs/review/reviewQueue.js.map +1 -1
- package/dist/cjs/review/reviewRequests.d.ts +86 -0
- package/dist/cjs/review/reviewRequests.d.ts.map +1 -0
- package/dist/cjs/review/reviewRequests.js +266 -0
- package/dist/cjs/review/reviewRequests.js.map +1 -0
- package/dist/cjs/review/safeRelayr.d.ts +3 -1
- package/dist/cjs/review/safeRelayr.d.ts.map +1 -1
- package/dist/cjs/review/safeRelayr.js +9 -9
- package/dist/cjs/review/safeRelayr.js.map +1 -1
- package/dist/cjs/review/safeSend.d.ts +69 -0
- package/dist/cjs/review/safeSend.d.ts.map +1 -0
- package/dist/cjs/review/safeSend.js +306 -0
- package/dist/cjs/review/safeSend.js.map +1 -0
- package/dist/cjs/review/send.d.ts +272 -0
- package/dist/cjs/review/send.d.ts.map +1 -0
- package/dist/cjs/review/send.js +1163 -0
- package/dist/cjs/review/send.js.map +1 -0
- package/dist/cjs/review/sequence.d.ts +77 -0
- package/dist/cjs/review/sequence.d.ts.map +1 -0
- package/dist/cjs/review/sequence.js +232 -0
- package/dist/cjs/review/sequence.js.map +1 -0
- package/dist/cjs/review/sign.d.ts +111 -0
- package/dist/cjs/review/sign.d.ts.map +1 -0
- package/dist/cjs/review/sign.js +378 -0
- package/dist/cjs/review/sign.js.map +1 -0
- package/dist/cjs/review/simulation.d.ts +41 -2
- package/dist/cjs/review/simulation.d.ts.map +1 -1
- package/dist/cjs/review/simulation.js +99 -29
- package/dist/cjs/review/simulation.js.map +1 -1
- package/dist/cjs/review/transaction-message.d.ts +13 -0
- package/dist/cjs/review/transaction-message.d.ts.map +1 -1
- package/dist/cjs/review/transaction-message.js +25 -0
- package/dist/cjs/review/transaction-message.js.map +1 -1
- package/dist/cjs/review/transactionReview.d.ts +27 -19
- package/dist/cjs/review/transactionReview.d.ts.map +1 -1
- package/dist/cjs/review/transactionReview.js +22 -63
- package/dist/cjs/review/transactionReview.js.map +1 -1
- package/dist/cjs/review/wallet.d.ts +98 -0
- package/dist/cjs/review/wallet.d.ts.map +1 -0
- package/dist/cjs/review/wallet.js +234 -0
- package/dist/cjs/review/wallet.js.map +1 -0
- package/dist/cjs/review/writeHold.d.ts +138 -13
- package/dist/cjs/review/writeHold.d.ts.map +1 -1
- package/dist/cjs/review/writeHold.js +98 -18
- package/dist/cjs/review/writeHold.js.map +1 -1
- package/dist/cjs/review/writeRecovery.d.ts +17 -1
- package/dist/cjs/review/writeRecovery.d.ts.map +1 -1
- package/dist/cjs/review/writeRecovery.js +146 -45
- package/dist/cjs/review/writeRecovery.js.map +1 -1
- package/dist/cjs/safeService.d.ts +27 -4
- package/dist/cjs/safeService.d.ts.map +1 -1
- package/dist/cjs/safeService.js +120 -3
- package/dist/cjs/safeService.js.map +1 -1
- package/dist/cjs/testing.d.ts +24 -0
- package/dist/cjs/testing.d.ts.map +1 -1
- package/dist/cjs/testing.js +26 -1
- package/dist/cjs/testing.js.map +1 -1
- package/dist/cjs/v6/defifa.d.ts.map +1 -1
- package/dist/cjs/v6/defifa.js +24 -23
- package/dist/cjs/v6/defifa.js.map +1 -1
- package/dist/cjs/v6/executionErrors.d.ts.map +1 -1
- package/dist/cjs/v6/executionErrors.js +3 -2
- package/dist/cjs/v6/executionErrors.js.map +1 -1
- package/dist/cjs/v6/pay.d.ts +25 -8
- package/dist/cjs/v6/pay.d.ts.map +1 -1
- package/dist/cjs/v6/pay.js +117 -23
- package/dist/cjs/v6/pay.js.map +1 -1
- package/dist/cjs/v6/suckers.d.ts +30 -0
- package/dist/cjs/v6/suckers.d.ts.map +1 -1
- package/dist/cjs/v6/suckers.js +69 -5
- package/dist/cjs/v6/suckers.js.map +1 -1
- package/dist/esm/actions/suckerPairs.d.ts +5 -3
- package/dist/esm/actions/suckerPairs.d.ts.map +1 -1
- package/dist/esm/actions/suckerPairs.js +7 -27
- package/dist/esm/actions/suckerPairs.js.map +1 -1
- package/dist/esm/pause.d.ts +2 -0
- package/dist/esm/pause.d.ts.map +1 -1
- package/dist/esm/pause.js +16 -0
- package/dist/esm/pause.js.map +1 -1
- package/dist/esm/review/confirm.d.ts +56 -0
- package/dist/esm/review/confirm.d.ts.map +1 -0
- package/dist/esm/review/confirm.js +93 -0
- package/dist/esm/review/confirm.js.map +1 -0
- package/dist/esm/review/contractWrite.d.ts +5 -3
- package/dist/esm/review/contractWrite.d.ts.map +1 -1
- package/dist/esm/review/contractWrite.js +10 -8
- package/dist/esm/review/contractWrite.js.map +1 -1
- package/dist/esm/review/decode.d.ts +19 -1
- package/dist/esm/review/decode.d.ts.map +1 -1
- package/dist/esm/review/decode.js +29 -14
- package/dist/esm/review/decode.js.map +1 -1
- package/dist/esm/review/decodeCall.d.ts +21 -0
- package/dist/esm/review/decodeCall.d.ts.map +1 -0
- package/dist/esm/review/decodeCall.js +180 -0
- package/dist/esm/review/decodeCall.js.map +1 -0
- package/dist/esm/review/heldWrite.d.ts +4 -0
- package/dist/esm/review/heldWrite.d.ts.map +1 -1
- package/dist/esm/review/heldWrite.js +34 -30
- package/dist/esm/review/heldWrite.js.map +1 -1
- package/dist/esm/review/index.d.ts +12 -1
- package/dist/esm/review/index.d.ts.map +1 -1
- package/dist/esm/review/index.js +12 -1
- package/dist/esm/review/index.js.map +1 -1
- package/dist/esm/review/intents.d.ts +10 -0
- package/dist/esm/review/intents.d.ts.map +1 -1
- package/dist/esm/review/intents.js +12 -0
- package/dist/esm/review/intents.js.map +1 -1
- package/dist/esm/review/lineError.d.ts +72 -0
- package/dist/esm/review/lineError.d.ts.map +1 -0
- package/dist/esm/review/lineError.js +68 -0
- package/dist/esm/review/lineError.js.map +1 -0
- package/dist/esm/review/messages.d.ts +15 -3
- package/dist/esm/review/messages.d.ts.map +1 -1
- package/dist/esm/review/messages.js +15 -3
- package/dist/esm/review/messages.js.map +1 -1
- package/dist/esm/review/model.d.ts +149 -0
- package/dist/esm/review/model.d.ts.map +1 -0
- package/dist/esm/review/model.js +746 -0
- package/dist/esm/review/model.js.map +1 -0
- package/dist/esm/review/plan.d.ts +61 -0
- package/dist/esm/review/plan.d.ts.map +1 -0
- package/dist/esm/review/plan.js +136 -0
- package/dist/esm/review/plan.js.map +1 -0
- package/dist/esm/review/react/index.d.ts +1 -0
- package/dist/esm/review/react/index.d.ts.map +1 -1
- package/dist/esm/review/react/index.js +1 -0
- package/dist/esm/review/react/index.js.map +1 -1
- package/dist/esm/review/react/useHeldSend.js +3 -4
- package/dist/esm/review/react/useHeldSend.js.map +1 -1
- package/dist/esm/review/react/useHeldWrite.d.ts.map +1 -1
- package/dist/esm/review/react/useHeldWrite.js +2 -1
- package/dist/esm/review/react/useHeldWrite.js.map +1 -1
- package/dist/esm/review/react/useReviewedRun.d.ts +122 -0
- package/dist/esm/review/react/useReviewedRun.d.ts.map +1 -0
- package/dist/esm/review/react/useReviewedRun.js +439 -0
- package/dist/esm/review/react/useReviewedRun.js.map +1 -0
- package/dist/esm/review/receipt.d.ts +37 -1
- package/dist/esm/review/receipt.d.ts.map +1 -1
- package/dist/esm/review/receipt.js +72 -2
- package/dist/esm/review/receipt.js.map +1 -1
- package/dist/esm/review/relayr.d.ts +13 -4
- package/dist/esm/review/relayr.d.ts.map +1 -1
- package/dist/esm/review/relayr.js +51 -8
- package/dist/esm/review/relayr.js.map +1 -1
- package/dist/esm/review/relayrSend.d.ts +106 -0
- package/dist/esm/review/relayrSend.d.ts.map +1 -0
- package/dist/esm/review/relayrSend.js +787 -0
- package/dist/esm/review/relayrSend.js.map +1 -0
- package/dist/esm/review/reviewQueue.d.ts +10 -9
- package/dist/esm/review/reviewQueue.d.ts.map +1 -1
- package/dist/esm/review/reviewQueue.js +17 -26
- package/dist/esm/review/reviewQueue.js.map +1 -1
- package/dist/esm/review/reviewRequests.d.ts +86 -0
- package/dist/esm/review/reviewRequests.d.ts.map +1 -0
- package/dist/esm/review/reviewRequests.js +263 -0
- package/dist/esm/review/reviewRequests.js.map +1 -0
- package/dist/esm/review/safeRelayr.d.ts +3 -1
- package/dist/esm/review/safeRelayr.d.ts.map +1 -1
- package/dist/esm/review/safeRelayr.js +9 -9
- package/dist/esm/review/safeRelayr.js.map +1 -1
- package/dist/esm/review/safeSend.d.ts +69 -0
- package/dist/esm/review/safeSend.d.ts.map +1 -0
- package/dist/esm/review/safeSend.js +301 -0
- package/dist/esm/review/safeSend.js.map +1 -0
- package/dist/esm/review/send.d.ts +272 -0
- package/dist/esm/review/send.d.ts.map +1 -0
- package/dist/esm/review/send.js +1156 -0
- package/dist/esm/review/send.js.map +1 -0
- package/dist/esm/review/sequence.d.ts +77 -0
- package/dist/esm/review/sequence.d.ts.map +1 -0
- package/dist/esm/review/sequence.js +223 -0
- package/dist/esm/review/sequence.js.map +1 -0
- package/dist/esm/review/sign.d.ts +111 -0
- package/dist/esm/review/sign.d.ts.map +1 -0
- package/dist/esm/review/sign.js +372 -0
- package/dist/esm/review/sign.js.map +1 -0
- package/dist/esm/review/simulation.d.ts +41 -2
- package/dist/esm/review/simulation.d.ts.map +1 -1
- package/dist/esm/review/simulation.js +95 -29
- package/dist/esm/review/simulation.js.map +1 -1
- package/dist/esm/review/transaction-message.d.ts +13 -0
- package/dist/esm/review/transaction-message.d.ts.map +1 -1
- package/dist/esm/review/transaction-message.js +23 -0
- package/dist/esm/review/transaction-message.js.map +1 -1
- package/dist/esm/review/transactionReview.d.ts +27 -19
- package/dist/esm/review/transactionReview.d.ts.map +1 -1
- package/dist/esm/review/transactionReview.js +19 -56
- package/dist/esm/review/transactionReview.js.map +1 -1
- package/dist/esm/review/wallet.d.ts +98 -0
- package/dist/esm/review/wallet.d.ts.map +1 -0
- package/dist/esm/review/wallet.js +227 -0
- package/dist/esm/review/wallet.js.map +1 -0
- package/dist/esm/review/writeHold.d.ts +138 -13
- package/dist/esm/review/writeHold.d.ts.map +1 -1
- package/dist/esm/review/writeHold.js +96 -19
- package/dist/esm/review/writeHold.js.map +1 -1
- package/dist/esm/review/writeRecovery.d.ts +17 -1
- package/dist/esm/review/writeRecovery.d.ts.map +1 -1
- package/dist/esm/review/writeRecovery.js +149 -48
- package/dist/esm/review/writeRecovery.js.map +1 -1
- package/dist/esm/safeService.d.ts +27 -4
- package/dist/esm/safeService.d.ts.map +1 -1
- package/dist/esm/safeService.js +119 -4
- package/dist/esm/safeService.js.map +1 -1
- package/dist/esm/testing.d.ts +24 -0
- package/dist/esm/testing.d.ts.map +1 -1
- package/dist/esm/testing.js +23 -1
- package/dist/esm/testing.js.map +1 -1
- package/dist/esm/v6/defifa.d.ts.map +1 -1
- package/dist/esm/v6/defifa.js +24 -23
- package/dist/esm/v6/defifa.js.map +1 -1
- package/dist/esm/v6/executionErrors.d.ts.map +1 -1
- package/dist/esm/v6/executionErrors.js +3 -2
- package/dist/esm/v6/executionErrors.js.map +1 -1
- package/dist/esm/v6/pay.d.ts +25 -8
- package/dist/esm/v6/pay.d.ts.map +1 -1
- package/dist/esm/v6/pay.js +115 -22
- package/dist/esm/v6/pay.js.map +1 -1
- package/dist/esm/v6/suckers.d.ts +30 -0
- package/dist/esm/v6/suckers.d.ts.map +1 -1
- package/dist/esm/v6/suckers.js +67 -5
- package/dist/esm/v6/suckers.js.map +1 -1
- package/package.json +11 -2
|
@@ -0,0 +1,372 @@
|
|
|
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 { 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, nor is a self-reviewing wallet. A definite wallet
|
|
249
|
+
* rejection (EIP-1193 4001) returns no
|
|
250
|
+
* signature and throws {@link TransactionReviewCancelledError}.
|
|
251
|
+
*/
|
|
252
|
+
export async function signPrepared(prepared, account, adapter,
|
|
253
|
+
/** The caller's final gate before each signature; it throws to stop. */
|
|
254
|
+
beforeSign,
|
|
255
|
+
/** The caller's async recheck before each signature, ahead of `beforeSign`. */
|
|
256
|
+
reverify) {
|
|
257
|
+
const signatures = [];
|
|
258
|
+
const chained = adapter.kind !== "self-reviewing";
|
|
259
|
+
for (const { chainId, typedData, message } of prepared) {
|
|
260
|
+
signatures.push(await submitReviewedContractWrite({
|
|
261
|
+
request: { chainId },
|
|
262
|
+
expectedAccount: account,
|
|
263
|
+
review: () => Promise.resolve(),
|
|
264
|
+
switchChain: async (id) => {
|
|
265
|
+
if (chained && typedData && adapter.chainId() !== id) {
|
|
266
|
+
await adapter.switchChain(id);
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
currentAccount: () => adapter.account(),
|
|
270
|
+
...(reverify ? { reverify } : {}),
|
|
271
|
+
simulate: async () => undefined,
|
|
272
|
+
beforeSend: () => {
|
|
273
|
+
beforeSign?.();
|
|
274
|
+
if (chained && typedData && adapter.chainId() !== chainId) {
|
|
275
|
+
throw new ReviewLineError("Your wallet changed networks. Review the signature again.");
|
|
276
|
+
}
|
|
277
|
+
// Last, after every callback above could have run.
|
|
278
|
+
if (adapter.account()?.toLowerCase() !== account.toLowerCase()) {
|
|
279
|
+
throw new ReviewLineError("The connected account changed. Review again.");
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
// Only the wallet's own answer can read as a rejection.
|
|
283
|
+
write: async () => {
|
|
284
|
+
try {
|
|
285
|
+
return await (typedData
|
|
286
|
+
? adapter.signTypedData(typedData)
|
|
287
|
+
: adapter.signMessage(message));
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
if (isDefiniteWalletRejection(error)) {
|
|
291
|
+
throw new TransactionReviewCancelledError(REJECTED);
|
|
292
|
+
}
|
|
293
|
+
throw error;
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
}));
|
|
297
|
+
}
|
|
298
|
+
return signatures;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* The calls a prepared signature lets someone run, as a plan matches them,
|
|
302
|
+
* read from the exact payload signed: a Safe transaction's CALL or
|
|
303
|
+
* MultiSendCallOnly calls, from the Safe, when it pays no refund and its
|
|
304
|
+
* safeTxGas is 0 (so a failed call reverts, not spends the nonce), or a
|
|
305
|
+
* forward request's call, from its signer. Any other signature is refused
|
|
306
|
+
* under a plan.
|
|
307
|
+
*/
|
|
308
|
+
export function plannedCallsOf({ chainId, typedData, }) {
|
|
309
|
+
const message = typedData?.message;
|
|
310
|
+
if (typedData?.primaryType === "SafeTx" && message) {
|
|
311
|
+
const { to, data, value, operation, safeTxGas, gasPrice } = message;
|
|
312
|
+
const safe = typedData.domain?.verifyingContract;
|
|
313
|
+
const inner = operation === 1
|
|
314
|
+
? multiSendCallsOf({ to, data, operation })
|
|
315
|
+
: [{ to, data, value }];
|
|
316
|
+
if (safe && inner && safeTxGas === 0n && gasPrice === 0n)
|
|
317
|
+
return inner.map((call) => ({
|
|
318
|
+
chainId,
|
|
319
|
+
from: safe,
|
|
320
|
+
to: call.to,
|
|
321
|
+
data: call.data,
|
|
322
|
+
value: call.value,
|
|
323
|
+
}));
|
|
324
|
+
}
|
|
325
|
+
else if (typedData?.primaryType === "ForwardRequest" && message) {
|
|
326
|
+
const { from, to, data, value, gas } = message;
|
|
327
|
+
return [{ chainId, from, to, data, value, gas }];
|
|
328
|
+
}
|
|
329
|
+
throw new ReviewLineError(REVIEWED_PLAN_REFUSED_LINE);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Signs only what the person reviewed: one prompt for every signature, with
|
|
333
|
+
* the exact typed data or text and the calls each lets someone run, decoded.
|
|
334
|
+
* Nothing is signed unless the review handler returns core's confirmation
|
|
335
|
+
* ({@link registerReviewHandler}). The signatures come back in order.
|
|
336
|
+
*
|
|
337
|
+
* A self-reviewing adapter (Signa) is never prompted: `onPreview` gets the
|
|
338
|
+
* model, and the adapter the raw typed data or text to review on its own page.
|
|
339
|
+
*/
|
|
340
|
+
export async function signReviewed(signatures, action, deps) {
|
|
341
|
+
const { adapter } = deps;
|
|
342
|
+
const { account } = action;
|
|
343
|
+
await walletReady(adapter);
|
|
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
|
+
const own = adapter.kind === "self-reviewing";
|
|
354
|
+
if (action.plan)
|
|
355
|
+
spendPlan(action.plan, account, prepared.flatMap(plannedCallsOf));
|
|
356
|
+
if (own || !action.plan) {
|
|
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
|
+
if (own)
|
|
365
|
+
deps.onPreview?.(model);
|
|
366
|
+
// Nothing is sent, so there is nothing to simulate.
|
|
367
|
+
else
|
|
368
|
+
await promptReview(model, Promise.resolve({ status: "passed" }), Promise.resolve(model), action.signal);
|
|
369
|
+
}
|
|
370
|
+
return signPrepared(prepared, account, adapter, undefined, action.reverify);
|
|
371
|
+
}
|
|
372
|
+
//# 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;
|
|
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
|
|
20
|
+
throw new ReviewLineError("Transaction simulation gas must be positive.");
|
|
19
21
|
}
|
|
20
22
|
if (!Number.isSafeInteger(maxReturnBytes) || maxReturnBytes < 0) {
|
|
21
|
-
throw new
|
|
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
|
-
|
|
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
|
|
42
|
+
throw new ReviewLineError("Transaction simulation returned malformed data.");
|
|
40
43
|
}
|
|
41
44
|
if ((result.length - 2) / 2 > maxReturnBytes) {
|
|
42
|
-
throw new
|
|
45
|
+
throw new ReviewLineError("Transaction simulation returned too much data.");
|
|
43
46
|
}
|
|
44
47
|
return result;
|
|
45
48
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
53
|
-
|
|
54
|
-
|
|
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 }) => ({
|
|
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
|
|
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
|
|
182
|
+
throw simulationFailure(`${call.label} cannot run on ${chainName}: ${result?.status === "failure"
|
|
119
183
|
? revertDetail(result.error)
|
|
120
|
-
:
|
|
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
|
|
199
|
+
throw simulationFailure(`${call.label} cannot run on ${chainName}: ${revertDetail(error)}`, error);
|
|
134
200
|
}
|
|
135
201
|
}
|
|
136
202
|
}
|