@morpho-org/evm-simulation 4.2.1 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -17
- package/lib/cjs/authorizations.d.ts +95 -0
- package/lib/cjs/authorizations.js +2 -0
- package/lib/cjs/errors.d.ts +199 -12
- package/lib/cjs/errors.js +190 -12
- package/lib/cjs/index.d.ts +10 -2
- package/lib/cjs/index.js +19 -3
- package/lib/cjs/limits.d.ts +112 -0
- package/lib/cjs/limits.js +50 -0
- package/lib/cjs/params.d.ts +26 -0
- package/lib/cjs/params.js +5 -0
- package/lib/cjs/requirements/index.d.ts +1 -0
- package/lib/cjs/requirements/index.js +5 -0
- package/lib/cjs/requirements/requirements.d.ts +64 -0
- package/lib/cjs/requirements/requirements.js +149 -0
- package/lib/cjs/result.d.ts +49 -0
- package/lib/cjs/result.js +2 -0
- package/lib/cjs/simulate/asset-changes.d.ts +7 -5
- package/lib/cjs/simulate/asset-changes.js +6 -5
- package/lib/cjs/simulate/backends/client.d.ts +16 -0
- package/lib/cjs/simulate/backends/client.js +27 -0
- package/lib/cjs/simulate/backends/eth-simulate-v1.d.ts +69 -20
- package/lib/cjs/simulate/backends/eth-simulate-v1.js +174 -98
- package/lib/cjs/simulate/backends/index.d.ts +1 -2
- package/lib/cjs/simulate/backends/index.js +3 -4
- package/lib/cjs/simulate/backends/parse-response.d.ts +69 -0
- package/lib/cjs/simulate/backends/parse-response.js +168 -0
- package/lib/cjs/simulate/backends/resolve-assets.d.ts +26 -0
- package/lib/cjs/simulate/backends/resolve-assets.js +111 -0
- package/lib/cjs/simulate/backends/resolve-pinned-block.d.ts +33 -0
- package/lib/cjs/simulate/backends/resolve-pinned-block.js +46 -0
- package/lib/cjs/simulate/context.d.ts +14 -0
- package/lib/cjs/simulate/context.js +2 -0
- package/lib/cjs/simulate/measurement-plan.d.ts +29 -0
- package/lib/cjs/simulate/measurement-plan.js +115 -0
- package/lib/cjs/simulate/parsing/transfers.d.ts +4 -3
- package/lib/cjs/simulate/parsing/transfers.js +4 -6
- package/lib/cjs/simulate/pipeline/bundles-retention.d.ts +7 -10
- package/lib/cjs/simulate/pipeline/bundles-retention.js +11 -14
- package/lib/cjs/simulate/pipeline/resolve-chain.d.ts +5 -11
- package/lib/cjs/simulate/pipeline/resolve-chain.js +5 -10
- package/lib/cjs/simulate/plan/plan-execution.d.ts +58 -0
- package/lib/cjs/simulate/plan/plan-execution.js +75 -0
- package/lib/cjs/simulate/prepare.d.ts +30 -0
- package/lib/cjs/simulate/prepare.js +80 -0
- package/lib/cjs/simulate/request/index.d.ts +1 -0
- package/lib/cjs/simulate/request/index.js +5 -0
- package/lib/cjs/simulate/request/parse-request.d.ts +44 -0
- package/lib/cjs/simulate/request/parse-request.js +759 -0
- package/lib/cjs/simulate/result.d.ts +19 -0
- package/lib/cjs/simulate/result.js +29 -0
- package/lib/cjs/simulate/run-simulation.d.ts +18 -0
- package/lib/cjs/simulate/run-simulation.js +156 -0
- package/lib/cjs/simulate/simulate.d.ts +102 -51
- package/lib/cjs/simulate/simulate.js +101 -82
- package/lib/cjs/simulate/slippage.d.ts +18 -0
- package/lib/cjs/simulate/slippage.js +41 -0
- package/lib/cjs/simulate/state/contract.d.ts +19 -0
- package/lib/cjs/simulate/state/contract.js +2 -0
- package/lib/cjs/simulate/state/read-state.d.ts +60 -0
- package/lib/cjs/simulate/state/read-state.js +148 -0
- package/lib/cjs/simulate/verify-slippage.d.ts +24 -0
- package/lib/cjs/simulate/verify-slippage.js +85 -0
- package/lib/cjs/types.d.ts +37 -96
- package/lib/esm/authorizations.d.ts +95 -0
- package/lib/esm/authorizations.js +1 -0
- package/lib/esm/errors.d.ts +199 -12
- package/lib/esm/errors.js +182 -11
- package/lib/esm/index.d.ts +10 -2
- package/lib/esm/index.js +4 -1
- package/lib/esm/limits.d.ts +112 -0
- package/lib/esm/limits.js +47 -0
- package/lib/esm/params.d.ts +26 -0
- package/lib/esm/params.js +2 -0
- package/lib/esm/requirements/index.d.ts +1 -0
- package/lib/esm/requirements/index.js +1 -0
- package/lib/esm/requirements/requirements.d.ts +64 -0
- package/lib/esm/requirements/requirements.js +146 -0
- package/lib/esm/result.d.ts +49 -0
- package/lib/esm/result.js +1 -0
- package/lib/esm/simulate/asset-changes.d.ts +7 -5
- package/lib/esm/simulate/asset-changes.js +6 -5
- package/lib/esm/simulate/backends/client.d.ts +16 -0
- package/lib/esm/simulate/backends/client.js +24 -0
- package/lib/esm/simulate/backends/eth-simulate-v1.d.ts +69 -20
- package/lib/esm/simulate/backends/eth-simulate-v1.js +172 -99
- package/lib/esm/simulate/backends/index.d.ts +1 -2
- package/lib/esm/simulate/backends/index.js +1 -2
- package/lib/esm/simulate/backends/parse-response.d.ts +69 -0
- package/lib/esm/simulate/backends/parse-response.js +165 -0
- package/lib/esm/simulate/backends/resolve-assets.d.ts +26 -0
- package/lib/esm/simulate/backends/resolve-assets.js +108 -0
- package/lib/esm/simulate/backends/resolve-pinned-block.d.ts +33 -0
- package/lib/esm/simulate/backends/resolve-pinned-block.js +43 -0
- package/lib/esm/simulate/context.d.ts +14 -0
- package/lib/esm/simulate/context.js +1 -0
- package/lib/esm/simulate/measurement-plan.d.ts +29 -0
- package/lib/esm/simulate/measurement-plan.js +112 -0
- package/lib/esm/simulate/parsing/transfers.d.ts +4 -3
- package/lib/esm/simulate/parsing/transfers.js +4 -6
- package/lib/esm/simulate/pipeline/bundles-retention.d.ts +7 -10
- package/lib/esm/simulate/pipeline/bundles-retention.js +11 -14
- package/lib/esm/simulate/pipeline/resolve-chain.d.ts +5 -11
- package/lib/esm/simulate/pipeline/resolve-chain.js +5 -10
- package/lib/esm/simulate/plan/plan-execution.d.ts +58 -0
- package/lib/esm/simulate/plan/plan-execution.js +72 -0
- package/lib/esm/simulate/prepare.d.ts +30 -0
- package/lib/esm/simulate/prepare.js +77 -0
- package/lib/esm/simulate/request/index.d.ts +1 -0
- package/lib/esm/simulate/request/index.js +1 -0
- package/lib/esm/simulate/request/parse-request.d.ts +44 -0
- package/lib/esm/simulate/request/parse-request.js +756 -0
- package/lib/esm/simulate/result.d.ts +19 -0
- package/lib/esm/simulate/result.js +26 -0
- package/lib/esm/simulate/run-simulation.d.ts +18 -0
- package/lib/esm/simulate/run-simulation.js +153 -0
- package/lib/esm/simulate/simulate.d.ts +102 -51
- package/lib/esm/simulate/simulate.js +101 -82
- package/lib/esm/simulate/slippage.d.ts +18 -0
- package/lib/esm/simulate/slippage.js +38 -0
- package/lib/esm/simulate/state/contract.d.ts +19 -0
- package/lib/esm/simulate/state/contract.js +1 -0
- package/lib/esm/simulate/state/read-state.d.ts +60 -0
- package/lib/esm/simulate/state/read-state.js +144 -0
- package/lib/esm/simulate/verify-slippage.d.ts +24 -0
- package/lib/esm/simulate/verify-slippage.js +82 -0
- package/lib/esm/types.d.ts +37 -96
- package/package.json +7 -6
- package/lib/cjs/simulate/authorizations/index.d.ts +0 -2
- package/lib/cjs/simulate/authorizations/index.js +0 -7
- package/lib/cjs/simulate/authorizations/resolve.d.ts +0 -9
- package/lib/cjs/simulate/authorizations/resolve.js +0 -29
- package/lib/cjs/simulate/authorizations/validate.d.ts +0 -6
- package/lib/cjs/simulate/authorizations/validate.js +0 -23
- package/lib/cjs/simulate/backends/tenderly-rpc.d.ts +0 -23
- package/lib/cjs/simulate/backends/tenderly-rpc.js +0 -234
- package/lib/cjs/simulate/pipeline/build-simulation-txs.d.ts +0 -17
- package/lib/cjs/simulate/pipeline/build-simulation-txs.js +0 -50
- package/lib/cjs/simulate/pipeline/execute-simulation.d.ts +0 -22
- package/lib/cjs/simulate/pipeline/execute-simulation.js +0 -82
- package/lib/cjs/simulate/pipeline/index.d.ts +0 -4
- package/lib/cjs/simulate/pipeline/index.js +0 -11
- package/lib/cjs/simulate/pipeline/validate-input.d.ts +0 -10
- package/lib/cjs/simulate/pipeline/validate-input.js +0 -55
- package/lib/esm/simulate/authorizations/index.d.ts +0 -2
- package/lib/esm/simulate/authorizations/index.js +0 -2
- package/lib/esm/simulate/authorizations/resolve.d.ts +0 -9
- package/lib/esm/simulate/authorizations/resolve.js +0 -26
- package/lib/esm/simulate/authorizations/validate.d.ts +0 -6
- package/lib/esm/simulate/authorizations/validate.js +0 -20
- package/lib/esm/simulate/backends/tenderly-rpc.d.ts +0 -23
- package/lib/esm/simulate/backends/tenderly-rpc.js +0 -231
- package/lib/esm/simulate/pipeline/build-simulation-txs.d.ts +0 -17
- package/lib/esm/simulate/pipeline/build-simulation-txs.js +0 -47
- package/lib/esm/simulate/pipeline/execute-simulation.d.ts +0 -22
- package/lib/esm/simulate/pipeline/execute-simulation.js +0 -79
- package/lib/esm/simulate/pipeline/index.d.ts +0 -4
- package/lib/esm/simulate/pipeline/index.js +0 -4
- package/lib/esm/simulate/pipeline/validate-input.d.ts +0 -10
- package/lib/esm/simulate/pipeline/validate-input.js +0 -52
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { MarketId } from "@morpho-org/blue-sdk";
|
|
2
|
+
import type { Address } from "viem";
|
|
3
|
+
/** Every operation type; source of `OperationType`. */
|
|
4
|
+
export declare const OPERATION_TYPES: readonly ["blueSupply", "blueWithdraw", "blueSupplyCollateral", "blueBorrow", "blueSupplyCollateralBorrow", "blueRepay", "blueWithdrawCollateral", "blueRepayWithdrawCollateral", "blueRefinance", "vaultV1Deposit", "vaultV2Deposit", "vaultV1Withdraw", "vaultV2Withdraw", "vaultV1Redeem", "vaultV2Redeem", "vaultV2ForceWithdraw", "vaultV2ForceRedeem", "vaultV1InKindRedeem", "vaultV2InKindRedeem", "vaultV1MigrateToV2"];
|
|
5
|
+
/** Discriminator for operations and their limits. */
|
|
6
|
+
export type OperationType = (typeof OPERATION_TYPES)[number];
|
|
7
|
+
/** Operations acting on one Blue market; source of `BlueMarketOperationType`. */
|
|
8
|
+
export declare const BLUE_MARKET_OPERATION_TYPES: readonly ["blueSupply", "blueWithdraw", "blueSupplyCollateral", "blueBorrow", "blueSupplyCollateralBorrow", "blueRepay", "blueWithdrawCollateral", "blueRepayWithdrawCollateral"];
|
|
9
|
+
/** Operations acting on one Blue market. */
|
|
10
|
+
export type BlueMarketOperationType = (typeof BLUE_MARKET_OPERATION_TYPES)[number];
|
|
11
|
+
/** Operations acting on one vault (V1 or V2); source of `VaultOperationType`. */
|
|
12
|
+
export declare const VAULT_OPERATION_TYPES: readonly ["vaultV1Deposit", "vaultV2Deposit", "vaultV1Withdraw", "vaultV2Withdraw", "vaultV1Redeem", "vaultV2Redeem", "vaultV2ForceWithdraw", "vaultV2ForceRedeem", "vaultV1InKindRedeem", "vaultV2InKindRedeem"];
|
|
13
|
+
/** Operations acting on one vault (V1 or V2). */
|
|
14
|
+
export type VaultOperationType = (typeof VAULT_OPERATION_TYPES)[number];
|
|
15
|
+
/** Subject of an operation acting on one Blue market. */
|
|
16
|
+
export interface BlueMarketOperationSubject {
|
|
17
|
+
readonly operation: BlueMarketOperationType;
|
|
18
|
+
/** Blue market the operation acts on. */
|
|
19
|
+
readonly marketId: MarketId;
|
|
20
|
+
}
|
|
21
|
+
/** Subject of a Blue refinance between two markets. */
|
|
22
|
+
export interface BlueRefinanceSubject {
|
|
23
|
+
readonly operation: "blueRefinance";
|
|
24
|
+
/** Market the refinance closes. */
|
|
25
|
+
readonly sourceMarketId: MarketId;
|
|
26
|
+
/** Market the refinance opens. */
|
|
27
|
+
readonly targetMarketId: MarketId;
|
|
28
|
+
}
|
|
29
|
+
/** Subject of an operation acting on one vault (V1 or V2). */
|
|
30
|
+
export interface VaultOperationSubject {
|
|
31
|
+
readonly operation: VaultOperationType;
|
|
32
|
+
/** Vault the operation acts on. */
|
|
33
|
+
readonly vault: Address;
|
|
34
|
+
}
|
|
35
|
+
/** Subject of a Vault V1 → V2 migration. */
|
|
36
|
+
export interface VaultV1MigrateToV2Subject {
|
|
37
|
+
readonly operation: "vaultV1MigrateToV2";
|
|
38
|
+
/** Vault the migration exits. */
|
|
39
|
+
readonly sourceVault: Address;
|
|
40
|
+
/** Vault the migration enters. */
|
|
41
|
+
readonly targetVault: Address;
|
|
42
|
+
}
|
|
43
|
+
/** Protocol entity a limit's operation acts on, keyed by `operation`; shared by `SimulatedOperation` and the verification error context. */
|
|
44
|
+
export type SimulationOperationSubject = BlueMarketOperationSubject | BlueRefinanceSubject | VaultOperationSubject | VaultV1MigrateToV2Subject;
|
|
45
|
+
/** Caller-quoted net amounts in raw units over the whole bundle.
|
|
46
|
+
* Supply at least one amount. Unquoted amounts are not checked.
|
|
47
|
+
*/
|
|
48
|
+
export interface SlippageQuote {
|
|
49
|
+
/**
|
|
50
|
+
* Expected net assets credited to the receiver. For in-kind vault redemptions,
|
|
51
|
+
* this measures only the wallet balance of the vault asset, not Morpho positions.
|
|
52
|
+
*/
|
|
53
|
+
readonly assetsReceived?: bigint;
|
|
54
|
+
/**
|
|
55
|
+
* Expected net shares added to the position. For debt shares, this is a
|
|
56
|
+
* maximum: minting more debt shares than quoted is adverse.
|
|
57
|
+
*/
|
|
58
|
+
readonly sharesMinted?: bigint;
|
|
59
|
+
/** Expected net assets debited from the sender. */
|
|
60
|
+
readonly assetsPaid?: bigint;
|
|
61
|
+
/**
|
|
62
|
+
* Expected net shares removed from the position. For debt shares, this is a
|
|
63
|
+
* minimum: burning fewer debt shares than quoted is adverse.
|
|
64
|
+
*/
|
|
65
|
+
readonly sharesBurned?: bigint;
|
|
66
|
+
}
|
|
67
|
+
/** Caller quote and permitted adverse percentage deviation. */
|
|
68
|
+
export interface SlippageLimits {
|
|
69
|
+
readonly quote: SlippageQuote;
|
|
70
|
+
/** WAD-scaled fraction from 0 to 1e18 inclusive; 1e16 means 1%. No default. */
|
|
71
|
+
readonly slippageTolerance: bigint;
|
|
72
|
+
}
|
|
73
|
+
/** Caller-selected action and subject with the same quote/tolerance shape for every action.
|
|
74
|
+
* Measurements cover the entire bundle for the named subject, never an inferred
|
|
75
|
+
* individual transaction. Use separate simulations for per-transaction bounds.
|
|
76
|
+
*/
|
|
77
|
+
export type OperationLimit = SlippageLimits & {
|
|
78
|
+
/** Position/share owner; defaults to the transaction sender. */
|
|
79
|
+
readonly account?: Address;
|
|
80
|
+
/**
|
|
81
|
+
* Explicit asset paid; defaults to the action underlying. Use viem's
|
|
82
|
+
* `ethAddress` (`0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`) for native ETH;
|
|
83
|
+
* sentinels such as `zeroAddress` are read as ERC-20 tokens.
|
|
84
|
+
*/
|
|
85
|
+
readonly assetPaid?: Address;
|
|
86
|
+
/**
|
|
87
|
+
* Explicit asset received; defaults to the action underlying. Use viem's
|
|
88
|
+
* `ethAddress` (`0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`) for native ETH;
|
|
89
|
+
* sentinels such as `zeroAddress` are read as ERC-20 tokens.
|
|
90
|
+
*/
|
|
91
|
+
readonly assetReceived?: Address;
|
|
92
|
+
/** Asset receiver; defaults to the transaction sender. */
|
|
93
|
+
readonly receiver?: Address;
|
|
94
|
+
} & ({
|
|
95
|
+
readonly type: BlueMarketOperationType;
|
|
96
|
+
readonly marketId: MarketId;
|
|
97
|
+
} | {
|
|
98
|
+
readonly type: "blueRefinance";
|
|
99
|
+
readonly sourceMarketId: MarketId;
|
|
100
|
+
readonly targetMarketId: MarketId;
|
|
101
|
+
} | {
|
|
102
|
+
readonly type: VaultOperationType;
|
|
103
|
+
readonly vault: Address;
|
|
104
|
+
} | {
|
|
105
|
+
readonly type: "vaultV1MigrateToV2";
|
|
106
|
+
readonly sourceVault: Address;
|
|
107
|
+
readonly targetVault: Address;
|
|
108
|
+
});
|
|
109
|
+
/** Optional caller-selected checks. No action discovery or default bounds. */
|
|
110
|
+
export interface SimulationLimits {
|
|
111
|
+
readonly operations?: readonly OperationLimit[];
|
|
112
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** Every operation type; source of `OperationType`. */
|
|
2
|
+
export const OPERATION_TYPES = [
|
|
3
|
+
"blueSupply",
|
|
4
|
+
"blueWithdraw",
|
|
5
|
+
"blueSupplyCollateral",
|
|
6
|
+
"blueBorrow",
|
|
7
|
+
"blueSupplyCollateralBorrow",
|
|
8
|
+
"blueRepay",
|
|
9
|
+
"blueWithdrawCollateral",
|
|
10
|
+
"blueRepayWithdrawCollateral",
|
|
11
|
+
"blueRefinance",
|
|
12
|
+
"vaultV1Deposit",
|
|
13
|
+
"vaultV2Deposit",
|
|
14
|
+
"vaultV1Withdraw",
|
|
15
|
+
"vaultV2Withdraw",
|
|
16
|
+
"vaultV1Redeem",
|
|
17
|
+
"vaultV2Redeem",
|
|
18
|
+
"vaultV2ForceWithdraw",
|
|
19
|
+
"vaultV2ForceRedeem",
|
|
20
|
+
"vaultV1InKindRedeem",
|
|
21
|
+
"vaultV2InKindRedeem",
|
|
22
|
+
"vaultV1MigrateToV2",
|
|
23
|
+
];
|
|
24
|
+
/** Operations acting on one Blue market; source of `BlueMarketOperationType`. */
|
|
25
|
+
export const BLUE_MARKET_OPERATION_TYPES = [
|
|
26
|
+
"blueSupply",
|
|
27
|
+
"blueWithdraw",
|
|
28
|
+
"blueSupplyCollateral",
|
|
29
|
+
"blueBorrow",
|
|
30
|
+
"blueSupplyCollateralBorrow",
|
|
31
|
+
"blueRepay",
|
|
32
|
+
"blueWithdrawCollateral",
|
|
33
|
+
"blueRepayWithdrawCollateral",
|
|
34
|
+
];
|
|
35
|
+
/** Operations acting on one vault (V1 or V2); source of `VaultOperationType`. */
|
|
36
|
+
export const VAULT_OPERATION_TYPES = [
|
|
37
|
+
"vaultV1Deposit",
|
|
38
|
+
"vaultV2Deposit",
|
|
39
|
+
"vaultV1Withdraw",
|
|
40
|
+
"vaultV2Withdraw",
|
|
41
|
+
"vaultV1Redeem",
|
|
42
|
+
"vaultV2Redeem",
|
|
43
|
+
"vaultV2ForceWithdraw",
|
|
44
|
+
"vaultV2ForceRedeem",
|
|
45
|
+
"vaultV1InKindRedeem",
|
|
46
|
+
"vaultV2InKindRedeem",
|
|
47
|
+
];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { BlockTag } from "viem";
|
|
2
|
+
import type { SimulationAuthorization } from "./authorizations.js";
|
|
3
|
+
import type { SimulationLimits } from "./limits.js";
|
|
4
|
+
import type { SimulationTransaction } from "./types.js";
|
|
5
|
+
/** Every simulation mode; source of `SimulationMode`. */
|
|
6
|
+
export declare const SIMULATION_MODES: readonly ["preview", "final"];
|
|
7
|
+
/** Simulation mode: `"preview"` accepts pending authorizations, `"final"` does not. */
|
|
8
|
+
export type SimulationMode = (typeof SIMULATION_MODES)[number];
|
|
9
|
+
/**
|
|
10
|
+
* Input to `simulate()`. `authorizations` is accepted only in "preview";
|
|
11
|
+
* `mode` defaults to "final".
|
|
12
|
+
*/
|
|
13
|
+
export interface SimulateParams {
|
|
14
|
+
readonly chainId: number;
|
|
15
|
+
readonly transactions: readonly SimulationTransaction[];
|
|
16
|
+
/** Defaults to "final". */
|
|
17
|
+
readonly mode?: SimulationMode;
|
|
18
|
+
/** Pending wallet requests, in order. Preview only; rejected in final. */
|
|
19
|
+
readonly authorizations?: readonly SimulationAuthorization[];
|
|
20
|
+
/** Resolved once; defaults to "latest" ("finalized" on Monad, whose
|
|
21
|
+
* "latest" block is not final). Only canonical (mined) blocks can be
|
|
22
|
+
* pinned; `pending` has no stable hash and is rejected at runtime. */
|
|
23
|
+
readonly blockNumber?: bigint | Exclude<BlockTag, "pending">;
|
|
24
|
+
/** Caller-selected quotes and percentage tolerances. Omitted limits are unchecked. */
|
|
25
|
+
readonly limits?: SimulationLimits;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { toSimulationAuthorizations } from "./requirements.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { toSimulationAuthorizations } from "./requirements.js";
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ActionRequirement } from "@morpho-org/morpho-sdk";
|
|
2
|
+
import type { Address } from "viem";
|
|
3
|
+
import type { SimulationAuthorization } from "../authorizations.js";
|
|
4
|
+
import type { SimulationMode } from "../params.js";
|
|
5
|
+
/**
|
|
6
|
+
* Maps morpho-sdk action requirements, in order, onto simulation authorization descriptors.
|
|
7
|
+
*
|
|
8
|
+
* The adapter is a pure mapper — nothing is decoded or validated; `simulate()`'s request parser
|
|
9
|
+
* validates each authorization's shape and semantics when the request is parsed. Call requirements
|
|
10
|
+
* (`erc20Approval`, `blueAuthorization`) are mapped straight from `action.args` (the approval
|
|
11
|
+
* token is the requirement's `to`). Signature requirements (`permit`,
|
|
12
|
+
* `permit2SignatureTransfer`, `authorization`) carry their EIP-712 payload through unchanged; a
|
|
13
|
+
* missing payload throws {@link AuthorizationRequestMismatchError}. Any other requirement type
|
|
14
|
+
* throws {@link UnsupportedOperationError}.
|
|
15
|
+
*
|
|
16
|
+
* The function is pure and synchronous: no RPC reads, no clock, no signing.
|
|
17
|
+
*
|
|
18
|
+
* @param params - Mapping parameters.
|
|
19
|
+
* @param params.chainId - The chain the requirements were resolved on; carried into error contexts.
|
|
20
|
+
* @param params.mode - Simulation mode carried into error contexts (`"preview"` or `"final"`).
|
|
21
|
+
* @param params.blockNumber - Pinned block the simulation is verified against; carried into error contexts.
|
|
22
|
+
* @param params.owner - The account the requirements were resolved for (transaction sender).
|
|
23
|
+
* @param params.requirements - Requirements returned by `ActionOutput.getRequirements()`.
|
|
24
|
+
* @returns One {@link SimulationAuthorization} per input requirement, in the same order.
|
|
25
|
+
* @throws {AuthorizationRequestMismatchError} when a signature requirement carries no `typedData`.
|
|
26
|
+
* @throws {UnsupportedOperationError} when a requirement's action type is not a supported
|
|
27
|
+
* authorization.
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* import { toSimulationAuthorizations } from "@morpho-org/evm-simulation";
|
|
31
|
+
* import { morphoViemExtension } from "@morpho-org/morpho-sdk";
|
|
32
|
+
* import { vaults } from "@morpho-org/morpho-test";
|
|
33
|
+
* import { createPublicClient, http, type Address } from "viem";
|
|
34
|
+
* import { mainnet } from "viem/chains";
|
|
35
|
+
*
|
|
36
|
+
* async function prepare(userAddress: Address, blockNumber: bigint) {
|
|
37
|
+
* const client = createPublicClient({ chain: mainnet, transport: http() })
|
|
38
|
+
* .extend(morphoViemExtension());
|
|
39
|
+
* const vault = client.morpho.vaultV1(
|
|
40
|
+
* vaults[mainnet.id].steakUsdc.address,
|
|
41
|
+
* mainnet.id,
|
|
42
|
+
* );
|
|
43
|
+
* const vaultData = await vault.getData();
|
|
44
|
+
* const requirements = await vault
|
|
45
|
+
* .deposit({ amount: 1_000_000n, userAddress, vaultData })
|
|
46
|
+
* .getRequirements();
|
|
47
|
+
* const authorizations = toSimulationAuthorizations({
|
|
48
|
+
* chainId: mainnet.id,
|
|
49
|
+
* mode: "final",
|
|
50
|
+
* blockNumber,
|
|
51
|
+
* owner: userAddress,
|
|
52
|
+
* requirements,
|
|
53
|
+
* });
|
|
54
|
+
* return authorizations; // readonly SimulationAuthorization[], one entry per requirement
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function toSimulationAuthorizations(params: {
|
|
59
|
+
readonly chainId: number;
|
|
60
|
+
readonly mode: SimulationMode;
|
|
61
|
+
readonly blockNumber: bigint;
|
|
62
|
+
readonly owner: Address;
|
|
63
|
+
readonly requirements: readonly ActionRequirement[];
|
|
64
|
+
}): readonly SimulationAuthorization[];
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { isRequirementApproval, isRequirementBlueAuthorization, isRequirementSignature, } from "@morpho-org/morpho-sdk";
|
|
2
|
+
import { AuthorizationRequestMismatchError, UnsupportedOperationError, } from "../errors.js";
|
|
3
|
+
const mismatch = (ctx) => (message, options) => {
|
|
4
|
+
throw new AuthorizationRequestMismatchError(`${message}. Rebuild the wallet request from getRequirements()`, {
|
|
5
|
+
context: {
|
|
6
|
+
stage: "preparation",
|
|
7
|
+
chainId: ctx.chainId,
|
|
8
|
+
mode: ctx.mode,
|
|
9
|
+
blockNumber: ctx.blockNumber,
|
|
10
|
+
authorizationIndex: ctx.index,
|
|
11
|
+
},
|
|
12
|
+
...options,
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
const unsupported = (ctx) => (message, options) => {
|
|
16
|
+
throw new UnsupportedOperationError(message, {
|
|
17
|
+
context: {
|
|
18
|
+
stage: "preparation",
|
|
19
|
+
chainId: ctx.chainId,
|
|
20
|
+
mode: ctx.mode,
|
|
21
|
+
blockNumber: ctx.blockNumber,
|
|
22
|
+
authorizationIndex: ctx.index,
|
|
23
|
+
},
|
|
24
|
+
...options,
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
const toErc2612Permit = (action, ctx) => {
|
|
28
|
+
if (action.typedData == null) {
|
|
29
|
+
mismatch(ctx)("Permit requirement carries no typedData payload");
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
type: "erc2612Permit",
|
|
33
|
+
typedData: action.typedData,
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
const toPermit2SignatureTransfer = (action, ctx) => {
|
|
37
|
+
if (action.typedData == null) {
|
|
38
|
+
mismatch(ctx)("Permit2 requirement carries no typedData payload");
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
type: "permit2SignatureTransfer",
|
|
42
|
+
owner: ctx.owner,
|
|
43
|
+
typedData: action.typedData,
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
const toBlueAuthorizationSignature = (action, ctx) => {
|
|
47
|
+
if (action.typedData == null) {
|
|
48
|
+
mismatch(ctx)("Authorization requirement carries no typedData payload");
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
type: "blueAuthorizationSignature",
|
|
52
|
+
typedData: action.typedData,
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
const toErc20Approval = (requirement, ctx) => ({
|
|
56
|
+
type: "erc20Approval",
|
|
57
|
+
token: requirement.to,
|
|
58
|
+
owner: ctx.owner,
|
|
59
|
+
spender: requirement.action.args.spender,
|
|
60
|
+
amount: requirement.action.args.amount,
|
|
61
|
+
});
|
|
62
|
+
const toBlueAuthorization = (requirement, ctx) => ({
|
|
63
|
+
type: "blueAuthorization",
|
|
64
|
+
authorizer: ctx.owner,
|
|
65
|
+
authorized: requirement.action.args.authorized,
|
|
66
|
+
isAuthorized: requirement.action.args.isAuthorized,
|
|
67
|
+
});
|
|
68
|
+
/**
|
|
69
|
+
* Maps morpho-sdk action requirements, in order, onto simulation authorization descriptors.
|
|
70
|
+
*
|
|
71
|
+
* The adapter is a pure mapper — nothing is decoded or validated; `simulate()`'s request parser
|
|
72
|
+
* validates each authorization's shape and semantics when the request is parsed. Call requirements
|
|
73
|
+
* (`erc20Approval`, `blueAuthorization`) are mapped straight from `action.args` (the approval
|
|
74
|
+
* token is the requirement's `to`). Signature requirements (`permit`,
|
|
75
|
+
* `permit2SignatureTransfer`, `authorization`) carry their EIP-712 payload through unchanged; a
|
|
76
|
+
* missing payload throws {@link AuthorizationRequestMismatchError}. Any other requirement type
|
|
77
|
+
* throws {@link UnsupportedOperationError}.
|
|
78
|
+
*
|
|
79
|
+
* The function is pure and synchronous: no RPC reads, no clock, no signing.
|
|
80
|
+
*
|
|
81
|
+
* @param params - Mapping parameters.
|
|
82
|
+
* @param params.chainId - The chain the requirements were resolved on; carried into error contexts.
|
|
83
|
+
* @param params.mode - Simulation mode carried into error contexts (`"preview"` or `"final"`).
|
|
84
|
+
* @param params.blockNumber - Pinned block the simulation is verified against; carried into error contexts.
|
|
85
|
+
* @param params.owner - The account the requirements were resolved for (transaction sender).
|
|
86
|
+
* @param params.requirements - Requirements returned by `ActionOutput.getRequirements()`.
|
|
87
|
+
* @returns One {@link SimulationAuthorization} per input requirement, in the same order.
|
|
88
|
+
* @throws {AuthorizationRequestMismatchError} when a signature requirement carries no `typedData`.
|
|
89
|
+
* @throws {UnsupportedOperationError} when a requirement's action type is not a supported
|
|
90
|
+
* authorization.
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* import { toSimulationAuthorizations } from "@morpho-org/evm-simulation";
|
|
94
|
+
* import { morphoViemExtension } from "@morpho-org/morpho-sdk";
|
|
95
|
+
* import { vaults } from "@morpho-org/morpho-test";
|
|
96
|
+
* import { createPublicClient, http, type Address } from "viem";
|
|
97
|
+
* import { mainnet } from "viem/chains";
|
|
98
|
+
*
|
|
99
|
+
* async function prepare(userAddress: Address, blockNumber: bigint) {
|
|
100
|
+
* const client = createPublicClient({ chain: mainnet, transport: http() })
|
|
101
|
+
* .extend(morphoViemExtension());
|
|
102
|
+
* const vault = client.morpho.vaultV1(
|
|
103
|
+
* vaults[mainnet.id].steakUsdc.address,
|
|
104
|
+
* mainnet.id,
|
|
105
|
+
* );
|
|
106
|
+
* const vaultData = await vault.getData();
|
|
107
|
+
* const requirements = await vault
|
|
108
|
+
* .deposit({ amount: 1_000_000n, userAddress, vaultData })
|
|
109
|
+
* .getRequirements();
|
|
110
|
+
* const authorizations = toSimulationAuthorizations({
|
|
111
|
+
* chainId: mainnet.id,
|
|
112
|
+
* mode: "final",
|
|
113
|
+
* blockNumber,
|
|
114
|
+
* owner: userAddress,
|
|
115
|
+
* requirements,
|
|
116
|
+
* });
|
|
117
|
+
* return authorizations; // readonly SimulationAuthorization[], one entry per requirement
|
|
118
|
+
* }
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
export function toSimulationAuthorizations(params) {
|
|
122
|
+
const { chainId, mode, blockNumber, owner, requirements } = params;
|
|
123
|
+
return requirements.map((requirement, index) => {
|
|
124
|
+
const ctx = { chainId, mode, blockNumber, owner, index };
|
|
125
|
+
if (isRequirementApproval(requirement)) {
|
|
126
|
+
return toErc20Approval(requirement, ctx);
|
|
127
|
+
}
|
|
128
|
+
if (isRequirementBlueAuthorization(requirement)) {
|
|
129
|
+
return toBlueAuthorization(requirement, ctx);
|
|
130
|
+
}
|
|
131
|
+
if (isRequirementSignature(requirement)) {
|
|
132
|
+
const { action } = requirement;
|
|
133
|
+
switch (action.type) {
|
|
134
|
+
case "permit":
|
|
135
|
+
return toErc2612Permit(action, ctx);
|
|
136
|
+
case "permit2SignatureTransfer":
|
|
137
|
+
return toPermit2SignatureTransfer(action, ctx);
|
|
138
|
+
case "authorization":
|
|
139
|
+
return toBlueAuthorizationSignature(action, ctx);
|
|
140
|
+
default:
|
|
141
|
+
return unsupported(ctx)(`Signature requirement action type "${action.type}" is not supported. Only permit, permit2SignatureTransfer, and authorization signatures are supported`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return unsupported(ctx)(`Requirement action type "${requirement.action.type}" is not supported. Only erc20Approval, blueAuthorization, permit, permit2SignatureTransfer, and authorization requirements are supported`);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Address } from "viem";
|
|
2
|
+
import type { SimulationAuthorization } from "./authorizations.js";
|
|
3
|
+
import type { SimulationLimits, SimulationOperationSubject, SlippageLimits } from "./limits.js";
|
|
4
|
+
import type { SimulationMode } from "./params.js";
|
|
5
|
+
import type { SimulationCall, SimulationResult, SimulationTransaction } from "./types.js";
|
|
6
|
+
/** One operation described by the caller's `limits.operations`. */
|
|
7
|
+
export type SimulatedOperation = {
|
|
8
|
+
/** Quote and percentage tolerance checked against the named subject over the whole bundle. */
|
|
9
|
+
readonly checkedLimits: SlippageLimits;
|
|
10
|
+
/** Resolved selector from the limit; defaults to the transaction sender. */
|
|
11
|
+
readonly account: Address;
|
|
12
|
+
/** Resolved selector from the limit; defaults to the transaction sender. */
|
|
13
|
+
readonly receiver: Address;
|
|
14
|
+
} & SimulationOperationSubject;
|
|
15
|
+
/** How a pending authorization was modeled in preview. */
|
|
16
|
+
export interface AuthorizationPreparation {
|
|
17
|
+
readonly authorizationIndex: number;
|
|
18
|
+
readonly authorization: SimulationAuthorization;
|
|
19
|
+
/** Approval calls simulated before the user transactions. */
|
|
20
|
+
readonly calls: readonly {
|
|
21
|
+
readonly transaction: SimulationTransaction;
|
|
22
|
+
readonly result: SimulationCall;
|
|
23
|
+
}[];
|
|
24
|
+
}
|
|
25
|
+
/** Optional slippage checks; execution success does not imply economic verification. */
|
|
26
|
+
export interface SimulationVerification {
|
|
27
|
+
readonly mode: SimulationMode;
|
|
28
|
+
readonly chainId: number;
|
|
29
|
+
/**
|
|
30
|
+
* Block `eth_simulateV1` executed in: the pinned state block or its
|
|
31
|
+
* successor, depending on the node. Not a pin to pass back as
|
|
32
|
+
* `SimulateParams.blockNumber`.
|
|
33
|
+
*/
|
|
34
|
+
readonly blockNumber: bigint;
|
|
35
|
+
/**
|
|
36
|
+
* Timestamp (seconds) of the block `eth_simulateV1` executed in: the
|
|
37
|
+
* pinned state block or its successor, depending on the node.
|
|
38
|
+
*/
|
|
39
|
+
readonly blockTimestamp: bigint;
|
|
40
|
+
/** Caller-supplied quotes and tolerances only; omitted limits remain unchecked. */
|
|
41
|
+
readonly limits: Required<SimulationLimits>;
|
|
42
|
+
readonly operations: readonly SimulatedOperation[];
|
|
43
|
+
/** Preview only; always empty in final. */
|
|
44
|
+
readonly authorizations: readonly AuthorizationPreparation[];
|
|
45
|
+
}
|
|
46
|
+
/** `simulationTxs` equals the caller's `transactions`; `txIdx` indexes only those. */
|
|
47
|
+
export interface VerifiedSimulationResult extends SimulationResult {
|
|
48
|
+
readonly verification: SimulationVerification;
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -5,18 +5,20 @@ export interface AssetChangeEntry {
|
|
|
5
5
|
account: Address;
|
|
6
6
|
token: Address;
|
|
7
7
|
diff: bigint;
|
|
8
|
+
/** Not populated by `eth_simulateV1`; kept for forward compatibility. */
|
|
8
9
|
symbol?: string;
|
|
9
10
|
decimals?: number;
|
|
10
11
|
}
|
|
11
12
|
/**
|
|
12
13
|
* Collapse the native-ETH sentinel to viem's lowercase `ethAddress`, checksumming
|
|
13
14
|
* any real token address. `eth_simulateV1` synthesizes native moves from the
|
|
14
|
-
* sentinel `0xeee…eee`,
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* sentinel `0xeee…eee`, possibly in checksummed or any other case. Native ETH
|
|
16
|
+
* is keyed by the exact `ethAddress` constant here and in the bundles-retention
|
|
17
|
+
* guard, so a checksummed
|
|
17
18
|
* sentinel would land on a separate map key and silently escape retention checks.
|
|
18
|
-
* This is the single source of truth for token normalization
|
|
19
|
-
* transfer-log parser and the
|
|
19
|
+
* This is the single source of truth for token normalization, applied by the
|
|
20
|
+
* transfer-log parser; asset-change aggregation and the bundler-retention guard
|
|
21
|
+
* rely on its `ethAddress` keying.
|
|
20
22
|
*
|
|
21
23
|
* @param address - Token address emitting a transfer or carried by an asset change.
|
|
22
24
|
* @returns `ethAddress` for the native sentinel, else the checksummed address.
|
|
@@ -2,12 +2,13 @@ import { ethAddress, getAddress } from "viem";
|
|
|
2
2
|
/**
|
|
3
3
|
* Collapse the native-ETH sentinel to viem's lowercase `ethAddress`, checksumming
|
|
4
4
|
* any real token address. `eth_simulateV1` synthesizes native moves from the
|
|
5
|
-
* sentinel `0xeee…eee`,
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* sentinel `0xeee…eee`, possibly in checksummed or any other case. Native ETH
|
|
6
|
+
* is keyed by the exact `ethAddress` constant here and in the bundles-retention
|
|
7
|
+
* guard, so a checksummed
|
|
8
8
|
* sentinel would land on a separate map key and silently escape retention checks.
|
|
9
|
-
* This is the single source of truth for token normalization
|
|
10
|
-
* transfer-log parser and the
|
|
9
|
+
* This is the single source of truth for token normalization, applied by the
|
|
10
|
+
* transfer-log parser; asset-change aggregation and the bundler-retention guard
|
|
11
|
+
* rely on its `ethAddress` keying.
|
|
11
12
|
*
|
|
12
13
|
* @param address - Token address emitting a transfer or carried by an asset change.
|
|
13
14
|
* @returns `ethAddress` for the native sentinel, else the checksummed address.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type PublicClient } from "viem";
|
|
2
|
+
/**
|
|
3
|
+
* Create the viem public client shared by every simulation backend stage
|
|
4
|
+
* (pinned block resolution, binding/pinned reads, `eth_simulateV1`).
|
|
5
|
+
*
|
|
6
|
+
* A supplied abort signal is bound into the transport: a failed or aborted
|
|
7
|
+
* request must not consume another attempt or a fresh budget, and the pipeline
|
|
8
|
+
* abort signal owns the overall execution deadline, so the client sends zero
|
|
9
|
+
* retries and disables viem's own timeout when a signal is present.
|
|
10
|
+
*
|
|
11
|
+
* @param rpcUrl - Endpoint URL; each caller supplies the transport it trusts.
|
|
12
|
+
* @param signal - Optional pipeline abort signal shared by every request.
|
|
13
|
+
* @returns A viem {@link PublicClient} honoring the shared abort/timeout budget.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export declare function createSimulationClient(rpcUrl: string, signal?: AbortSignal): PublicClient;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createPublicClient, http } from "viem";
|
|
2
|
+
/**
|
|
3
|
+
* Create the viem public client shared by every simulation backend stage
|
|
4
|
+
* (pinned block resolution, binding/pinned reads, `eth_simulateV1`).
|
|
5
|
+
*
|
|
6
|
+
* A supplied abort signal is bound into the transport: a failed or aborted
|
|
7
|
+
* request must not consume another attempt or a fresh budget, and the pipeline
|
|
8
|
+
* abort signal owns the overall execution deadline, so the client sends zero
|
|
9
|
+
* retries and disables viem's own timeout when a signal is present.
|
|
10
|
+
*
|
|
11
|
+
* @param rpcUrl - Endpoint URL; each caller supplies the transport it trusts.
|
|
12
|
+
* @param signal - Optional pipeline abort signal shared by every request.
|
|
13
|
+
* @returns A viem {@link PublicClient} honoring the shared abort/timeout budget.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export function createSimulationClient(rpcUrl, signal) {
|
|
17
|
+
return createPublicClient({
|
|
18
|
+
transport: http(rpcUrl, {
|
|
19
|
+
fetchOptions: signal ? { signal } : undefined,
|
|
20
|
+
retryCount: 0,
|
|
21
|
+
timeout: signal ? 0 : undefined,
|
|
22
|
+
}),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -1,24 +1,73 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type {
|
|
1
|
+
import { type Client, type PublicClient } from "viem";
|
|
2
|
+
import type { SimulationMode } from "../../params.js";
|
|
3
|
+
import type { ExecutionPlan } from "../plan/plan-execution.js";
|
|
4
|
+
import type { SimulationExecution } from "./parse-response.js";
|
|
5
|
+
import type { PinnedBlock } from "./resolve-pinned-block.js";
|
|
6
|
+
/** The JSON-RPC methods this boundary calls. */
|
|
7
|
+
type RpcLabel = "eth_getBlock" | "eth_chainId" | "eth_simulateV1";
|
|
8
|
+
/** Run one RPC call; anything thrown becomes a typed boundary error. @internal */
|
|
9
|
+
export declare const rpc: <T>(label: RpcLabel, call: () => Promise<T>) => Promise<T>;
|
|
10
|
+
/** Validate the endpoint identity through the same URL-safe RPC boundary. @internal */
|
|
11
|
+
export declare function assertEndpointChain(params: {
|
|
12
|
+
readonly client: Pick<PublicClient, "getChainId">;
|
|
13
|
+
readonly chainId: number;
|
|
14
|
+
readonly mode: SimulationMode;
|
|
15
|
+
readonly blockNumber?: bigint;
|
|
16
|
+
}): Promise<void>;
|
|
3
17
|
/**
|
|
4
|
-
*
|
|
18
|
+
* Execute an {@link ExecutionPlan} through a single `eth_simulateV1` call and
|
|
19
|
+
* collect the pinned execution.
|
|
5
20
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
21
|
+
* The caller checks the endpoint chain identity and resolves the pinned state
|
|
22
|
+
* block before this boundary. This function uses that same block for the
|
|
23
|
+
* simulation and reorg check under the shared abort/timeout budget.
|
|
8
24
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
25
|
+
* The boundary performs these steps:
|
|
26
|
+
*
|
|
27
|
+
* 1. **`eth_simulateV1`** — one `blockStateCalls` entry carrying the planned
|
|
28
|
+
* calls with their per-call `from`, `traceTransfers: true` so the node
|
|
29
|
+
* synthesizes native-ETH moves as transfer logs, and `validation: false`
|
|
30
|
+
* (`true` on Monad, whose nodes reject `false` and charge no gas in the
|
|
31
|
+
* simulated block). Validation-off means gas is not charged, which is how
|
|
32
|
+
* gas is separated from economic effects.
|
|
33
|
+
* **No balance override is
|
|
34
|
+
* applied** — `value` transfers are funded by the sender's real native
|
|
35
|
+
* balance.
|
|
36
|
+
* 2. **Response validation** — the response is parsed before the reorg
|
|
37
|
+
* re-fetch so revert/mismatch evidence already in hand surfaces instead
|
|
38
|
+
* of being downgraded to a bypassable {@link ExternalServiceError} by a
|
|
39
|
+
* failing re-fetch. The simulated block must be exactly
|
|
40
|
+
* `stateBlockNumber` or `stateBlockNumber + 1`: geth-style nodes report
|
|
41
|
+
* the former's successor while Anvil reports the pinned block itself.
|
|
42
|
+
* The result records whatever the node returns; consumers must read
|
|
43
|
+
* {@link ExecutionBlock.blockNumber} and never assume +1.
|
|
44
|
+
* 3. **Reorg check** — the pinned state block is re-fetched last to detect a reorg
|
|
45
|
+
* that swapped its hash mid-flight (`InvalidSimulationResponseError`).
|
|
46
|
+
*
|
|
47
|
+
* The endpoint must support `eth_simulateV1` with per-call `from`; there is
|
|
48
|
+
* no fallback backend.
|
|
49
|
+
*
|
|
50
|
+
* @param params - Shared simulation client, execution plan, already-pinned
|
|
51
|
+
* state block, and the `validation` flag to send.
|
|
52
|
+
* @returns Deep-frozen {@link SimulationExecution} — per-transaction call
|
|
53
|
+
* results and the resolved {@link ExecutionBlock}.
|
|
54
|
+
* @throws {ExternalServiceError} For transport failures, timeouts,
|
|
55
|
+
* or malformed JSON-RPC envelopes.
|
|
56
|
+
* @throws {InvalidSimulationResponseError} For a response that cannot be
|
|
57
|
+
* trusted (bad shape, call-count mismatch, block
|
|
58
|
+
* other than the pinned state block or its successor, a block timestamp
|
|
59
|
+
* earlier than the pinned block's, a per-call result that fails normalization,
|
|
60
|
+
* or a state-block hash that changed or is no longer served mid-flight).
|
|
61
|
+
* @throws {MissingVerificationEvidenceError} When a planned state read fails.
|
|
62
|
+
* @throws {SimulationRevertedError} When a preparation or user transaction
|
|
63
|
+
* reverts or the node reports a bundle-level revert (code 3 / insufficient
|
|
64
|
+
* funds).
|
|
65
|
+
* @internal
|
|
16
66
|
*/
|
|
17
|
-
export declare function
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}): Promise<RawSimulationResult>;
|
|
67
|
+
export declare function executePlan(params: {
|
|
68
|
+
client: Client & Pick<PublicClient, "getBlock">;
|
|
69
|
+
plan: ExecutionPlan;
|
|
70
|
+
stateBlock: PinnedBlock;
|
|
71
|
+
validation: boolean;
|
|
72
|
+
}): Promise<SimulationExecution>;
|
|
73
|
+
export {};
|