@prb/effect-evm-safe 1.0.0-beta.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/dist/constants/index.d.ts +5 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +6 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/react-hooks/index.d.ts +5 -0
- package/dist/react-hooks/index.d.ts.map +1 -0
- package/dist/react-hooks/index.js +6 -0
- package/dist/react-hooks/index.js.map +1 -0
- package/dist/react-hooks/safe-app-origins.d.ts +8 -0
- package/dist/react-hooks/safe-app-origins.d.ts.map +1 -0
- package/dist/react-hooks/safe-app-origins.js +124 -0
- package/dist/react-hooks/safe-app-origins.js.map +1 -0
- package/dist/react-hooks/use-is-host-safe-app.d.ts +2 -0
- package/dist/react-hooks/use-is-host-safe-app.d.ts.map +1 -0
- package/dist/react-hooks/use-is-host-safe-app.js +16 -0
- package/dist/react-hooks/use-is-host-safe-app.js.map +1 -0
- package/dist/react-hooks/use-is-safe-app-context.d.ts +2 -0
- package/dist/react-hooks/use-is-safe-app-context.d.ts.map +1 -0
- package/dist/react-hooks/use-is-safe-app-context.js +41 -0
- package/dist/react-hooks/use-is-safe-app-context.js.map +1 -0
- package/dist/react-hooks/use-is-safe-multisig-wallet.d.ts +2 -0
- package/dist/react-hooks/use-is-safe-multisig-wallet.d.ts.map +1 -0
- package/dist/react-hooks/use-is-safe-multisig-wallet.js +24 -0
- package/dist/react-hooks/use-is-safe-multisig-wallet.js.map +1 -0
- package/dist/safe/adapter.d.ts +7 -0
- package/dist/safe/adapter.d.ts.map +1 -0
- package/dist/safe/adapter.js +13 -0
- package/dist/safe/adapter.js.map +1 -0
- package/dist/safe/detection.d.ts +26 -0
- package/dist/safe/detection.d.ts.map +1 -0
- package/dist/safe/detection.js +102 -0
- package/dist/safe/detection.js.map +1 -0
- package/dist/safe/detection.test.integration.d.ts +2 -0
- package/dist/safe/detection.test.integration.d.ts.map +1 -0
- package/dist/safe/detection.test.integration.js +92 -0
- package/dist/safe/detection.test.integration.js.map +1 -0
- package/dist/safe/errors.d.ts +79 -0
- package/dist/safe/errors.d.ts.map +1 -0
- package/dist/safe/errors.js +34 -0
- package/dist/safe/errors.js.map +1 -0
- package/dist/safe/index.d.ts +8 -0
- package/dist/safe/index.d.ts.map +1 -0
- package/dist/safe/index.js +6 -0
- package/dist/safe/index.js.map +1 -0
- package/dist/safe/internal/poll.d.ts +6 -0
- package/dist/safe/internal/poll.d.ts.map +1 -0
- package/dist/safe/internal/poll.js +21 -0
- package/dist/safe/internal/poll.js.map +1 -0
- package/dist/safe/internal/sdk-types.d.ts +3 -0
- package/dist/safe/internal/sdk-types.d.ts.map +1 -0
- package/dist/safe/internal/sdk-types.js +2 -0
- package/dist/safe/internal/sdk-types.js.map +1 -0
- package/dist/safe/live.d.ts +7 -0
- package/dist/safe/live.d.ts.map +1 -0
- package/dist/safe/live.js +203 -0
- package/dist/safe/live.js.map +1 -0
- package/dist/safe/service.d.ts +26 -0
- package/dist/safe/service.d.ts.map +1 -0
- package/dist/safe/service.js +4 -0
- package/dist/safe/service.js.map +1 -0
- package/dist/safe/service.test.integration.d.ts +2 -0
- package/dist/safe/service.test.integration.d.ts.map +1 -0
- package/dist/safe/service.test.integration.js +171 -0
- package/dist/safe/service.test.integration.js.map +1 -0
- package/dist/safe/simulation/abis.d.ts +73 -0
- package/dist/safe/simulation/abis.d.ts.map +1 -0
- package/dist/safe/simulation/abis.js +61 -0
- package/dist/safe/simulation/abis.js.map +1 -0
- package/dist/safe/simulation/addresses.d.ts +4 -0
- package/dist/safe/simulation/addresses.d.ts.map +1 -0
- package/dist/safe/simulation/addresses.js +56 -0
- package/dist/safe/simulation/addresses.js.map +1 -0
- package/dist/safe/simulation/encoding.d.ts +16 -0
- package/dist/safe/simulation/encoding.d.ts.map +1 -0
- package/dist/safe/simulation/encoding.js +36 -0
- package/dist/safe/simulation/encoding.js.map +1 -0
- package/dist/safe/simulation/errors.d.ts +56 -0
- package/dist/safe/simulation/errors.d.ts.map +1 -0
- package/dist/safe/simulation/errors.js +37 -0
- package/dist/safe/simulation/errors.js.map +1 -0
- package/dist/safe/simulation/index.d.ts +7 -0
- package/dist/safe/simulation/index.d.ts.map +1 -0
- package/dist/safe/simulation/index.js +6 -0
- package/dist/safe/simulation/index.js.map +1 -0
- package/dist/safe/simulation/internal/calldata/calldata.d.ts +5 -0
- package/dist/safe/simulation/internal/calldata/calldata.d.ts.map +1 -0
- package/dist/safe/simulation/internal/calldata/calldata.js +17 -0
- package/dist/safe/simulation/internal/calldata/calldata.js.map +1 -0
- package/dist/safe/simulation/internal/calldata/index.d.ts +2 -0
- package/dist/safe/simulation/internal/calldata/index.d.ts.map +1 -0
- package/dist/safe/simulation/internal/calldata/index.js +2 -0
- package/dist/safe/simulation/internal/calldata/index.js.map +1 -0
- package/dist/safe/simulation/internal/contracts/contracts.d.ts +5 -0
- package/dist/safe/simulation/internal/contracts/contracts.d.ts.map +1 -0
- package/dist/safe/simulation/internal/contracts/contracts.js +25 -0
- package/dist/safe/simulation/internal/contracts/contracts.js.map +1 -0
- package/dist/safe/simulation/internal/contracts/index.d.ts +2 -0
- package/dist/safe/simulation/internal/contracts/index.d.ts.map +1 -0
- package/dist/safe/simulation/internal/contracts/index.js +2 -0
- package/dist/safe/simulation/internal/contracts/index.js.map +1 -0
- package/dist/safe/simulation/internal/evaluation/evaluation.d.ts +6 -0
- package/dist/safe/simulation/internal/evaluation/evaluation.d.ts.map +1 -0
- package/dist/safe/simulation/internal/evaluation/evaluation.js +20 -0
- package/dist/safe/simulation/internal/evaluation/evaluation.js.map +1 -0
- package/dist/safe/simulation/internal/evaluation/index.d.ts +2 -0
- package/dist/safe/simulation/internal/evaluation/index.d.ts.map +1 -0
- package/dist/safe/simulation/internal/evaluation/index.js +2 -0
- package/dist/safe/simulation/internal/evaluation/index.js.map +1 -0
- package/dist/safe/simulation/internal/execution/execution.d.ts +9 -0
- package/dist/safe/simulation/internal/execution/execution.d.ts.map +1 -0
- package/dist/safe/simulation/internal/execution/execution.js +65 -0
- package/dist/safe/simulation/internal/execution/execution.js.map +1 -0
- package/dist/safe/simulation/internal/execution/index.d.ts +2 -0
- package/dist/safe/simulation/internal/execution/index.d.ts.map +1 -0
- package/dist/safe/simulation/internal/execution/index.js +2 -0
- package/dist/safe/simulation/internal/execution/index.js.map +1 -0
- package/dist/safe/simulation/internal/limits/index.d.ts +2 -0
- package/dist/safe/simulation/internal/limits/index.d.ts.map +1 -0
- package/dist/safe/simulation/internal/limits/index.js +2 -0
- package/dist/safe/simulation/internal/limits/index.js.map +1 -0
- package/dist/safe/simulation/internal/limits/limits.d.ts +5 -0
- package/dist/safe/simulation/internal/limits/limits.d.ts.map +1 -0
- package/dist/safe/simulation/internal/limits/limits.js +18 -0
- package/dist/safe/simulation/internal/limits/limits.js.map +1 -0
- package/dist/safe/simulation/internal/types/index.d.ts +2 -0
- package/dist/safe/simulation/internal/types/index.d.ts.map +1 -0
- package/dist/safe/simulation/internal/types/index.js +2 -0
- package/dist/safe/simulation/internal/types/index.js.map +1 -0
- package/dist/safe/simulation/internal/types/types.d.ts +11 -0
- package/dist/safe/simulation/internal/types/types.d.ts.map +1 -0
- package/dist/safe/simulation/internal/types/types.js +2 -0
- package/dist/safe/simulation/internal/types/types.js.map +1 -0
- package/dist/safe/simulation/internal/validation/index.d.ts +2 -0
- package/dist/safe/simulation/internal/validation/index.d.ts.map +1 -0
- package/dist/safe/simulation/internal/validation/index.js +2 -0
- package/dist/safe/simulation/internal/validation/index.js.map +1 -0
- package/dist/safe/simulation/internal/validation/validation.d.ts +5 -0
- package/dist/safe/simulation/internal/validation/validation.d.ts.map +1 -0
- package/dist/safe/simulation/internal/validation/validation.js +27 -0
- package/dist/safe/simulation/internal/validation/validation.js.map +1 -0
- package/dist/safe/simulation/service.d.ts +14 -0
- package/dist/safe/simulation/service.d.ts.map +1 -0
- package/dist/safe/simulation/service.js +25 -0
- package/dist/safe/simulation/service.js.map +1 -0
- package/dist/safe/simulation/types.d.ts +20 -0
- package/dist/safe/simulation/types.d.ts.map +1 -0
- package/dist/safe/simulation/types.js +2 -0
- package/dist/safe/simulation/types.js.map +1 -0
- package/dist/safe/types.d.ts +61 -0
- package/dist/safe/types.d.ts.map +1 -0
- package/dist/safe/types.js +2 -0
- package/dist/safe/types.js.map +1 -0
- package/package.json +105 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
export class GasLimitOverflowError extends Schema.TaggedError()("GasLimitOverflowError", {
|
|
3
|
+
blockGasLimit: Schema.BigInt,
|
|
4
|
+
estimatedGas: Schema.BigInt,
|
|
5
|
+
message: Schema.String,
|
|
6
|
+
threshold: Schema.BigInt,
|
|
7
|
+
}) {
|
|
8
|
+
}
|
|
9
|
+
export class SafeMultisigSimulationFailedError extends Schema.TaggedError()("SafeMultisigSimulationFailedError", {
|
|
10
|
+
cause: Schema.optional(Schema.Unknown),
|
|
11
|
+
message: Schema.String,
|
|
12
|
+
}) {
|
|
13
|
+
}
|
|
14
|
+
export class SafeMultisigContractsNotDeployedError extends Schema.TaggedError()("SafeMultisigContractsNotDeployedError", {
|
|
15
|
+
chainId: Schema.Number,
|
|
16
|
+
message: Schema.String,
|
|
17
|
+
missingContract: Schema.Literal("multiSend", "simulateAccessor"),
|
|
18
|
+
}) {
|
|
19
|
+
}
|
|
20
|
+
export class TxSizeTooLargeError extends Schema.TaggedError()("TxSizeTooLargeError", {
|
|
21
|
+
actualSize: Schema.Number,
|
|
22
|
+
maxSize: Schema.Number,
|
|
23
|
+
message: Schema.String,
|
|
24
|
+
}) {
|
|
25
|
+
}
|
|
26
|
+
export class SimulationDecodeError extends Schema.TaggedError()("SimulationDecodeError", {
|
|
27
|
+
cause: Schema.Unknown,
|
|
28
|
+
message: Schema.String,
|
|
29
|
+
revertData: Schema.String,
|
|
30
|
+
}) {
|
|
31
|
+
}
|
|
32
|
+
export class InvalidGasThresholdError extends Schema.TaggedError()("InvalidGasThresholdError", {
|
|
33
|
+
message: Schema.String,
|
|
34
|
+
value: Schema.Number,
|
|
35
|
+
}) {
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/safe/simulation/errors.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,MAAM,OAAO,qBAAsB,SAAQ,MAAM,CAAC,WAAW,EAAyB,CACpF,uBAAuB,EACvB;IACE,aAAa,EAAE,MAAM,CAAC,MAAM;IAC5B,YAAY,EAAE,MAAM,CAAC,MAAM;IAC3B,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM;CACzB,CACF;CAAG;AAGJ,MAAM,OAAO,iCAAkC,SAAQ,MAAM,CAAC,WAAW,EAAqC,CAC5G,mCAAmC,EACnC;IACE,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CACF;CAAG;AAGJ,MAAM,OAAO,qCAAsC,SAAQ,MAAM,CAAC,WAAW,EAAyC,CACpH,uCAAuC,EACvC;IACE,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,kBAAkB,CAAC;CACjE,CACF;CAAG;AAGJ,MAAM,OAAO,mBAAoB,SAAQ,MAAM,CAAC,WAAW,EAAuB,CAChF,qBAAqB,EACrB;IACE,UAAU,EAAE,MAAM,CAAC,MAAM;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CACF;CAAG;AAGJ,MAAM,OAAO,qBAAsB,SAAQ,MAAM,CAAC,WAAW,EAAyB,CACpF,uBAAuB,EACvB;IACE,KAAK,EAAE,MAAM,CAAC,OAAO;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,UAAU,EAAE,MAAM,CAAC,MAAM;CAC1B,CACF;CAAG;AAGJ,MAAM,OAAO,wBAAyB,SAAQ,MAAM,CAAC,WAAW,EAA4B,CAC1F,0BAA0B,EAC1B;IACE,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM;CACrB,CACF;CAAG","sourcesContent":["/**\n * Tagged errors for Safe multisig gas simulation operations.\n *\n * These errors use Effect-TS Schema.TaggedError pattern for type-safe error handling.\n */\nimport { Schema } from \"effect\";\n\n/** Gas consumption exceeds block gas limit threshold */\nexport class GasLimitOverflowError extends Schema.TaggedError<GasLimitOverflowError>()(\n \"GasLimitOverflowError\",\n {\n blockGasLimit: Schema.BigInt,\n estimatedGas: Schema.BigInt,\n message: Schema.String,\n threshold: Schema.BigInt,\n }\n) {}\n\n/** Safe simulation failed */\nexport class SafeMultisigSimulationFailedError extends Schema.TaggedError<SafeMultisigSimulationFailedError>()(\n \"SafeMultisigSimulationFailedError\",\n {\n cause: Schema.optional(Schema.Unknown),\n message: Schema.String,\n }\n) {}\n\n/** Safe contracts not deployed on this chain */\nexport class SafeMultisigContractsNotDeployedError extends Schema.TaggedError<SafeMultisigContractsNotDeployedError>()(\n \"SafeMultisigContractsNotDeployedError\",\n {\n chainId: Schema.Number,\n message: Schema.String,\n missingContract: Schema.Literal(\"multiSend\", \"simulateAccessor\"),\n }\n) {}\n\n/** Transaction size too large */\nexport class TxSizeTooLargeError extends Schema.TaggedError<TxSizeTooLargeError>()(\n \"TxSizeTooLargeError\",\n {\n actualSize: Schema.Number,\n maxSize: Schema.Number,\n message: Schema.String,\n }\n) {}\n\n/** Simulation revert data decode failed */\nexport class SimulationDecodeError extends Schema.TaggedError<SimulationDecodeError>()(\n \"SimulationDecodeError\",\n {\n cause: Schema.Unknown,\n message: Schema.String,\n revertData: Schema.String,\n }\n) {}\n\n/** Invalid gas threshold percent */\nexport class InvalidGasThresholdError extends Schema.TaggedError<InvalidGasThresholdError>()(\n \"InvalidGasThresholdError\",\n {\n message: Schema.String,\n value: Schema.Number,\n }\n) {}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { safeAbis } from "./abis.js";
|
|
2
|
+
export { getMultiSendAddress, getSimulateAccessorAddress, } from "./addresses.js";
|
|
3
|
+
export { decodeSimulationData, encodeMultiSend } from "./encoding.js";
|
|
4
|
+
export { GasLimitOverflowError, InvalidGasThresholdError, SafeMultisigContractsNotDeployedError, SafeMultisigSimulationFailedError, SimulationDecodeError, TxSizeTooLargeError, } from "./errors.js";
|
|
5
|
+
export { SafeMultisigSimulationService, SafeMultisigSimulationServiceLive, type SafeMultisigSimulationServiceShape, } from "./service.js";
|
|
6
|
+
export type { SafeMultisigSimulateBatchParams, SafeMultisigSimulationResult, SafeMultisigSimulationTx, SafeOperation, } from "./types.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/safe/simulation/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EACL,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,qCAAqC,EACrC,iCAAiC,EACjC,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,6BAA6B,EAC7B,iCAAiC,EACjC,KAAK,kCAAkC,GACxC,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,+BAA+B,EAC/B,4BAA4B,EAC5B,wBAAwB,EACxB,aAAa,GACd,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { safeAbis } from "./abis.js";
|
|
2
|
+
export { getMultiSendAddress, getSimulateAccessorAddress, } from "./addresses.js";
|
|
3
|
+
export { decodeSimulationData, encodeMultiSend } from "./encoding.js";
|
|
4
|
+
export { GasLimitOverflowError, InvalidGasThresholdError, SafeMultisigContractsNotDeployedError, SafeMultisigSimulationFailedError, SimulationDecodeError, TxSizeTooLargeError, } from "./errors.js";
|
|
5
|
+
export { SafeMultisigSimulationService, SafeMultisigSimulationServiceLive, } from "./service.js";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/safe/simulation/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EACL,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,qCAAqC,EACrC,iCAAiC,EACjC,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,6BAA6B,EAC7B,iCAAiC,GAElC,MAAM,cAAc,CAAC","sourcesContent":["// Errors\n\n// ABIs (for advanced usage)\nexport { safeAbis } from \"./abis.js\";\n// Address utilities\nexport {\n getMultiSendAddress,\n getSimulateAccessorAddress,\n} from \"./addresses.js\";\n// Encoding utilities\nexport { decodeSimulationData, encodeMultiSend } from \"./encoding.js\";\nexport {\n GasLimitOverflowError,\n InvalidGasThresholdError,\n SafeMultisigContractsNotDeployedError,\n SafeMultisigSimulationFailedError,\n SimulationDecodeError,\n TxSizeTooLargeError,\n} from \"./errors.js\";\n// Service\nexport {\n SafeMultisigSimulationService,\n SafeMultisigSimulationServiceLive,\n type SafeMultisigSimulationServiceShape,\n} from \"./service.js\";\n// Types\nexport type {\n SafeMultisigSimulateBatchParams,\n SafeMultisigSimulationResult,\n SafeMultisigSimulationTx,\n SafeOperation,\n} from \"./types.js\";\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Hex } from "viem";
|
|
2
|
+
import type { SafeMultisigSimulateBatchParams } from "../../types.js";
|
|
3
|
+
import type { SafeMultisigContracts } from "../types/index.js";
|
|
4
|
+
export declare function buildSafeCalldata(contracts: SafeMultisigContracts, transactions: SafeMultisigSimulateBatchParams["transactions"]): Hex;
|
|
5
|
+
//# sourceMappingURL=calldata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calldata.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/calldata/calldata.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAIhC,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAK/D,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,qBAAqB,EAChC,YAAY,EAAE,+BAA+B,CAAC,cAAc,CAAC,GAC5D,GAAG,CAcL"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { encodeFunctionData } from "viem";
|
|
2
|
+
import { safeAbis } from "../../abis.js";
|
|
3
|
+
import { encodeMultiSend } from "../../encoding.js";
|
|
4
|
+
export function buildSafeCalldata(contracts, transactions) {
|
|
5
|
+
const multiSendCalldata = encodeMultiSend(transactions);
|
|
6
|
+
const simulateAccessorCalldata = encodeFunctionData({
|
|
7
|
+
abi: safeAbis.simulateAccessor,
|
|
8
|
+
args: [contracts.multiSendAddr, 0n, multiSendCalldata, 1],
|
|
9
|
+
functionName: "simulate",
|
|
10
|
+
});
|
|
11
|
+
return encodeFunctionData({
|
|
12
|
+
abi: safeAbis.multisig,
|
|
13
|
+
args: [contracts.simulateAccessorAddr, simulateAccessorCalldata],
|
|
14
|
+
functionName: "simulateAndRevert",
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=calldata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calldata.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/calldata/calldata.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAOpD,MAAM,UAAU,iBAAiB,CAC/B,SAAgC,EAChC,YAA6D;IAE7D,MAAM,iBAAiB,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;IAExD,MAAM,wBAAwB,GAAG,kBAAkB,CAAC;QAClD,GAAG,EAAE,QAAQ,CAAC,gBAAgB;QAC9B,IAAI,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,EAAE,EAAE,iBAAiB,EAAE,CAAC,CAAC;QACzD,YAAY,EAAE,UAAU;KACzB,CAAC,CAAC;IAEH,OAAO,kBAAkB,CAAC;QACxB,GAAG,EAAE,QAAQ,CAAC,QAAQ;QACtB,IAAI,EAAE,CAAC,SAAS,CAAC,oBAAoB,EAAE,wBAAwB,CAAC;QAChE,YAAY,EAAE,mBAAmB;KAClC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Calldata construction utilities for Safe simulation.\n */\nimport type { Hex } from \"viem\";\nimport { encodeFunctionData } from \"viem\";\nimport { safeAbis } from \"../../abis.js\";\nimport { encodeMultiSend } from \"../../encoding.js\";\nimport type { SafeMultisigSimulateBatchParams } from \"../../types.js\";\nimport type { SafeMultisigContracts } from \"../types/index.js\";\n\n/**\n * Build the final simulateAndRevert calldata for Safe.\n */\nexport function buildSafeCalldata(\n contracts: SafeMultisigContracts,\n transactions: SafeMultisigSimulateBatchParams[\"transactions\"]\n): Hex {\n const multiSendCalldata = encodeMultiSend(transactions);\n\n const simulateAccessorCalldata = encodeFunctionData({\n abi: safeAbis.simulateAccessor,\n args: [contracts.multiSendAddr, 0n, multiSendCalldata, 1], // 1 = DelegateCall\n functionName: \"simulate\",\n });\n\n return encodeFunctionData({\n abi: safeAbis.multisig,\n args: [contracts.simulateAccessorAddr, simulateAccessorCalldata],\n functionName: \"simulateAndRevert\",\n });\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/calldata/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/calldata/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC","sourcesContent":["export { buildSafeCalldata } from \"./calldata.js\";\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { SafeMultisigContractsNotDeployedError } from "../../errors.js";
|
|
3
|
+
import type { SafeMultisigContracts } from "../types/index.js";
|
|
4
|
+
export declare function resolveSafeMultisigContracts(chainId: number): Effect.Effect<SafeMultisigContracts, SafeMultisigContractsNotDeployedError>;
|
|
5
|
+
//# sourceMappingURL=contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/contracts/contracts.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,qCAAqC,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAK/D,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,GACd,MAAM,CAAC,MAAM,CAAC,qBAAqB,EAAE,qCAAqC,CAAC,CA2B7E"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { getMultiSendAddress, getSimulateAccessorAddress } from "../../addresses.js";
|
|
3
|
+
import { SafeMultisigContractsNotDeployedError } from "../../errors.js";
|
|
4
|
+
export function resolveSafeMultisigContracts(chainId) {
|
|
5
|
+
return Effect.gen(function* () {
|
|
6
|
+
const multiSendAddr = getMultiSendAddress(chainId);
|
|
7
|
+
const simulateAccessorAddr = getSimulateAccessorAddress(chainId);
|
|
8
|
+
if (!multiSendAddr) {
|
|
9
|
+
return yield* Effect.fail(new SafeMultisigContractsNotDeployedError({
|
|
10
|
+
chainId,
|
|
11
|
+
message: "MultiSend contract not deployed on this chain",
|
|
12
|
+
missingContract: "multiSend",
|
|
13
|
+
}));
|
|
14
|
+
}
|
|
15
|
+
if (!simulateAccessorAddr) {
|
|
16
|
+
return yield* Effect.fail(new SafeMultisigContractsNotDeployedError({
|
|
17
|
+
chainId,
|
|
18
|
+
message: "SimulateAccessor contract not deployed on this chain",
|
|
19
|
+
missingContract: "simulateAccessor",
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
return { multiSendAddr, simulateAccessorAddr };
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/contracts/contracts.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,qCAAqC,EAAE,MAAM,iBAAiB,CAAC;AAMxE,MAAM,UAAU,4BAA4B,CAC1C,OAAe;IAEf,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,MAAM,aAAa,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,oBAAoB,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;QAEjE,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,qCAAqC,CAAC;gBACxC,OAAO;gBACP,OAAO,EAAE,+CAA+C;gBACxD,eAAe,EAAE,WAAW;aAC7B,CAAC,CACH,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,qCAAqC,CAAC;gBACxC,OAAO;gBACP,OAAO,EAAE,sDAAsD;gBAC/D,eAAe,EAAE,kBAAkB;aACpC,CAAC,CACH,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Resolve contract addresses needed to construct Safe simulation calldata.\n */\nimport { Effect } from \"effect\";\nimport { getMultiSendAddress, getSimulateAccessorAddress } from \"../../addresses.js\";\nimport { SafeMultisigContractsNotDeployedError } from \"../../errors.js\";\nimport type { SafeMultisigContracts } from \"../types/index.js\";\n\n/**\n * Resolve the Safe helper contract addresses for the chain.\n */\nexport function resolveSafeMultisigContracts(\n chainId: number\n): Effect.Effect<SafeMultisigContracts, SafeMultisigContractsNotDeployedError> {\n return Effect.gen(function* () {\n const multiSendAddr = getMultiSendAddress(chainId);\n const simulateAccessorAddr = getSimulateAccessorAddress(chainId);\n\n if (!multiSendAddr) {\n return yield* Effect.fail(\n new SafeMultisigContractsNotDeployedError({\n chainId,\n message: \"MultiSend contract not deployed on this chain\",\n missingContract: \"multiSend\",\n })\n );\n }\n\n if (!simulateAccessorAddr) {\n return yield* Effect.fail(\n new SafeMultisigContractsNotDeployedError({\n chainId,\n message: \"SimulateAccessor contract not deployed on this chain\",\n missingContract: \"simulateAccessor\",\n })\n );\n }\n\n return { multiSendAddr, simulateAccessorAddr };\n });\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/contracts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/contracts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC","sourcesContent":["export { resolveSafeMultisigContracts } from \"./contracts.js\";\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { GasLimitOverflowError, SafeMultisigSimulationFailedError } from "../../errors.js";
|
|
3
|
+
import type { SafeMultisigSimulationResult } from "../../types.js";
|
|
4
|
+
import type { LatestBlock, SimulationDecoded } from "../types/index.js";
|
|
5
|
+
export declare function evaluateSimulationResult(result: SimulationDecoded, block: LatestBlock, gasThresholdPercent?: number): Effect.Effect<SafeMultisigSimulationResult, GasLimitOverflowError | SafeMultisigSimulationFailedError>;
|
|
6
|
+
//# sourceMappingURL=evaluation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluation.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/evaluation/evaluation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,iCAAiC,EAAE,MAAM,iBAAiB,CAAC;AAC3F,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAKxE,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,WAAW,EAClB,mBAAmB,CAAC,EAAE,MAAM,GAC3B,MAAM,CAAC,MAAM,CACd,4BAA4B,EAC5B,qBAAqB,GAAG,iCAAiC,CAC1D,CAwBA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { GasLimitOverflowError, SafeMultisigSimulationFailedError } from "../../errors.js";
|
|
3
|
+
export function evaluateSimulationResult(result, block, gasThresholdPercent) {
|
|
4
|
+
const threshold = (block.gasLimit * BigInt(gasThresholdPercent ?? 95)) / 100n;
|
|
5
|
+
if (result.success && result.gas > threshold) {
|
|
6
|
+
return Effect.fail(new GasLimitOverflowError({
|
|
7
|
+
blockGasLimit: block.gasLimit,
|
|
8
|
+
estimatedGas: result.gas,
|
|
9
|
+
message: "Gas consumption exceeds threshold of block gas limit. Try splitting into smaller batches.",
|
|
10
|
+
threshold,
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
13
|
+
if (!result.success) {
|
|
14
|
+
return Effect.fail(new SafeMultisigSimulationFailedError({
|
|
15
|
+
message: "Transaction simulation failed - the transaction would revert",
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
return Effect.succeed({ estimatedGas: result.gas, success: true });
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=evaluation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluation.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/evaluation/evaluation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,iCAAiC,EAAE,MAAM,iBAAiB,CAAC;AAO3F,MAAM,UAAU,wBAAwB,CACtC,MAAyB,EACzB,KAAkB,EAClB,mBAA4B;IAK5B,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAE9E,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,GAAG,SAAS,EAAE,CAAC;QAC7C,OAAO,MAAM,CAAC,IAAI,CAChB,IAAI,qBAAqB,CAAC;YACxB,aAAa,EAAE,KAAK,CAAC,QAAQ;YAC7B,YAAY,EAAE,MAAM,CAAC,GAAG;YACxB,OAAO,EACL,2FAA2F;YAC7F,SAAS;SACV,CAAC,CACH,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC,IAAI,CAChB,IAAI,iCAAiC,CAAC;YACpC,OAAO,EAAE,8DAA8D;SACxE,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AACrE,CAAC","sourcesContent":["/**\n * Final evaluation of simulation outcomes against policy thresholds.\n */\nimport { Effect } from \"effect\";\nimport { GasLimitOverflowError, SafeMultisigSimulationFailedError } from \"../../errors.js\";\nimport type { SafeMultisigSimulationResult } from \"../../types.js\";\nimport type { LatestBlock, SimulationDecoded } from \"../types/index.js\";\n\n/**\n * Apply success and gas threshold checks to the decoded result.\n */\nexport function evaluateSimulationResult(\n result: SimulationDecoded,\n block: LatestBlock,\n gasThresholdPercent?: number\n): Effect.Effect<\n SafeMultisigSimulationResult,\n GasLimitOverflowError | SafeMultisigSimulationFailedError\n> {\n const threshold = (block.gasLimit * BigInt(gasThresholdPercent ?? 95)) / 100n;\n\n if (result.success && result.gas > threshold) {\n return Effect.fail(\n new GasLimitOverflowError({\n blockGasLimit: block.gasLimit,\n estimatedGas: result.gas,\n message:\n \"Gas consumption exceeds threshold of block gas limit. Try splitting into smaller batches.\",\n threshold,\n })\n );\n }\n\n if (!result.success) {\n return Effect.fail(\n new SafeMultisigSimulationFailedError({\n message: \"Transaction simulation failed - the transaction would revert\",\n })\n );\n }\n\n return Effect.succeed({ estimatedGas: result.gas, success: true });\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/evaluation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/evaluation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC","sourcesContent":["export { evaluateSimulationResult } from \"./evaluation.js\";\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { Address, Hex, PublicClient } from "viem";
|
|
3
|
+
import { SafeMultisigSimulationFailedError, SimulationDecodeError } from "../../errors.js";
|
|
4
|
+
import type { LatestBlock, SimulationDecoded } from "../types/index.js";
|
|
5
|
+
export declare function extractRevertData(error: unknown): string | undefined;
|
|
6
|
+
export declare function callSimulateAndExtractRevertData(client: PublicClient, safeAddress: Address, safeCalldata: Hex): Promise<string>;
|
|
7
|
+
export declare function simulateAndDecode(client: PublicClient, safeAddress: Address, safeCalldata: Hex): Effect.Effect<SimulationDecoded, SafeMultisigSimulationFailedError | SimulationDecodeError>;
|
|
8
|
+
export declare function fetchLatestBlock(client: PublicClient): Effect.Effect<LatestBlock, SafeMultisigSimulationFailedError>;
|
|
9
|
+
//# sourceMappingURL=execution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/execution/execution.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAGvD,OAAO,EAAE,iCAAiC,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC3F,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAKxE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAiBpE;AAKD,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,YAAY,EACpB,WAAW,EAAE,OAAO,EACpB,YAAY,EAAE,GAAG,GAChB,OAAO,CAAC,MAAM,CAAC,CAejB;AAKD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,YAAY,EACpB,WAAW,EAAE,OAAO,EACpB,YAAY,EAAE,GAAG,GAChB,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,iCAAiC,GAAG,qBAAqB,CAAC,CAqB7F;AAKD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,YAAY,GACnB,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,iCAAiC,CAAC,CAS/D"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { BaseError as CoreError } from "viem";
|
|
3
|
+
import { decodeSimulationData } from "../../encoding.js";
|
|
4
|
+
import { SafeMultisigSimulationFailedError, SimulationDecodeError } from "../../errors.js";
|
|
5
|
+
export function extractRevertData(error) {
|
|
6
|
+
if (!(error instanceof CoreError)) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
const revertError = error.walk((err) => {
|
|
10
|
+
const typedErr = err;
|
|
11
|
+
return typeof typedErr.data === "string";
|
|
12
|
+
});
|
|
13
|
+
if (!revertError) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
const typedErr = revertError;
|
|
17
|
+
const extractedData = typedErr.data;
|
|
18
|
+
return typeof extractedData === "string" ? extractedData : undefined;
|
|
19
|
+
}
|
|
20
|
+
export async function callSimulateAndExtractRevertData(client, safeAddress, safeCalldata) {
|
|
21
|
+
try {
|
|
22
|
+
await client.call({
|
|
23
|
+
account: safeAddress,
|
|
24
|
+
data: safeCalldata,
|
|
25
|
+
to: safeAddress,
|
|
26
|
+
});
|
|
27
|
+
throw new Error("simulateAndRevert did not revert");
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
const revertData = extractRevertData(error);
|
|
31
|
+
if (revertData) {
|
|
32
|
+
return revertData;
|
|
33
|
+
}
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function simulateAndDecode(client, safeAddress, safeCalldata) {
|
|
38
|
+
return Effect.gen(function* () {
|
|
39
|
+
const revertData = yield* Effect.tryPromise({
|
|
40
|
+
catch: (error) => new SafeMultisigSimulationFailedError({
|
|
41
|
+
cause: error,
|
|
42
|
+
message: "Network error or unexpected behavior during simulation",
|
|
43
|
+
}),
|
|
44
|
+
try: () => callSimulateAndExtractRevertData(client, safeAddress, safeCalldata),
|
|
45
|
+
});
|
|
46
|
+
return yield* Effect.try({
|
|
47
|
+
catch: (error) => new SimulationDecodeError({
|
|
48
|
+
cause: error,
|
|
49
|
+
message: "Failed to decode simulation revert data - unexpected format",
|
|
50
|
+
revertData,
|
|
51
|
+
}),
|
|
52
|
+
try: () => decodeSimulationData(revertData),
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
export function fetchLatestBlock(client) {
|
|
57
|
+
return Effect.tryPromise({
|
|
58
|
+
catch: (e) => new SafeMultisigSimulationFailedError({
|
|
59
|
+
cause: e,
|
|
60
|
+
message: `Failed to fetch block: ${e}`,
|
|
61
|
+
}),
|
|
62
|
+
try: () => client.getBlock({ blockTag: "latest" }),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=execution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/execution/execution.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,SAAS,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,iCAAiC,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAM3F,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,CAAC,CAAC,KAAK,YAAY,SAAS,CAAC,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;QACrC,MAAM,QAAQ,GAAG,GAAyC,CAAC;QAC3D,OAAO,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,QAAQ,GAAG,WAAiD,CAAC;IACnE,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC;IACpC,OAAO,OAAO,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;AACvE,CAAC;AAKD,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,MAAoB,EACpB,WAAoB,EACpB,YAAiB;IAEjB,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC;YAChB,OAAO,EAAE,WAAW;YACpB,IAAI,EAAE,YAAY;YAClB,EAAE,EAAE,WAAW;SAChB,CAAC,CAAC;QACH,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAKD,MAAM,UAAU,iBAAiB,CAC/B,MAAoB,EACpB,WAAoB,EACpB,YAAiB;IAEjB,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;YAC1C,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,IAAI,iCAAiC,CAAC;gBACpC,KAAK,EAAE,KAAK;gBACZ,OAAO,EAAE,wDAAwD;aAClE,CAAC;YACJ,GAAG,EAAE,GAAG,EAAE,CAAC,gCAAgC,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,CAAC;SAC/E,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;YACvB,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,IAAI,qBAAqB,CAAC;gBACxB,KAAK,EAAE,KAAK;gBACZ,OAAO,EAAE,6DAA6D;gBACtE,UAAU;aACX,CAAC;YACJ,GAAG,EAAE,GAAG,EAAE,CAAC,oBAAoB,CAAC,UAAU,CAAC;SAC5C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAKD,MAAM,UAAU,gBAAgB,CAC9B,MAAoB;IAEpB,OAAO,MAAM,CAAC,UAAU,CAAC;QACvB,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CACX,IAAI,iCAAiC,CAAC;YACpC,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,0BAA0B,CAAC,EAAE;SACvC,CAAC;QACJ,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;KACnD,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * On-chain execution and decoding helpers for Safe simulation.\n */\nimport { Effect } from \"effect\";\nimport type { Address, Hex, PublicClient } from \"viem\";\nimport { BaseError as CoreError } from \"viem\";\nimport { decodeSimulationData } from \"../../encoding.js\";\nimport { SafeMultisigSimulationFailedError, SimulationDecodeError } from \"../../errors.js\";\nimport type { LatestBlock, SimulationDecoded } from \"../types/index.js\";\n\n/**\n * Extract revert data from a viem CoreError tree, if present.\n */\nexport function extractRevertData(error: unknown): string | undefined {\n if (!(error instanceof CoreError)) {\n return undefined;\n }\n\n const revertError = error.walk((err) => {\n const typedErr = err as unknown as Record<string, unknown>;\n return typeof typedErr.data === \"string\";\n });\n\n if (!revertError) {\n return undefined;\n }\n\n const typedErr = revertError as unknown as Record<string, unknown>;\n const extractedData = typedErr.data;\n return typeof extractedData === \"string\" ? extractedData : undefined;\n}\n\n/**\n * Execute simulateAndRevert and return the revert data payload.\n */\nexport async function callSimulateAndExtractRevertData(\n client: PublicClient,\n safeAddress: Address,\n safeCalldata: Hex\n): Promise<string> {\n try {\n await client.call({\n account: safeAddress,\n data: safeCalldata,\n to: safeAddress,\n });\n throw new Error(\"simulateAndRevert did not revert\");\n } catch (error: unknown) {\n const revertData = extractRevertData(error);\n if (revertData) {\n return revertData;\n }\n throw error;\n }\n}\n\n/**\n * Run the on-chain call and decode the revert payload into a gas estimate.\n */\nexport function simulateAndDecode(\n client: PublicClient,\n safeAddress: Address,\n safeCalldata: Hex\n): Effect.Effect<SimulationDecoded, SafeMultisigSimulationFailedError | SimulationDecodeError> {\n return Effect.gen(function* () {\n const revertData = yield* Effect.tryPromise({\n catch: (error) =>\n new SafeMultisigSimulationFailedError({\n cause: error,\n message: \"Network error or unexpected behavior during simulation\",\n }),\n try: () => callSimulateAndExtractRevertData(client, safeAddress, safeCalldata),\n });\n\n return yield* Effect.try({\n catch: (error) =>\n new SimulationDecodeError({\n cause: error,\n message: \"Failed to decode simulation revert data - unexpected format\",\n revertData,\n }),\n try: () => decodeSimulationData(revertData),\n });\n });\n}\n\n/**\n * Fetch the latest block to derive the gas threshold.\n */\nexport function fetchLatestBlock(\n client: PublicClient\n): Effect.Effect<LatestBlock, SafeMultisigSimulationFailedError> {\n return Effect.tryPromise({\n catch: (e) =>\n new SafeMultisigSimulationFailedError({\n cause: e,\n message: `Failed to fetch block: ${e}`,\n }),\n try: () => client.getBlock({ blockTag: \"latest\" }),\n });\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/execution/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gCAAgC,EAChC,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/execution/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gCAAgC,EAChC,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC","sourcesContent":["export {\n callSimulateAndExtractRevertData,\n extractRevertData,\n fetchLatestBlock,\n simulateAndDecode,\n} from \"./execution.js\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/limits/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/limits/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC","sourcesContent":["export { enforceTxSizeLimit } from \"./limits.js\";\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { Hex } from "viem";
|
|
3
|
+
import { TxSizeTooLargeError } from "../../errors.js";
|
|
4
|
+
export declare function enforceTxSizeLimit(safeCalldata: Hex, txSizeLimit?: number): Effect.Effect<void, TxSizeTooLargeError>;
|
|
5
|
+
//# sourceMappingURL=limits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/limits/limits.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAKtD,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,GAAG,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAiB1C"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { TxSizeTooLargeError } from "../../errors.js";
|
|
3
|
+
export function enforceTxSizeLimit(safeCalldata, txSizeLimit) {
|
|
4
|
+
if (!txSizeLimit) {
|
|
5
|
+
return Effect.void;
|
|
6
|
+
}
|
|
7
|
+
return Effect.gen(function* () {
|
|
8
|
+
const sizeInBytes = (safeCalldata.length - 2) / 2;
|
|
9
|
+
if (sizeInBytes > txSizeLimit) {
|
|
10
|
+
return yield* Effect.fail(new TxSizeTooLargeError({
|
|
11
|
+
actualSize: sizeInBytes,
|
|
12
|
+
maxSize: txSizeLimit,
|
|
13
|
+
message: `Transaction size (${sizeInBytes} bytes) exceeds chain limit (${txSizeLimit} bytes). Try splitting into smaller batches.`,
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=limits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limits.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/limits/limits.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAKtD,MAAM,UAAU,kBAAkB,CAChC,YAAiB,EACjB,WAAoB;IAEpB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IAED,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,MAAM,WAAW,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAClD,IAAI,WAAW,GAAG,WAAW,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,mBAAmB,CAAC;gBACtB,UAAU,EAAE,WAAW;gBACvB,OAAO,EAAE,WAAW;gBACpB,OAAO,EAAE,qBAAqB,WAAW,gCAAgC,WAAW,8CAA8C;aACnI,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Size limit enforcement for Safe simulation calldata.\n */\nimport { Effect } from \"effect\";\nimport type { Hex } from \"viem\";\nimport { TxSizeTooLargeError } from \"../../errors.js\";\n\n/**\n * Enforce chain-specific transaction size constraints (if provided).\n */\nexport function enforceTxSizeLimit(\n safeCalldata: Hex,\n txSizeLimit?: number\n): Effect.Effect<void, TxSizeTooLargeError> {\n if (!txSizeLimit) {\n return Effect.void;\n }\n\n return Effect.gen(function* () {\n const sizeInBytes = (safeCalldata.length - 2) / 2;\n if (sizeInBytes > txSizeLimit) {\n return yield* Effect.fail(\n new TxSizeTooLargeError({\n actualSize: sizeInBytes,\n maxSize: txSizeLimit,\n message: `Transaction size (${sizeInBytes} bytes) exceeds chain limit (${txSizeLimit} bytes). Try splitting into smaller batches.`,\n })\n );\n }\n });\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/types/index.ts"],"names":[],"mappings":"","sourcesContent":["export type { LatestBlock, SafeMultisigContracts, SimulationDecoded } from \"./types.js\";\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Address, PublicClient } from "viem";
|
|
2
|
+
export type SafeMultisigContracts = {
|
|
3
|
+
readonly multiSendAddr: Address;
|
|
4
|
+
readonly simulateAccessorAddr: Address;
|
|
5
|
+
};
|
|
6
|
+
export type SimulationDecoded = {
|
|
7
|
+
readonly gas: bigint;
|
|
8
|
+
readonly success: boolean;
|
|
9
|
+
};
|
|
10
|
+
export type LatestBlock = Awaited<ReturnType<PublicClient["getBlock"]>>;
|
|
11
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/types/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAKlD,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;CACxC,CAAC;AAKF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B,CAAC;AAKF,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/types/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Shared type definitions for Safe simulation internals.\n */\nimport type { Address, PublicClient } from \"viem\";\n\n/**\n * Resolved Safe contract addresses required for simulation.\n */\nexport type SafeMultisigContracts = {\n readonly multiSendAddr: Address;\n readonly simulateAccessorAddr: Address;\n};\n\n/**\n * Decoded revert payload for simulateAndRevert.\n */\nexport type SimulationDecoded = {\n readonly gas: bigint;\n readonly success: boolean;\n};\n\n/**\n * Block type alias used by helpers to avoid re-deriving it everywhere.\n */\nexport type LatestBlock = Awaited<ReturnType<PublicClient[\"getBlock\"]>>;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/validation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/validation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC","sourcesContent":["export { validateSimulationParams } from \"./validation.js\";\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { InvalidGasThresholdError, SafeMultisigSimulationFailedError } from "../../errors.js";
|
|
3
|
+
import type { SafeMultisigSimulateBatchParams } from "../../types.js";
|
|
4
|
+
export declare function validateSimulationParams(params: SafeMultisigSimulateBatchParams): Effect.Effect<SafeMultisigSimulateBatchParams, InvalidGasThresholdError | SafeMultisigSimulationFailedError>;
|
|
5
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/validation/validation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,wBAAwB,EAAE,iCAAiC,EAAE,MAAM,iBAAiB,CAAC;AAC9F,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AAKtE,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,+BAA+B,GACtC,MAAM,CAAC,MAAM,CACd,+BAA+B,EAC/B,wBAAwB,GAAG,iCAAiC,CAC7D,CAkCA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { zeroAddress } from "viem";
|
|
3
|
+
import { InvalidGasThresholdError, SafeMultisigSimulationFailedError } from "../../errors.js";
|
|
4
|
+
export function validateSimulationParams(params) {
|
|
5
|
+
return Effect.gen(function* () {
|
|
6
|
+
const { gasThresholdPercent, safeAddress, transactions } = params;
|
|
7
|
+
if (transactions.length === 0) {
|
|
8
|
+
return yield* Effect.fail(new SafeMultisigSimulationFailedError({
|
|
9
|
+
message: "Cannot simulate empty transaction batch",
|
|
10
|
+
}));
|
|
11
|
+
}
|
|
12
|
+
if (safeAddress === zeroAddress) {
|
|
13
|
+
return yield* Effect.fail(new SafeMultisigSimulationFailedError({
|
|
14
|
+
message: "Invalid Safe address: cannot be zero address",
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
if (gasThresholdPercent !== undefined &&
|
|
18
|
+
(gasThresholdPercent < 1 || gasThresholdPercent > 100)) {
|
|
19
|
+
return yield* Effect.fail(new InvalidGasThresholdError({
|
|
20
|
+
message: "gasThresholdPercent must be between 1 and 100 (inclusive)",
|
|
21
|
+
value: gasThresholdPercent,
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
return params;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../../../src/safe/simulation/internal/validation/validation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,EAAE,wBAAwB,EAAE,iCAAiC,EAAE,MAAM,iBAAiB,CAAC;AAM9F,MAAM,UAAU,wBAAwB,CACtC,MAAuC;IAKvC,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,MAAM,EAAE,mBAAmB,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;QAElE,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,iCAAiC,CAAC;gBACpC,OAAO,EAAE,yCAAyC;aACnD,CAAC,CACH,CAAC;QACJ,CAAC;QAED,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,iCAAiC,CAAC;gBACpC,OAAO,EAAE,8CAA8C;aACxD,CAAC,CACH,CAAC;QACJ,CAAC;QAED,IACE,mBAAmB,KAAK,SAAS;YACjC,CAAC,mBAAmB,GAAG,CAAC,IAAI,mBAAmB,GAAG,GAAG,CAAC,EACtD,CAAC;YACD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,wBAAwB,CAAC;gBAC3B,OAAO,EAAE,2DAA2D;gBACpE,KAAK,EAAE,mBAAmB;aAC3B,CAAC,CACH,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Input validation for Safe batch simulation parameters.\n */\nimport { Effect } from \"effect\";\nimport { zeroAddress } from \"viem\";\nimport { InvalidGasThresholdError, SafeMultisigSimulationFailedError } from \"../../errors.js\";\nimport type { SafeMultisigSimulateBatchParams } from \"../../types.js\";\n\n/**\n * Validate user-supplied simulation inputs before any chain calls.\n */\nexport function validateSimulationParams(\n params: SafeMultisigSimulateBatchParams\n): Effect.Effect<\n SafeMultisigSimulateBatchParams,\n InvalidGasThresholdError | SafeMultisigSimulationFailedError\n> {\n return Effect.gen(function* () {\n const { gasThresholdPercent, safeAddress, transactions } = params;\n\n if (transactions.length === 0) {\n return yield* Effect.fail(\n new SafeMultisigSimulationFailedError({\n message: \"Cannot simulate empty transaction batch\",\n })\n );\n }\n\n if (safeAddress === zeroAddress) {\n return yield* Effect.fail(\n new SafeMultisigSimulationFailedError({\n message: \"Invalid Safe address: cannot be zero address\",\n })\n );\n }\n\n if (\n gasThresholdPercent !== undefined &&\n (gasThresholdPercent < 1 || gasThresholdPercent > 100)\n ) {\n return yield* Effect.fail(\n new InvalidGasThresholdError({\n message: \"gasThresholdPercent must be between 1 and 100 (inclusive)\",\n value: gasThresholdPercent,\n })\n );\n }\n\n return params;\n });\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ClientNotFoundError } from "@prb/effect-evm/core";
|
|
2
|
+
import { PublicClientService } from "@prb/effect-evm/core";
|
|
3
|
+
import { Context, Effect, Layer } from "effect";
|
|
4
|
+
import type { GasLimitOverflowError, InvalidGasThresholdError, SafeMultisigContractsNotDeployedError, SafeMultisigSimulationFailedError, SimulationDecodeError, TxSizeTooLargeError } from "./errors.js";
|
|
5
|
+
import type { SafeMultisigSimulateBatchParams, SafeMultisigSimulationResult } from "./types.js";
|
|
6
|
+
export type SafeMultisigSimulationServiceShape = {
|
|
7
|
+
readonly simulateBatch: (params: SafeMultisigSimulateBatchParams) => Effect.Effect<SafeMultisigSimulationResult, ClientNotFoundError | InvalidGasThresholdError | SafeMultisigContractsNotDeployedError | TxSizeTooLargeError | SafeMultisigSimulationFailedError | SimulationDecodeError | GasLimitOverflowError>;
|
|
8
|
+
};
|
|
9
|
+
declare const SafeMultisigSimulationService_base: Context.TagClass<SafeMultisigSimulationService, "ew3/SafeMultisigSimulation", SafeMultisigSimulationServiceShape>;
|
|
10
|
+
export declare class SafeMultisigSimulationService extends SafeMultisigSimulationService_base {
|
|
11
|
+
}
|
|
12
|
+
export declare const SafeMultisigSimulationServiceLive: Layer.Layer<SafeMultisigSimulationService, never, PublicClientService>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/safe/simulation/service.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,KAAK,EACV,qBAAqB,EACrB,wBAAwB,EACxB,qCAAqC,EACrC,iCAAiC,EACjC,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAOrB,OAAO,KAAK,EAAE,+BAA+B,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAEhG,MAAM,MAAM,kCAAkC,GAAG;IAU/C,QAAQ,CAAC,aAAa,EAAE,CACtB,MAAM,EAAE,+BAA+B,KACpC,MAAM,CAAC,MAAM,CAChB,4BAA4B,EAC1B,mBAAmB,GACnB,wBAAwB,GACxB,qCAAqC,GACrC,mBAAmB,GACnB,iCAAiC,GACjC,qBAAqB,GACrB,qBAAqB,CACxB,CAAC;CACH,CAAC;;AAEF,qBAAa,6BAA8B,SAAQ,kCAGhD;CAAG;AAEN,eAAO,MAAM,iCAAiC,wEAyB7C,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { PublicClientService } from "@prb/effect-evm/core";
|
|
2
|
+
import { Context, Effect, Layer } from "effect";
|
|
3
|
+
import { buildSafeCalldata } from "./internal/calldata/index.js";
|
|
4
|
+
import { resolveSafeMultisigContracts } from "./internal/contracts/index.js";
|
|
5
|
+
import { evaluateSimulationResult } from "./internal/evaluation/index.js";
|
|
6
|
+
import { fetchLatestBlock, simulateAndDecode } from "./internal/execution/index.js";
|
|
7
|
+
import { enforceTxSizeLimit } from "./internal/limits/index.js";
|
|
8
|
+
import { validateSimulationParams } from "./internal/validation/index.js";
|
|
9
|
+
export class SafeMultisigSimulationService extends Context.Tag("ew3/SafeMultisigSimulation")() {
|
|
10
|
+
}
|
|
11
|
+
export const SafeMultisigSimulationServiceLive = Layer.effect(SafeMultisigSimulationService, Effect.gen(function* () {
|
|
12
|
+
const publicClientService = yield* PublicClientService;
|
|
13
|
+
return SafeMultisigSimulationService.of({
|
|
14
|
+
simulateBatch: (params) => Effect.gen(function* () {
|
|
15
|
+
const { chainId, safeAddress, transactions, txSizeLimit, gasThresholdPercent } = yield* validateSimulationParams(params);
|
|
16
|
+
const contracts = yield* resolveSafeMultisigContracts(chainId);
|
|
17
|
+
const safeCalldata = buildSafeCalldata(contracts, transactions);
|
|
18
|
+
yield* enforceTxSizeLimit(safeCalldata, txSizeLimit);
|
|
19
|
+
const client = yield* publicClientService.get(chainId);
|
|
20
|
+
const [result, block] = yield* Effect.all([simulateAndDecode(client, safeAddress, safeCalldata), fetchLatestBlock(client)], { concurrency: "unbounded" });
|
|
21
|
+
return yield* evaluateSimulationResult(result, block, gasThresholdPercent);
|
|
22
|
+
}),
|
|
23
|
+
});
|
|
24
|
+
}));
|
|
25
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/safe/simulation/service.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAShD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AA2B1E,MAAM,OAAO,6BAA8B,SAAQ,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,EAGzF;CAAG;AAEN,MAAM,CAAC,MAAM,iCAAiC,GAAG,KAAK,CAAC,MAAM,CAC3D,6BAA6B,EAC7B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,mBAAmB,GAAG,KAAK,CAAC,CAAC,mBAAmB,CAAC;IAEvD,OAAO,6BAA6B,CAAC,EAAE,CAAC;QACtC,aAAa,EAAE,CAAC,MAAuC,EAAE,EAAE,CACzD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,mBAAmB,EAAE,GAC5E,KAAK,CAAC,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;YAC1C,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,4BAA4B,CAAC,OAAO,CAAC,CAAC;YAC/D,MAAM,YAAY,GAAG,iBAAiB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YAEhE,KAAK,CAAC,CAAC,kBAAkB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;YAErD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACvD,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CACvC,CAAC,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,EAChF,EAAE,WAAW,EAAE,WAAW,EAAE,CAC7B,CAAC;YAEF,OAAO,KAAK,CAAC,CAAC,wBAAwB,CAAC,MAAM,EAAE,KAAK,EAAE,mBAAmB,CAAC,CAAC;QAC7E,CAAC,CAAC;KACL,CAAC,CAAC;AACL,CAAC,CAAC,CACH,CAAC","sourcesContent":["/**\n * Safe batch simulation service using Effect-TS.\n *\n * Simulates Safe multisig batch transactions to estimate gas consumption before execution.\n * Uses Safe's simulateAndRevert algorithm to get accurate gas estimates.\n *\n * @see https://github.com/safe-global/safe-smart-account/blob/c4859f4/contracts/common/StorageAccessible.sol#L32-L43\n */\n\nimport type { ClientNotFoundError } from \"@prb/effect-evm/core\";\nimport { PublicClientService } from \"@prb/effect-evm/core\";\nimport { Context, Effect, Layer } from \"effect\";\nimport type {\n GasLimitOverflowError,\n InvalidGasThresholdError,\n SafeMultisigContractsNotDeployedError,\n SafeMultisigSimulationFailedError,\n SimulationDecodeError,\n TxSizeTooLargeError,\n} from \"./errors.js\";\nimport { buildSafeCalldata } from \"./internal/calldata/index.js\";\nimport { resolveSafeMultisigContracts } from \"./internal/contracts/index.js\";\nimport { evaluateSimulationResult } from \"./internal/evaluation/index.js\";\nimport { fetchLatestBlock, simulateAndDecode } from \"./internal/execution/index.js\";\nimport { enforceTxSizeLimit } from \"./internal/limits/index.js\";\nimport { validateSimulationParams } from \"./internal/validation/index.js\";\nimport type { SafeMultisigSimulateBatchParams, SafeMultisigSimulationResult } from \"./types.js\";\n\nexport type SafeMultisigSimulationServiceShape = {\n /**\n * Simulate a batch of transactions in Safe context.\n *\n * Uses simulateAndRevert algorithm to estimate gas consumption. This always reverts,\n * and we decode the revert data to extract the gas estimate.\n *\n * @param params - Simulation parameters including chainId, safeAddress, and transactions\n * @returns Gas estimate and success flag\n */\n readonly simulateBatch: (\n params: SafeMultisigSimulateBatchParams\n ) => Effect.Effect<\n SafeMultisigSimulationResult,\n | ClientNotFoundError\n | InvalidGasThresholdError\n | SafeMultisigContractsNotDeployedError\n | TxSizeTooLargeError\n | SafeMultisigSimulationFailedError\n | SimulationDecodeError\n | GasLimitOverflowError\n >;\n};\n\nexport class SafeMultisigSimulationService extends Context.Tag(\"ew3/SafeMultisigSimulation\")<\n SafeMultisigSimulationService,\n SafeMultisigSimulationServiceShape\n>() {}\n\nexport const SafeMultisigSimulationServiceLive = Layer.effect(\n SafeMultisigSimulationService,\n Effect.gen(function* () {\n const publicClientService = yield* PublicClientService;\n\n return SafeMultisigSimulationService.of({\n simulateBatch: (params: SafeMultisigSimulateBatchParams) =>\n Effect.gen(function* () {\n const { chainId, safeAddress, transactions, txSizeLimit, gasThresholdPercent } =\n yield* validateSimulationParams(params);\n const contracts = yield* resolveSafeMultisigContracts(chainId);\n const safeCalldata = buildSafeCalldata(contracts, transactions);\n\n yield* enforceTxSizeLimit(safeCalldata, txSizeLimit);\n\n const client = yield* publicClientService.get(chainId);\n const [result, block] = yield* Effect.all(\n [simulateAndDecode(client, safeAddress, safeCalldata), fetchLatestBlock(client)],\n { concurrency: \"unbounded\" }\n );\n\n return yield* evaluateSimulationResult(result, block, gasThresholdPercent);\n }),\n });\n })\n);\n"]}
|