damm-sdk 1.4.21 → 1.4.23

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ccip.router.d.ts","sourceRoot":"","sources":["../../../src/integrations/ccip/ccip.router.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAIpC;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQhE,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,YAAa,MAAM,KAAG,MAMtD,CAAC;AAIF,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAClC,qCAAqC;IACrC,QAAQ,EAAE,SAAS,CAAC;IACpB,0CAA0C;IAC1C,IAAI,EAAE,SAAS,CAAC;IAChB,uBAAuB;IACvB,YAAY,EAAE,SAAS,eAAe,EAAE,CAAC;IACzC,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAC;IAClB,mCAAmC;IACnC,SAAS,EAAE,SAAS,CAAC;CACxB,CAAC,CAAC;AAIH,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAC9B,wBAAwB,EAAE,MAAM,CAAC;IACjC,OAAO,EAAE,cAAc,CAAC;CAC3B,CAAC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,SAAU,UAAU,KAAG,SAcrD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa;mBAIP,OAAO;UAChB,UAAU;MAChB,WAAW,IAAI,CAOlB,CAAC;AAIF,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAChC,wBAAwB,EAAE,MAAM,CAAC;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB,SAAU,YAAY,KAAG,SAcrD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW;mBAIL,OAAO;UAChB,YAAY;MAClB,WAAW,IAAI,CAOlB,CAAC;AAIF;;;GAGG;AACH,eAAO,MAAM,gBAAgB;cAKf,OAAO;WACV,OAAO;YACN,MAAM;MACd,cAWH,CAAC"}
1
+ {"version":3,"file":"ccip.router.d.ts","sourceRoot":"","sources":["../../../src/integrations/ccip/ccip.router.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAIpC;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAShE,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,YAAa,MAAM,KAAG,MAMtD,CAAC;AAIF,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAClC,qCAAqC;IACrC,QAAQ,EAAE,SAAS,CAAC;IACpB,0CAA0C;IAC1C,IAAI,EAAE,SAAS,CAAC;IAChB,uBAAuB;IACvB,YAAY,EAAE,SAAS,eAAe,EAAE,CAAC;IACzC,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAC;IAClB,mCAAmC;IACnC,SAAS,EAAE,SAAS,CAAC;CACxB,CAAC,CAAC;AAIH,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAC9B,wBAAwB,EAAE,MAAM,CAAC;IACjC,OAAO,EAAE,cAAc,CAAC;CAC3B,CAAC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,SAAU,UAAU,KAAG,SAcrD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa;mBAIP,OAAO;UAChB,UAAU;MAChB,WAAW,IAAI,CAOlB,CAAC;AAIF,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAChC,wBAAwB,EAAE,MAAM,CAAC;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB,SAAU,YAAY,KAAG,SAcrD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW;mBAIL,OAAO;UAChB,YAAY;MAClB,WAAW,IAAI,CAOlB,CAAC;AAIF;;;GAGG;AACH,eAAO,MAAM,gBAAgB;cAKf,OAAO;WACV,OAAO;YACN,MAAM;MACd,cAWH,CAAC"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Enso RouterV2 transaction builders.
3
+ *
4
+ * Enso's `/v1/shortcuts/route` API only returns `routeSingle(Token tokenOut,
5
+ * bytes data)` calldata. Our Zodiac Roles scopes only permit the stricter
6
+ * 4-arg `safeRouteSingle(Token tokenIn, Token tokenOut, address receiver,
7
+ * bytes data)`, which validates tokenIn consumption and an explicit receiver.
8
+ *
9
+ * The shortcut `bundle` payload is identical between the two entry points —
10
+ * safeRouteSingle just layers additional validation on top — so we fetch the
11
+ * route once, extract the bundle, and re-encode as safeRouteSingle.
12
+ *
13
+ * Workflow:
14
+ * ensoSafeRouteSingleTrx({ api args, routerAddress })
15
+ * → fetchEnsoRoute(...) (HTTP)
16
+ * → rewrapRouteSingleAsSafeRouteSingle(...) (pure)
17
+ * → createCall({ to: routerAddress, data, … }) (Unwrapable<Call>)
18
+ */
19
+ import { type Address } from "viem";
20
+ import type { Call, HexString, Unwrapable } from "../../types";
21
+ import { type EnsoRouteArgs } from "./enso.route.api.ts";
22
+ export declare enum EnsoTokenType {
23
+ Native = 0,
24
+ ERC20 = 1
25
+ }
26
+ export type EnsoToken = Readonly<{
27
+ tokenType: EnsoTokenType;
28
+ data: HexString;
29
+ }>;
30
+ /**
31
+ * Encode a token as Enso's `Token` struct:
32
+ * - ERC20: (tokenType=1, abi.encode(address, uint256))
33
+ * - Native: (tokenType=0, abi.encode(uint256))
34
+ */
35
+ export declare const encodeEnsoToken: (token: Address, amount: bigint) => EnsoToken;
36
+ export declare class UnexpectedEnsoSelectorError extends Error {
37
+ readonly selector: string;
38
+ constructor(selector: string);
39
+ }
40
+ export type RewrapArgs = Readonly<{
41
+ routeSingleCalldata: HexString;
42
+ tokenIn: Address;
43
+ amountIn: bigint;
44
+ receiver: Address;
45
+ }>;
46
+ /**
47
+ * Decode `routeSingle(tokenOut, bundle)` calldata, then re-encode as
48
+ * `safeRouteSingle(tokenIn, tokenOut, receiver, bundle)` using the same
49
+ * bundle payload. The bundle is byte-identical; only the wrapper changes.
50
+ *
51
+ * Throws `UnexpectedEnsoSelectorError` if the input doesn't start with the
52
+ * routeSingle selector — a fail-fast guard in case Enso's API ever switches
53
+ * output format.
54
+ */
55
+ export declare const rewrapRouteSingleAsSafeRouteSingle: (args: RewrapArgs) => HexString;
56
+ export declare class EnsoUnexpectedRouterError extends Error {
57
+ readonly got: Address;
58
+ readonly expected: Address;
59
+ constructor(got: Address, expected: Address);
60
+ }
61
+ export type EnsoSafeRouteSingleTrxArgs = EnsoRouteArgs & Readonly<{
62
+ /** Address of the Enso RouterV2 on the target chain. Must match the scope in Zodiac Roles. */
63
+ routerAddress: Address;
64
+ }>;
65
+ /**
66
+ * Fetch an Enso route and return a `safeRouteSingle` call ready to be added
67
+ * to a MultisendBuilder.
68
+ *
69
+ * Aborts (throws) if Enso's API returns a tx targeting any address other than
70
+ * the provided RouterV2 — this protects against the API silently switching to
71
+ * EnsoWallet or EnsoShortcutsDelegate, neither of which our Zodiac scope
72
+ * permits.
73
+ */
74
+ export declare const ensoSafeRouteSingleTrx: (args: EnsoSafeRouteSingleTrxArgs) => Promise<Unwrapable<Call>>;
75
+ //# sourceMappingURL=enso.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enso.d.ts","sourceRoot":"","sources":["../../../src/integrations/enso/enso.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAA+D,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AACjG,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG/D,OAAO,EAAkB,KAAK,aAAa,EAA0B,MAAM,qBAAqB,CAAC;AAIjG,oBAAY,aAAa;IACrB,MAAM,IAAI;IACV,KAAK,IAAI;CACZ;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;IAC7B,SAAS,EAAE,aAAa,CAAC;IACzB,IAAI,EAAE,SAAS,CAAC;CACnB,CAAC,CAAC;AAMH;;;;GAIG;AACH,eAAO,MAAM,eAAe,UAAW,OAAO,UAAU,MAAM,KAAG,SAWhE,CAAC;AAMF,qBAAa,2BAA4B,SAAQ,KAAK;IAClD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBACd,QAAQ,EAAE,MAAM;CAQ/B;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAC9B,mBAAmB,EAAE,SAAS,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACrB,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,kCAAkC,SAAU,UAAU,KAAG,SAyBrE,CAAC;AAIF,qBAAa,yBAA0B,SAAQ,KAAK;IAChD,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;gBACf,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO;CAS9C;AAED,MAAM,MAAM,0BAA0B,GAAG,aAAa,GAClD,QAAQ,CAAC;IACL,8FAA8F;IAC9F,aAAa,EAAE,OAAO,CAAC;CAC1B,CAAC,CAAC;AAEP;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,SAAgB,0BAA0B,KAAG,QAAQ,WAAW,IAAI,CAAC,CAsBvG,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Enso Shortcuts API client.
3
+ *
4
+ * Fetches a swap route from Enso's public `/v1/shortcuts/route` endpoint and
5
+ * returns the raw `tx.data` (which is always `routeSingle` calldata — see
6
+ * `enso.ts` for the rewrap into `safeRouteSingle`).
7
+ *
8
+ * API reference: https://docs.enso.build/pages/api-reference/shortcuts/route
9
+ */
10
+ import type { Address } from "viem";
11
+ import type { HexString } from "../../types";
12
+ export declare const ENSO_API_BASE: "https://api.enso.finance";
13
+ /**
14
+ * Raw response shape from the Enso route endpoint. We only model the fields
15
+ * we use; Enso returns many more (amountOut, priceImpact, route, …) that are
16
+ * intentionally ignored.
17
+ */
18
+ export type EnsoRouteResponse = Readonly<{
19
+ tx: Readonly<{
20
+ to: HexString;
21
+ data: HexString;
22
+ value: string;
23
+ }>;
24
+ }>;
25
+ export type EnsoRouteArgs = Readonly<{
26
+ chainId: number;
27
+ /** Caller address — also used as `receiver` by default. */
28
+ fromAddress: Address;
29
+ /** Destination for the swap output. Typically equal to `fromAddress` (the Safe). */
30
+ receiver: Address;
31
+ tokenIn: Address;
32
+ tokenOut: Address;
33
+ /** Decimal string, no decimals adjustment — matches token units. */
34
+ amountIn: string;
35
+ /**
36
+ * Slippage in integer basis points (e.g. 20 = 0.2%, 300 = 3%).
37
+ *
38
+ * Enso's `slippage` param is a number string in bips. Passing a decimal
39
+ * like `0.2` triggers a 400 Bad Request ("slippage must be a number
40
+ * string").
41
+ */
42
+ slippageBips: number;
43
+ /** Optional Enso API key for 10 rps; no key = 1 rps global limit. */
44
+ apiKey?: string;
45
+ /** Override the API base URL (useful for tests). */
46
+ apiBase?: string;
47
+ }>;
48
+ export declare class EnsoRouteApiError extends Error {
49
+ readonly status: number;
50
+ readonly statusText: string;
51
+ readonly tokenIn: Address;
52
+ readonly tokenOut: Address;
53
+ constructor({ status, statusText, tokenIn, tokenOut, }: {
54
+ status: number;
55
+ statusText: string;
56
+ tokenIn: Address;
57
+ tokenOut: Address;
58
+ });
59
+ }
60
+ /**
61
+ * Fetch a shortcut route from Enso. Always returns `routeSingle` calldata —
62
+ * use `rewrapRouteSingleAsSafeRouteSingle` in `enso.ts` to convert to
63
+ * `safeRouteSingle` before submitting on-chain if your Safe's Zodiac scope
64
+ * only permits safeRouteSingle.
65
+ */
66
+ export declare const fetchEnsoRoute: (args: EnsoRouteArgs) => Promise<EnsoRouteResponse>;
67
+ //# sourceMappingURL=enso.route.api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enso.route.api.d.ts","sourceRoot":"","sources":["../../../src/integrations/enso/enso.route.api.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,eAAO,MAAM,aAAa,4BAAsC,CAAC;AAEjE;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACrC,EAAE,EAAE,QAAQ,CAAC;QACT,EAAE,EAAE,SAAS,CAAC;QACd,IAAI,EAAE,SAAS,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACN,CAAC,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,WAAW,EAAE,OAAO,CAAC;IACrB,oFAAoF;IACpF,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH,qBAAa,iBAAkB,SAAQ,KAAK;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;gBAEf,EACR,MAAM,EACN,UAAU,EACV,OAAO,EACP,QAAQ,GACX,EAAE;QACC,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;KACrB;CAQJ;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,SAAgB,aAAa,KAAG,QAAQ,iBAAiB,CA0CnF,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Enso RouterV2 — minimal ABI covering the entry points we use:
3
+ *
4
+ * routeSingle(Token tokenOut, bytes data)
5
+ * safeRouteSingle(Token tokenIn, Token tokenOut, address receiver, bytes data)
6
+ *
7
+ * `Token` is Enso's internal struct `{ uint8 tokenType, bytes data }` where:
8
+ * - tokenType = 0 (Native): data = abi.encode(uint256 amount)
9
+ * - tokenType = 1 (ERC20): data = abi.encode(address token, uint256 amount)
10
+ *
11
+ * We intentionally expose only these two selectors — we never call the Enso
12
+ * router with routeMulti / safeRouteMulti / delegate variants from any DAMM
13
+ * context, and shipping their ABIs here would just invite unaudited usage.
14
+ */
15
+ declare const _default: readonly [{
16
+ readonly name: "routeSingle";
17
+ readonly type: "function";
18
+ readonly stateMutability: "payable";
19
+ readonly inputs: readonly [{
20
+ readonly name: "tokenOut";
21
+ readonly type: "tuple";
22
+ readonly components: readonly [{
23
+ readonly name: "tokenType";
24
+ readonly type: "uint8";
25
+ }, {
26
+ readonly name: "data";
27
+ readonly type: "bytes";
28
+ }];
29
+ }, {
30
+ readonly name: "data";
31
+ readonly type: "bytes";
32
+ }];
33
+ readonly outputs: readonly [];
34
+ }, {
35
+ readonly name: "safeRouteSingle";
36
+ readonly type: "function";
37
+ readonly stateMutability: "payable";
38
+ readonly inputs: readonly [{
39
+ readonly name: "tokenIn";
40
+ readonly type: "tuple";
41
+ readonly components: readonly [{
42
+ readonly name: "tokenType";
43
+ readonly type: "uint8";
44
+ }, {
45
+ readonly name: "data";
46
+ readonly type: "bytes";
47
+ }];
48
+ }, {
49
+ readonly name: "tokenOut";
50
+ readonly type: "tuple";
51
+ readonly components: readonly [{
52
+ readonly name: "tokenType";
53
+ readonly type: "uint8";
54
+ }, {
55
+ readonly name: "data";
56
+ readonly type: "bytes";
57
+ }];
58
+ }, {
59
+ readonly name: "receiver";
60
+ readonly type: "address";
61
+ }, {
62
+ readonly name: "data";
63
+ readonly type: "bytes";
64
+ }];
65
+ readonly outputs: readonly [];
66
+ }];
67
+ export default _default;
68
+ //# sourceMappingURL=enso.router.abi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enso.router.abi.d.ts","sourceRoot":"","sources":["../../../src/integrations/enso/enso.router.abi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWH,wBAuBW"}
@@ -0,0 +1,4 @@
1
+ export { default as ensoRouterAbi } from "./enso.router.abi";
2
+ export * from "./enso";
3
+ export * from "./enso.route.api";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/integrations/enso/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC7D,cAAc,QAAQ,CAAC;AACvB,cAAc,kBAAkB,CAAC"}
@@ -24,4 +24,5 @@ export * from "./fluidLite";
24
24
  export * from "./weth";
25
25
  export * from "./pendle";
26
26
  export * from "./wormhole";
27
+ export * from "./enso";
27
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/integrations/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/integrations/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC"}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "main": "./dist/index.cjs",
5
5
  "types": "./dist/index.d.ts",
6
6
  "type": "module",
7
- "version": "1.4.21",
7
+ "version": "1.4.23",
8
8
  "files": [
9
9
  "dist",
10
10
  "src",
@@ -19,6 +19,7 @@ export const CCIP_CHAIN_SELECTORS: Readonly<Record<number, string>> = Object.fre
19
19
  137: "4051577828743386545", // Polygon
20
20
  56: "11344663589394136015", // BSC
21
21
  143: "8481857512324358265", // Monad
22
+ 4326: "6093540873831549674", // MegaETH
22
23
  });
23
24
 
24
25
  /**
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Enso Shortcuts API client.
3
+ *
4
+ * Fetches a swap route from Enso's public `/v1/shortcuts/route` endpoint and
5
+ * returns the raw `tx.data` (which is always `routeSingle` calldata — see
6
+ * `enso.ts` for the rewrap into `safeRouteSingle`).
7
+ *
8
+ * API reference: https://docs.enso.build/pages/api-reference/shortcuts/route
9
+ */
10
+
11
+ import type { Address } from "viem";
12
+ import type { HexString } from "../../types";
13
+
14
+ export const ENSO_API_BASE = "https://api.enso.finance" as const;
15
+
16
+ /**
17
+ * Raw response shape from the Enso route endpoint. We only model the fields
18
+ * we use; Enso returns many more (amountOut, priceImpact, route, …) that are
19
+ * intentionally ignored.
20
+ */
21
+ export type EnsoRouteResponse = Readonly<{
22
+ tx: Readonly<{
23
+ to: HexString;
24
+ data: HexString;
25
+ value: string;
26
+ }>;
27
+ }>;
28
+
29
+ export type EnsoRouteArgs = Readonly<{
30
+ chainId: number;
31
+ /** Caller address — also used as `receiver` by default. */
32
+ fromAddress: Address;
33
+ /** Destination for the swap output. Typically equal to `fromAddress` (the Safe). */
34
+ receiver: Address;
35
+ tokenIn: Address;
36
+ tokenOut: Address;
37
+ /** Decimal string, no decimals adjustment — matches token units. */
38
+ amountIn: string;
39
+ /**
40
+ * Slippage in integer basis points (e.g. 20 = 0.2%, 300 = 3%).
41
+ *
42
+ * Enso's `slippage` param is a number string in bips. Passing a decimal
43
+ * like `0.2` triggers a 400 Bad Request ("slippage must be a number
44
+ * string").
45
+ */
46
+ slippageBips: number;
47
+ /** Optional Enso API key for 10 rps; no key = 1 rps global limit. */
48
+ apiKey?: string;
49
+ /** Override the API base URL (useful for tests). */
50
+ apiBase?: string;
51
+ }>;
52
+
53
+ export class EnsoRouteApiError extends Error {
54
+ readonly status: number;
55
+ readonly statusText: string;
56
+ readonly tokenIn: Address;
57
+ readonly tokenOut: Address;
58
+
59
+ constructor({
60
+ status,
61
+ statusText,
62
+ tokenIn,
63
+ tokenOut,
64
+ }: {
65
+ status: number;
66
+ statusText: string;
67
+ tokenIn: Address;
68
+ tokenOut: Address;
69
+ }) {
70
+ super(`Enso route API request failed with status ${status} (${statusText}) for swap ${tokenIn} -> ${tokenOut}`);
71
+ this.name = "EnsoRouteApiError";
72
+ this.status = status;
73
+ this.statusText = statusText;
74
+ this.tokenIn = tokenIn;
75
+ this.tokenOut = tokenOut;
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Fetch a shortcut route from Enso. Always returns `routeSingle` calldata —
81
+ * use `rewrapRouteSingleAsSafeRouteSingle` in `enso.ts` to convert to
82
+ * `safeRouteSingle` before submitting on-chain if your Safe's Zodiac scope
83
+ * only permits safeRouteSingle.
84
+ */
85
+ export const fetchEnsoRoute = async (args: EnsoRouteArgs): Promise<EnsoRouteResponse> => {
86
+ const {
87
+ chainId,
88
+ fromAddress,
89
+ receiver,
90
+ tokenIn,
91
+ tokenOut,
92
+ amountIn,
93
+ slippageBips,
94
+ apiKey,
95
+ apiBase = ENSO_API_BASE,
96
+ } = args;
97
+
98
+ const params = new URLSearchParams({
99
+ chainId: String(chainId),
100
+ fromAddress,
101
+ receiver,
102
+ tokenIn,
103
+ tokenOut,
104
+ amountIn,
105
+ slippage: String(slippageBips),
106
+ });
107
+
108
+ const headers: Record<string, string> = { Accept: "application/json" };
109
+ if (apiKey) {
110
+ headers["Authorization"] = `Bearer ${apiKey}`;
111
+ }
112
+
113
+ const response = await fetch(`${apiBase}/api/v1/shortcuts/route?${params.toString()}`, {
114
+ headers,
115
+ });
116
+
117
+ if (!response.ok) {
118
+ throw new EnsoRouteApiError({
119
+ status: response.status,
120
+ statusText: response.statusText,
121
+ tokenIn,
122
+ tokenOut,
123
+ });
124
+ }
125
+
126
+ return (await response.json()) as EnsoRouteResponse;
127
+ };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Enso RouterV2 — minimal ABI covering the entry points we use:
3
+ *
4
+ * routeSingle(Token tokenOut, bytes data)
5
+ * safeRouteSingle(Token tokenIn, Token tokenOut, address receiver, bytes data)
6
+ *
7
+ * `Token` is Enso's internal struct `{ uint8 tokenType, bytes data }` where:
8
+ * - tokenType = 0 (Native): data = abi.encode(uint256 amount)
9
+ * - tokenType = 1 (ERC20): data = abi.encode(address token, uint256 amount)
10
+ *
11
+ * We intentionally expose only these two selectors — we never call the Enso
12
+ * router with routeMulti / safeRouteMulti / delegate variants from any DAMM
13
+ * context, and shipping their ABIs here would just invite unaudited usage.
14
+ */
15
+
16
+ const tokenTuple = {
17
+ name: "token",
18
+ type: "tuple",
19
+ components: [
20
+ { name: "tokenType", type: "uint8" },
21
+ { name: "data", type: "bytes" },
22
+ ],
23
+ } as const;
24
+
25
+ export default [
26
+ {
27
+ name: "routeSingle",
28
+ type: "function",
29
+ stateMutability: "payable",
30
+ inputs: [
31
+ { ...tokenTuple, name: "tokenOut" },
32
+ { name: "data", type: "bytes" },
33
+ ],
34
+ outputs: [],
35
+ },
36
+ {
37
+ name: "safeRouteSingle",
38
+ type: "function",
39
+ stateMutability: "payable",
40
+ inputs: [
41
+ { ...tokenTuple, name: "tokenIn" },
42
+ { ...tokenTuple, name: "tokenOut" },
43
+ { name: "receiver", type: "address" },
44
+ { name: "data", type: "bytes" },
45
+ ],
46
+ outputs: [],
47
+ },
48
+ ] as const;
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Enso RouterV2 transaction builders.
3
+ *
4
+ * Enso's `/v1/shortcuts/route` API only returns `routeSingle(Token tokenOut,
5
+ * bytes data)` calldata. Our Zodiac Roles scopes only permit the stricter
6
+ * 4-arg `safeRouteSingle(Token tokenIn, Token tokenOut, address receiver,
7
+ * bytes data)`, which validates tokenIn consumption and an explicit receiver.
8
+ *
9
+ * The shortcut `bundle` payload is identical between the two entry points —
10
+ * safeRouteSingle just layers additional validation on top — so we fetch the
11
+ * route once, extract the bundle, and re-encode as safeRouteSingle.
12
+ *
13
+ * Workflow:
14
+ * ensoSafeRouteSingleTrx({ api args, routerAddress })
15
+ * → fetchEnsoRoute(...) (HTTP)
16
+ * → rewrapRouteSingleAsSafeRouteSingle(...) (pure)
17
+ * → createCall({ to: routerAddress, data, … }) (Unwrapable<Call>)
18
+ */
19
+
20
+ import { decodeFunctionData, encodeAbiParameters, encodeFunctionData, type Address } from "viem";
21
+ import type { Call, HexString, Unwrapable } from "../../types";
22
+ import { createCall } from "../../types";
23
+ import ensoRouterAbi from "./enso.router.abi.ts";
24
+ import { fetchEnsoRoute, type EnsoRouteArgs, type EnsoRouteResponse } from "./enso.route.api.ts";
25
+
26
+ // --- Token struct --------------------------------------------------------
27
+
28
+ export enum EnsoTokenType {
29
+ Native = 0,
30
+ ERC20 = 1,
31
+ }
32
+
33
+ export type EnsoToken = Readonly<{
34
+ tokenType: EnsoTokenType;
35
+ data: HexString;
36
+ }>;
37
+
38
+ const ZERO_ADDRESS: Address = "0x0000000000000000000000000000000000000000";
39
+
40
+ const isNativeToken = (token: Address): boolean => token.toLowerCase() === ZERO_ADDRESS;
41
+
42
+ /**
43
+ * Encode a token as Enso's `Token` struct:
44
+ * - ERC20: (tokenType=1, abi.encode(address, uint256))
45
+ * - Native: (tokenType=0, abi.encode(uint256))
46
+ */
47
+ export const encodeEnsoToken = (token: Address, amount: bigint): EnsoToken => {
48
+ if (isNativeToken(token)) {
49
+ return {
50
+ tokenType: EnsoTokenType.Native,
51
+ data: encodeAbiParameters([{ type: "uint256" }], [amount]),
52
+ };
53
+ }
54
+ return {
55
+ tokenType: EnsoTokenType.ERC20,
56
+ data: encodeAbiParameters([{ type: "address" }, { type: "uint256" }], [token, amount]),
57
+ };
58
+ };
59
+
60
+ // --- routeSingle → safeRouteSingle rewrap --------------------------------
61
+
62
+ const ROUTE_SINGLE_SELECTOR = "0xb94c3609" as const;
63
+
64
+ export class UnexpectedEnsoSelectorError extends Error {
65
+ readonly selector: string;
66
+ constructor(selector: string) {
67
+ super(
68
+ `Expected routeSingle selector ${ROUTE_SINGLE_SELECTOR}, got ${selector}. ` +
69
+ `The Enso API may have changed its output format.`,
70
+ );
71
+ this.name = "UnexpectedEnsoSelectorError";
72
+ this.selector = selector;
73
+ }
74
+ }
75
+
76
+ export type RewrapArgs = Readonly<{
77
+ routeSingleCalldata: HexString;
78
+ tokenIn: Address;
79
+ amountIn: bigint;
80
+ receiver: Address;
81
+ }>;
82
+
83
+ /**
84
+ * Decode `routeSingle(tokenOut, bundle)` calldata, then re-encode as
85
+ * `safeRouteSingle(tokenIn, tokenOut, receiver, bundle)` using the same
86
+ * bundle payload. The bundle is byte-identical; only the wrapper changes.
87
+ *
88
+ * Throws `UnexpectedEnsoSelectorError` if the input doesn't start with the
89
+ * routeSingle selector — a fail-fast guard in case Enso's API ever switches
90
+ * output format.
91
+ */
92
+ export const rewrapRouteSingleAsSafeRouteSingle = (args: RewrapArgs): HexString => {
93
+ const { routeSingleCalldata, tokenIn, amountIn, receiver } = args;
94
+
95
+ const selector = routeSingleCalldata.slice(0, 10).toLowerCase();
96
+ if (selector !== ROUTE_SINGLE_SELECTOR) {
97
+ throw new UnexpectedEnsoSelectorError(selector);
98
+ }
99
+
100
+ const decoded = decodeFunctionData({
101
+ abi: ensoRouterAbi,
102
+ data: routeSingleCalldata,
103
+ });
104
+
105
+ if (decoded.functionName !== "routeSingle") {
106
+ throw new UnexpectedEnsoSelectorError(selector);
107
+ }
108
+ const [tokenOutStruct, bundle] = decoded.args as readonly [EnsoToken, HexString];
109
+
110
+ const tokenInStruct = encodeEnsoToken(tokenIn, amountIn);
111
+
112
+ return encodeFunctionData({
113
+ abi: ensoRouterAbi,
114
+ functionName: "safeRouteSingle",
115
+ args: [tokenInStruct, tokenOutStruct, receiver, bundle],
116
+ }) as HexString;
117
+ };
118
+
119
+ // --- High-level helper: fetch route + rewrap + build Call ----------------
120
+
121
+ export class EnsoUnexpectedRouterError extends Error {
122
+ readonly got: Address;
123
+ readonly expected: Address;
124
+ constructor(got: Address, expected: Address) {
125
+ super(
126
+ `Enso API routed to ${got} but we expected RouterV2 ${expected}. ` +
127
+ `Unsupported routing (e.g. EnsoWallet / ShortcutsDelegate) — aborting.`,
128
+ );
129
+ this.name = "EnsoUnexpectedRouterError";
130
+ this.got = got;
131
+ this.expected = expected;
132
+ }
133
+ }
134
+
135
+ export type EnsoSafeRouteSingleTrxArgs = EnsoRouteArgs &
136
+ Readonly<{
137
+ /** Address of the Enso RouterV2 on the target chain. Must match the scope in Zodiac Roles. */
138
+ routerAddress: Address;
139
+ }>;
140
+
141
+ /**
142
+ * Fetch an Enso route and return a `safeRouteSingle` call ready to be added
143
+ * to a MultisendBuilder.
144
+ *
145
+ * Aborts (throws) if Enso's API returns a tx targeting any address other than
146
+ * the provided RouterV2 — this protects against the API silently switching to
147
+ * EnsoWallet or EnsoShortcutsDelegate, neither of which our Zodiac scope
148
+ * permits.
149
+ */
150
+ export const ensoSafeRouteSingleTrx = async (args: EnsoSafeRouteSingleTrxArgs): Promise<Unwrapable<Call>> => {
151
+ const { routerAddress, tokenIn, amountIn, receiver } = args;
152
+
153
+ const route: EnsoRouteResponse = await fetchEnsoRoute(args);
154
+
155
+ if (route.tx.to.toLowerCase() !== routerAddress.toLowerCase()) {
156
+ throw new EnsoUnexpectedRouterError(route.tx.to as Address, routerAddress);
157
+ }
158
+
159
+ const safeRouteSingleCalldata = rewrapRouteSingleAsSafeRouteSingle({
160
+ routeSingleCalldata: route.tx.data,
161
+ tokenIn,
162
+ amountIn: BigInt(amountIn),
163
+ receiver,
164
+ });
165
+
166
+ return createCall({
167
+ to: routerAddress,
168
+ data: safeRouteSingleCalldata,
169
+ operation: 0,
170
+ value: BigInt(route.tx.value || "0"),
171
+ });
172
+ };
@@ -0,0 +1,3 @@
1
+ export { default as ensoRouterAbi } from "./enso.router.abi";
2
+ export * from "./enso";
3
+ export * from "./enso.route.api";
@@ -24,3 +24,4 @@ export * from "./fluidLite";
24
24
  export * from "./weth";
25
25
  export * from "./pendle";
26
26
  export * from "./wormhole";
27
+ export * from "./enso";
@@ -1013,6 +1013,19 @@
1013
1013
  "safeL2Singleton": "0x29fcB43b46531BcA003ddC8FCB67FFE91900C762",
1014
1014
  "proxyFactory": "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67"
1015
1015
  }
1016
+ },
1017
+ "tokens": {
1018
+ "wsteth": "0x601aC63637933D88285A025C685AC4e9a92a98dA",
1019
+ "usdt0": "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb"
1020
+ },
1021
+ "aaveV3": {
1022
+ "pool": "0x7e324AbC5De01d112AfC03a584966ff199741C28"
1023
+ },
1024
+ "ccip": {
1025
+ "router": "0xfa546248C54939AA6C48279CdC1EAf9A1125c411"
1026
+ },
1027
+ "OFTAdapters": {
1028
+ "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb": "0x9151434b16b9763660705744891fa906f660ecc5"
1016
1029
  }
1017
1030
  }
1018
1031
  }