@varla/sdk 2.9.0 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +66 -8
- package/CHANGELOG.md +17 -0
- package/README.md +73 -0
- package/dist/abi/full/VarlaOracle.d.ts +151 -1
- package/dist/abi/full/VarlaOracle.d.ts.map +1 -1
- package/dist/abi/full/VarlaOracle.js +195 -1
- package/dist/abi/full/VarlaOracle.js.map +1 -1
- package/dist/abi/subsets/VarlaOracle.registry.d.ts +66 -0
- package/dist/abi/subsets/VarlaOracle.registry.d.ts.map +1 -1
- package/dist/abi/subsets/VarlaOracle.registry.js +83 -0
- package/dist/abi/subsets/VarlaOracle.registry.js.map +1 -1
- package/dist/generated.d.ts +217 -1
- package/dist/generated.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/safe.d.ts +108 -0
- package/dist/safe.d.ts.map +1 -0
- package/dist/safe.js +148 -0
- package/dist/safe.js.map +1 -0
- package/dist/views/core.d.ts +90 -0
- package/dist/views/core.d.ts.map +1 -1
- package/dist/views/core.js +110 -0
- package/dist/views/core.js.map +1 -1
- package/package.json +5 -1
- package/src/abi/full/VarlaOracle.ts +195 -1
- package/src/abi/subsets/VarlaOracle.registry.ts +83 -0
- package/src/index.ts +2 -0
- package/src/safe.ts +226 -0
- package/src/views/core.ts +185 -0
|
@@ -138,6 +138,27 @@ export const VARLAORACLE_ABI = [
|
|
|
138
138
|
"name": "InvalidLiquidationGracePeriod",
|
|
139
139
|
"type": "error"
|
|
140
140
|
},
|
|
141
|
+
{
|
|
142
|
+
"inputs": [
|
|
143
|
+
{
|
|
144
|
+
"internalType": "uint8",
|
|
145
|
+
"name": "tier",
|
|
146
|
+
"type": "uint8"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"internalType": "uint256",
|
|
150
|
+
"name": "gracePeriod",
|
|
151
|
+
"type": "uint256"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"internalType": "uint256",
|
|
155
|
+
"name": "decayPeriod",
|
|
156
|
+
"type": "uint256"
|
|
157
|
+
}
|
|
158
|
+
],
|
|
159
|
+
"name": "InvalidLowLiquidityConfig",
|
|
160
|
+
"type": "error"
|
|
161
|
+
},
|
|
141
162
|
{
|
|
142
163
|
"inputs": [
|
|
143
164
|
{
|
|
@@ -338,6 +359,68 @@ export const VARLAORACLE_ABI = [
|
|
|
338
359
|
"name": "LiquidationGracePeriodUpdated",
|
|
339
360
|
"type": "event"
|
|
340
361
|
},
|
|
362
|
+
{
|
|
363
|
+
"anonymous": false,
|
|
364
|
+
"inputs": [
|
|
365
|
+
{
|
|
366
|
+
"indexed": true,
|
|
367
|
+
"internalType": "uint8",
|
|
368
|
+
"name": "tier",
|
|
369
|
+
"type": "uint8"
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
"indexed": false,
|
|
373
|
+
"internalType": "uint256",
|
|
374
|
+
"name": "oldGracePeriod",
|
|
375
|
+
"type": "uint256"
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
"indexed": false,
|
|
379
|
+
"internalType": "uint256",
|
|
380
|
+
"name": "oldDecayPeriod",
|
|
381
|
+
"type": "uint256"
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
"indexed": false,
|
|
385
|
+
"internalType": "uint256",
|
|
386
|
+
"name": "newGracePeriod",
|
|
387
|
+
"type": "uint256"
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
"indexed": false,
|
|
391
|
+
"internalType": "uint256",
|
|
392
|
+
"name": "newDecayPeriod",
|
|
393
|
+
"type": "uint256"
|
|
394
|
+
}
|
|
395
|
+
],
|
|
396
|
+
"name": "LowLiquidityConfigUpdated",
|
|
397
|
+
"type": "event"
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
"anonymous": false,
|
|
401
|
+
"inputs": [
|
|
402
|
+
{
|
|
403
|
+
"indexed": true,
|
|
404
|
+
"internalType": "uint256",
|
|
405
|
+
"name": "positionId",
|
|
406
|
+
"type": "uint256"
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
"indexed": false,
|
|
410
|
+
"internalType": "uint256",
|
|
411
|
+
"name": "oldLowLiquiditySince",
|
|
412
|
+
"type": "uint256"
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
"indexed": false,
|
|
416
|
+
"internalType": "uint256",
|
|
417
|
+
"name": "newLowLiquiditySince",
|
|
418
|
+
"type": "uint256"
|
|
419
|
+
}
|
|
420
|
+
],
|
|
421
|
+
"name": "LowLiquiditySinceUpdated",
|
|
422
|
+
"type": "event"
|
|
423
|
+
},
|
|
341
424
|
{
|
|
342
425
|
"anonymous": false,
|
|
343
426
|
"inputs": [
|
|
@@ -718,6 +801,32 @@ export const VARLAORACLE_ABI = [
|
|
|
718
801
|
"stateMutability": "view",
|
|
719
802
|
"type": "function"
|
|
720
803
|
},
|
|
804
|
+
{
|
|
805
|
+
"inputs": [],
|
|
806
|
+
"name": "MAX_LOW_LIQUIDITY_DECAY_PERIOD",
|
|
807
|
+
"outputs": [
|
|
808
|
+
{
|
|
809
|
+
"internalType": "uint256",
|
|
810
|
+
"name": "",
|
|
811
|
+
"type": "uint256"
|
|
812
|
+
}
|
|
813
|
+
],
|
|
814
|
+
"stateMutability": "view",
|
|
815
|
+
"type": "function"
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
"inputs": [],
|
|
819
|
+
"name": "MAX_LOW_LIQUIDITY_GRACE_PERIOD",
|
|
820
|
+
"outputs": [
|
|
821
|
+
{
|
|
822
|
+
"internalType": "uint256",
|
|
823
|
+
"name": "",
|
|
824
|
+
"type": "uint256"
|
|
825
|
+
}
|
|
826
|
+
],
|
|
827
|
+
"stateMutability": "view",
|
|
828
|
+
"type": "function"
|
|
829
|
+
},
|
|
721
830
|
{
|
|
722
831
|
"inputs": [],
|
|
723
832
|
"name": "MAX_MAX_STALENESS",
|
|
@@ -1169,6 +1278,44 @@ export const VARLAORACLE_ABI = [
|
|
|
1169
1278
|
"stateMutability": "view",
|
|
1170
1279
|
"type": "function"
|
|
1171
1280
|
},
|
|
1281
|
+
{
|
|
1282
|
+
"inputs": [
|
|
1283
|
+
{
|
|
1284
|
+
"internalType": "uint256",
|
|
1285
|
+
"name": "positionId",
|
|
1286
|
+
"type": "uint256"
|
|
1287
|
+
}
|
|
1288
|
+
],
|
|
1289
|
+
"name": "getLowLiquidityFactor",
|
|
1290
|
+
"outputs": [
|
|
1291
|
+
{
|
|
1292
|
+
"internalType": "uint256",
|
|
1293
|
+
"name": "",
|
|
1294
|
+
"type": "uint256"
|
|
1295
|
+
}
|
|
1296
|
+
],
|
|
1297
|
+
"stateMutability": "view",
|
|
1298
|
+
"type": "function"
|
|
1299
|
+
},
|
|
1300
|
+
{
|
|
1301
|
+
"inputs": [
|
|
1302
|
+
{
|
|
1303
|
+
"internalType": "uint256",
|
|
1304
|
+
"name": "positionId",
|
|
1305
|
+
"type": "uint256"
|
|
1306
|
+
}
|
|
1307
|
+
],
|
|
1308
|
+
"name": "getLowLiquiditySince",
|
|
1309
|
+
"outputs": [
|
|
1310
|
+
{
|
|
1311
|
+
"internalType": "uint256",
|
|
1312
|
+
"name": "",
|
|
1313
|
+
"type": "uint256"
|
|
1314
|
+
}
|
|
1315
|
+
],
|
|
1316
|
+
"stateMutability": "view",
|
|
1317
|
+
"type": "function"
|
|
1318
|
+
},
|
|
1172
1319
|
{
|
|
1173
1320
|
"inputs": [
|
|
1174
1321
|
{
|
|
@@ -1258,7 +1405,7 @@ export const VARLAORACLE_ABI = [
|
|
|
1258
1405
|
},
|
|
1259
1406
|
{
|
|
1260
1407
|
"internalType": "uint256",
|
|
1261
|
-
"name": "
|
|
1408
|
+
"name": "ltvAdjustmentFactorWad",
|
|
1262
1409
|
"type": "uint256"
|
|
1263
1410
|
},
|
|
1264
1411
|
{
|
|
@@ -1629,6 +1776,30 @@ export const VARLAORACLE_ABI = [
|
|
|
1629
1776
|
"stateMutability": "view",
|
|
1630
1777
|
"type": "function"
|
|
1631
1778
|
},
|
|
1779
|
+
{
|
|
1780
|
+
"inputs": [
|
|
1781
|
+
{
|
|
1782
|
+
"internalType": "uint256",
|
|
1783
|
+
"name": "",
|
|
1784
|
+
"type": "uint256"
|
|
1785
|
+
}
|
|
1786
|
+
],
|
|
1787
|
+
"name": "lowLiquidityConfig",
|
|
1788
|
+
"outputs": [
|
|
1789
|
+
{
|
|
1790
|
+
"internalType": "uint256",
|
|
1791
|
+
"name": "gracePeriod",
|
|
1792
|
+
"type": "uint256"
|
|
1793
|
+
},
|
|
1794
|
+
{
|
|
1795
|
+
"internalType": "uint256",
|
|
1796
|
+
"name": "decayPeriod",
|
|
1797
|
+
"type": "uint256"
|
|
1798
|
+
}
|
|
1799
|
+
],
|
|
1800
|
+
"stateMutability": "view",
|
|
1801
|
+
"type": "function"
|
|
1802
|
+
},
|
|
1632
1803
|
{
|
|
1633
1804
|
"inputs": [],
|
|
1634
1805
|
"name": "maxStaleness",
|
|
@@ -1735,6 +1906,29 @@ export const VARLAORACLE_ABI = [
|
|
|
1735
1906
|
"stateMutability": "nonpayable",
|
|
1736
1907
|
"type": "function"
|
|
1737
1908
|
},
|
|
1909
|
+
{
|
|
1910
|
+
"inputs": [
|
|
1911
|
+
{
|
|
1912
|
+
"internalType": "uint8",
|
|
1913
|
+
"name": "tier",
|
|
1914
|
+
"type": "uint8"
|
|
1915
|
+
},
|
|
1916
|
+
{
|
|
1917
|
+
"internalType": "uint256",
|
|
1918
|
+
"name": "gracePeriod",
|
|
1919
|
+
"type": "uint256"
|
|
1920
|
+
},
|
|
1921
|
+
{
|
|
1922
|
+
"internalType": "uint256",
|
|
1923
|
+
"name": "decayPeriod",
|
|
1924
|
+
"type": "uint256"
|
|
1925
|
+
}
|
|
1926
|
+
],
|
|
1927
|
+
"name": "setLowLiquidityConfig",
|
|
1928
|
+
"outputs": [],
|
|
1929
|
+
"stateMutability": "nonpayable",
|
|
1930
|
+
"type": "function"
|
|
1931
|
+
},
|
|
1738
1932
|
{
|
|
1739
1933
|
"inputs": [
|
|
1740
1934
|
{
|
|
@@ -138,6 +138,27 @@ export const VARLAORACLE_ABI_REGISTRY = [
|
|
|
138
138
|
"name": "InvalidLiquidationGracePeriod",
|
|
139
139
|
"type": "error"
|
|
140
140
|
},
|
|
141
|
+
{
|
|
142
|
+
"inputs": [
|
|
143
|
+
{
|
|
144
|
+
"internalType": "uint8",
|
|
145
|
+
"name": "tier",
|
|
146
|
+
"type": "uint8"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"internalType": "uint256",
|
|
150
|
+
"name": "gracePeriod",
|
|
151
|
+
"type": "uint256"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"internalType": "uint256",
|
|
155
|
+
"name": "decayPeriod",
|
|
156
|
+
"type": "uint256"
|
|
157
|
+
}
|
|
158
|
+
],
|
|
159
|
+
"name": "InvalidLowLiquidityConfig",
|
|
160
|
+
"type": "error"
|
|
161
|
+
},
|
|
141
162
|
{
|
|
142
163
|
"inputs": [
|
|
143
164
|
{
|
|
@@ -338,6 +359,68 @@ export const VARLAORACLE_ABI_REGISTRY = [
|
|
|
338
359
|
"name": "LiquidationGracePeriodUpdated",
|
|
339
360
|
"type": "event"
|
|
340
361
|
},
|
|
362
|
+
{
|
|
363
|
+
"anonymous": false,
|
|
364
|
+
"inputs": [
|
|
365
|
+
{
|
|
366
|
+
"indexed": true,
|
|
367
|
+
"internalType": "uint8",
|
|
368
|
+
"name": "tier",
|
|
369
|
+
"type": "uint8"
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
"indexed": false,
|
|
373
|
+
"internalType": "uint256",
|
|
374
|
+
"name": "oldGracePeriod",
|
|
375
|
+
"type": "uint256"
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
"indexed": false,
|
|
379
|
+
"internalType": "uint256",
|
|
380
|
+
"name": "oldDecayPeriod",
|
|
381
|
+
"type": "uint256"
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
"indexed": false,
|
|
385
|
+
"internalType": "uint256",
|
|
386
|
+
"name": "newGracePeriod",
|
|
387
|
+
"type": "uint256"
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
"indexed": false,
|
|
391
|
+
"internalType": "uint256",
|
|
392
|
+
"name": "newDecayPeriod",
|
|
393
|
+
"type": "uint256"
|
|
394
|
+
}
|
|
395
|
+
],
|
|
396
|
+
"name": "LowLiquidityConfigUpdated",
|
|
397
|
+
"type": "event"
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
"anonymous": false,
|
|
401
|
+
"inputs": [
|
|
402
|
+
{
|
|
403
|
+
"indexed": true,
|
|
404
|
+
"internalType": "uint256",
|
|
405
|
+
"name": "positionId",
|
|
406
|
+
"type": "uint256"
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
"indexed": false,
|
|
410
|
+
"internalType": "uint256",
|
|
411
|
+
"name": "oldLowLiquiditySince",
|
|
412
|
+
"type": "uint256"
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
"indexed": false,
|
|
416
|
+
"internalType": "uint256",
|
|
417
|
+
"name": "newLowLiquiditySince",
|
|
418
|
+
"type": "uint256"
|
|
419
|
+
}
|
|
420
|
+
],
|
|
421
|
+
"name": "LowLiquiditySinceUpdated",
|
|
422
|
+
"type": "event"
|
|
423
|
+
},
|
|
341
424
|
{
|
|
342
425
|
"anonymous": false,
|
|
343
426
|
"inputs": [
|
package/src/index.ts
CHANGED
|
@@ -13,6 +13,8 @@ export * from "./events/index.js";
|
|
|
13
13
|
export * from "./format.js";
|
|
14
14
|
// Chain/platform metadata (UI-friendly).
|
|
15
15
|
export * from "./meta.js";
|
|
16
|
+
// Safe MultiSend encoding (proxy wallet support).
|
|
17
|
+
export * from "./safe.js";
|
|
16
18
|
export * from "./types.js";
|
|
17
19
|
// Higher-level read helpers (views/facades).
|
|
18
20
|
export * from "./views/index.js";
|
package/src/safe.ts
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
// Note: explicit .js extension is required for Node ESM resolution.
|
|
2
|
+
|
|
3
|
+
import { type Address, concat, encodeFunctionData, encodePacked, type Hex } from "viem";
|
|
4
|
+
|
|
5
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
6
|
+
// Constants
|
|
7
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Canonical Safe MultiSend contract address.
|
|
11
|
+
* Deployed at the same address on all EVM chains (Safe v1.3.0+ deterministic deployment).
|
|
12
|
+
*
|
|
13
|
+
* @see https://github.com/safe-global/safe-deployments
|
|
14
|
+
*/
|
|
15
|
+
export const SAFE_MULTISEND_ADDRESS: Address = "0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Canonical Safe MultiSend "call only" contract address.
|
|
19
|
+
* Same as MultiSend but restricted to CALL operations (no DELEGATECALL).
|
|
20
|
+
*/
|
|
21
|
+
export const SAFE_MULTISEND_CALL_ONLY_ADDRESS: Address =
|
|
22
|
+
"0x9641d764fc13c8B624c04430C7356C1C7C8102e2";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* ABI for the Safe MultiSend contract.
|
|
26
|
+
*/
|
|
27
|
+
const MULTISEND_ABI = [
|
|
28
|
+
{
|
|
29
|
+
name: "multiSend",
|
|
30
|
+
type: "function",
|
|
31
|
+
stateMutability: "payable",
|
|
32
|
+
inputs: [{ name: "transactions", type: "bytes" }],
|
|
33
|
+
outputs: [],
|
|
34
|
+
},
|
|
35
|
+
] as const;
|
|
36
|
+
|
|
37
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
38
|
+
// Types
|
|
39
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Operation type for Safe transactions.
|
|
43
|
+
* - `0` = CALL (standard external call)
|
|
44
|
+
* - `1` = DELEGATECALL (execute in Safe context)
|
|
45
|
+
*/
|
|
46
|
+
export type SafeOperation = 0 | 1;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* A single transaction in a Safe MultiSend batch.
|
|
50
|
+
*/
|
|
51
|
+
export type SafeMultiSendTx = {
|
|
52
|
+
/** Target contract address. */
|
|
53
|
+
to: Address;
|
|
54
|
+
/** ETH value to send (default: 0). */
|
|
55
|
+
value?: bigint;
|
|
56
|
+
/** Encoded calldata. */
|
|
57
|
+
data: Hex;
|
|
58
|
+
/** Operation type (default: 0 = CALL). */
|
|
59
|
+
operation?: SafeOperation;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Input for building a Safe MultiSend batch.
|
|
64
|
+
* Accepts raw `SafeMultiSendTx` objects or `prepare*()` simulation results.
|
|
65
|
+
*
|
|
66
|
+
* The `request` property from `simulateContract` contains `{ to, data, value }` —
|
|
67
|
+
* exactly what we need.
|
|
68
|
+
*/
|
|
69
|
+
export type SafeMultiSendInput =
|
|
70
|
+
| SafeMultiSendTx
|
|
71
|
+
| { request: { to: Address; data: Hex; value?: bigint } };
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Result of encoding a Safe MultiSend batch.
|
|
75
|
+
*/
|
|
76
|
+
export type SafeMultiSendResult = {
|
|
77
|
+
/** Address of the MultiSend contract to call. */
|
|
78
|
+
to: Address;
|
|
79
|
+
/** Encoded `multiSend(bytes)` calldata. */
|
|
80
|
+
data: Hex;
|
|
81
|
+
/** Total ETH value across all transactions. */
|
|
82
|
+
value: bigint;
|
|
83
|
+
/** Number of transactions in the batch. */
|
|
84
|
+
count: number;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
88
|
+
// Helpers
|
|
89
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
90
|
+
|
|
91
|
+
function normalizeInput(input: SafeMultiSendInput): SafeMultiSendTx {
|
|
92
|
+
if ("request" in input) {
|
|
93
|
+
return {
|
|
94
|
+
to: input.request.to,
|
|
95
|
+
data: input.request.data,
|
|
96
|
+
value: input.request.value ?? 0n,
|
|
97
|
+
operation: 0,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return input;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Encode a single transaction into the Safe MultiSend packed format.
|
|
105
|
+
*
|
|
106
|
+
* Format (tightly packed, no padding):
|
|
107
|
+
* ```
|
|
108
|
+
* uint8 operation (1 byte)
|
|
109
|
+
* address to (20 bytes)
|
|
110
|
+
* uint256 value (32 bytes)
|
|
111
|
+
* uint256 dataLength (32 bytes)
|
|
112
|
+
* bytes data (variable)
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @see https://github.com/safe-global/safe-smart-account/blob/main/contracts/libraries/MultiSend.sol
|
|
116
|
+
*/
|
|
117
|
+
function encodeSingleTx(tx: SafeMultiSendTx): Hex {
|
|
118
|
+
const op = tx.operation ?? 0;
|
|
119
|
+
const value = tx.value ?? 0n;
|
|
120
|
+
const dataBytes = tx.data as Hex;
|
|
121
|
+
// Strip "0x" prefix for length calculation
|
|
122
|
+
const dataLen = (dataBytes.length - 2) / 2;
|
|
123
|
+
|
|
124
|
+
return encodePacked(
|
|
125
|
+
["uint8", "address", "uint256", "uint256", "bytes"],
|
|
126
|
+
[op, tx.to, value, BigInt(dataLen), dataBytes],
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
131
|
+
// Public API
|
|
132
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Encode multiple transactions into a Safe MultiSend batch.
|
|
136
|
+
*
|
|
137
|
+
* Accepts either raw `SafeMultiSendTx` objects or the result of SDK `prepare*()`
|
|
138
|
+
* helpers (which return `{ request: { to, data, value } }`).
|
|
139
|
+
*
|
|
140
|
+
* Returns the encoded `multiSend(bytes)` calldata ready to be submitted to
|
|
141
|
+
* a Gnosis Safe via `execTransaction` or Safe SDK.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* import { encodeSafeMultiSend } from "@varla/sdk/safe";
|
|
146
|
+
* import * as actions from "@varla/sdk/actions";
|
|
147
|
+
*
|
|
148
|
+
* const approve = await actions.prepareErc1155SetApprovalForAll({ ... });
|
|
149
|
+
* const deposit = await actions.prepareCoreDeposit({ account: safeAddress, ... });
|
|
150
|
+
* const borrow = await actions.prepareCoreBorrow({ account: safeAddress, ... });
|
|
151
|
+
*
|
|
152
|
+
* const batch = encodeSafeMultiSend([approve, deposit, borrow]);
|
|
153
|
+
* // batch.to → MultiSend contract address
|
|
154
|
+
* // batch.data → encoded multiSend(bytes) calldata
|
|
155
|
+
* // batch.value → total ETH value
|
|
156
|
+
*
|
|
157
|
+
* // Submit via Safe SDK:
|
|
158
|
+
* // safeSdk.createTransaction({ safeTransactionData: {
|
|
159
|
+
* // to: batch.to,
|
|
160
|
+
* // data: batch.data,
|
|
161
|
+
* // value: batch.value.toString(),
|
|
162
|
+
* // operation: 1, // DELEGATECALL to MultiSend
|
|
163
|
+
* // }});
|
|
164
|
+
* ```
|
|
165
|
+
*
|
|
166
|
+
* @param inputs - Array of transactions (raw or from `prepare*()` results).
|
|
167
|
+
* @param options - Optional: override MultiSend contract address.
|
|
168
|
+
* @returns Encoded batch ready for Safe submission.
|
|
169
|
+
* @throws If inputs array is empty.
|
|
170
|
+
*/
|
|
171
|
+
export function encodeSafeMultiSend(
|
|
172
|
+
inputs: readonly SafeMultiSendInput[],
|
|
173
|
+
options?: {
|
|
174
|
+
/** Override the MultiSend contract address. */
|
|
175
|
+
multiSendAddress?: Address;
|
|
176
|
+
},
|
|
177
|
+
): SafeMultiSendResult {
|
|
178
|
+
if (inputs.length === 0) throw new Error("encodeSafeMultiSend: inputs must not be empty");
|
|
179
|
+
|
|
180
|
+
const txs = inputs.map(normalizeInput);
|
|
181
|
+
|
|
182
|
+
// If only one transaction, return it directly (no need for MultiSend wrapper).
|
|
183
|
+
if (txs.length === 1) {
|
|
184
|
+
const tx = txs[0]!;
|
|
185
|
+
return {
|
|
186
|
+
to: tx.to,
|
|
187
|
+
data: tx.data,
|
|
188
|
+
value: tx.value ?? 0n,
|
|
189
|
+
count: 1,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Pack all transactions
|
|
194
|
+
const packed = txs.map(encodeSingleTx);
|
|
195
|
+
const packedData = concat(packed);
|
|
196
|
+
|
|
197
|
+
// Encode the multiSend(bytes) call
|
|
198
|
+
const multiSendCalldata = encodeFunctionData({
|
|
199
|
+
abi: MULTISEND_ABI,
|
|
200
|
+
functionName: "multiSend",
|
|
201
|
+
args: [packedData],
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const totalValue = txs.reduce((sum, tx) => sum + (tx.value ?? 0n), 0n);
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
to: options?.multiSendAddress ?? SAFE_MULTISEND_ADDRESS,
|
|
208
|
+
data: multiSendCalldata,
|
|
209
|
+
value: totalValue,
|
|
210
|
+
count: txs.length,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Convenience: encode a Safe MultiSend batch using the "call only" MultiSend
|
|
216
|
+
* contract (no DELEGATECALL allowed in sub-transactions).
|
|
217
|
+
*
|
|
218
|
+
* This is safer for use cases where the batch should only perform external calls.
|
|
219
|
+
*/
|
|
220
|
+
export function encodeSafeMultiSendCallOnly(
|
|
221
|
+
inputs: readonly SafeMultiSendInput[],
|
|
222
|
+
): SafeMultiSendResult {
|
|
223
|
+
return encodeSafeMultiSend(inputs, {
|
|
224
|
+
multiSendAddress: SAFE_MULTISEND_CALL_ONLY_ADDRESS,
|
|
225
|
+
});
|
|
226
|
+
}
|