sally-defi-ts-sdk 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +263 -0
  3. package/dist/aio/client.d.ts +93 -0
  4. package/dist/aio/client.d.ts.map +1 -0
  5. package/dist/aio/client.js +283 -0
  6. package/dist/aio/client.js.map +1 -0
  7. package/dist/aio/index.d.ts +20 -0
  8. package/dist/aio/index.d.ts.map +1 -0
  9. package/dist/aio/index.js +19 -0
  10. package/dist/aio/index.js.map +1 -0
  11. package/dist/aio/modules/fees.d.ts +19 -0
  12. package/dist/aio/modules/fees.d.ts.map +1 -0
  13. package/dist/aio/modules/fees.js +47 -0
  14. package/dist/aio/modules/fees.js.map +1 -0
  15. package/dist/aio/modules/liquidity.d.ts +47 -0
  16. package/dist/aio/modules/liquidity.d.ts.map +1 -0
  17. package/dist/aio/modules/liquidity.js +115 -0
  18. package/dist/aio/modules/liquidity.js.map +1 -0
  19. package/dist/aio/modules/prices.d.ts +18 -0
  20. package/dist/aio/modules/prices.d.ts.map +1 -0
  21. package/dist/aio/modules/prices.js +48 -0
  22. package/dist/aio/modules/prices.js.map +1 -0
  23. package/dist/aio/modules/swap.d.ts +50 -0
  24. package/dist/aio/modules/swap.d.ts.map +1 -0
  25. package/dist/aio/modules/swap.js +267 -0
  26. package/dist/aio/modules/swap.js.map +1 -0
  27. package/dist/aio/modules/wallet.d.ts +13 -0
  28. package/dist/aio/modules/wallet.d.ts.map +1 -0
  29. package/dist/aio/modules/wallet.js +27 -0
  30. package/dist/aio/modules/wallet.js.map +1 -0
  31. package/dist/aio/token.d.ts +19 -0
  32. package/dist/aio/token.d.ts.map +1 -0
  33. package/dist/aio/token.js +50 -0
  34. package/dist/aio/token.js.map +1 -0
  35. package/dist/client.d.ts +142 -0
  36. package/dist/client.d.ts.map +1 -0
  37. package/dist/client.js +452 -0
  38. package/dist/client.js.map +1 -0
  39. package/dist/constants.d.ts +36 -0
  40. package/dist/constants.d.ts.map +1 -0
  41. package/dist/constants.js +39 -0
  42. package/dist/constants.js.map +1 -0
  43. package/dist/data/deployment.json +1 -0
  44. package/dist/deployment.d.ts +44 -0
  45. package/dist/deployment.d.ts.map +1 -0
  46. package/dist/deployment.js +118 -0
  47. package/dist/deployment.js.map +1 -0
  48. package/dist/errors.d.ts +57 -0
  49. package/dist/errors.d.ts.map +1 -0
  50. package/dist/errors.js +197 -0
  51. package/dist/errors.js.map +1 -0
  52. package/dist/index.d.ts +48 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +47 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/modules/fees.d.ts +32 -0
  57. package/dist/modules/fees.d.ts.map +1 -0
  58. package/dist/modules/fees.js +64 -0
  59. package/dist/modules/fees.js.map +1 -0
  60. package/dist/modules/liquidity.d.ts +134 -0
  61. package/dist/modules/liquidity.d.ts.map +1 -0
  62. package/dist/modules/liquidity.js +277 -0
  63. package/dist/modules/liquidity.js.map +1 -0
  64. package/dist/modules/prices.d.ts +47 -0
  65. package/dist/modules/prices.d.ts.map +1 -0
  66. package/dist/modules/prices.js +85 -0
  67. package/dist/modules/prices.js.map +1 -0
  68. package/dist/modules/swap.d.ts +102 -0
  69. package/dist/modules/swap.d.ts.map +1 -0
  70. package/dist/modules/swap.js +400 -0
  71. package/dist/modules/swap.js.map +1 -0
  72. package/dist/modules/wallet.d.ts +16 -0
  73. package/dist/modules/wallet.d.ts.map +1 -0
  74. package/dist/modules/wallet.js +30 -0
  75. package/dist/modules/wallet.js.map +1 -0
  76. package/dist/permit2.d.ts +97 -0
  77. package/dist/permit2.d.ts.map +1 -0
  78. package/dist/permit2.js +130 -0
  79. package/dist/permit2.js.map +1 -0
  80. package/dist/previews.d.ts +57 -0
  81. package/dist/previews.d.ts.map +1 -0
  82. package/dist/previews.js +69 -0
  83. package/dist/previews.js.map +1 -0
  84. package/dist/safety.d.ts +80 -0
  85. package/dist/safety.d.ts.map +1 -0
  86. package/dist/safety.js +133 -0
  87. package/dist/safety.js.map +1 -0
  88. package/dist/token.d.ts +215 -0
  89. package/dist/token.d.ts.map +1 -0
  90. package/dist/token.js +239 -0
  91. package/dist/token.js.map +1 -0
  92. package/dist/types.d.ts +229 -0
  93. package/dist/types.d.ts.map +1 -0
  94. package/dist/types.js +462 -0
  95. package/dist/types.js.map +1 -0
  96. package/dist/util.d.ts +13 -0
  97. package/dist/util.d.ts.map +1 -0
  98. package/dist/util.js +22 -0
  99. package/dist/util.js.map +1 -0
  100. package/package.json +48 -0
  101. package/src/aio/client.ts +329 -0
  102. package/src/aio/index.ts +20 -0
  103. package/src/aio/modules/fees.ts +60 -0
  104. package/src/aio/modules/liquidity.ts +181 -0
  105. package/src/aio/modules/prices.ts +57 -0
  106. package/src/aio/modules/swap.ts +347 -0
  107. package/src/aio/modules/wallet.ts +34 -0
  108. package/src/aio/token.ts +59 -0
  109. package/src/client.ts +526 -0
  110. package/src/constants.ts +43 -0
  111. package/src/data/deployment.json +1 -0
  112. package/src/deployment.ts +132 -0
  113. package/src/errors.ts +215 -0
  114. package/src/index.ts +90 -0
  115. package/src/modules/fees.ts +78 -0
  116. package/src/modules/liquidity.ts +446 -0
  117. package/src/modules/prices.ts +97 -0
  118. package/src/modules/swap.ts +502 -0
  119. package/src/modules/wallet.ts +37 -0
  120. package/src/permit2.ts +169 -0
  121. package/src/previews.ts +95 -0
  122. package/src/safety.ts +152 -0
  123. package/src/token.ts +254 -0
  124. package/src/types.ts +438 -0
  125. package/src/util.ts +20 -0
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Hybrid swaps — quote, compare, simulate, guard, execute.
3
+ *
4
+ * The high-level {@link Swap.execute} does the safe thing by default:
5
+ *
6
+ * 1. **approve** the input (exact amount, not infinite) to the swap proxy,
7
+ * 2. **enumerate** candidate routes (best / deep / per-version),
8
+ * 3. **integrity-check** each so funds can never enter a wrong/mismatched pool,
9
+ * 4. **simulate** every candidate on-chain (`eth_call` of the real
10
+ * `executeHybridSwap`, which returns the realized output) and pick the best,
11
+ * 5. **honeypot/tax preflight** the output token via the `getTokenInfos` probe,
12
+ * 6. set `minOut` from the *simulated* output and a slippage floor,
13
+ * 7. send, then **assert the received balance grew by >= minOut** (trust the chain).
14
+ *
15
+ * Use {@link Swap.plan} to get the same vetted {@link SwapPlan} without sending.
16
+ */
17
+ import type { SallyClient } from "../client.js";
18
+ import { RouteCandidate, SafetyConfig, SwapPlan } from "../safety.js";
19
+ import { SwapPath, TokenInfo } from "../types.js";
20
+ export interface ExecuteOptions {
21
+ slippageBps?: number | null;
22
+ minOutput?: bigint | null;
23
+ path?: SwapPath | null;
24
+ referral?: string;
25
+ deadline?: number | null;
26
+ config?: SafetyConfig | null;
27
+ approval?: "approve" | "permit" | "none";
28
+ force?: boolean;
29
+ buildOnly?: boolean;
30
+ tx?: Record<string, any>;
31
+ }
32
+ export declare class Swap {
33
+ private _c;
34
+ private _swap;
35
+ private _wnative;
36
+ constructor(client: SallyClient);
37
+ private _a;
38
+ wnative(): Promise<string>;
39
+ /** Best cross-version route for `amountIn`. `getBestSwapPath`. */
40
+ quote(tokenIn: string, tokenOut: string, amountIn: bigint): Promise<SwapPath>;
41
+ quoteV2(tokenIn: string, tokenOut: string, amountIn: bigint): Promise<SwapPath>;
42
+ quoteV3(tokenIn: string, tokenOut: string, amountIn: bigint): Promise<SwapPath>;
43
+ quoteV4(tokenIn: string, tokenOut: string, amountIn: bigint): Promise<SwapPath>;
44
+ /** Deeper, more exhaustive route search. `getBestSwapPathDeep` (Lens). */
45
+ quoteDeep(tokenIn: string, tokenOut: string, amountIn: bigint): Promise<SwapPath>;
46
+ /** Honeypot / buy-sell-tax round-trip probe. `getTokenInfos`. */
47
+ tokenInfo(token: string, opts?: {
48
+ probeValue?: bigint | null;
49
+ }): Promise<TokenInfo>;
50
+ perHopSlippageBps(): Promise<number>;
51
+ /** Stablecoins the protocol prices against. `getUsdStables`. */
52
+ usdStables(): Promise<string[]>;
53
+ poolManagerV4(): Promise<string>;
54
+ /**
55
+ * Slippage floor: `amountOut * (1 - bps/10000)`.
56
+ *
57
+ * Clamped to >= 1 when the output is positive, so integer flooring on a tiny
58
+ * output can never produce `minOut == 0` (which would disable the on-chain
59
+ * slippage guard and expose the swap to a 100% sandwich).
60
+ */
61
+ static minOut(amountOut: bigint | SwapPath | null, slippageBps: number): bigint;
62
+ minOut(amountOut: bigint | SwapPath | null, slippageBps: number): bigint;
63
+ deadline(secs?: number | null): number;
64
+ /** All distinct quoted routes (best / deep / per-version), deduped by pools. */
65
+ candidates(tokenIn: string, tokenOut: string, amountIn: bigint): Promise<RouteCandidate[]>;
66
+ /**
67
+ * `eth_call` the real `executeHybridSwap` and return realized output.
68
+ *
69
+ * Returns `null` if the route reverts. Requires `sender` to hold the input
70
+ * token + allowance (or `value` for native in) — exactly what `execute`
71
+ * arranges before planning.
72
+ */
73
+ simulateRoute(route: SwapPath, amountIn: bigint, opts?: {
74
+ value?: bigint;
75
+ sender?: string | null;
76
+ }): Promise<bigint | null>;
77
+ /** Impact vs the marginal (small-trade) price, in bps. null if unknown. */
78
+ private _priceImpactBps;
79
+ /**
80
+ * Honeypot/tax probe on the output token + price-impact check.
81
+ *
82
+ * Returns `[tokenSafety, priceImpactBps, blockReasons, warnings]`. Shared by
83
+ * `plan` and the supplied-path branch of `execute` so neither is a safety bypass.
84
+ */
85
+ private _safetyPreflight;
86
+ /** Build a fully-vetted {@link SwapPlan} without sending anything. */
87
+ plan(tokenIn: string, tokenOut: string, amountIn: bigint, opts?: {
88
+ slippageBps?: number | null;
89
+ config?: SafetyConfig | null;
90
+ sender?: string | null;
91
+ }): Promise<SwapPlan>;
92
+ /**
93
+ * Plan (vet + simulate), enforce guards, send, verify balance delta.
94
+ *
95
+ * `approval`: `"approve"` (default, exact-amount ERC-20 approve), `"permit"`
96
+ * (EIP-2612 signature where supported, else approve), or `"none"` (assume
97
+ * allowance already set). With `buildOnly=true` nothing is sent: returns a
98
+ * {@link SwapBuild}. Set `force=true` to bypass safety blocks (NOT recommended).
99
+ */
100
+ execute(tokenIn: string, tokenOut: string, amountIn: bigint, opts?: ExecuteOptions): Promise<any>;
101
+ }
102
+ //# sourceMappingURL=swap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../../src/modules/swap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEtE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAKlD,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC1B;AAED,qBAAa,IAAI;IACf,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,MAAM,EAAE,WAAW;IAK/B,OAAO,CAAC,EAAE;IAIJ,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAQhC,kEAAkE;IAC5D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAM7E,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAM/E,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAM/E,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAMrF,0EAA0E;IACpE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAWvF,iEAAiE;IAC3D,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAWvF,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAI1C,gEAAgE;IAC1D,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAK/B,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAKtC;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;IAM/E,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;IAIxE,QAAQ,CAAC,IAAI,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM;IAO5C,gFAAgF;IAC1E,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAiChG;;;;;;OAMG;IACG,aAAa,CACjB,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAO,GACpD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAmBzB,2EAA2E;YAC7D,eAAe;IAoB7B;;;;;OAKG;YACW,gBAAgB;IAmC9B,sEAAsE;IAChE,IAAI,CACR,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAO,GAC/F,OAAO,CAAC,QAAQ,CAAC;IAsEpB;;;;;;;OAOG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,GAAG,CAAC;CA6I5G"}
@@ -0,0 +1,400 @@
1
+ /**
2
+ * Hybrid swaps — quote, compare, simulate, guard, execute.
3
+ *
4
+ * The high-level {@link Swap.execute} does the safe thing by default:
5
+ *
6
+ * 1. **approve** the input (exact amount, not infinite) to the swap proxy,
7
+ * 2. **enumerate** candidate routes (best / deep / per-version),
8
+ * 3. **integrity-check** each so funds can never enter a wrong/mismatched pool,
9
+ * 4. **simulate** every candidate on-chain (`eth_call` of the real
10
+ * `executeHybridSwap`, which returns the realized output) and pick the best,
11
+ * 5. **honeypot/tax preflight** the output token via the `getTokenInfos` probe,
12
+ * 6. set `minOut` from the *simulated* output and a slippage floor,
13
+ * 7. send, then **assert the received balance grew by >= minOut** (trust the chain).
14
+ *
15
+ * Use {@link Swap.plan} to get the same vetted {@link SwapPlan} without sending.
16
+ */
17
+ import { getAddress } from "ethers";
18
+ import { SallyError, SallyRouteError, SallySafetyError } from "../errors.js";
19
+ import { RouteCandidate, SafetyConfig, SwapPlan } from "../safety.js";
20
+ import { MAX_UINT256, ZERO, isNative } from "../token.js";
21
+ import { SwapPath, TokenInfo } from "../types.js";
22
+ import { pyRound } from "../util.js";
23
+ const MAX_DEADLINE = 2n ** 256n - 1n;
24
+ export class Swap {
25
+ _c;
26
+ _swap;
27
+ _wnative = null;
28
+ constructor(client) {
29
+ this._c = client;
30
+ this._swap = client.swapContract;
31
+ }
32
+ _a(x) {
33
+ return getAddress(x);
34
+ }
35
+ async wnative() {
36
+ if (this._wnative === null) {
37
+ this._wnative = String(await this._c.call(this._swap.getFunction("wnative"), []));
38
+ }
39
+ return this._wnative;
40
+ }
41
+ // -- quoting ----------------------------------------------------------- //
42
+ /** Best cross-version route for `amountIn`. `getBestSwapPath`. */
43
+ async quote(tokenIn, tokenOut, amountIn) {
44
+ return SwapPath.fromRaw(await this._c.call(this._swap.getFunction("getBestSwapPath"), [this._a(tokenIn), this._a(tokenOut), amountIn]));
45
+ }
46
+ async quoteV2(tokenIn, tokenOut, amountIn) {
47
+ return SwapPath.fromRaw(await this._c.call(this._swap.getFunction("getSwapPathV2"), [this._a(tokenIn), this._a(tokenOut), amountIn]));
48
+ }
49
+ async quoteV3(tokenIn, tokenOut, amountIn) {
50
+ return SwapPath.fromRaw(await this._c.call(this._swap.getFunction("getSwapPathV3"), [this._a(tokenIn), this._a(tokenOut), amountIn]));
51
+ }
52
+ async quoteV4(tokenIn, tokenOut, amountIn) {
53
+ return SwapPath.fromRaw(await this._c.call(this._swap.getFunction("getSwapPathV4"), [this._a(tokenIn), this._a(tokenOut), amountIn]));
54
+ }
55
+ /** Deeper, more exhaustive route search. `getBestSwapPathDeep` (Lens). */
56
+ async quoteDeep(tokenIn, tokenOut, amountIn) {
57
+ return SwapPath.fromRaw(await this._c.call(this._c.lensContract.getFunction("getBestSwapPathDeep"), [
58
+ this._a(tokenIn),
59
+ this._a(tokenOut),
60
+ amountIn,
61
+ ]));
62
+ }
63
+ // -- token safety probe ------------------------------------------------ //
64
+ /** Honeypot / buy-sell-tax round-trip probe. `getTokenInfos`. */
65
+ async tokenInfo(token, opts = {}) {
66
+ let probeValue = opts.probeValue ?? null;
67
+ if (probeValue === null)
68
+ probeValue = new SafetyConfig().probeValue;
69
+ const raw = await this._swap.getFunction("getTokenInfos").staticCall(this._a(token), {
70
+ from: ZERO,
71
+ value: probeValue,
72
+ });
73
+ return TokenInfo.fromRaw(raw);
74
+ }
75
+ // -- protocol config reads -------------------------------------------- //
76
+ async perHopSlippageBps() {
77
+ return Number(await this._c.call(this._swap.getFunction("perHopSlippageBps"), []));
78
+ }
79
+ /** Stablecoins the protocol prices against. `getUsdStables`. */
80
+ async usdStables() {
81
+ const r = await this._c.call(this._swap.getFunction("getUsdStables"), []);
82
+ return [...r].map((a) => String(a));
83
+ }
84
+ async poolManagerV4() {
85
+ return String(await this._c.call(this._swap.getFunction("poolManagerV4"), []));
86
+ }
87
+ // -- helpers ----------------------------------------------------------- //
88
+ /**
89
+ * Slippage floor: `amountOut * (1 - bps/10000)`.
90
+ *
91
+ * Clamped to >= 1 when the output is positive, so integer flooring on a tiny
92
+ * output can never produce `minOut == 0` (which would disable the on-chain
93
+ * slippage guard and expose the swap to a 100% sandwich).
94
+ */
95
+ static minOut(amountOut, slippageBps) {
96
+ const out = amountOut instanceof SwapPath ? amountOut.estimatedAmountOut : (amountOut ?? 0n);
97
+ const floor = (out * BigInt(10_000 - slippageBps)) / 10000n;
98
+ return out > 0n ? (floor > 1n ? floor : 1n) : 0n;
99
+ }
100
+ minOut(amountOut, slippageBps) {
101
+ return Swap.minOut(amountOut, slippageBps);
102
+ }
103
+ deadline(secs = null) {
104
+ // Wall-clock based (like the Uniswap SDK): robust even if the node reports a
105
+ // stale `latest` block while mining ahead.
106
+ const s = secs !== null ? secs : new SafetyConfig().deadlineSecs;
107
+ return Math.floor(Date.now() / 1000) + s;
108
+ }
109
+ /** All distinct quoted routes (best / deep / per-version), deduped by pools. */
110
+ async candidates(tokenIn, tokenOut, amountIn) {
111
+ tokenIn = this._a(tokenIn);
112
+ tokenOut = this._a(tokenOut);
113
+ const out = [];
114
+ const seen = new Set();
115
+ const fns = [
116
+ ["best", (a, b, c) => this.quote(a, b, c)],
117
+ ["deep", (a, b, c) => this.quoteDeep(a, b, c)],
118
+ ["v2", (a, b, c) => this.quoteV2(a, b, c)],
119
+ ["v3", (a, b, c) => this.quoteV3(a, b, c)],
120
+ ["v4", (a, b, c) => this.quoteV4(a, b, c)],
121
+ ];
122
+ for (const [label, fn] of fns) {
123
+ let route;
124
+ try {
125
+ route = await fn(tokenIn, tokenOut, amountIn);
126
+ }
127
+ catch (exc) {
128
+ if (exc instanceof SallyError)
129
+ continue;
130
+ throw exc;
131
+ }
132
+ if (route.stepCount === 0)
133
+ continue;
134
+ const key = JSON.stringify([
135
+ route.poolAddresses.map((p) => p.toLowerCase()),
136
+ route.stepCount,
137
+ route.estimatedAmountOut.toString(),
138
+ ]);
139
+ if (seen.has(key))
140
+ continue;
141
+ seen.add(key);
142
+ out.push(new RouteCandidate(label, route, route.estimatedAmountOut));
143
+ }
144
+ return out;
145
+ }
146
+ /**
147
+ * `eth_call` the real `executeHybridSwap` and return realized output.
148
+ *
149
+ * Returns `null` if the route reverts. Requires `sender` to hold the input
150
+ * token + allowance (or `value` for native in) — exactly what `execute`
151
+ * arranges before planning.
152
+ */
153
+ async simulateRoute(route, amountIn, opts = {}) {
154
+ const value = opts.value ?? 0n;
155
+ const sender = opts.sender ?? this._c.address;
156
+ if (sender == null)
157
+ return null;
158
+ try {
159
+ const r = await this._swap.getFunction("executeHybridSwap").staticCall(route.toTuple(), amountIn, 0, MAX_DEADLINE, ZERO, { from: sender, value });
160
+ return BigInt(r);
161
+ }
162
+ catch {
163
+ return null;
164
+ }
165
+ }
166
+ /** Impact vs the marginal (small-trade) price, in bps. null if unknown. */
167
+ async _priceImpactBps(tokenIn, tokenOut, amountIn, realized) {
168
+ const probe = amountIn / 1000n > 1n ? amountIn / 1000n : 1n;
169
+ let probeOut;
170
+ try {
171
+ probeOut = (await this.quote(tokenIn, tokenOut, probe)).estimatedAmountOut;
172
+ }
173
+ catch (exc) {
174
+ if (exc instanceof SallyError)
175
+ return null;
176
+ throw exc;
177
+ }
178
+ if (probeOut <= 0n || realized <= 0n)
179
+ return null;
180
+ const expected = (probeOut * amountIn) / probe;
181
+ if (expected <= 0n)
182
+ return null;
183
+ return Math.max(0, pyRound((Number(expected - realized) / Number(expected)) * 10_000));
184
+ }
185
+ /**
186
+ * Honeypot/tax probe on the output token + price-impact check.
187
+ *
188
+ * Returns `[tokenSafety, priceImpactBps, blockReasons, warnings]`. Shared by
189
+ * `plan` and the supplied-path branch of `execute` so neither is a safety bypass.
190
+ */
191
+ async _safetyPreflight(quoteIn, tokenOut, amountIn, realized, cfg) {
192
+ const blocks = [];
193
+ const warns = [];
194
+ let safety = null;
195
+ if (cfg.checkHoneypot && !isNative(tokenOut)) {
196
+ try {
197
+ safety = await this.tokenInfo(tokenOut, { probeValue: cfg.probeValue });
198
+ }
199
+ catch {
200
+ safety = null;
201
+ }
202
+ if (safety !== null && safety.buySuccess) {
203
+ if (safety.isHoneypot)
204
+ blocks.push("honeypot");
205
+ const tax = Math.max(safety.buyTaxBps, safety.sellTaxBps);
206
+ if (tax >= cfg.taxBlockBps)
207
+ blocks.push(`tax_${tax}bps`);
208
+ else if (tax >= cfg.taxWarnBps)
209
+ warns.push(`high_tax_${tax}bps`);
210
+ }
211
+ else {
212
+ warns.push("safety_probe_unavailable");
213
+ }
214
+ }
215
+ const impact = await this._priceImpactBps(quoteIn, tokenOut, amountIn, realized);
216
+ if (impact !== null) {
217
+ if (impact >= cfg.priceImpactBlockBps)
218
+ blocks.push(`price_impact_${impact}bps`);
219
+ else if (impact >= cfg.priceImpactWarnBps)
220
+ warns.push(`price_impact_${impact}bps`);
221
+ }
222
+ return [safety, impact, blocks, warns];
223
+ }
224
+ // -- planning ---------------------------------------------------------- //
225
+ /** Build a fully-vetted {@link SwapPlan} without sending anything. */
226
+ async plan(tokenIn, tokenOut, amountIn, opts = {}) {
227
+ const cfg = opts.config ?? this._c.safety;
228
+ const slippageBps = opts.slippageBps == null ? cfg.slippageBps : opts.slippageBps;
229
+ tokenIn = this._a(tokenIn);
230
+ tokenOut = this._a(tokenOut);
231
+ const nativeIn = isNative(tokenIn);
232
+ const value = nativeIn ? amountIn : 0n;
233
+ const sender = opts.sender ?? this._c.address;
234
+ const wnative = await this.wnative();
235
+ // Routes are quoted in wrapped-native terms; the contract wraps the native
236
+ // value itself at execution. Integrity still maps the native sentinel back.
237
+ const quoteIn = nativeIn ? this._a(wnative) : tokenIn;
238
+ const cands = await this.candidates(quoteIn, tokenOut, amountIn);
239
+ if (cands.length === 0) {
240
+ throw new SallyError(`No route found ${tokenIn} -> ${tokenOut} for ${amountIn}`);
241
+ }
242
+ // integrity — guards against funds entering the wrong pool
243
+ if (cfg.checkIntegrity) {
244
+ for (const c of cands) {
245
+ c.integrityProblems = c.route.checkIntegrity(tokenIn, tokenOut, wnative);
246
+ }
247
+ }
248
+ // simulate each usable candidate end-to-end
249
+ if (cfg.simulate && sender != null) {
250
+ for (const c of cands) {
251
+ if (c.usable) {
252
+ c.simulatedOut = await this.simulateRoute(c.route, amountIn, { value, sender });
253
+ }
254
+ }
255
+ }
256
+ const usable = cands.filter((c) => c.usable);
257
+ const pool = usable.length ? usable : cands;
258
+ const best = pool.reduce((a, b) => (b.score > a.score ? b : a));
259
+ const blockReasons = [];
260
+ const warnings = [];
261
+ if (usable.length === 0)
262
+ blockReasons.push("no_valid_route");
263
+ if (best.integrityProblems.length) {
264
+ blockReasons.push("integrity");
265
+ warnings.push(...best.integrityProblems);
266
+ }
267
+ const realized = best.score;
268
+ const [safety, impact, sblocks, swarns] = await this._safetyPreflight(quoteIn, tokenOut, amountIn, realized, cfg);
269
+ blockReasons.push(...sblocks);
270
+ warnings.push(...swarns);
271
+ return new SwapPlan(tokenIn, tokenOut, amountIn, best.route, best.quotedOut, best.simulatedOut, this.minOut(realized, slippageBps), impact, safety, cands, warnings, blockReasons);
272
+ }
273
+ // -- execution --------------------------------------------------------- //
274
+ /**
275
+ * Plan (vet + simulate), enforce guards, send, verify balance delta.
276
+ *
277
+ * `approval`: `"approve"` (default, exact-amount ERC-20 approve), `"permit"`
278
+ * (EIP-2612 signature where supported, else approve), or `"none"` (assume
279
+ * allowance already set). With `buildOnly=true` nothing is sent: returns a
280
+ * {@link SwapBuild}. Set `force=true` to bypass safety blocks (NOT recommended).
281
+ */
282
+ async execute(tokenIn, tokenOut, amountIn, opts = {}) {
283
+ let cfg = opts.config ?? this._c.safety;
284
+ const referral = opts.referral ?? ZERO;
285
+ const approval = opts.approval ?? "approve";
286
+ const force = opts.force ?? false;
287
+ const buildOnly = opts.buildOnly ?? false;
288
+ const txOpts = opts.tx ?? {};
289
+ const me = this._c.requireAddress();
290
+ tokenIn = this._a(tokenIn);
291
+ tokenOut = this._a(tokenOut);
292
+ const nativeIn = isNative(tokenIn);
293
+ const value = nativeIn ? amountIn : 0n;
294
+ const wnative = await this.wnative();
295
+ // 1) authorise the input first so the simulation's transferFrom succeeds.
296
+ let approveTx = null;
297
+ let needsApproval = false;
298
+ if (!nativeIn && approval !== "none") {
299
+ const spender = this._c.addresses["swap"];
300
+ const amount = cfg.unlimitedApproval ? MAX_UINT256 : amountIn;
301
+ const tok = this._c.token(tokenIn);
302
+ if (buildOnly) {
303
+ // Don't send: build the unsigned approve tx if allowance is short.
304
+ if ((await tok.allowance(me, spender)) < amount) {
305
+ needsApproval = true;
306
+ approveTx = await tok.buildApprove(spender, amount);
307
+ // The swap eth_call can't pull tokens yet → vet via quote, not sim.
308
+ cfg = cfg.replace({ simulate: false });
309
+ }
310
+ }
311
+ else {
312
+ let usedPermit = false;
313
+ if (approval === "permit" && (await tok.supportsPermit())) {
314
+ if ((await tok.allowance(me, spender)) < amount) {
315
+ try {
316
+ await tok.permit(spender, amount);
317
+ usedPermit = true;
318
+ }
319
+ catch {
320
+ // Some tokens advertise nonces but reject EIP-2612 permits
321
+ // (non-standard impls). Fall back to a plain approve.
322
+ usedPermit = false;
323
+ }
324
+ }
325
+ else {
326
+ usedPermit = true;
327
+ }
328
+ }
329
+ if (!usedPermit) {
330
+ await tok.ensureAllowance(spender, amount);
331
+ }
332
+ }
333
+ }
334
+ // 2) plan (unless a fixed path was supplied)
335
+ let plan;
336
+ if (opts.path == null) {
337
+ plan = await this.plan(tokenIn, tokenOut, amountIn, {
338
+ slippageBps: opts.slippageBps ?? null,
339
+ config: cfg,
340
+ });
341
+ }
342
+ else {
343
+ const path = opts.path;
344
+ const problems = cfg.checkIntegrity ? path.checkIntegrity(tokenIn, tokenOut, wnative) : [];
345
+ if (problems.length && !force) {
346
+ throw new SallyRouteError(`supplied path failed integrity: ${problems}`);
347
+ }
348
+ const sim = cfg.simulate ? await this.simulateRoute(path, amountIn, { value }) : null;
349
+ const sb = opts.slippageBps != null ? opts.slippageBps : cfg.slippageBps;
350
+ // If we simulated and the supplied path REVERTS, block — do not fall back
351
+ // to the caller's unvalidated quote (which could set minOut to 0).
352
+ const reasons = problems.length ? ["integrity"] : [];
353
+ if (cfg.simulate && sim === null)
354
+ reasons.push("no_valid_route");
355
+ const floor = sim !== null ? this.minOut(sim, sb) : this.minOut(path, sb);
356
+ // A zero floor disables the on-chain slippage guard — block regardless of
357
+ // which safety toggles are off.
358
+ if (floor === 0n)
359
+ reasons.push("zero_min_out");
360
+ // Run the SAME honeypot/tax + price-impact preflight as plan().
361
+ const quoteIn = nativeIn ? this._a(wnative) : tokenIn;
362
+ const realized = sim !== null ? sim : path.estimatedAmountOut;
363
+ const [safety, impact, sblocks, swarns] = await this._safetyPreflight(quoteIn, tokenOut, amountIn, realized, cfg);
364
+ plan = new SwapPlan(tokenIn, tokenOut, amountIn, path, path.estimatedAmountOut, sim, floor, impact, safety, [], swarns, [...reasons, ...sblocks]);
365
+ }
366
+ // 3) enforce guards
367
+ if (!plan.isSafe && !force) {
368
+ if (plan.blockReasons.includes("integrity") || plan.blockReasons.includes("no_valid_route")) {
369
+ throw new SallyRouteError(`route rejected: ${plan.blockReasons} ${plan.warnings}`);
370
+ }
371
+ throw new SallySafetyError(`swap blocked: ${plan.blockReasons}`, plan.blockReasons);
372
+ }
373
+ const minOut = opts.minOutput != null ? opts.minOutput : plan.minOut;
374
+ const deadline = opts.deadline != null ? opts.deadline : this.deadline(cfg.deadlineSecs);
375
+ // 4) balance-delta baseline (ERC-20 out only). Skip for native AND wrapped-
376
+ // native out: Sally may pay out unwrapped native, so an ERC-20 balanceOf
377
+ // would not move — the contract's own minOut guard still protects there.
378
+ const track = !isNative(tokenOut) && tokenOut.toLowerCase() !== wnative.toLowerCase();
379
+ const before = track ? await this._c.token(tokenOut).balanceOf(me) : 0n;
380
+ // 5) build the chosen, vetted route
381
+ const fn = this._swap.getFunction("executeHybridSwap");
382
+ const args = [plan.route.toTuple(), amountIn, minOut, deadline, this._a(referral)];
383
+ if (buildOnly) {
384
+ // Sign-externally: return the vetted plan + unsigned txs, send nothing.
385
+ const { SwapBuild } = await import("../previews.js");
386
+ const swapTx = await this._c.send(fn, args, { value, simulate: false, buildOnly: true });
387
+ return new SwapBuild({ plan, swapTx, approveTx, needsApproval });
388
+ }
389
+ const receipt = await this._c.send(fn, args, { value, ...txOpts });
390
+ // 6) trust the chain: received balance must have grown by >= minOut
391
+ if (track && cfg.balanceDeltaAssert) {
392
+ const gained = (await this._c.token(tokenOut).balanceOf(me)) - before;
393
+ if (gained < minOut) {
394
+ throw new SallySafetyError(`received ${gained} < min_out ${minOut} (balance-delta check failed)`, ["balance_delta"]);
395
+ }
396
+ }
397
+ return receipt;
398
+ }
399
+ }
400
+ //# sourceMappingURL=swap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swap.js","sourceRoot":"","sources":["../../src/modules/swap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /** Wallet balance reads with live USD valuation (Lens via swap proxy). */
2
+ import type { SallyClient } from "../client.js";
3
+ import { WalletBalance } from "../types.js";
4
+ export declare class Wallet {
5
+ private _c;
6
+ private _lens;
7
+ constructor(client: SallyClient);
8
+ private _addrs;
9
+ /** Balances + USD value for `tokens`. `getWalletBalance`. */
10
+ balances(wallet: string, tokens: string[]): Promise<WalletBalance[]>;
11
+ /** Same but the gas-lean variant. `getWalletBalanceRaw`. */
12
+ balancesRaw(wallet: string, tokens: string[]): Promise<WalletBalance[]>;
13
+ /** Sum of USD value across `tokens` (float, human units). */
14
+ totalUsd(wallet: string, tokens: string[]): Promise<number>;
15
+ }
16
+ //# sourceMappingURL=wallet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/modules/wallet.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAG1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,qBAAa,MAAM;IACjB,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,KAAK,CAAW;gBAEZ,MAAM,EAAE,WAAW;IAK/B,OAAO,CAAC,MAAM;IAId,6DAA6D;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAK1E,4DAA4D;IACtD,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAK7E,6DAA6D;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAIlE"}
@@ -0,0 +1,30 @@
1
+ /** Wallet balance reads with live USD valuation (Lens via swap proxy). */
2
+ import { getAddress } from "ethers";
3
+ import { WalletBalance } from "../types.js";
4
+ export class Wallet {
5
+ _c;
6
+ _lens;
7
+ constructor(client) {
8
+ this._c = client;
9
+ this._lens = client.lensContract;
10
+ }
11
+ _addrs(tokens) {
12
+ return tokens.map((t) => getAddress(t));
13
+ }
14
+ /** Balances + USD value for `tokens`. `getWalletBalance`. */
15
+ async balances(wallet, tokens) {
16
+ const r = await this._c.call(this._lens.getFunction("getWalletBalance"), [getAddress(wallet), this._addrs(tokens)]);
17
+ return [...r].map((x) => WalletBalance.fromRaw(x));
18
+ }
19
+ /** Same but the gas-lean variant. `getWalletBalanceRaw`. */
20
+ async balancesRaw(wallet, tokens) {
21
+ const r = await this._c.call(this._lens.getFunction("getWalletBalanceRaw"), [getAddress(wallet), this._addrs(tokens)]);
22
+ return [...r].map((x) => WalletBalance.fromRaw(x));
23
+ }
24
+ /** Sum of USD value across `tokens` (float, human units). */
25
+ async totalUsd(wallet, tokens) {
26
+ const bals = await this.balances(wallet, tokens);
27
+ return bals.reduce((acc, b) => acc + b.usdValueFloat, 0);
28
+ }
29
+ }
30
+ //# sourceMappingURL=wallet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../src/modules/wallet.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAE1E,OAAO,EAAY,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,MAAM;IACT,EAAE,CAAc;IAChB,KAAK,CAAW;IAExB,YAAY,MAAmB;QAC7B,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC;IACnC,CAAC;IAEO,MAAM,CAAC,MAAgB;QAC7B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,6DAA6D;IAC7D,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,MAAgB;QAC7C,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,kBAAkB,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACpH,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,MAAgB;QAChD,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,qBAAqB,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACvH,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,6DAA6D;IAC7D,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,MAAgB;QAC7C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;CACF"}