@varla/sdk 2.10.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 +63 -5
- package/CHANGELOG.md +9 -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/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
|
@@ -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
|
+
}
|