@panoptic-eng/sdk 1.0.72 → 1.0.73
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/dist/{cow-DMLTQhqt.js → cow-12OtZc7G.js} +1 -1
- package/dist/index.d.ts +1101 -663
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8545 -4122
- package/dist/index.js.map +1 -1
- package/dist/{irm-BI9so_9s.js → irm-BntFNP1P.js} +81 -3
- package/dist/{rates-BOGkyjVy.js → rates-c9XVKm3m.js} +1128 -504
- package/dist/{router-CL6snZVH.js → router-lUA1kp8A.js} +1 -2
- package/dist/safe/index.d.ts +166 -0
- package/dist/safe/index.d.ts.map +1 -0
- package/dist/safe/index.js +278 -0
- package/dist/safe/index.js.map +1 -0
- package/dist/{v2-DIrXTXMw.js → v2-xSELV6jf.js} +13 -91
- package/dist/{writes-BNNd0vjF.js → writes-_ZxthOkP.js} +5 -629
- package/dist/zodiac/index.d.ts.map +1 -1
- package/package.json +5 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { StateViewAbi } from "./StateView-q4yMpBY6.js";
|
|
2
|
-
import { PanopticError, getBlockMeta, getPool, getPoolMetadata, stateViewAbi, submitWrite, uniswapV3PoolAbi } from "./rates-
|
|
2
|
+
import { PanopticError, decodeAllLegs, decodeTokenId, getBlockMeta, getPool, getPoolMetadata, stateViewAbi, submitWrite, uniswapV3PoolAbi } from "./rates-c9XVKm3m.js";
|
|
3
3
|
import { getLegLiquidityRange, tickToSqrtPriceX96 } from "./greeks-CEv-Uex1.js";
|
|
4
|
-
import { decodeAllLegs, decodeTokenId } from "./writes-BNNd0vjF.js";
|
|
5
4
|
import { BaseError, ContractFunctionRevertedError, ExecutionRevertedError, encodeAbiParameters, encodeFunctionData, encodePacked, erc20Abi, isAddressEqual, maxUint256, toHex, zeroAddress } from "viem";
|
|
6
5
|
import Decimal from "decimal.js";
|
|
7
6
|
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { Address, Hex } from "viem";
|
|
2
|
+
|
|
3
|
+
//#region src/safe/signedSafeTx.d.ts
|
|
4
|
+
declare const safeAbi: readonly [{
|
|
5
|
+
readonly type: "event";
|
|
6
|
+
readonly name: "ExecutionSuccess";
|
|
7
|
+
readonly inputs: readonly [{
|
|
8
|
+
readonly name: "txHash";
|
|
9
|
+
readonly type: "bytes32";
|
|
10
|
+
readonly indexed: true;
|
|
11
|
+
}, {
|
|
12
|
+
readonly name: "payment";
|
|
13
|
+
readonly type: "uint256";
|
|
14
|
+
readonly indexed: false;
|
|
15
|
+
}];
|
|
16
|
+
}, {
|
|
17
|
+
readonly type: "function";
|
|
18
|
+
readonly name: "execTransaction";
|
|
19
|
+
readonly stateMutability: "payable";
|
|
20
|
+
readonly inputs: readonly [{
|
|
21
|
+
readonly name: "to";
|
|
22
|
+
readonly type: "address";
|
|
23
|
+
}, {
|
|
24
|
+
readonly name: "value";
|
|
25
|
+
readonly type: "uint256";
|
|
26
|
+
}, {
|
|
27
|
+
readonly name: "data";
|
|
28
|
+
readonly type: "bytes";
|
|
29
|
+
}, {
|
|
30
|
+
readonly name: "operation";
|
|
31
|
+
readonly type: "uint8";
|
|
32
|
+
}, {
|
|
33
|
+
readonly name: "safeTxGas";
|
|
34
|
+
readonly type: "uint256";
|
|
35
|
+
}, {
|
|
36
|
+
readonly name: "baseGas";
|
|
37
|
+
readonly type: "uint256";
|
|
38
|
+
}, {
|
|
39
|
+
readonly name: "gasPrice";
|
|
40
|
+
readonly type: "uint256";
|
|
41
|
+
}, {
|
|
42
|
+
readonly name: "gasToken";
|
|
43
|
+
readonly type: "address";
|
|
44
|
+
}, {
|
|
45
|
+
readonly name: "refundReceiver";
|
|
46
|
+
readonly type: "address";
|
|
47
|
+
}, {
|
|
48
|
+
readonly name: "signatures";
|
|
49
|
+
readonly type: "bytes";
|
|
50
|
+
}];
|
|
51
|
+
readonly outputs: readonly [{
|
|
52
|
+
readonly name: "success";
|
|
53
|
+
readonly type: "bool";
|
|
54
|
+
}];
|
|
55
|
+
}, {
|
|
56
|
+
readonly type: "function";
|
|
57
|
+
readonly name: "VERSION";
|
|
58
|
+
readonly stateMutability: "view";
|
|
59
|
+
readonly inputs: readonly [];
|
|
60
|
+
readonly outputs: readonly [{
|
|
61
|
+
readonly type: "string";
|
|
62
|
+
}];
|
|
63
|
+
}, {
|
|
64
|
+
readonly type: "function";
|
|
65
|
+
readonly name: "nonce";
|
|
66
|
+
readonly stateMutability: "view";
|
|
67
|
+
readonly inputs: readonly [];
|
|
68
|
+
readonly outputs: readonly [{
|
|
69
|
+
readonly type: "uint256";
|
|
70
|
+
}];
|
|
71
|
+
}, {
|
|
72
|
+
readonly type: "function";
|
|
73
|
+
readonly name: "getThreshold";
|
|
74
|
+
readonly stateMutability: "view";
|
|
75
|
+
readonly inputs: readonly [];
|
|
76
|
+
readonly outputs: readonly [{
|
|
77
|
+
readonly type: "uint256";
|
|
78
|
+
}];
|
|
79
|
+
}, {
|
|
80
|
+
readonly type: "function";
|
|
81
|
+
readonly name: "getOwners";
|
|
82
|
+
readonly stateMutability: "view";
|
|
83
|
+
readonly inputs: readonly [];
|
|
84
|
+
readonly outputs: readonly [{
|
|
85
|
+
readonly type: "address[]";
|
|
86
|
+
}];
|
|
87
|
+
}];
|
|
88
|
+
/** A plain call the owner asked their wallet to send from the Safe. */
|
|
89
|
+
interface SafeCall {
|
|
90
|
+
to: Address;
|
|
91
|
+
value: bigint;
|
|
92
|
+
data: Hex;
|
|
93
|
+
}
|
|
94
|
+
interface SafeTx extends SafeCall {
|
|
95
|
+
operation: 0 | 1;
|
|
96
|
+
safeTxGas: bigint;
|
|
97
|
+
baseGas: bigint;
|
|
98
|
+
gasPrice: bigint;
|
|
99
|
+
gasToken: Address;
|
|
100
|
+
refundReceiver: Address;
|
|
101
|
+
nonce: bigint;
|
|
102
|
+
}
|
|
103
|
+
interface SignedSafeTx {
|
|
104
|
+
safe: Address;
|
|
105
|
+
chainId: number;
|
|
106
|
+
tx: SafeTx;
|
|
107
|
+
safeTxHash: Hex;
|
|
108
|
+
signer: Address;
|
|
109
|
+
/** Packed `signatures` argument for `execTransaction`. */
|
|
110
|
+
signatures: Hex;
|
|
111
|
+
}
|
|
112
|
+
type SignedSafeTxErrorCode = 'INVALID_SIGNATURE' | 'THRESHOLD_NOT_MET' | 'SIGNATURE_MISMATCH';
|
|
113
|
+
declare class SignedSafeTxError extends Error {
|
|
114
|
+
readonly code: SignedSafeTxErrorCode;
|
|
115
|
+
constructor(code: SignedSafeTxErrorCode, message: string);
|
|
116
|
+
}
|
|
117
|
+
/** EIP-712 SafeTx hash (Safe ≥ 1.3 domain: chainId + verifyingContract). */
|
|
118
|
+
declare function hashSafeTx(params: {
|
|
119
|
+
chainId: number;
|
|
120
|
+
safe: Address;
|
|
121
|
+
tx: SafeTx;
|
|
122
|
+
}): Hex;
|
|
123
|
+
/**
|
|
124
|
+
* A wallet signing a plain call for a Safe owner (Rabby, Safe{Wallet}) signs it
|
|
125
|
+
* with no refund or gas fields; only the nonce varies.
|
|
126
|
+
*/
|
|
127
|
+
declare function safeTxForCall(call: SafeCall, nonce: bigint): SafeTx;
|
|
128
|
+
/** True for a 65-byte ECDSA signature — what a Safe-owner wallet returns instead of a tx hash. */
|
|
129
|
+
declare function isSafeOwnerSignature(value: unknown): value is Hex;
|
|
130
|
+
/**
|
|
131
|
+
* Rejects anything that cannot be a Safe owner's ECDSA signature, without any
|
|
132
|
+
* RPC: 65 bytes, supported v (raw 0/1/27/28 or `eth_sign` 31/32), and r, s in
|
|
133
|
+
* the curve range.
|
|
134
|
+
*/
|
|
135
|
+
declare function assertSafeOwnerSignature(signature: Hex): void;
|
|
136
|
+
/**
|
|
137
|
+
* Recovers the signer of `safeTxHash`, accepting raw ECDSA (v 27/28, or 0/1)
|
|
138
|
+
* and `eth_sign` (v 31/32) signatures, and returns the signature in the form
|
|
139
|
+
* the Safe verifies.
|
|
140
|
+
*/
|
|
141
|
+
declare function recoverSafeTxSigner(safeTxHash: Hex, signature: Hex): Promise<{
|
|
142
|
+
signer: Address;
|
|
143
|
+
signature: Hex;
|
|
144
|
+
}>;
|
|
145
|
+
/**
|
|
146
|
+
* Resolves an owner's signature over a plain call into an executable SafeTx,
|
|
147
|
+
* given the Safe's on-chain `nonce`, `owners` and `threshold`. The signed nonce
|
|
148
|
+
* is not part of the call, so it is searched from the on-chain nonce forward
|
|
149
|
+
* (wallets may sign ahead of queued transactions).
|
|
150
|
+
*/
|
|
151
|
+
declare function resolveSignedSafeTx(params: {
|
|
152
|
+
chainId: number;
|
|
153
|
+
safe: Address;
|
|
154
|
+
call: SafeCall;
|
|
155
|
+
signature: Hex;
|
|
156
|
+
state: {
|
|
157
|
+
nonce: bigint;
|
|
158
|
+
threshold: bigint;
|
|
159
|
+
owners: readonly Address[];
|
|
160
|
+
};
|
|
161
|
+
nonceWindow?: number;
|
|
162
|
+
}): Promise<SignedSafeTx>;
|
|
163
|
+
/** `execTransaction` arguments for a resolved signed SafeTx. */
|
|
164
|
+
declare function execTransactionArgs(signed: SignedSafeTx): readonly [Address, bigint, `0x${string}`, 0 | 1, bigint, bigint, bigint, Address, Address, `0x${string}`]; //#endregion
|
|
165
|
+
export { SafeCall, SafeTx, SignedSafeTx, SignedSafeTxError, SignedSafeTxErrorCode, assertSafeOwnerSignature, execTransactionArgs, hashSafeTx, isSafeOwnerSignature, recoverSafeTxSigner, resolveSignedSafeTx, safeAbi, safeTxForCall };
|
|
166
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":["Address","Hex","safeAbi","SafeCall","SafeTx","SignedSafeTx","SignedSafeTxErrorCode","SignedSafeTxError","Error","hashSafeTx","safeTxForCall","isSafeOwnerSignature","assertSafeOwnerSignature","recoverSafeTxSigner","Promise","resolveSignedSafeTx","execTransactionArgs"],"sources":["../../src/safe/signedSafeTx.d.ts"],"sourcesContent":null,"mappings":"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"}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { concatHex, getAddress, hashMessage, hashTypedData, hexToBigInt, hexToNumber, isAddressEqual, numberToHex, recoverAddress, sliceHex, zeroAddress } from "viem";
|
|
2
|
+
|
|
3
|
+
//#region src/safe/signedSafeTx.ts
|
|
4
|
+
const safeAbi = [
|
|
5
|
+
{
|
|
6
|
+
type: "event",
|
|
7
|
+
name: "ExecutionSuccess",
|
|
8
|
+
inputs: [{
|
|
9
|
+
name: "txHash",
|
|
10
|
+
type: "bytes32",
|
|
11
|
+
indexed: true
|
|
12
|
+
}, {
|
|
13
|
+
name: "payment",
|
|
14
|
+
type: "uint256",
|
|
15
|
+
indexed: false
|
|
16
|
+
}]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
type: "function",
|
|
20
|
+
name: "execTransaction",
|
|
21
|
+
stateMutability: "payable",
|
|
22
|
+
inputs: [
|
|
23
|
+
{
|
|
24
|
+
name: "to",
|
|
25
|
+
type: "address"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: "value",
|
|
29
|
+
type: "uint256"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: "data",
|
|
33
|
+
type: "bytes"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: "operation",
|
|
37
|
+
type: "uint8"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: "safeTxGas",
|
|
41
|
+
type: "uint256"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: "baseGas",
|
|
45
|
+
type: "uint256"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: "gasPrice",
|
|
49
|
+
type: "uint256"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: "gasToken",
|
|
53
|
+
type: "address"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: "refundReceiver",
|
|
57
|
+
type: "address"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "signatures",
|
|
61
|
+
type: "bytes"
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
outputs: [{
|
|
65
|
+
name: "success",
|
|
66
|
+
type: "bool"
|
|
67
|
+
}]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
type: "function",
|
|
71
|
+
name: "VERSION",
|
|
72
|
+
stateMutability: "view",
|
|
73
|
+
inputs: [],
|
|
74
|
+
outputs: [{ type: "string" }]
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
type: "function",
|
|
78
|
+
name: "nonce",
|
|
79
|
+
stateMutability: "view",
|
|
80
|
+
inputs: [],
|
|
81
|
+
outputs: [{ type: "uint256" }]
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
type: "function",
|
|
85
|
+
name: "getThreshold",
|
|
86
|
+
stateMutability: "view",
|
|
87
|
+
inputs: [],
|
|
88
|
+
outputs: [{ type: "uint256" }]
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
type: "function",
|
|
92
|
+
name: "getOwners",
|
|
93
|
+
stateMutability: "view",
|
|
94
|
+
inputs: [],
|
|
95
|
+
outputs: [{ type: "address[]" }]
|
|
96
|
+
}
|
|
97
|
+
];
|
|
98
|
+
var SignedSafeTxError = class extends Error {
|
|
99
|
+
constructor(code, message) {
|
|
100
|
+
super(message);
|
|
101
|
+
this.code = code;
|
|
102
|
+
this.name = "SignedSafeTxError";
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
const SAFE_TX_TYPES = { SafeTx: [
|
|
106
|
+
{
|
|
107
|
+
name: "to",
|
|
108
|
+
type: "address"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: "value",
|
|
112
|
+
type: "uint256"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: "data",
|
|
116
|
+
type: "bytes"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "operation",
|
|
120
|
+
type: "uint8"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: "safeTxGas",
|
|
124
|
+
type: "uint256"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: "baseGas",
|
|
128
|
+
type: "uint256"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: "gasPrice",
|
|
132
|
+
type: "uint256"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: "gasToken",
|
|
136
|
+
type: "address"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: "refundReceiver",
|
|
140
|
+
type: "address"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
name: "nonce",
|
|
144
|
+
type: "uint256"
|
|
145
|
+
}
|
|
146
|
+
] };
|
|
147
|
+
/** EIP-712 SafeTx hash (Safe ≥ 1.3 domain: chainId + verifyingContract). */
|
|
148
|
+
function hashSafeTx(params) {
|
|
149
|
+
return hashTypedData({
|
|
150
|
+
domain: {
|
|
151
|
+
chainId: params.chainId,
|
|
152
|
+
verifyingContract: params.safe
|
|
153
|
+
},
|
|
154
|
+
types: SAFE_TX_TYPES,
|
|
155
|
+
primaryType: "SafeTx",
|
|
156
|
+
message: params.tx
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* A wallet signing a plain call for a Safe owner (Rabby, Safe{Wallet}) signs it
|
|
161
|
+
* with no refund or gas fields; only the nonce varies.
|
|
162
|
+
*/
|
|
163
|
+
function safeTxForCall(call, nonce) {
|
|
164
|
+
return {
|
|
165
|
+
...call,
|
|
166
|
+
operation: 0,
|
|
167
|
+
safeTxGas: 0n,
|
|
168
|
+
baseGas: 0n,
|
|
169
|
+
gasPrice: 0n,
|
|
170
|
+
gasToken: zeroAddress,
|
|
171
|
+
refundReceiver: zeroAddress,
|
|
172
|
+
nonce
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/** True for a 65-byte ECDSA signature — what a Safe-owner wallet returns instead of a tx hash. */
|
|
176
|
+
function isSafeOwnerSignature(value) {
|
|
177
|
+
return typeof value === "string" && /^0x[0-9a-fA-F]{130}$/.test(value);
|
|
178
|
+
}
|
|
179
|
+
const SECP256K1_N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n;
|
|
180
|
+
const SUPPORTED_V = new Set([
|
|
181
|
+
0,
|
|
182
|
+
1,
|
|
183
|
+
27,
|
|
184
|
+
28,
|
|
185
|
+
31,
|
|
186
|
+
32
|
|
187
|
+
]);
|
|
188
|
+
/**
|
|
189
|
+
* Rejects anything that cannot be a Safe owner's ECDSA signature, without any
|
|
190
|
+
* RPC: 65 bytes, supported v (raw 0/1/27/28 or `eth_sign` 31/32), and r, s in
|
|
191
|
+
* the curve range.
|
|
192
|
+
*/
|
|
193
|
+
function assertSafeOwnerSignature(signature) {
|
|
194
|
+
if (!isSafeOwnerSignature(signature)) throw new SignedSafeTxError("INVALID_SIGNATURE", "expected a 65-byte ECDSA signature");
|
|
195
|
+
const r = hexToBigInt(sliceHex(signature, 0, 32));
|
|
196
|
+
const s = hexToBigInt(sliceHex(signature, 32, 64));
|
|
197
|
+
const v = hexToNumber(sliceHex(signature, 64, 65));
|
|
198
|
+
if (!SUPPORTED_V.has(v)) throw new SignedSafeTxError("INVALID_SIGNATURE", `unsupported signature v=${v}`);
|
|
199
|
+
if (r === 0n || r >= SECP256K1_N || s === 0n || s >= SECP256K1_N) throw new SignedSafeTxError("INVALID_SIGNATURE", "signature r/s out of range");
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Recovers the signer of `safeTxHash`, accepting raw ECDSA (v 27/28, or 0/1)
|
|
203
|
+
* and `eth_sign` (v 31/32) signatures, and returns the signature in the form
|
|
204
|
+
* the Safe verifies.
|
|
205
|
+
*/
|
|
206
|
+
async function recoverSafeTxSigner(safeTxHash, signature) {
|
|
207
|
+
assertSafeOwnerSignature(signature);
|
|
208
|
+
const rs = sliceHex(signature, 0, 64);
|
|
209
|
+
const v = hexToNumber(sliceHex(signature, 64, 65));
|
|
210
|
+
const ethSign = v === 31 || v === 32;
|
|
211
|
+
const normalized = ethSign ? signature : concatHex([rs, numberToHex(v < 27 ? v + 27 : v, { size: 1 })]);
|
|
212
|
+
try {
|
|
213
|
+
const signer = ethSign ? await recoverAddress({
|
|
214
|
+
hash: hashMessage({ raw: safeTxHash }),
|
|
215
|
+
signature: concatHex([rs, numberToHex(v - 4, { size: 1 })])
|
|
216
|
+
}) : await recoverAddress({
|
|
217
|
+
hash: safeTxHash,
|
|
218
|
+
signature: normalized
|
|
219
|
+
});
|
|
220
|
+
return {
|
|
221
|
+
signer,
|
|
222
|
+
signature: normalized
|
|
223
|
+
};
|
|
224
|
+
} catch (error) {
|
|
225
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
226
|
+
throw new SignedSafeTxError("INVALID_SIGNATURE", `signature recovery failed: ${reason}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Resolves an owner's signature over a plain call into an executable SafeTx,
|
|
231
|
+
* given the Safe's on-chain `nonce`, `owners` and `threshold`. The signed nonce
|
|
232
|
+
* is not part of the call, so it is searched from the on-chain nonce forward
|
|
233
|
+
* (wallets may sign ahead of queued transactions).
|
|
234
|
+
*/
|
|
235
|
+
async function resolveSignedSafeTx(params) {
|
|
236
|
+
const safe = getAddress(params.safe);
|
|
237
|
+
const nonceWindow = params.nonceWindow ?? 5;
|
|
238
|
+
const { nonce, threshold, owners } = params.state;
|
|
239
|
+
if (threshold !== 1n) throw new SignedSafeTxError("THRESHOLD_NOT_MET", `Safe threshold is ${threshold}; a single owner signature cannot execute`);
|
|
240
|
+
for (let offset = 0n; offset < BigInt(nonceWindow); offset++) {
|
|
241
|
+
const tx = safeTxForCall(params.call, nonce + offset);
|
|
242
|
+
const safeTxHash = hashSafeTx({
|
|
243
|
+
chainId: params.chainId,
|
|
244
|
+
safe,
|
|
245
|
+
tx
|
|
246
|
+
});
|
|
247
|
+
const { signer, signature } = await recoverSafeTxSigner(safeTxHash, params.signature);
|
|
248
|
+
if (owners.some((owner) => isAddressEqual(owner, signer))) return {
|
|
249
|
+
safe,
|
|
250
|
+
chainId: params.chainId,
|
|
251
|
+
tx,
|
|
252
|
+
safeTxHash,
|
|
253
|
+
signer,
|
|
254
|
+
signatures: signature
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
throw new SignedSafeTxError("SIGNATURE_MISMATCH", `signature does not recover to an owner of ${safe} for nonces ${nonce}..${nonce + BigInt(nonceWindow) - 1n}`);
|
|
258
|
+
}
|
|
259
|
+
/** `execTransaction` arguments for a resolved signed SafeTx. */
|
|
260
|
+
function execTransactionArgs(signed) {
|
|
261
|
+
const { tx } = signed;
|
|
262
|
+
return [
|
|
263
|
+
tx.to,
|
|
264
|
+
tx.value,
|
|
265
|
+
tx.data,
|
|
266
|
+
tx.operation,
|
|
267
|
+
tx.safeTxGas,
|
|
268
|
+
tx.baseGas,
|
|
269
|
+
tx.gasPrice,
|
|
270
|
+
tx.gasToken,
|
|
271
|
+
tx.refundReceiver,
|
|
272
|
+
signed.signatures
|
|
273
|
+
];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
//#endregion
|
|
277
|
+
export { SignedSafeTxError, assertSafeOwnerSignature, execTransactionArgs, hashSafeTx, isSafeOwnerSignature, recoverSafeTxSigner, resolveSignedSafeTx, safeAbi, safeTxForCall };
|
|
278
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["code: SignedSafeTxErrorCode","message: string","params: { chainId: number; safe: Address; tx: SafeTx }","call: SafeCall","nonce: bigint","value: unknown","signature: Hex","safeTxHash: Hex","params: {\n chainId: number\n safe: Address\n call: SafeCall\n signature: Hex\n state: { nonce: bigint; threshold: bigint; owners: readonly Address[] }\n nonceWindow?: number\n}","signed: SignedSafeTx"],"sources":["../../src/safe/signedSafeTx.ts"],"sourcesContent":["import {\n type Address,\n type Hex,\n concatHex,\n getAddress,\n hashMessage,\n hashTypedData,\n hexToBigInt,\n hexToNumber,\n isAddressEqual,\n numberToHex,\n recoverAddress,\n sliceHex,\n zeroAddress,\n} from 'viem'\n\nexport const safeAbi = [\n {\n type: 'event',\n name: 'ExecutionSuccess',\n inputs: [\n { name: 'txHash', type: 'bytes32', indexed: true },\n { name: 'payment', type: 'uint256', indexed: false },\n ],\n },\n {\n type: 'function',\n name: 'execTransaction',\n stateMutability: 'payable',\n inputs: [\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'data', type: 'bytes' },\n { name: 'operation', type: 'uint8' },\n { name: 'safeTxGas', type: 'uint256' },\n { name: 'baseGas', type: 'uint256' },\n { name: 'gasPrice', type: 'uint256' },\n { name: 'gasToken', type: 'address' },\n { name: 'refundReceiver', type: 'address' },\n { name: 'signatures', type: 'bytes' },\n ],\n outputs: [{ name: 'success', type: 'bool' }],\n },\n {\n type: 'function',\n name: 'VERSION',\n stateMutability: 'view',\n inputs: [],\n outputs: [{ type: 'string' }],\n },\n {\n type: 'function',\n name: 'nonce',\n stateMutability: 'view',\n inputs: [],\n outputs: [{ type: 'uint256' }],\n },\n {\n type: 'function',\n name: 'getThreshold',\n stateMutability: 'view',\n inputs: [],\n outputs: [{ type: 'uint256' }],\n },\n {\n type: 'function',\n name: 'getOwners',\n stateMutability: 'view',\n inputs: [],\n outputs: [{ type: 'address[]' }],\n },\n] as const\n\n/** A plain call the owner asked their wallet to send from the Safe. */\nexport interface SafeCall {\n to: Address\n value: bigint\n data: Hex\n}\n\nexport interface SafeTx extends SafeCall {\n operation: 0 | 1\n safeTxGas: bigint\n baseGas: bigint\n gasPrice: bigint\n gasToken: Address\n refundReceiver: Address\n nonce: bigint\n}\n\nexport interface SignedSafeTx {\n safe: Address\n chainId: number\n tx: SafeTx\n safeTxHash: Hex\n signer: Address\n /** Packed `signatures` argument for `execTransaction`. */\n signatures: Hex\n}\n\nexport type SignedSafeTxErrorCode = 'INVALID_SIGNATURE' | 'THRESHOLD_NOT_MET' | 'SIGNATURE_MISMATCH'\n\nexport class SignedSafeTxError extends Error {\n constructor(\n readonly code: SignedSafeTxErrorCode,\n message: string,\n ) {\n super(message)\n this.name = 'SignedSafeTxError'\n }\n}\n\nconst SAFE_TX_TYPES = {\n SafeTx: [\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'data', type: 'bytes' },\n { name: 'operation', type: 'uint8' },\n { name: 'safeTxGas', type: 'uint256' },\n { name: 'baseGas', type: 'uint256' },\n { name: 'gasPrice', type: 'uint256' },\n { name: 'gasToken', type: 'address' },\n { name: 'refundReceiver', type: 'address' },\n { name: 'nonce', type: 'uint256' },\n ],\n} as const\n\n/** EIP-712 SafeTx hash (Safe ≥ 1.3 domain: chainId + verifyingContract). */\nexport function hashSafeTx(params: { chainId: number; safe: Address; tx: SafeTx }): Hex {\n return hashTypedData({\n domain: { chainId: params.chainId, verifyingContract: params.safe },\n types: SAFE_TX_TYPES,\n primaryType: 'SafeTx',\n message: params.tx,\n })\n}\n\n/**\n * A wallet signing a plain call for a Safe owner (Rabby, Safe{Wallet}) signs it\n * with no refund or gas fields; only the nonce varies.\n */\nexport function safeTxForCall(call: SafeCall, nonce: bigint): SafeTx {\n return {\n ...call,\n operation: 0,\n safeTxGas: 0n,\n baseGas: 0n,\n gasPrice: 0n,\n gasToken: zeroAddress,\n refundReceiver: zeroAddress,\n nonce,\n }\n}\n\n/** True for a 65-byte ECDSA signature — what a Safe-owner wallet returns instead of a tx hash. */\nexport function isSafeOwnerSignature(value: unknown): value is Hex {\n return typeof value === 'string' && /^0x[0-9a-fA-F]{130}$/.test(value)\n}\n\nconst SECP256K1_N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n\nconst SUPPORTED_V = new Set([0, 1, 27, 28, 31, 32])\n\n/**\n * Rejects anything that cannot be a Safe owner's ECDSA signature, without any\n * RPC: 65 bytes, supported v (raw 0/1/27/28 or `eth_sign` 31/32), and r, s in\n * the curve range.\n */\nexport function assertSafeOwnerSignature(signature: Hex): void {\n if (!isSafeOwnerSignature(signature)) {\n throw new SignedSafeTxError('INVALID_SIGNATURE', 'expected a 65-byte ECDSA signature')\n }\n const r = hexToBigInt(sliceHex(signature, 0, 32))\n const s = hexToBigInt(sliceHex(signature, 32, 64))\n const v = hexToNumber(sliceHex(signature, 64, 65))\n if (!SUPPORTED_V.has(v)) {\n throw new SignedSafeTxError('INVALID_SIGNATURE', `unsupported signature v=${v}`)\n }\n if (r === 0n || r >= SECP256K1_N || s === 0n || s >= SECP256K1_N) {\n throw new SignedSafeTxError('INVALID_SIGNATURE', 'signature r/s out of range')\n }\n}\n\n/**\n * Recovers the signer of `safeTxHash`, accepting raw ECDSA (v 27/28, or 0/1)\n * and `eth_sign` (v 31/32) signatures, and returns the signature in the form\n * the Safe verifies.\n */\nexport async function recoverSafeTxSigner(\n safeTxHash: Hex,\n signature: Hex,\n): Promise<{ signer: Address; signature: Hex }> {\n assertSafeOwnerSignature(signature)\n const rs = sliceHex(signature, 0, 64)\n const v = hexToNumber(sliceHex(signature, 64, 65))\n const ethSign = v === 31 || v === 32\n const normalized = ethSign\n ? signature\n : concatHex([rs, numberToHex(v < 27 ? v + 27 : v, { size: 1 })])\n try {\n const signer = ethSign\n ? await recoverAddress({\n hash: hashMessage({ raw: safeTxHash }),\n signature: concatHex([rs, numberToHex(v - 4, { size: 1 })]),\n })\n : await recoverAddress({ hash: safeTxHash, signature: normalized })\n return { signer, signature: normalized }\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error)\n throw new SignedSafeTxError('INVALID_SIGNATURE', `signature recovery failed: ${reason}`)\n }\n}\n\n/**\n * Resolves an owner's signature over a plain call into an executable SafeTx,\n * given the Safe's on-chain `nonce`, `owners` and `threshold`. The signed nonce\n * is not part of the call, so it is searched from the on-chain nonce forward\n * (wallets may sign ahead of queued transactions).\n */\nexport async function resolveSignedSafeTx(params: {\n chainId: number\n safe: Address\n call: SafeCall\n signature: Hex\n state: { nonce: bigint; threshold: bigint; owners: readonly Address[] }\n nonceWindow?: number\n}): Promise<SignedSafeTx> {\n const safe = getAddress(params.safe)\n const nonceWindow = params.nonceWindow ?? 5\n const { nonce, threshold, owners } = params.state\n if (threshold !== 1n) {\n throw new SignedSafeTxError(\n 'THRESHOLD_NOT_MET',\n `Safe threshold is ${threshold}; a single owner signature cannot execute`,\n )\n }\n\n for (let offset = 0n; offset < BigInt(nonceWindow); offset++) {\n const tx = safeTxForCall(params.call, nonce + offset)\n const safeTxHash = hashSafeTx({ chainId: params.chainId, safe, tx })\n const { signer, signature } = await recoverSafeTxSigner(safeTxHash, params.signature)\n if (owners.some((owner) => isAddressEqual(owner, signer))) {\n return { safe, chainId: params.chainId, tx, safeTxHash, signer, signatures: signature }\n }\n }\n throw new SignedSafeTxError(\n 'SIGNATURE_MISMATCH',\n `signature does not recover to an owner of ${safe} for nonces ${nonce}..${nonce + BigInt(nonceWindow) - 1n}`,\n )\n}\n\n/** `execTransaction` arguments for a resolved signed SafeTx. */\nexport function execTransactionArgs(signed: SignedSafeTx) {\n const { tx } = signed\n return [\n tx.to,\n tx.value,\n tx.data,\n tx.operation,\n tx.safeTxGas,\n tx.baseGas,\n tx.gasPrice,\n tx.gasToken,\n tx.refundReceiver,\n signed.signatures,\n ] as const\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { UniswapV3PoolAbi, applyOwedInterest, getAccountBuyingPower, getAccountCollateral, getNetLiquidationValue, panopticQueryAbi$1 as panopticQueryAbi, readBlockAndAggregate, requireReturnData } from "./irm-
|
|
2
|
-
import { AccountInsolventError, ChunkLimitError, DEFAULT_VEGOID, InvalidHistoryRangeError, MulticallResultMissingError, NotEnoughTokensError, PanopticError, PanopticValidationError, SafeModeError, StaleDataError, StorageDataNotFoundError, UnhealthyPoolError, WrongUniswapPoolError, applyMintBufferPerToken, availableToBorrow, collateralTrackerV2Abi, decodeLeftRightSigned, decodeLeftRightUnsigned, decodePositionBalance, getBlockMeta, getClosedPositionsKey, getPendingPositionsKey, getPool, getPoolMetaKey, getPoolMetadata, getPositionMetaKey, getPositionsKey, getTrackedChunksKey, getTrackedPositionIds, isPanopticErrorType, jsonSerializer, mintableAfterBuffer, panopticFactoryV3Abi, panopticFactoryV4Abi, panopticGuardianAbi, panopticLiquidatorAbi, panopticPoolV2Abi, panopticQueryAbi as panopticQueryAbi$1, parsePanopticError, riskEngineAbi, riskEngineMulticall, semiFungiblePositionManagerV3Abi, semiFungiblePositionManagerV4Abi, stateViewAbi, uniswapV3PoolAbi } from "./rates-
|
|
1
|
+
import { UniswapV3PoolAbi, applyOwedInterest, getAccountBuyingPower, getAccountCollateral, getNetLiquidationValue, panopticQueryAbi$1 as panopticQueryAbi, readBlockAndAggregate, requireReturnData } from "./irm-BntFNP1P.js";
|
|
2
|
+
import { AccountInsolventError, ChunkLimitError, DEFAULT_VEGOID, InvalidHistoryRangeError, MulticallResultMissingError, NotEnoughTokensError, PanopticError, PanopticValidationError, SafeModeError, StaleDataError, StorageDataNotFoundError, UnhealthyPoolError, WrongUniswapPoolError, addLegToTokenId, applyMintBufferPerToken, availableToBorrow, collateralTrackerV2Abi, countLegs, decodeAllLegs, decodeLeftRightSigned, decodeLeftRightUnsigned, decodePositionBalance, decodeTokenId, getBlockMeta, getClosedPositionsKey, getPendingPositionsKey, getPool, getPoolMetaKey, getPoolMetadata, getPositionMetaKey, getPositionsKey, getTrackedChunksKey, getTrackedPositionIds, isPanopticErrorType, jsonSerializer, mintableAfterBuffer, panopticFactoryV3Abi, panopticFactoryV4Abi, panopticGuardianAbi, panopticLiquidatorAbi, panopticPoolV2Abi, panopticQueryAbi as panopticQueryAbi$1, parsePanopticError, riskEngineAbi, riskEngineMulticall, semiFungiblePositionManagerV3Abi, semiFungiblePositionManagerV4Abi, stateViewAbi, uniswapV3PoolAbi } from "./rates-c9XVKm3m.js";
|
|
3
3
|
import { MAX_TICK, MAX_TRACKED_CHUNKS, MIN_TICK, NO_LOWER_LIQUIDATION_TICK, NO_UPPER_LIQUIDATION_TICK, WAD, calculatePositionDelta, calculatePositionDeltaDebtOnly, calculatePositionGamma, calculatePositionValue, getLegLiquidityRange, priceToTick, sqrtPriceX96ToTick, tickLimits, tickToPriceDecimalScaled, tickToSqrtPriceX96, toVaultFrameAtTick } from "./greeks-CEv-Uex1.js";
|
|
4
|
-
import {
|
|
5
|
-
import { feesFromFeeGrowthDelta, getLpPositionFunding, getMaxLpPositionSize, getPriceHistory, preparePositionGamma, quoteSwapExactOutViaRouter, quoteSwapExactOutViaV3Router } from "./router-
|
|
6
|
-
import { ContractFunctionExecutionError, decodeFunctionResult, encodeAbiParameters, encodeFunctionData, getAddress, hexToString, isAddress, isAddressEqual, isHex, keccak256,
|
|
7
|
-
import { multicall } from "viem/actions";
|
|
4
|
+
import { buildBatchDispatchArgs, buildProtectedSettlePlan, buildSettleSequenceCalls, buildUniqueCredit, buildUniqueLoan, createTokenIdBuilder, getCurrentPositionSizes, getPoolTokensForSimulation, loadCheckpoint, resolveTokenIndex, simulateDispatch, simulateOpenPosition, simulateWithTokenFlow } from "./writes-_ZxthOkP.js";
|
|
5
|
+
import { feesFromFeeGrowthDelta, getLpPositionFunding, getMaxLpPositionSize, getPriceHistory, preparePositionGamma, quoteSwapExactOutViaRouter, quoteSwapExactOutViaV3Router } from "./router-lUA1kp8A.js";
|
|
6
|
+
import { ContractFunctionExecutionError, decodeFunctionResult, encodeAbiParameters, encodeFunctionData, getAddress, hexToString, isAddress, isAddressEqual, isHex, keccak256, parseEventLogs, trim, zeroAddress } from "viem";
|
|
8
7
|
import Decimal from "decimal.js";
|
|
8
|
+
import { multicall } from "viem/actions";
|
|
9
9
|
|
|
10
10
|
//#region src/panoptic/v2/clients/blocksByTimestamp.ts
|
|
11
11
|
/**
|
|
@@ -1464,10 +1464,10 @@ async function getChunkLiquidities(params) {
|
|
|
1464
1464
|
*/
|
|
1465
1465
|
async function getFactoryTokenURI(params) {
|
|
1466
1466
|
const { client, factoryAddress, version, tokenId } = params;
|
|
1467
|
-
const abi
|
|
1467
|
+
const abi = version === "v3" ? panopticFactoryV3Abi : panopticFactoryV4Abi;
|
|
1468
1468
|
return client.readContract({
|
|
1469
1469
|
address: factoryAddress,
|
|
1470
|
-
abi
|
|
1470
|
+
abi,
|
|
1471
1471
|
functionName: "tokenURI",
|
|
1472
1472
|
args: [tokenId]
|
|
1473
1473
|
});
|
|
@@ -1477,10 +1477,10 @@ async function getFactoryTokenURI(params) {
|
|
|
1477
1477
|
*/
|
|
1478
1478
|
async function getFactoryOwnerOf(params) {
|
|
1479
1479
|
const { client, factoryAddress, version, tokenId } = params;
|
|
1480
|
-
const abi
|
|
1480
|
+
const abi = version === "v3" ? panopticFactoryV3Abi : panopticFactoryV4Abi;
|
|
1481
1481
|
return client.readContract({
|
|
1482
1482
|
address: factoryAddress,
|
|
1483
|
-
abi
|
|
1483
|
+
abi,
|
|
1484
1484
|
functionName: "ownerOf",
|
|
1485
1485
|
args: [tokenId]
|
|
1486
1486
|
});
|
|
@@ -1490,10 +1490,10 @@ async function getFactoryOwnerOf(params) {
|
|
|
1490
1490
|
*/
|
|
1491
1491
|
async function getFactoryConstructMetadata(params) {
|
|
1492
1492
|
const { client, factoryAddress, version, panopticPoolAddress, symbol0, symbol1, fee } = params;
|
|
1493
|
-
const abi
|
|
1493
|
+
const abi = version === "v3" ? panopticFactoryV3Abi : panopticFactoryV4Abi;
|
|
1494
1494
|
return client.readContract({
|
|
1495
1495
|
address: factoryAddress,
|
|
1496
|
-
abi
|
|
1496
|
+
abi,
|
|
1497
1497
|
functionName: "constructMetadata",
|
|
1498
1498
|
args: [
|
|
1499
1499
|
panopticPoolAddress,
|
|
@@ -10303,84 +10303,6 @@ async function getCollateralCurve({ client, poolAddress, account, queryAddress,
|
|
|
10303
10303
|
};
|
|
10304
10304
|
}
|
|
10305
10305
|
|
|
10306
|
-
//#endregion
|
|
10307
|
-
//#region src/panoptic/v2/reads/positionValueCurve.ts
|
|
10308
|
-
const abi = parseAbi(["function computeNetLiquidationValue(uint256[] positionIdList, uint256 shortPremium, uint256 longPremium, uint256[] positionBalanceArray, int24[] atTicks) pure returns (int256[] value0, int256[] value1)"]);
|
|
10309
|
-
/** Stable identity for a position-dependent curve; streamia and spot are separate inputs. */
|
|
10310
|
-
function positionValueKey(positions) {
|
|
10311
|
-
return [...positions].sort((a, b) => a.tokenId < b.tokenId ? -1 : a.tokenId > b.tokenId ? 1 : 0).map(({ tokenId, positionSize }) => `${tokenId}:${positionSize}`).join(",");
|
|
10312
|
-
}
|
|
10313
|
-
/** All changes in the curve's active liquidity, independent of the current market tick. */
|
|
10314
|
-
function positionValueTicks(positions) {
|
|
10315
|
-
const ticks = new Set([-887272n, 887272n]);
|
|
10316
|
-
for (const { tokenId, positionSize } of positions) {
|
|
10317
|
-
if (tokenId < 0n || tokenId >= 1n << 256n || positionSize <= 0n || positionSize >= 1n << 128n) throw new RangeError("Invalid position id or size");
|
|
10318
|
-
const { legs, tickSpacing } = decodeTokenId(tokenId);
|
|
10319
|
-
for (const leg of legs) {
|
|
10320
|
-
if (leg.width === 0n) continue;
|
|
10321
|
-
const width = leg.width * tickSpacing;
|
|
10322
|
-
const lower = leg.strike - width / 2n;
|
|
10323
|
-
const upper = leg.strike + (width + 1n) / 2n;
|
|
10324
|
-
if (lower < -887272n || upper > 887272n || lower >= upper) throw new RangeError("Invalid position range");
|
|
10325
|
-
ticks.add(lower);
|
|
10326
|
-
ticks.add(upper);
|
|
10327
|
-
}
|
|
10328
|
-
}
|
|
10329
|
-
return [...ticks].sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
10330
|
-
}
|
|
10331
|
-
/** Read the immutable, premium-free part of NLV from the deployed pure calculation. */
|
|
10332
|
-
async function getPositionValueCurve({ client, queryAddress, positions }) {
|
|
10333
|
-
const ticks = positionValueTicks(positions);
|
|
10334
|
-
const [values0, values1] = await client.readContract({
|
|
10335
|
-
address: queryAddress,
|
|
10336
|
-
abi,
|
|
10337
|
-
functionName: "computeNetLiquidationValue",
|
|
10338
|
-
args: [
|
|
10339
|
-
positions.map((p) => p.tokenId),
|
|
10340
|
-
0n,
|
|
10341
|
-
0n,
|
|
10342
|
-
positions.map((p) => p.positionSize),
|
|
10343
|
-
ticks.map(Number)
|
|
10344
|
-
]
|
|
10345
|
-
});
|
|
10346
|
-
return ticks.map((tick, i) => ({
|
|
10347
|
-
tick,
|
|
10348
|
-
value0: values0[i],
|
|
10349
|
-
value1: values1[i]
|
|
10350
|
-
}));
|
|
10351
|
-
}
|
|
10352
|
-
/**
|
|
10353
|
-
* Between leg boundaries, token0 is affine in inverse sqrt price and token1 in sqrt price.
|
|
10354
|
-
* Endpoint interpolation differs from contract integer rounding by at most a few wei per leg.
|
|
10355
|
-
*/
|
|
10356
|
-
function preparePositionValueCurve(curve) {
|
|
10357
|
-
if (curve.length < 2) throw new RangeError("Incomplete position value curve");
|
|
10358
|
-
for (let i = 0; i < curve.length; i++) if (curve[i].tick < -887272n || curve[i].tick > 887272n || i > 0 && curve[i].tick <= curve[i - 1].tick) throw new RangeError("Invalid position value curve ticks");
|
|
10359
|
-
const points = curve.map((point) => ({
|
|
10360
|
-
...point,
|
|
10361
|
-
sqrt: tickToSqrtPriceX96(point.tick)
|
|
10362
|
-
}));
|
|
10363
|
-
return (tick) => {
|
|
10364
|
-
if (tick < points[0].tick || tick > points[points.length - 1].tick) throw new RangeError("Tick outside position value curve");
|
|
10365
|
-
let lo = 0;
|
|
10366
|
-
let hi = points.length - 1;
|
|
10367
|
-
while (hi - lo > 1) {
|
|
10368
|
-
const mid = Math.floor((lo + hi) / 2);
|
|
10369
|
-
if (points[mid].tick <= tick) lo = mid;
|
|
10370
|
-
else hi = mid;
|
|
10371
|
-
}
|
|
10372
|
-
const left = points[lo];
|
|
10373
|
-
const right = points[hi];
|
|
10374
|
-
const sqrt = tickToSqrtPriceX96(tick);
|
|
10375
|
-
const numerator = sqrt - left.sqrt;
|
|
10376
|
-
const denominator = right.sqrt - left.sqrt;
|
|
10377
|
-
return {
|
|
10378
|
-
value0: left.value0 + (right.value0 - left.value0) * numerator * right.sqrt / (denominator * sqrt),
|
|
10379
|
-
value1: left.value1 + (right.value1 - left.value1) * numerator / denominator
|
|
10380
|
-
};
|
|
10381
|
-
};
|
|
10382
|
-
}
|
|
10383
|
-
|
|
10384
10306
|
//#endregion
|
|
10385
10307
|
//#region src/panoptic/v2/reads/positionVolatilityHistory.ts
|
|
10386
10308
|
const signedSlot = (value) => BigInt.asIntN(128, value);
|
|
@@ -10597,4 +10519,4 @@ async function getPositionVolatilityHistory({ client, poolAddress, account, toke
|
|
|
10597
10519
|
}
|
|
10598
10520
|
|
|
10599
10521
|
//#endregion
|
|
10600
|
-
export { DEFAULT_MIN_SWAP_RATIO_BPS, DEFAULT_RECONNECT_CONFIG, MARKET_INDICATOR_PERIODS, REQUIRED_BASE_ERROR_SENTINEL, STRIKE_LADDER_TARGET_STRIKES, VARIANCE_RATIO_LAG, addPendingPosition, addTrackedChunks, apportion, assertCanBurn, assertCanForceExercise, assertCanLiquidate, assertCanMint, assertFresh, assertHealthy, assertLpPositionFunded, assertTradeable, buildCreditWrappedDispatch, buildSfpmSwapCalldata, buildSfpmSwapPlan, buildTemporaryLoanRecoveryDispatch, buildTokenShortfallRecoveryDispatch, calculateAccountGreeksPure, calculateMarketIndicator, calculateSpreadWad, calculateVarianceProfile, checkCollateralAcrossTicks, classifyStrategyGroups, classifyStrike, cleanupStalePendingPositions, clearPendingPositions, clearTrackedChunks, clearTradeHistory, collateralCurveTicks, collateralRuleKindFor, computeV4PoolId, confirmPendingPosition, convertToAssets, convertToShares, createEventPoller, createEventSubscription, createFlowNeutralTokenId, decodePanopticTokenURI, emptyLiquidateParams, encodePoolKeyBytes, encodeV3PoolKeyBytes, ensureSfpmV3PoolInitialized, estimateBlockNumbers, estimateCloseZapSwap, estimateCollateralBreakdown, estimateCollateralRequired, failPendingPosition, feeGrowthInsideX128, fetchPoolSwaps, fetchSfpmV3PoolId, fetchUniswapFeeData, getAccountGreeks, getAccountHistory, getChunkLiquidities, getChunkSpreads, getClosePositionTransferEstimate, getClosedPositions, getCollateralCurve, getCollateralCurveInputs, getCollateralRequiredBase, getCollateralSharePrices, getCollateralTotalAssetsBatch, getDeltaHedgeParams, getEnforcedTickLimits, getExecutableLpMaxSize, getFactoryConstructMetadata, getFactoryOwnerOf, getFactoryTokenURI, getGuardianUnlockState, getHedgeLimits, getItmAmounts, getMarginBuffer, getMaxPositionSize, getMaxRedeem, getMaxWithdrawable, getNativeTokenPrice, getNotEnoughTokensError, getOpenPositionPreview, getPanopticPoolAddress, getPanopticPoolFromPoolId, getPendingPositions, getPoolLiquidities, getPortfolioValue, getPositionChunkData, getPositionEnrichmentData, getPositionMintFunding,
|
|
10522
|
+
export { DEFAULT_MIN_SWAP_RATIO_BPS, DEFAULT_RECONNECT_CONFIG, MARKET_INDICATOR_PERIODS, REQUIRED_BASE_ERROR_SENTINEL, STRIKE_LADDER_TARGET_STRIKES, VARIANCE_RATIO_LAG, addPendingPosition, addTrackedChunks, apportion, assertCanBurn, assertCanForceExercise, assertCanLiquidate, assertCanMint, assertFresh, assertHealthy, assertLpPositionFunded, assertTradeable, buildCreditWrappedDispatch, buildSfpmSwapCalldata, buildSfpmSwapPlan, buildTemporaryLoanRecoveryDispatch, buildTokenShortfallRecoveryDispatch, calculateAccountGreeksPure, calculateMarketIndicator, calculateSpreadWad, calculateVarianceProfile, checkCollateralAcrossTicks, classifyStrategyGroups, classifyStrike, cleanupStalePendingPositions, clearPendingPositions, clearTrackedChunks, clearTradeHistory, collateralCurveTicks, collateralRuleKindFor, computeV4PoolId, confirmPendingPosition, convertToAssets, convertToShares, createEventPoller, createEventSubscription, createFlowNeutralTokenId, decodePanopticTokenURI, emptyLiquidateParams, encodePoolKeyBytes, encodeV3PoolKeyBytes, ensureSfpmV3PoolInitialized, estimateBlockNumbers, estimateCloseZapSwap, estimateCollateralBreakdown, estimateCollateralRequired, failPendingPosition, feeGrowthInsideX128, fetchPoolSwaps, fetchSfpmV3PoolId, fetchUniswapFeeData, getAccountGreeks, getAccountHistory, getChunkLiquidities, getChunkSpreads, getClosePositionTransferEstimate, getClosedPositions, getCollateralCurve, getCollateralCurveInputs, getCollateralRequiredBase, getCollateralSharePrices, getCollateralTotalAssetsBatch, getDeltaHedgeParams, getEnforcedTickLimits, getExecutableLpMaxSize, getFactoryConstructMetadata, getFactoryOwnerOf, getFactoryTokenURI, getGuardianUnlockState, getHedgeLimits, getItmAmounts, getMarginBuffer, getMaxPositionSize, getMaxRedeem, getMaxWithdrawable, getNativeTokenPrice, getNotEnoughTokensError, getOpenPositionPreview, getPanopticPoolAddress, getPanopticPoolFromPoolId, getPendingPositions, getPoolLiquidities, getPortfolioValue, getPositionChunkData, getPositionEnrichmentData, getPositionMintFunding, getPositionVolatilityHistory, getRealizedPnL, getRequiredCreditForITM, getSafeMode, getStreamiaHistory, getSyncStatus, getTrackedChunks, getTradeHistory, getUniswapFeeHistory, getUniswapV3PoolFromId, getUniswapV3PoolInfo, getUniswapV3PoolLiquidities, getUniswapV4PoolBasicState, getUniswapV4PoolInfo, getUniswapV4PoolKeyFromId, getUniswapV4PoolLiquidities, interpolateBlocks, isGasError, isNonceError, isRetryableRpcError, isolateGroupTokenId, ladderStrikeSequence, logReturns, marketPnlInQuote, marketRiskFromValues, marketScenario, minePoolAddress, minePoolAddressLocalAsync, multicallRead, netLiquidationValueInQuote, optimizeTokenIdRiskPartners, parseCollateralLog, parsePoolLog, parseStreamedKey, parseStreamedSwap, parseSwapLog, prepareIndicatorCandles, previewDeposit, previewMint, previewRedeem, previewWithdraw, quoteLiquidation, quoteOneTokenFlow, quoteSfpmSwap, quoteTemporaryLoanRecovery, quoteTokenShortfallRecovery, quoteTokenShortfallSwap, realizedBeta, removeTrackedChunks, resolveBlockNumbers, resolveLadderStrike, resolvePanopticPoolFromPoolId, resolveUniswapV4PoolKey, saveClosedPosition, scaleCollateralRequired, scanChunks, screenAccountExact, simulateBatchDispatch, simulateClosePosition, simulateClosePremiumProtection, simulateDeployNewPool, simulateDeposit, simulateForceExercise, simulateLiquidate, simulateSFPMBurn, simulateSFPMMint, simulateSwapExactIn, simulateSwapExactOut, simulateWithdraw, slippageBpsToTickDistance, streamPoolSwaps, subscribePoolSwaps, watchEvents, watchPoolSwaps };
|