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,97 @@
1
+ /**
2
+ * Permit2 + EIP-2612 signature approvals.
3
+ *
4
+ * Two distinct things live here:
5
+ *
6
+ * - **EIP-2612** (`signPermit2612`) — the token-native `permit(owner,spender,
7
+ * value,nonce,deadline,v,r,s)`. Used by {@link Token.permit} so a swap can
8
+ * authorise the proxy with a *signature* instead of a separate `approve` tx, on
9
+ * tokens that support it (USDC, DAI-family wrappers, many others).
10
+ *
11
+ * - **Permit2** (`Permit2`, `0x000000000022D473030F116dDEE9F6B43aC78BA3`) —
12
+ * Uniswap's universal approval contract. Sally's controller uses it
13
+ * *internally* for the V4 PositionManager pull; user swaps do not require it.
14
+ *
15
+ * Both produce EIP-712 signatures via ethers; nothing is broadcast here.
16
+ */
17
+ import { Contract, type Signer } from "ethers";
18
+ import type { SallyClient } from "./client.js";
19
+ export declare const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
20
+ export declare const MAX_UINT160: bigint;
21
+ export declare const MAX_UINT48: bigint;
22
+ /** Sign an EIP-2612 `Permit` and return `[v, r, s]` (v number, r/s 0x-hex bytes32). */
23
+ export declare function signPermit2612(account: Signer, opts: {
24
+ token: string;
25
+ tokenName: string;
26
+ version: string;
27
+ chainId: number;
28
+ owner: string;
29
+ spender: string;
30
+ value: bigint;
31
+ nonce: number;
32
+ deadline: number;
33
+ }): Promise<[number, string, string]>;
34
+ /** Sign a Permit2 `PermitSingle` and return the 65-byte signature (0x-hex). */
35
+ export declare function signPermitSingle(account: Signer, opts: {
36
+ chainId: number;
37
+ token: string;
38
+ spender: string;
39
+ amount: bigint;
40
+ expiration: number | bigint;
41
+ nonce: number | bigint;
42
+ sigDeadline: number | bigint;
43
+ }): Promise<string>;
44
+ export declare const PERMIT2_ABI: readonly [{
45
+ readonly name: "allowance";
46
+ readonly type: "function";
47
+ readonly stateMutability: "view";
48
+ readonly inputs: readonly [{
49
+ readonly name: "user";
50
+ readonly type: "address";
51
+ }, {
52
+ readonly name: "token";
53
+ readonly type: "address";
54
+ }, {
55
+ readonly name: "spender";
56
+ readonly type: "address";
57
+ }];
58
+ readonly outputs: readonly [{
59
+ readonly name: "amount";
60
+ readonly type: "uint160";
61
+ }, {
62
+ readonly name: "expiration";
63
+ readonly type: "uint48";
64
+ }, {
65
+ readonly name: "nonce";
66
+ readonly type: "uint48";
67
+ }];
68
+ }, {
69
+ readonly name: "approve";
70
+ readonly type: "function";
71
+ readonly stateMutability: "nonpayable";
72
+ readonly inputs: readonly [{
73
+ readonly name: "token";
74
+ readonly type: "address";
75
+ }, {
76
+ readonly name: "spender";
77
+ readonly type: "address";
78
+ }, {
79
+ readonly name: "amount";
80
+ readonly type: "uint160";
81
+ }, {
82
+ readonly name: "expiration";
83
+ readonly type: "uint48";
84
+ }];
85
+ readonly outputs: readonly [];
86
+ }];
87
+ /** Thin helper around the canonical Permit2 contract for advanced flows. */
88
+ export declare class Permit2 {
89
+ private _c;
90
+ readonly address: string;
91
+ readonly contract: Contract;
92
+ constructor(client: SallyClient);
93
+ allowance(owner: string, token: string, spender: string): Promise<[bigint, number, number]>;
94
+ /** On-chain `Permit2.approve` (after the token is approved to Permit2). */
95
+ approveToken(token: string, spender: string, amount?: bigint, expiration?: bigint, tx?: Record<string, any>): Promise<any>;
96
+ }
97
+ //# sourceMappingURL=permit2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permit2.d.ts","sourceRoot":"","sources":["../src/permit2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,QAAQ,EAAyB,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,eAAO,MAAM,eAAe,+CAA+C,CAAC;AAC5E,eAAO,MAAM,WAAW,QAAkB,CAAC;AAC3C,eAAO,MAAM,UAAU,QAAiB,CAAC;AAKzC,uFAAuF;AACvF,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;IACJ,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,GACA,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CA0BnC;AAKD,+EAA+E;AAC/E,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;IACJ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;CAC9B,GACA,OAAO,CAAC,MAAM,CAAC,CA8BjB;AAGD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBd,CAAC;AAEX,4EAA4E;AAC5E,qBAAa,OAAO;IAClB,OAAO,CAAC,EAAE,CAAc;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;gBAEhB,MAAM,EAAE,WAAW;IAMzB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAKjG,2EAA2E;IACrE,YAAY,CAChB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAoB,EAC5B,UAAU,GAAE,MAAmB,EAC/B,EAAE,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAC3B,OAAO,CAAC,GAAG,CAAC;CAIhB"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Permit2 + EIP-2612 signature approvals.
3
+ *
4
+ * Two distinct things live here:
5
+ *
6
+ * - **EIP-2612** (`signPermit2612`) — the token-native `permit(owner,spender,
7
+ * value,nonce,deadline,v,r,s)`. Used by {@link Token.permit} so a swap can
8
+ * authorise the proxy with a *signature* instead of a separate `approve` tx, on
9
+ * tokens that support it (USDC, DAI-family wrappers, many others).
10
+ *
11
+ * - **Permit2** (`Permit2`, `0x000000000022D473030F116dDEE9F6B43aC78BA3`) —
12
+ * Uniswap's universal approval contract. Sally's controller uses it
13
+ * *internally* for the V4 PositionManager pull; user swaps do not require it.
14
+ *
15
+ * Both produce EIP-712 signatures via ethers; nothing is broadcast here.
16
+ */
17
+ import { Contract, getAddress, Signature } from "ethers";
18
+ // Canonical Permit2, identical on every EVM chain (CREATE2).
19
+ export const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
20
+ export const MAX_UINT160 = 2n ** 160n - 1n;
21
+ export const MAX_UINT48 = 2n ** 48n - 1n;
22
+ // --------------------------------------------------------------------------- //
23
+ // EIP-2612
24
+ // --------------------------------------------------------------------------- //
25
+ /** Sign an EIP-2612 `Permit` and return `[v, r, s]` (v number, r/s 0x-hex bytes32). */
26
+ export async function signPermit2612(account, opts) {
27
+ const domain = {
28
+ name: opts.tokenName,
29
+ version: opts.version,
30
+ chainId: opts.chainId,
31
+ verifyingContract: getAddress(opts.token),
32
+ };
33
+ const types = {
34
+ Permit: [
35
+ { name: "owner", type: "address" },
36
+ { name: "spender", type: "address" },
37
+ { name: "value", type: "uint256" },
38
+ { name: "nonce", type: "uint256" },
39
+ { name: "deadline", type: "uint256" },
40
+ ],
41
+ };
42
+ const message = {
43
+ owner: getAddress(opts.owner),
44
+ spender: getAddress(opts.spender),
45
+ value: opts.value,
46
+ nonce: opts.nonce,
47
+ deadline: opts.deadline,
48
+ };
49
+ const sig = await account.signTypedData(domain, types, message);
50
+ const split = Signature.from(sig);
51
+ return [split.v, split.r, split.s];
52
+ }
53
+ // --------------------------------------------------------------------------- //
54
+ // Permit2 (AllowanceTransfer — PermitSingle)
55
+ // --------------------------------------------------------------------------- //
56
+ /** Sign a Permit2 `PermitSingle` and return the 65-byte signature (0x-hex). */
57
+ export async function signPermitSingle(account, opts) {
58
+ const domain = {
59
+ name: "Permit2",
60
+ chainId: opts.chainId,
61
+ verifyingContract: PERMIT2_ADDRESS,
62
+ };
63
+ const types = {
64
+ PermitDetails: [
65
+ { name: "token", type: "address" },
66
+ { name: "amount", type: "uint160" },
67
+ { name: "expiration", type: "uint48" },
68
+ { name: "nonce", type: "uint48" },
69
+ ],
70
+ PermitSingle: [
71
+ { name: "details", type: "PermitDetails" },
72
+ { name: "spender", type: "address" },
73
+ { name: "sigDeadline", type: "uint256" },
74
+ ],
75
+ };
76
+ const message = {
77
+ details: {
78
+ token: getAddress(opts.token),
79
+ amount: opts.amount,
80
+ expiration: opts.expiration,
81
+ nonce: opts.nonce,
82
+ },
83
+ spender: getAddress(opts.spender),
84
+ sigDeadline: opts.sigDeadline,
85
+ };
86
+ return account.signTypedData(domain, types, message);
87
+ }
88
+ // Minimal Permit2 ABI for allowance reads + approve.
89
+ export const PERMIT2_ABI = [
90
+ {
91
+ name: "allowance", type: "function", stateMutability: "view",
92
+ inputs: [
93
+ { name: "user", type: "address" }, { name: "token", type: "address" },
94
+ { name: "spender", type: "address" },
95
+ ],
96
+ outputs: [
97
+ { name: "amount", type: "uint160" }, { name: "expiration", type: "uint48" },
98
+ { name: "nonce", type: "uint48" },
99
+ ],
100
+ },
101
+ {
102
+ name: "approve", type: "function", stateMutability: "nonpayable",
103
+ inputs: [
104
+ { name: "token", type: "address" }, { name: "spender", type: "address" },
105
+ { name: "amount", type: "uint160" }, { name: "expiration", type: "uint48" },
106
+ ],
107
+ outputs: [],
108
+ },
109
+ ];
110
+ /** Thin helper around the canonical Permit2 contract for advanced flows. */
111
+ export class Permit2 {
112
+ _c;
113
+ address;
114
+ contract;
115
+ constructor(client) {
116
+ this._c = client;
117
+ this.address = getAddress(PERMIT2_ADDRESS);
118
+ this.contract = new Contract(this.address, PERMIT2_ABI, client.w3);
119
+ }
120
+ async allowance(owner, token, spender) {
121
+ const r = await this.contract.allowance(getAddress(owner), getAddress(token), getAddress(spender));
122
+ return [BigInt(r[0]), Number(r[1]), Number(r[2])];
123
+ }
124
+ /** On-chain `Permit2.approve` (after the token is approved to Permit2). */
125
+ async approveToken(token, spender, amount = MAX_UINT160, expiration = MAX_UINT48, tx = {}) {
126
+ const fn = this.contract.getFunction("approve");
127
+ return this._c.send(fn, [getAddress(token), getAddress(spender), amount, expiration], tx);
128
+ }
129
+ }
130
+ //# sourceMappingURL=permit2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permit2.js","sourceRoot":"","sources":["../src/permit2.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Transaction previews for sign-externally mode.
3
+ *
4
+ * A {@link TxPreview} is what you inspect before signing with your own wallet:
5
+ * the fully-populated **unsigned** transaction, the ABI-decoded function + args,
6
+ * the simulated on-chain result (`eth_call`, decoded per the ABI), the decoded
7
+ * revert reason if it would fail, and the gas estimate. It answers "what happens
8
+ * to my wallet if I broadcast this?" — without holding your key.
9
+ */
10
+ import type { SwapPlan } from "./safety.js";
11
+ /** Inspectable, simulated, unsigned transaction. */
12
+ export declare class TxPreview {
13
+ unsignedTx: Record<string, any>;
14
+ sender: string;
15
+ to: string;
16
+ function: string;
17
+ args: Record<string, any>;
18
+ value: bigint;
19
+ simulatedReturn: any;
20
+ revert: string | null;
21
+ gas: bigint | null;
22
+ constructor(opts: {
23
+ unsignedTx: Record<string, any>;
24
+ sender: string;
25
+ to: string;
26
+ function: string;
27
+ args?: Record<string, any>;
28
+ value?: bigint;
29
+ simulatedReturn?: any;
30
+ revert?: string | null;
31
+ gas?: bigint | null;
32
+ });
33
+ get willRevert(): boolean;
34
+ summary(): string;
35
+ }
36
+ /**
37
+ * A swap prepared for external signing.
38
+ *
39
+ * Inspect `plan` to see the wallet effect (expected output, min received, price
40
+ * impact, honeypot/tax screen), then sign + broadcast the unsigned txs yourself —
41
+ * `approveTx` first (if `needsApproval`), then `swapTx`.
42
+ */
43
+ export declare class SwapBuild {
44
+ plan: SwapPlan;
45
+ swapTx: Record<string, any>;
46
+ approveTx: Record<string, any> | null;
47
+ needsApproval: boolean;
48
+ constructor(opts: {
49
+ plan: SwapPlan;
50
+ swapTx: Record<string, any>;
51
+ approveTx?: Record<string, any> | null;
52
+ needsApproval?: boolean;
53
+ });
54
+ get isSafe(): boolean;
55
+ summary(): string;
56
+ }
57
+ //# sourceMappingURL=previews.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"previews.d.ts","sourceRoot":"","sources":["../src/previews.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,oDAAoD;AACpD,qBAAa,SAAS;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,GAAG,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;gBAEP,IAAI,EAAE;QAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,MAAM,EAAE,MAAM,CAAC;QACf,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,eAAe,CAAC,EAAE,GAAG,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACrB;IAYD,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,OAAO,IAAI,MAAM;CASlB;AAED;;;;;;GAMG;AACH,qBAAa,SAAS;IACpB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IACtC,aAAa,EAAE,OAAO,CAAC;gBAEX,IAAI,EAAE;QAChB,IAAI,EAAE,QAAQ,CAAC;QACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;QACvC,aAAa,CAAC,EAAE,OAAO,CAAC;KACzB;IAOD,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,OAAO,IAAI,MAAM;CAIlB"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Transaction previews for sign-externally mode.
3
+ *
4
+ * A {@link TxPreview} is what you inspect before signing with your own wallet:
5
+ * the fully-populated **unsigned** transaction, the ABI-decoded function + args,
6
+ * the simulated on-chain result (`eth_call`, decoded per the ABI), the decoded
7
+ * revert reason if it would fail, and the gas estimate. It answers "what happens
8
+ * to my wallet if I broadcast this?" — without holding your key.
9
+ */
10
+ /** Inspectable, simulated, unsigned transaction. */
11
+ export class TxPreview {
12
+ unsignedTx; // sign with your own wallet, then broadcastTransaction
13
+ sender;
14
+ to;
15
+ function; // decoded function name
16
+ args; // decoded named arguments
17
+ value;
18
+ simulatedReturn; // decoded eth_call result (null if it reverts)
19
+ revert; // decoded revert reason if it would revert
20
+ gas; // estimated gas (null if it reverts)
21
+ constructor(opts) {
22
+ this.unsignedTx = opts.unsignedTx;
23
+ this.sender = opts.sender;
24
+ this.to = opts.to;
25
+ this.function = opts.function;
26
+ this.args = opts.args ?? {};
27
+ this.value = opts.value ?? 0n;
28
+ this.simulatedReturn = opts.simulatedReturn ?? null;
29
+ this.revert = opts.revert ?? null;
30
+ this.gas = opts.gas ?? null;
31
+ }
32
+ get willRevert() {
33
+ return this.revert !== null;
34
+ }
35
+ summary() {
36
+ if (this.willRevert) {
37
+ return `TxPreview(${this.function} -> WOULD REVERT: ${this.revert})`;
38
+ }
39
+ return (`TxPreview(${this.function} on ${this.to.slice(0, 10)}… ` +
40
+ `returns=${this.simulatedReturn} gas~${this.gas} value=${this.value})`);
41
+ }
42
+ }
43
+ /**
44
+ * A swap prepared for external signing.
45
+ *
46
+ * Inspect `plan` to see the wallet effect (expected output, min received, price
47
+ * impact, honeypot/tax screen), then sign + broadcast the unsigned txs yourself —
48
+ * `approveTx` first (if `needsApproval`), then `swapTx`.
49
+ */
50
+ export class SwapBuild {
51
+ plan;
52
+ swapTx; // unsigned executeHybridSwap
53
+ approveTx; // unsigned ERC-20 approve (if needed)
54
+ needsApproval;
55
+ constructor(opts) {
56
+ this.plan = opts.plan;
57
+ this.swapTx = opts.swapTx;
58
+ this.approveTx = opts.approveTx ?? null;
59
+ this.needsApproval = opts.needsApproval ?? false;
60
+ }
61
+ get isSafe() {
62
+ return this.plan?.isSafe ?? false;
63
+ }
64
+ summary() {
65
+ const appr = this.needsApproval ? " +approve" : "";
66
+ return `SwapBuild(${this.plan.summary()}${appr})`;
67
+ }
68
+ }
69
+ //# sourceMappingURL=previews.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"previews.js","sourceRoot":"","sources":["../src/previews.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,oDAAoD;AACpD,MAAM,OAAO,SAAS;IACpB,UAAU,CAAsB,CAAC,uDAAuD;IACxF,MAAM,CAAS;IACf,EAAE,CAAS;IACX,QAAQ,CAAS,CAAC,wBAAwB;IAC1C,IAAI,CAAsB,CAAC,0BAA0B;IACrD,KAAK,CAAS;IACd,eAAe,CAAM,CAAC,+CAA+C;IACrE,MAAM,CAAgB,CAAC,2CAA2C;IAClE,GAAG,CAAgB,CAAC,qCAAqC;IAEzD,YAAY,IAUX;QACC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC;QACpD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;QAClC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC;IAC9B,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC;IAC9B,CAAC;IAED,OAAO;QACL,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,OAAO,aAAa,IAAI,CAAC,QAAQ,qBAAqB,IAAI,CAAC,MAAM,GAAG,CAAC;QACvE,CAAC;QACD,OAAO,CACL,aAAa,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK;YAC1D,WAAW,IAAI,CAAC,eAAe,SAAS,IAAI,CAAC,GAAG,WAAW,IAAI,CAAC,KAAK,GAAG,CACzE,CAAC;IACJ,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,OAAO,SAAS;IACpB,IAAI,CAAW;IACf,MAAM,CAAsB,CAAC,6BAA6B;IAC1D,SAAS,CAA6B,CAAC,sCAAsC;IAC7E,aAAa,CAAU;IAEvB,YAAY,IAKX;QACC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC;QACxC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,KAAK,CAAC;IACnD,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,KAAK,CAAC;IACpC,CAAC;IAED,OAAO;QACL,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,OAAO,aAAa,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,CAAC;IACpD,CAAC;CACF"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Swap-safety configuration and the inspectable {@link SwapPlan}.
3
+ *
4
+ * The SDK never lets funds move on a route it has not (a) integrity-checked and
5
+ * (b) — when possible — simulated end-to-end. {@link SwapPlan} is the artifact of
6
+ * that work: the chosen route, every candidate it beat, the realized output from
7
+ * an on-chain simulation, the slippage floor, price-impact and the honeypot/tax
8
+ * probe. `execute` builds a plan, enforces {@link SafetyConfig}, sends, then
9
+ * asserts the received balance actually grew by `minOut` (trust the chain).
10
+ */
11
+ import type { SwapPath, TokenInfo } from "./types.js";
12
+ export declare const DEFAULT_SLIPPAGE_BPS = 50;
13
+ export declare const DEFAULT_DEADLINE_SECS = 1200;
14
+ export declare const DEFAULT_PROBE_VALUE: bigint;
15
+ /** Tunable guard rails. Pass one to `new SallyClient(..., { safety })` or per call. */
16
+ export declare class SafetyConfig {
17
+ readonly slippageBps: number;
18
+ readonly deadlineSecs: number;
19
+ readonly priceImpactWarnBps: number;
20
+ readonly priceImpactBlockBps: number;
21
+ readonly taxWarnBps: number;
22
+ readonly taxBlockBps: number;
23
+ readonly checkIntegrity: boolean;
24
+ readonly checkHoneypot: boolean;
25
+ readonly simulate: boolean;
26
+ readonly balanceDeltaAssert: boolean;
27
+ readonly probeValue: bigint;
28
+ readonly unlimitedApproval: boolean;
29
+ constructor(opts?: Partial<SafetyConfigFields>);
30
+ /** Return a copy with some fields overridden (mirrors dataclasses.replace). */
31
+ replace(opts: Partial<SafetyConfigFields>): SafetyConfig;
32
+ private fields;
33
+ }
34
+ export interface SafetyConfigFields {
35
+ slippageBps: number;
36
+ deadlineSecs: number;
37
+ priceImpactWarnBps: number;
38
+ priceImpactBlockBps: number;
39
+ taxWarnBps: number;
40
+ taxBlockBps: number;
41
+ checkIntegrity: boolean;
42
+ checkHoneypot: boolean;
43
+ simulate: boolean;
44
+ balanceDeltaAssert: boolean;
45
+ probeValue: bigint;
46
+ unlimitedApproval: boolean;
47
+ }
48
+ /** One quoted route plus its simulated realized output (null if it reverted). */
49
+ export declare class RouteCandidate {
50
+ label: string;
51
+ route: SwapPath;
52
+ quotedOut: bigint;
53
+ simulatedOut: bigint | null;
54
+ integrityProblems: string[];
55
+ constructor(label: string, route: SwapPath, quotedOut: bigint, simulatedOut?: bigint | null, integrityProblems?: string[]);
56
+ get usable(): boolean;
57
+ /** Ranking key: realized output if simulated, else the quote. */
58
+ get score(): bigint;
59
+ }
60
+ /** A fully-vetted swap, ready to execute (or inspect/reject). */
61
+ export declare class SwapPlan {
62
+ tokenIn: string;
63
+ tokenOut: string;
64
+ amountIn: bigint;
65
+ route: SwapPath;
66
+ quotedOut: bigint;
67
+ simulatedOut: bigint | null;
68
+ minOut: bigint;
69
+ priceImpactBps: number | null;
70
+ tokenSafety: TokenInfo | null;
71
+ candidates: RouteCandidate[];
72
+ warnings: string[];
73
+ blockReasons: string[];
74
+ constructor(tokenIn: string, tokenOut: string, amountIn: bigint, route: SwapPath, quotedOut: bigint, simulatedOut: bigint | null, minOut: bigint, priceImpactBps: number | null, tokenSafety: TokenInfo | null, candidates: RouteCandidate[], warnings?: string[], blockReasons?: string[]);
75
+ get isSafe(): boolean;
76
+ /** Best available estimate of output (simulated if present, else quoted). */
77
+ get expectedOut(): bigint;
78
+ summary(): string;
79
+ }
80
+ //# sourceMappingURL=safety.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"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"}
package/dist/safety.js ADDED
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Swap-safety configuration and the inspectable {@link SwapPlan}.
3
+ *
4
+ * The SDK never lets funds move on a route it has not (a) integrity-checked and
5
+ * (b) — when possible — simulated end-to-end. {@link SwapPlan} is the artifact of
6
+ * that work: the chosen route, every candidate it beat, the realized output from
7
+ * an on-chain simulation, the slippage floor, price-impact and the honeypot/tax
8
+ * probe. `execute` builds a plan, enforces {@link SafetyConfig}, sends, then
9
+ * asserts the received balance actually grew by `minOut` (trust the chain).
10
+ */
11
+ // Defaults aligned with mainstream SDKs (Uniswap interface / 1inch).
12
+ export const DEFAULT_SLIPPAGE_BPS = 50; // 0.5%
13
+ export const DEFAULT_DEADLINE_SECS = 1200; // 20 min
14
+ export const DEFAULT_PROBE_VALUE = 10n ** 16n; // 0.01 native, for the getTokenInfos honeypot probe
15
+ /** Tunable guard rails. Pass one to `new SallyClient(..., { safety })` or per call. */
16
+ export class SafetyConfig {
17
+ slippageBps;
18
+ deadlineSecs;
19
+ // price impact (bps of expected-at-marginal-price)
20
+ priceImpactWarnBps;
21
+ priceImpactBlockBps;
22
+ // transfer tax (bps), measured by the getTokenInfos round-trip probe
23
+ taxWarnBps;
24
+ taxBlockBps;
25
+ // toggles
26
+ checkIntegrity;
27
+ checkHoneypot;
28
+ simulate;
29
+ balanceDeltaAssert;
30
+ probeValue;
31
+ // approval: exact-amount by default (safer than infinite approve)
32
+ unlimitedApproval;
33
+ constructor(opts = {}) {
34
+ this.slippageBps = opts.slippageBps ?? DEFAULT_SLIPPAGE_BPS;
35
+ this.deadlineSecs = opts.deadlineSecs ?? DEFAULT_DEADLINE_SECS;
36
+ this.priceImpactWarnBps = opts.priceImpactWarnBps ?? 500; // 5% -> warning
37
+ this.priceImpactBlockBps = opts.priceImpactBlockBps ?? 1500; // 15% -> hard block
38
+ this.taxWarnBps = opts.taxWarnBps ?? 1000; // 10%
39
+ this.taxBlockBps = opts.taxBlockBps ?? 5000; // 50%
40
+ this.checkIntegrity = opts.checkIntegrity ?? true;
41
+ this.checkHoneypot = opts.checkHoneypot ?? true;
42
+ this.simulate = opts.simulate ?? true;
43
+ this.balanceDeltaAssert = opts.balanceDeltaAssert ?? true;
44
+ this.probeValue = opts.probeValue ?? DEFAULT_PROBE_VALUE;
45
+ this.unlimitedApproval = opts.unlimitedApproval ?? false;
46
+ }
47
+ /** Return a copy with some fields overridden (mirrors dataclasses.replace). */
48
+ replace(opts) {
49
+ return new SafetyConfig({ ...this.fields(), ...opts });
50
+ }
51
+ fields() {
52
+ return {
53
+ slippageBps: this.slippageBps,
54
+ deadlineSecs: this.deadlineSecs,
55
+ priceImpactWarnBps: this.priceImpactWarnBps,
56
+ priceImpactBlockBps: this.priceImpactBlockBps,
57
+ taxWarnBps: this.taxWarnBps,
58
+ taxBlockBps: this.taxBlockBps,
59
+ checkIntegrity: this.checkIntegrity,
60
+ checkHoneypot: this.checkHoneypot,
61
+ simulate: this.simulate,
62
+ balanceDeltaAssert: this.balanceDeltaAssert,
63
+ probeValue: this.probeValue,
64
+ unlimitedApproval: this.unlimitedApproval,
65
+ };
66
+ }
67
+ }
68
+ /** One quoted route plus its simulated realized output (null if it reverted). */
69
+ export class RouteCandidate {
70
+ label;
71
+ route;
72
+ quotedOut;
73
+ simulatedOut;
74
+ integrityProblems;
75
+ constructor(label, route, quotedOut, simulatedOut = null, integrityProblems = []) {
76
+ this.label = label;
77
+ this.route = route;
78
+ this.quotedOut = quotedOut;
79
+ this.simulatedOut = simulatedOut;
80
+ this.integrityProblems = integrityProblems;
81
+ }
82
+ get usable() {
83
+ return this.integrityProblems.length === 0 && (this.simulatedOut === null || this.simulatedOut > 0n);
84
+ }
85
+ /** Ranking key: realized output if simulated, else the quote. */
86
+ get score() {
87
+ return this.simulatedOut !== null ? this.simulatedOut : this.quotedOut;
88
+ }
89
+ }
90
+ /** A fully-vetted swap, ready to execute (or inspect/reject). */
91
+ export class SwapPlan {
92
+ tokenIn;
93
+ tokenOut;
94
+ amountIn;
95
+ route;
96
+ quotedOut;
97
+ simulatedOut;
98
+ minOut;
99
+ priceImpactBps;
100
+ tokenSafety;
101
+ candidates;
102
+ warnings;
103
+ blockReasons;
104
+ constructor(tokenIn, tokenOut, amountIn, route, quotedOut, simulatedOut, minOut, priceImpactBps, tokenSafety, candidates, warnings = [], blockReasons = []) {
105
+ this.tokenIn = tokenIn;
106
+ this.tokenOut = tokenOut;
107
+ this.amountIn = amountIn;
108
+ this.route = route;
109
+ this.quotedOut = quotedOut;
110
+ this.simulatedOut = simulatedOut;
111
+ this.minOut = minOut;
112
+ this.priceImpactBps = priceImpactBps;
113
+ this.tokenSafety = tokenSafety;
114
+ this.candidates = candidates;
115
+ this.warnings = warnings;
116
+ this.blockReasons = blockReasons;
117
+ }
118
+ get isSafe() {
119
+ return this.blockReasons.length === 0;
120
+ }
121
+ /** Best available estimate of output (simulated if present, else quoted). */
122
+ get expectedOut() {
123
+ return this.simulatedOut !== null ? this.simulatedOut : this.quotedOut;
124
+ }
125
+ summary() {
126
+ const sim = this.simulatedOut !== null ? `${this.simulatedOut}` : "n/a";
127
+ return (`SwapPlan(${this.amountIn} ${this.tokenIn.slice(0, 8)}… -> ${this.tokenOut.slice(0, 8)}… ` +
128
+ `out~${this.expectedOut} sim=${sim} min=${this.minOut} ` +
129
+ `impact=${this.priceImpactBps}bps steps=${this.route.stepCount} ` +
130
+ `${this.isSafe ? "SAFE" : "BLOCKED:" + this.blockReasons.join(",")})`);
131
+ }
132
+ }
133
+ //# sourceMappingURL=safety.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safety.js","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"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"}