@masterpeach/market-sdk 0.2.0-beta.20260930.1

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/index.js ADDED
@@ -0,0 +1,2705 @@
1
+ import {
2
+ createPreparedTransactionStore,
3
+ immutableClone,
4
+ resolveLiveWalletAccount,
5
+ transactionResultFromReceipt
6
+ } from "./chunk-TMU4HSZR.js";
7
+ import {
8
+ marketAccessManagerAbi,
9
+ marketClaimFeePolicyAbi,
10
+ marketExtsloadAbi,
11
+ marketMarketCalendarAbi,
12
+ marketPoolRegistryAbi,
13
+ marketRampAbi,
14
+ marketRampReaderAbi,
15
+ marketRwaRampAbi,
16
+ marketStateViewAbi
17
+ } from "./chunk-TTVBOGKZ.js";
18
+
19
+ // src/actions/authorizations.ts
20
+ import { getAddress as getAddress3 } from "viem";
21
+
22
+ // src/errors.ts
23
+ var InvalidMarketConfigError = class extends Error {
24
+ constructor(field, message) {
25
+ super(message);
26
+ this.field = field;
27
+ this.name = "InvalidMarketConfigError";
28
+ }
29
+ field;
30
+ };
31
+ var MarketDeploymentVerificationError = class extends Error {
32
+ constructor(field, expected, actual) {
33
+ super(`Market deployment mismatch: ${field}.`);
34
+ this.field = field;
35
+ this.expected = expected;
36
+ this.actual = actual;
37
+ this.name = "MarketDeploymentVerificationError";
38
+ }
39
+ field;
40
+ expected;
41
+ actual;
42
+ };
43
+ var MarketReadError = class extends Error {
44
+ constructor(cause) {
45
+ super("Market RPC read failed. Inspect cause for transport or contract revert details.", {
46
+ cause
47
+ });
48
+ this.name = "MarketReadError";
49
+ }
50
+ };
51
+ var MarketFeatureUnavailableError = class extends Error {
52
+ constructor(feature) {
53
+ super(`Market feature is unavailable for this configuration: ${feature}.`);
54
+ this.feature = feature;
55
+ this.name = "MarketFeatureUnavailableError";
56
+ }
57
+ feature;
58
+ };
59
+ var MarketSettlingError = class extends Error {
60
+ constructor(hook2) {
61
+ super("The Market ledger is settling; a consistent position snapshot is unavailable.");
62
+ this.hook = hook2;
63
+ this.name = "MarketSettlingError";
64
+ }
65
+ hook;
66
+ };
67
+ var MarketTransactionError = class extends Error {
68
+ constructor(stage, cause) {
69
+ super(
70
+ `Market transaction ${stage} failed. Inspect cause for RPC, signature or contract details.`,
71
+ { cause }
72
+ );
73
+ this.stage = stage;
74
+ this.name = "MarketTransactionError";
75
+ }
76
+ stage;
77
+ };
78
+ var MarketTransactionReplacedError = class extends Error {
79
+ constructor(originalHash, replacementHash, reason) {
80
+ super(`Market transaction was ${reason}; inspect the replacement before continuing.`);
81
+ this.originalHash = originalHash;
82
+ this.replacementHash = replacementHash;
83
+ this.reason = reason;
84
+ this.name = "MarketTransactionReplacedError";
85
+ }
86
+ originalHash;
87
+ replacementHash;
88
+ reason;
89
+ };
90
+
91
+ // src/math/identifiers.ts
92
+ import {
93
+ encodeAbiParameters,
94
+ getAddress,
95
+ isAddress,
96
+ isAddressEqual,
97
+ keccak256,
98
+ zeroAddress
99
+ } from "viem";
100
+ function assertMarketUint(value, field, bits = 256) {
101
+ if (typeof value !== "bigint" || value < 0n || value >= 1n << BigInt(bits)) {
102
+ throw new InvalidMarketConfigError(field, `Expected a uint${bits} bigint.`);
103
+ }
104
+ }
105
+ function assertMarketPoolId(value) {
106
+ if (!/^0x[0-9a-fA-F]{64}$/.test(value)) {
107
+ throw new InvalidMarketConfigError("poolId", "Expected a 32-byte pool ID.");
108
+ }
109
+ }
110
+ function assertMarketAddress(address, field, allowNative = false) {
111
+ if (!isAddress(address) || !allowNative && isAddressEqual(address, zeroAddress)) {
112
+ throw new InvalidMarketConfigError(field, "Expected a valid non-zero address.");
113
+ }
114
+ }
115
+ function defineMarketPoolKey(key) {
116
+ assertMarketAddress(key.currency0, "currency0", true);
117
+ assertMarketAddress(key.currency1, "currency1");
118
+ assertMarketAddress(key.hooks, "hooks");
119
+ if (BigInt(key.currency0) >= BigInt(key.currency1)) {
120
+ throw new InvalidMarketConfigError(
121
+ "currencies",
122
+ "Currencies must be distinct and sorted by address."
123
+ );
124
+ }
125
+ if (key.fee !== 8388608) {
126
+ throw new InvalidMarketConfigError(
127
+ "fee",
128
+ "Peach Market pools require the v4 dynamic fee flag."
129
+ );
130
+ }
131
+ if (!Number.isInteger(key.tickSpacing) || key.tickSpacing < 1 || key.tickSpacing > 32767) {
132
+ throw new InvalidMarketConfigError("tickSpacing", "Expected v4 tick spacing in [1, 32767].");
133
+ }
134
+ return Object.freeze({
135
+ currency0: getAddress(key.currency0),
136
+ currency1: getAddress(key.currency1),
137
+ fee: key.fee,
138
+ tickSpacing: key.tickSpacing,
139
+ hooks: getAddress(key.hooks)
140
+ });
141
+ }
142
+ function getMarketPoolId(input) {
143
+ const key = defineMarketPoolKey(input);
144
+ return keccak256(
145
+ encodeAbiParameters(
146
+ [
147
+ { type: "address" },
148
+ { type: "address" },
149
+ { type: "uint24" },
150
+ { type: "int24" },
151
+ { type: "address" }
152
+ ],
153
+ [key.currency0, key.currency1, key.fee, key.tickSpacing, key.hooks]
154
+ )
155
+ );
156
+ }
157
+ function getMarketRangeId(poolId, tickLower, tickUpper, tickSpacing = 1) {
158
+ assertMarketPoolId(poolId);
159
+ if (!Number.isInteger(tickSpacing) || tickSpacing < 1 || tickSpacing > 32767) {
160
+ throw new InvalidMarketConfigError("tickSpacing", "Expected v4 tick spacing in [1, 32767].");
161
+ }
162
+ if (!Number.isInteger(tickLower) || !Number.isInteger(tickUpper) || tickLower < -887272 || tickUpper > 887272 || tickLower >= tickUpper || tickLower % tickSpacing !== 0 || tickUpper % tickSpacing !== 0) {
163
+ throw new InvalidMarketConfigError(
164
+ "ticks",
165
+ "Expected ordered, aligned ticks in the v4 tick range."
166
+ );
167
+ }
168
+ return BigInt(
169
+ keccak256(
170
+ encodeAbiParameters(
171
+ [{ type: "bytes32" }, { type: "int24" }, { type: "int24" }],
172
+ [poolId, tickLower, tickUpper]
173
+ )
174
+ )
175
+ );
176
+ }
177
+ function getMarketSwapDirection(key, base, quote, side) {
178
+ const normalized = defineMarketPoolKey(key);
179
+ assertMarketAddress(base, "base", true);
180
+ assertMarketAddress(quote, "quote", true);
181
+ const baseIs0 = isAddressEqual(base, normalized.currency0) && isAddressEqual(quote, normalized.currency1);
182
+ const baseIs1 = isAddressEqual(base, normalized.currency1) && isAddressEqual(quote, normalized.currency0);
183
+ if (!baseIs0 && !baseIs1 || side !== "buy" && side !== "sell") {
184
+ throw new InvalidMarketConfigError(
185
+ "direction",
186
+ "Base/quote must match both pool currencies and side must be buy/sell."
187
+ );
188
+ }
189
+ return side === "sell" ? baseIs0 : baseIs1;
190
+ }
191
+
192
+ // src/actions/snapshot.ts
193
+ import { isAddressEqual as isAddressEqual2, keccak256 as keccak2562 } from "viem";
194
+
195
+ // src/deployment.ts
196
+ import { getAddress as getAddress2, isAddress as isAddress2, zeroAddress as zeroAddress2 } from "viem";
197
+ function invalid(field, message) {
198
+ throw new InvalidMarketConfigError(field, message);
199
+ }
200
+ function contract(input, field) {
201
+ if (!isAddress2(input.address) || input.address.toLowerCase() === zeroAddress2) {
202
+ invalid(`${field}.address`, "Expected a non-zero EVM address.");
203
+ }
204
+ if (!/^0x[0-9a-fA-F]{64}$/.test(input.runtimeCodeHash) || /^0x0+$/.test(input.runtimeCodeHash)) {
205
+ invalid(`${field}.runtimeCodeHash`, "Expected a non-zero 32-byte runtime code hash.");
206
+ }
207
+ return Object.freeze({
208
+ address: getAddress2(input.address),
209
+ runtimeCodeHash: input.runtimeCodeHash
210
+ });
211
+ }
212
+ var capabilityKeys = ["liquidity", "nativeLiquidity", "claimOperator", "management"];
213
+ function hook(input, index) {
214
+ const field = `hooks.${index}`;
215
+ if (!["ramp", "ramp-eth", "rwa-ramp"].includes(input.kind)) {
216
+ invalid(`${field}.kind`, "Unsupported Market Hook kind.");
217
+ }
218
+ if (input.implementation !== "ramp-v1") {
219
+ invalid(`${field}.implementation`, "Unsupported Market implementation.");
220
+ }
221
+ if (input.kind === "rwa-ramp" !== (input.calendar !== void 0)) {
222
+ invalid(`${field}.calendar`, "Only RWA Hooks must include a calendar.");
223
+ }
224
+ for (const key of capabilityKeys) {
225
+ if (!["disabled", "unverified", "verified"].includes(input.capabilities[key])) {
226
+ invalid(`${field}.capabilities.${key}`, "Explicit capability acceptance status is required.");
227
+ }
228
+ }
229
+ if (input.kind !== "ramp-eth" && input.capabilities.nativeLiquidity !== "disabled") {
230
+ invalid(`${field}.capabilities.nativeLiquidity`, "Native liquidity requires RampETH.");
231
+ }
232
+ const capabilities = Object.freeze({
233
+ liquidity: input.capabilities.liquidity,
234
+ nativeLiquidity: input.capabilities.nativeLiquidity,
235
+ claimOperator: input.capabilities.claimOperator,
236
+ management: input.capabilities.management
237
+ });
238
+ return Object.freeze({
239
+ ...contract(input, field),
240
+ kind: input.kind,
241
+ implementation: input.implementation,
242
+ claimFeePolicy: contract(input.claimFeePolicy, `${field}.claimFeePolicy`),
243
+ ...input.calendar ? { calendar: contract(input.calendar, `${field}.calendar`) } : {},
244
+ capabilities
245
+ });
246
+ }
247
+ function defineMarketDeployment(input) {
248
+ if (!Number.isSafeInteger(input.chainId) || input.chainId <= 0) {
249
+ invalid("chainId", "Expected a positive safe integer.");
250
+ }
251
+ if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(input.deploymentId)) {
252
+ invalid("deploymentId", "Expected a non-empty lowercase deployment identifier.");
253
+ }
254
+ if (input.hooks.length === 0) invalid("hooks", "At least one supported Hook is required.");
255
+ const hooks = input.hooks.map(hook);
256
+ if (new Set(hooks.map((entry) => entry.address)).size !== hooks.length) {
257
+ invalid("hooks", "Duplicate Hook addresses are not allowed.");
258
+ }
259
+ let poolStateReader;
260
+ if (input.poolStateReader?.kind === "state-view") {
261
+ poolStateReader = Object.freeze({
262
+ kind: "state-view",
263
+ contract: contract(input.poolStateReader.contract, "poolStateReader.contract")
264
+ });
265
+ } else if (input.poolStateReader?.kind === "extsload") {
266
+ if (input.poolStateReader.layout !== "uniswap-v4-v1") {
267
+ invalid("poolStateReader.layout", "Unsupported PoolManager storage layout.");
268
+ }
269
+ poolStateReader = Object.freeze({ kind: "extsload", layout: "uniswap-v4-v1" });
270
+ } else if (input.poolStateReader !== void 0) {
271
+ invalid("poolStateReader.kind", "Unsupported pool state reader.");
272
+ }
273
+ return Object.freeze({
274
+ chainId: input.chainId,
275
+ deploymentId: input.deploymentId,
276
+ poolManager: contract(input.poolManager, "poolManager"),
277
+ registry: contract(input.registry, "registry"),
278
+ authority: contract(input.authority, "authority"),
279
+ ...input.reader ? { reader: contract(input.reader, "reader") } : {},
280
+ ...poolStateReader ? { poolStateReader } : {},
281
+ hooks: Object.freeze(hooks)
282
+ });
283
+ }
284
+
285
+ // src/actions/snapshot.ts
286
+ async function readMarketSnapshot(context, options, read) {
287
+ const deployment = defineMarketDeployment(context.deployment);
288
+ const publicClient = context.publicClient;
289
+ const { blockNumber, blockHash } = options;
290
+ if (blockNumber !== void 0) assertMarketUint(blockNumber, "blockNumber");
291
+ if (blockHash !== void 0 && (blockNumber === void 0 || !/^0x[0-9a-fA-F]{64}$/.test(blockHash))) {
292
+ throw new InvalidMarketConfigError(
293
+ "blockHash",
294
+ "A block hash requires a valid explicit block number."
295
+ );
296
+ }
297
+ try {
298
+ const chainId = await publicClient.getChainId();
299
+ if (chainId !== deployment.chainId)
300
+ throw new MarketDeploymentVerificationError("chainId", deployment.chainId, chainId);
301
+ const block = await publicClient.getBlock(
302
+ blockNumber === void 0 ? { blockTag: "latest" } : { blockNumber }
303
+ );
304
+ if (block.number === null || block.hash === null)
305
+ throw new MarketDeploymentVerificationError("block", "mined block", block);
306
+ if (blockNumber !== void 0 && block.number !== blockNumber)
307
+ throw new MarketDeploymentVerificationError("blockNumber", blockNumber, block.number);
308
+ if (blockHash !== void 0 && block.hash.toLowerCase() !== blockHash.toLowerCase())
309
+ throw new MarketDeploymentVerificationError("blockHash", blockHash, block.hash);
310
+ const snapshot = Object.freeze({
311
+ chainId,
312
+ deploymentId: deployment.deploymentId,
313
+ blockNumber: block.number,
314
+ blockHash: block.hash,
315
+ timestamp: block.timestamp
316
+ });
317
+ const data = await read({ publicClient, deployment, block: snapshot });
318
+ const finalBlock = await publicClient.getBlock({ blockNumber: block.number });
319
+ if (finalBlock.hash !== block.hash)
320
+ throw new MarketDeploymentVerificationError("blockHash", block.hash, finalBlock.hash);
321
+ return Object.freeze({ block: snapshot, data });
322
+ } catch (error) {
323
+ if (error instanceof InvalidMarketConfigError || error instanceof MarketDeploymentVerificationError || error instanceof MarketFeatureUnavailableError || error instanceof MarketSettlingError || error instanceof MarketReadError || error instanceof MarketTransactionError)
324
+ throw error;
325
+ throw new MarketReadError(error);
326
+ }
327
+ }
328
+ function requireMarketHook(scope, address) {
329
+ assertMarketAddress(address, "hook");
330
+ const hook2 = scope.deployment.hooks.find((entry) => isAddressEqual2(entry.address, address));
331
+ if (!hook2) throw new MarketFeatureUnavailableError(`unsupported Hook ${address}`);
332
+ return hook2;
333
+ }
334
+ async function assertMarketCode(scope, contract2) {
335
+ const code = await scope.publicClient.getCode({
336
+ address: contract2.address,
337
+ blockNumber: scope.block.blockNumber
338
+ });
339
+ const actual = code && code !== "0x" ? keccak2562(code) : null;
340
+ if (actual !== contract2.runtimeCodeHash.toLowerCase())
341
+ throw new MarketDeploymentVerificationError(contract2.address, contract2.runtimeCodeHash, actual);
342
+ }
343
+
344
+ // src/actions/authorizations.ts
345
+ function getMarketShareAuthorization(context, params) {
346
+ assertMarketAddress(params.owner, "owner");
347
+ assertMarketAddress(params.operator, "operator");
348
+ assertMarketUint(params.rangeId, "rangeId");
349
+ const owner = getAddress3(params.owner);
350
+ const operator = getAddress3(params.operator);
351
+ const rangeId = params.rangeId;
352
+ const hook2 = requireMarketHook(context, params.hook).address;
353
+ return readMarketSnapshot(context, params, async (scope) => {
354
+ const target = {
355
+ address: hook2,
356
+ abi: marketRampAbi,
357
+ blockNumber: scope.block.blockNumber
358
+ };
359
+ if (await scope.publicClient.readContract({ ...target, functionName: "isSettling" }))
360
+ throw new MarketSettlingError(hook2);
361
+ const [shares, allowance, isShareOperator, isClaimOperator] = await Promise.all([
362
+ scope.publicClient.readContract({
363
+ ...target,
364
+ functionName: "balanceOf",
365
+ args: [owner, rangeId]
366
+ }),
367
+ scope.publicClient.readContract({
368
+ ...target,
369
+ functionName: "allowance",
370
+ args: [owner, operator, rangeId]
371
+ }),
372
+ scope.publicClient.readContract({
373
+ ...target,
374
+ functionName: "isOperator",
375
+ args: [owner, operator]
376
+ }),
377
+ scope.publicClient.readContract({
378
+ ...target,
379
+ functionName: "isClaimOperator",
380
+ args: [owner, rangeId, operator]
381
+ })
382
+ ]);
383
+ return { hook: hook2, rangeId, owner, operator, shares, allowance, isShareOperator, isClaimOperator };
384
+ });
385
+ }
386
+ function getMarketClaimOperator(context, params) {
387
+ const { owner, operator, rangeId } = params;
388
+ assertMarketAddress(owner, "owner");
389
+ assertMarketAddress(operator, "operator");
390
+ assertMarketUint(rangeId, "rangeId");
391
+ const hook2 = requireMarketHook(context, params.hook).address;
392
+ return readMarketSnapshot(context, params, async (scope) => ({
393
+ hook: hook2,
394
+ owner,
395
+ operator,
396
+ rangeId,
397
+ approved: await scope.publicClient.readContract({
398
+ address: hook2,
399
+ abi: marketRampAbi,
400
+ functionName: "isClaimOperator",
401
+ args: [owner, rangeId, operator],
402
+ blockNumber: scope.block.blockNumber
403
+ })
404
+ }));
405
+ }
406
+
407
+ // src/actions/earnings.ts
408
+ import { encodeAbiParameters as encodeAbiParameters3, encodePacked, isAddressEqual as isAddressEqual4, keccak256 as keccak2564, toHex as toHex2 } from "viem";
409
+
410
+ // src/math/earnings.ts
411
+ var Q128 = 1n << 128n;
412
+ function calculateMarketClaimableFees(ledger) {
413
+ const { position } = ledger;
414
+ const { state, effectiveClaimFeeBps } = position.range;
415
+ assertMarketUint(state.totalShares, "totalShares", 128);
416
+ assertMarketUint(position.shares, "shares", 128);
417
+ assertMarketUint(ledger.managerLiquidity, "managerLiquidity", 128);
418
+ if (position.shares > state.totalShares || state.totalShares !== ledger.managerLiquidity)
419
+ throw new InvalidMarketConfigError(
420
+ "liquidity",
421
+ "Hook shares and manager liquidity are inconsistent."
422
+ );
423
+ if (!Number.isInteger(effectiveClaimFeeBps) || effectiveClaimFeeBps < 0 || effectiveClaimFeeBps > 2e3)
424
+ throw new InvalidMarketConfigError("effectiveClaimFeeBps", "Invalid effective fee rate.");
425
+ function token(owed, acc, checkpoint, remainder, live, last) {
426
+ for (const [name, value] of [
427
+ ["acc", acc],
428
+ ["checkpoint", checkpoint],
429
+ ["live", live],
430
+ ["last", last]
431
+ ])
432
+ assertMarketUint(value, name);
433
+ assertMarketUint(owed, "owed", 128);
434
+ assertMarketUint(remainder, "remainder", 128);
435
+ if (checkpoint > acc)
436
+ throw new InvalidMarketConfigError(
437
+ "checkpoint",
438
+ "Net checkpoint exceeds the checked Hook accumulator."
439
+ );
440
+ const gross = state.totalShares === 0n ? 0n : BigInt.asUintN(256, live - last) * state.totalShares / Q128;
441
+ assertMarketUint(gross, "pendingRangeGross", 127);
442
+ const cut = gross * BigInt(effectiveClaimFeeBps) / 10000n;
443
+ const nextAcc = acc + (state.totalShares === 0n ? 0n : (gross - cut) * Q128 / state.totalShares);
444
+ assertMarketUint(nextAcc, "nextAccumulator");
445
+ const syncedNumerator = position.shares * (acc - checkpoint) + remainder;
446
+ const numerator = position.shares * (nextAcc - checkpoint) + remainder;
447
+ const synchronized = syncedNumerator / Q128;
448
+ const earned = numerator / Q128;
449
+ assertMarketUint(earned, "earned", 128);
450
+ assertMarketUint(owed + earned, "claimable", 128);
451
+ return {
452
+ settled: owed,
453
+ synchronized,
454
+ pending: earned - synchronized,
455
+ claimable: owed + earned,
456
+ remainderX128: numerator % Q128,
457
+ pendingRangeGross: gross,
458
+ pendingRangeProtocolFee: cut
459
+ };
460
+ }
461
+ const token0 = token(
462
+ position.settledOwed0,
463
+ state.accFee0X128,
464
+ position.checkpoint0X128,
465
+ position.remainder0X128,
466
+ ledger.growth0X128,
467
+ ledger.lastGrowth0X128
468
+ );
469
+ const token1 = token(
470
+ position.settledOwed1,
471
+ state.accFee1X128,
472
+ position.checkpoint1X128,
473
+ position.remainder1X128,
474
+ ledger.growth1X128,
475
+ ledger.lastGrowth1X128
476
+ );
477
+ return {
478
+ ledger,
479
+ token0,
480
+ token1,
481
+ paused: position.range.globalPaused || position.range.poolPaused,
482
+ hasClaimableAmount: token0.claimable > 0n || token1.claimable > 0n
483
+ };
484
+ }
485
+
486
+ // src/math/pool-state.ts
487
+ import { encodeAbiParameters as encodeAbiParameters2, keccak256 as keccak2563, toHex } from "viem";
488
+ function marketPoolStorageSlots(poolId) {
489
+ assertMarketPoolId(poolId);
490
+ const slot = keccak2563(
491
+ encodeAbiParameters2([{ type: "bytes32" }, { type: "uint256" }], [poolId, 6n])
492
+ );
493
+ return [slot, toHex((BigInt(slot) + 3n) % (1n << 256n), { size: 32 })];
494
+ }
495
+ function decodeMarketPoolStateWords(words) {
496
+ const [slot0, liquidity] = words;
497
+ if (words.length !== 2 || slot0 === void 0 || liquidity === void 0 || !/^0x[0-9a-fA-F]{64}$/.test(slot0) || !/^0x[0-9a-fA-F]{64}$/.test(liquidity)) {
498
+ throw new InvalidMarketConfigError("extsload", "Expected exactly two 32-byte storage words.");
499
+ }
500
+ const raw = BigInt(slot0);
501
+ return {
502
+ sqrtPriceX96: raw & (1n << 160n) - 1n,
503
+ tick: Number(BigInt.asIntN(24, raw >> 160n)),
504
+ protocolFeePacked: Number(raw >> 184n & 0xffffffn),
505
+ storedLpFeePips: Number(raw >> 208n & 0xffffffn),
506
+ activeLiquidity: BigInt(liquidity) & (1n << 128n) - 1n
507
+ };
508
+ }
509
+
510
+ // src/actions/positions.ts
511
+ import { getAddress as getAddress4, isAddressEqual as isAddressEqual3 } from "viem";
512
+ async function readRange(scope, params) {
513
+ const hook2 = requireMarketHook(scope, params.hook);
514
+ const target = {
515
+ address: hook2.address,
516
+ abi: marketRampAbi,
517
+ blockNumber: scope.block.blockNumber
518
+ };
519
+ if (await scope.publicClient.readContract({ ...target, functionName: "isSettling" }))
520
+ throw new MarketSettlingError(hook2.address);
521
+ const [rawKey, tickLower, tickUpper, set] = await scope.publicClient.readContract({
522
+ ...target,
523
+ functionName: "rangeKey",
524
+ args: [params.rangeId]
525
+ });
526
+ if (!set) return { status: "unset", hook: hook2.address, rangeId: params.rangeId };
527
+ const key = defineMarketPoolKey(rawKey);
528
+ if (!isAddressEqual3(key.hooks, hook2.address))
529
+ throw new MarketDeploymentVerificationError("rangeKey.hooks", hook2.address, key.hooks);
530
+ const poolId = getMarketPoolId(key);
531
+ const expectedId = getMarketRangeId(poolId, tickLower, tickUpper, key.tickSpacing);
532
+ if (expectedId !== params.rangeId)
533
+ throw new MarketDeploymentVerificationError("rangeId", params.rangeId, expectedId);
534
+ const [state, globalPaused, poolPaused, effectiveClaimFeeBps] = await Promise.all([
535
+ scope.publicClient.readContract({
536
+ ...target,
537
+ functionName: "rangeState",
538
+ args: [params.rangeId]
539
+ }),
540
+ scope.publicClient.readContract({ ...target, functionName: "paused" }),
541
+ scope.publicClient.readContract({ ...target, functionName: "pausedFor", args: [poolId] }),
542
+ scope.publicClient.readContract({
543
+ ...target,
544
+ functionName: "effectiveClaimFee",
545
+ args: [params.rangeId]
546
+ })
547
+ ]);
548
+ return {
549
+ status: "set",
550
+ hook: hook2.address,
551
+ rangeId: params.rangeId,
552
+ key,
553
+ poolId,
554
+ tickLower,
555
+ tickUpper,
556
+ state,
557
+ globalPaused,
558
+ poolPaused,
559
+ effectiveClaimFeeBps
560
+ };
561
+ }
562
+ function getMarketRange(context, params) {
563
+ const { hook: hook2, rangeId } = params;
564
+ assertMarketAddress(hook2, "hook");
565
+ assertMarketUint(rangeId, "rangeId");
566
+ return readMarketSnapshot(context, params, (scope) => readRange(scope, { hook: hook2, rangeId }));
567
+ }
568
+ function getMarketPosition(context, params) {
569
+ const { hook: hook2, rangeId } = params;
570
+ assertMarketAddress(hook2, "hook");
571
+ assertMarketUint(rangeId, "rangeId");
572
+ assertMarketAddress(params.owner, "owner");
573
+ const owner = getAddress4(params.owner);
574
+ return readMarketSnapshot(context, params, async (scope) => {
575
+ const range = await readRange(scope, { hook: hook2, rangeId });
576
+ const target = {
577
+ address: range.hook,
578
+ abi: marketRampAbi,
579
+ blockNumber: scope.block.blockNumber
580
+ };
581
+ const [shares, position, remainder] = await Promise.all([
582
+ scope.publicClient.readContract({
583
+ ...target,
584
+ functionName: "balanceOf",
585
+ args: [owner, rangeId]
586
+ }),
587
+ scope.publicClient.readContract({
588
+ ...target,
589
+ functionName: "userPosition",
590
+ args: [rangeId, owner]
591
+ }),
592
+ scope.publicClient.readContract({
593
+ ...target,
594
+ functionName: "userFeeRemainder",
595
+ args: [rangeId, owner]
596
+ })
597
+ ]);
598
+ return {
599
+ range,
600
+ owner,
601
+ shares,
602
+ settledOwed0: position.owed0,
603
+ settledOwed1: position.owed1,
604
+ checkpoint0X128: position.checkpoint0X128,
605
+ checkpoint1X128: position.checkpoint1X128,
606
+ remainder0X128: remainder[0],
607
+ remainder1X128: remainder[1]
608
+ };
609
+ });
610
+ }
611
+
612
+ // src/actions/earnings.ts
613
+ function getMarketFeeSnapshot(context, input) {
614
+ const params = immutableClone(input);
615
+ return readMarketSnapshot(context, params, async (scope) => {
616
+ const position = (await getMarketPosition(context, { ...params, ...scope.block })).data;
617
+ const range = position.range;
618
+ if (range.status !== "set")
619
+ throw new MarketFeatureUnavailableError("earnings for an unset range");
620
+ const hook2 = requireMarketHook(scope, range.hook);
621
+ const reader = scope.deployment.poolStateReader;
622
+ if (!reader)
623
+ throw new MarketFeatureUnavailableError("poolStateReader for gross position baseline");
624
+ for (const contract2 of [hook2, hook2.claimFeePolicy, scope.deployment.poolManager])
625
+ await assertMarketCode(scope, contract2);
626
+ const target = {
627
+ address: hook2.address,
628
+ abi: marketRampAbi,
629
+ blockNumber: scope.block.blockNumber
630
+ };
631
+ const policy = {
632
+ address: hook2.claimFeePolicy.address,
633
+ abi: marketClaimFeePolicyAbi,
634
+ blockNumber: scope.block.blockNumber
635
+ };
636
+ const [
637
+ manager,
638
+ policyAddress,
639
+ ledgerAddress,
640
+ growth,
641
+ claimFeeSyncIndex,
642
+ policyHistoryLength,
643
+ currentClaimFeeBps,
644
+ allTimeMinClaimFeeBps
645
+ ] = await Promise.all([
646
+ scope.publicClient.readContract({ ...target, functionName: "poolManager" }),
647
+ scope.publicClient.readContract({ ...target, functionName: "claimFeePolicy" }),
648
+ scope.publicClient.readContract({ ...policy, functionName: "ledger" }),
649
+ scope.publicClient.readContract({
650
+ ...target,
651
+ functionName: "rangeGrowth",
652
+ args: [range.rangeId]
653
+ }),
654
+ scope.publicClient.readContract({
655
+ ...target,
656
+ functionName: "claimFeeSyncIndex",
657
+ args: [range.rangeId]
658
+ }),
659
+ scope.publicClient.readContract({ ...policy, functionName: "length", args: [range.poolId] }),
660
+ scope.publicClient.readContract({ ...policy, functionName: "current", args: [range.poolId] }),
661
+ scope.publicClient.readContract({ ...policy, functionName: "minimum", args: [range.poolId] })
662
+ ]);
663
+ for (const [name, expected, actual] of [
664
+ ["manager", scope.deployment.poolManager.address, manager],
665
+ ["policy", hook2.claimFeePolicy.address, policyAddress],
666
+ ["ledger", hook2.address, ledgerAddress]
667
+ ]) {
668
+ if (!isAddressEqual4(expected, actual))
669
+ throw new MarketDeploymentVerificationError(name, expected, actual);
670
+ }
671
+ const positionId = keccak2564(
672
+ encodePacked(
673
+ ["address", "int24", "int24", "bytes32"],
674
+ [hook2.address, range.tickLower, range.tickUpper, toHex2(range.rangeId, { size: 32 })]
675
+ )
676
+ );
677
+ let managerState;
678
+ if (reader.kind === "state-view") {
679
+ await assertMarketCode(scope, reader.contract);
680
+ const view = {
681
+ address: reader.contract.address,
682
+ abi: marketStateViewAbi,
683
+ blockNumber: scope.block.blockNumber
684
+ };
685
+ const bound = await scope.publicClient.readContract({ ...view, functionName: "poolManager" });
686
+ if (!isAddressEqual4(bound, manager))
687
+ throw new MarketDeploymentVerificationError("stateView.poolManager", manager, bound);
688
+ managerState = await scope.publicClient.readContract({
689
+ ...view,
690
+ functionName: "getPositionInfo",
691
+ args: [range.poolId, positionId]
692
+ });
693
+ } else {
694
+ const poolSlot = marketPoolStorageSlots(range.poolId)[0];
695
+ const base = BigInt(
696
+ keccak2564(
697
+ encodeAbiParameters3(
698
+ [{ type: "bytes32" }, { type: "uint256" }],
699
+ [positionId, BigInt.asUintN(256, BigInt(poolSlot) + 6n)]
700
+ )
701
+ )
702
+ );
703
+ const slots = [0n, 1n, 2n].map(
704
+ (offset) => toHex2(BigInt.asUintN(256, base + offset), { size: 32 })
705
+ );
706
+ const words = await scope.publicClient.readContract({
707
+ address: manager,
708
+ abi: marketExtsloadAbi,
709
+ functionName: "extsload",
710
+ args: [slots],
711
+ blockNumber: scope.block.blockNumber
712
+ });
713
+ const [liquidity, last0, last1] = words;
714
+ if (words.length !== 3 || !liquidity || !last0 || !last1 || words.some((word) => !/^0x[0-9a-fA-F]{64}$/.test(word)))
715
+ throw new MarketDeploymentVerificationError(
716
+ "position storage",
717
+ "three 32-byte words",
718
+ words
719
+ );
720
+ managerState = [BigInt(liquidity), BigInt(last0), BigInt(last1)];
721
+ }
722
+ if (managerState[0] !== range.state.totalShares)
723
+ throw new MarketDeploymentVerificationError(
724
+ "managerLiquidity",
725
+ range.state.totalShares,
726
+ managerState[0]
727
+ );
728
+ return immutableClone({
729
+ position: { ...position, range },
730
+ managerLiquidity: managerState[0],
731
+ lastGrowth0X128: managerState[1],
732
+ lastGrowth1X128: managerState[2],
733
+ growth0X128: growth[0],
734
+ growth1X128: growth[1],
735
+ claimFeeSyncIndex,
736
+ policyHistoryLength,
737
+ currentClaimFeeBps,
738
+ allTimeMinClaimFeeBps
739
+ });
740
+ });
741
+ }
742
+ async function estimateMarketClaimableFees(context, params) {
743
+ const snapshot = await getMarketFeeSnapshot(context, params);
744
+ return immutableClone({
745
+ block: snapshot.block,
746
+ data: calculateMarketClaimableFees(snapshot.data)
747
+ });
748
+ }
749
+
750
+ // src/actions/pools.ts
751
+ import { isAddressEqual as isAddressEqual5, zeroAddress as zeroAddress3 } from "viem";
752
+ function normalizePool(scope, raw) {
753
+ const key = defineMarketPoolKey(raw.key);
754
+ const expected = getMarketPoolId(key);
755
+ if (expected.toLowerCase() !== raw.id.toLowerCase())
756
+ throw new MarketDeploymentVerificationError("poolId", expected, raw.id);
757
+ const hookKind = scope.deployment.hooks.find((entry) => isAddressEqual5(entry.address, key.hooks))?.kind ?? null;
758
+ return { key, poolId: raw.id, active: raw.active, hookKind };
759
+ }
760
+ async function readMarketPoolAt(scope, poolId) {
761
+ const raw = await scope.publicClient.readContract({
762
+ address: scope.deployment.registry.address,
763
+ abi: marketPoolRegistryAbi,
764
+ functionName: "poolById",
765
+ args: [poolId],
766
+ blockNumber: scope.block.blockNumber
767
+ });
768
+ const pool = normalizePool(scope, raw);
769
+ if (pool.poolId.toLowerCase() !== poolId.toLowerCase())
770
+ throw new MarketDeploymentVerificationError("registry.poolId", poolId, pool.poolId);
771
+ return pool;
772
+ }
773
+ function requireMarketPoolHook(scope, pool) {
774
+ const hook2 = requireMarketHook(scope, pool.key.hooks);
775
+ if (isAddressEqual5(pool.key.currency0, zeroAddress3) && hook2.kind !== "ramp-eth") {
776
+ throw new InvalidMarketConfigError("currency0", "Native currency requires RampETH.");
777
+ }
778
+ return hook2;
779
+ }
780
+ function getMarketPool(context, poolId, options = {}) {
781
+ assertMarketPoolId(poolId);
782
+ return readMarketSnapshot(context, options, (scope) => readMarketPoolAt(scope, poolId));
783
+ }
784
+ function listMarketPools(context, params = {}) {
785
+ const { offset = 0n, limit = 20, activeOnly = false } = params;
786
+ assertMarketUint(offset, "offset");
787
+ if (!Number.isInteger(limit) || limit < 1 || limit > 100)
788
+ throw new InvalidMarketConfigError("limit", "Page size must be in [1, 100].");
789
+ return readMarketSnapshot(context, params, async (scope) => {
790
+ const target = {
791
+ address: scope.deployment.registry.address,
792
+ abi: marketPoolRegistryAbi,
793
+ blockNumber: scope.block.blockNumber
794
+ };
795
+ const totalCount = await scope.publicClient.readContract({
796
+ ...target,
797
+ functionName: "poolCount"
798
+ });
799
+ const end = offset + BigInt(limit) < totalCount ? offset + BigInt(limit) : totalCount;
800
+ const pools = [];
801
+ for (let start = offset; start < end; start += 8n) {
802
+ const count = Number(end - start < 8n ? end - start : 8n);
803
+ const batch = await Promise.all(
804
+ Array.from(
805
+ { length: count },
806
+ (_, index) => scope.publicClient.readContract({
807
+ ...target,
808
+ functionName: "poolAt",
809
+ args: [start + BigInt(index)]
810
+ })
811
+ )
812
+ );
813
+ for (const entry of batch) {
814
+ const pool = normalizePool(scope, entry);
815
+ if (!activeOnly || pool.active) pools.push(pool);
816
+ }
817
+ }
818
+ return { pools, totalCount, nextOffset: end < totalCount ? end : null };
819
+ });
820
+ }
821
+
822
+ // src/actions/fees.ts
823
+ function sessionName(value) {
824
+ if (value === 0) return "open";
825
+ if (value === 1) return "overnight";
826
+ if (value === 2) return "closed";
827
+ throw new MarketDeploymentVerificationError("session", "0, 1 or 2", value);
828
+ }
829
+ function getMarketCurrentFees(context, poolId, options = {}) {
830
+ assertMarketPoolId(poolId);
831
+ return readMarketSnapshot(context, options, async (scope) => {
832
+ const pool = await readMarketPoolAt(scope, poolId);
833
+ const hook2 = requireMarketPoolHook(scope, pool);
834
+ const target = {
835
+ address: hook2.address,
836
+ abi: marketRampAbi,
837
+ blockNumber: scope.block.blockNumber
838
+ };
839
+ const [fee0For1Pips, fee1For0Pips, globalPaused, poolPaused] = await Promise.all([
840
+ scope.publicClient.readContract({
841
+ ...target,
842
+ functionName: "currentFee",
843
+ args: [poolId, true]
844
+ }),
845
+ scope.publicClient.readContract({
846
+ ...target,
847
+ functionName: "currentFee",
848
+ args: [poolId, false]
849
+ }),
850
+ scope.publicClient.readContract({ ...target, functionName: "paused" }),
851
+ scope.publicClient.readContract({ ...target, functionName: "pausedFor", args: [poolId] })
852
+ ]);
853
+ return { pool, fee0For1Pips, fee1For0Pips, globalPaused, poolPaused };
854
+ });
855
+ }
856
+ async function readFeeBreakdown(scope, poolId, zeroForOne, timestamp, mode) {
857
+ const reader = scope.deployment.reader;
858
+ if (!reader) throw new MarketFeatureUnavailableError("feeBreakdown requires a Reader");
859
+ const pool = await readMarketPoolAt(scope, poolId);
860
+ const hook2 = requireMarketPoolHook(scope, pool);
861
+ const result = await scope.publicClient.readContract({
862
+ address: reader.address,
863
+ abi: marketRampReaderAbi,
864
+ functionName: "feeBreakdown",
865
+ args: [poolId, zeroForOne, timestamp],
866
+ blockNumber: scope.block.blockNumber
867
+ });
868
+ if (result.hasSession !== (hook2.kind === "rwa-ramp"))
869
+ throw new MarketDeploymentVerificationError(
870
+ "reader.hasSession",
871
+ hook2.kind === "rwa-ramp",
872
+ result.hasSession
873
+ );
874
+ return {
875
+ pool,
876
+ zeroForOne,
877
+ timestamp,
878
+ mode,
879
+ session: result.hasSession ? sessionName(result.session) : null,
880
+ baseFeePips: result.baseFee,
881
+ directionalPremiumPips: result.directionalPremium,
882
+ cappedAutonomousFeePips: result.cappedAutonomousFee,
883
+ overrideActive: result.overrideActive,
884
+ overrideFeePips: result.overrideFee,
885
+ overrideExpiry: BigInt(result.overrideExpiry),
886
+ overrideMinFeePips: result.overrideMinFee,
887
+ maxFeePips: result.maxFee,
888
+ finalFeePips: result.finalFee
889
+ };
890
+ }
891
+ function assertDirection(value) {
892
+ if (typeof value !== "boolean")
893
+ throw new InvalidMarketConfigError("zeroForOne", "Expected an explicit direction boolean.");
894
+ }
895
+ function getMarketFeeBreakdown(context, poolId, zeroForOne, options = {}) {
896
+ assertMarketPoolId(poolId);
897
+ assertDirection(zeroForOne);
898
+ return readMarketSnapshot(
899
+ context,
900
+ options,
901
+ (scope) => readFeeBreakdown(scope, poolId, zeroForOne, scope.block.timestamp, "current")
902
+ );
903
+ }
904
+ function previewMarketFeeAt(context, poolId, zeroForOne, timestamp, options = {}) {
905
+ assertMarketPoolId(poolId);
906
+ assertDirection(zeroForOne);
907
+ assertMarketUint(timestamp, "timestamp");
908
+ return readMarketSnapshot(
909
+ context,
910
+ options,
911
+ (scope) => readFeeBreakdown(scope, poolId, zeroForOne, timestamp, "preview")
912
+ );
913
+ }
914
+ function getMarketSession(context, poolId, options = {}) {
915
+ assertMarketPoolId(poolId);
916
+ const timestamp = options.timestamp;
917
+ if (timestamp !== void 0) assertMarketUint(timestamp, "timestamp");
918
+ return readMarketSnapshot(context, options, async (scope) => {
919
+ const pool = await readMarketPoolAt(scope, poolId);
920
+ const hook2 = requireMarketPoolHook(scope, pool);
921
+ const at = timestamp ?? scope.block.timestamp;
922
+ const session = hook2.kind === "rwa-ramp" ? sessionName(
923
+ await scope.publicClient.readContract({
924
+ address: hook2.address,
925
+ abi: marketRwaRampAbi,
926
+ functionName: "sessionAt",
927
+ args: [poolId, at],
928
+ blockNumber: scope.block.blockNumber
929
+ })
930
+ ) : null;
931
+ return { pool, session, timestamp: at, mode: timestamp === void 0 ? "current" : "preview" };
932
+ });
933
+ }
934
+
935
+ // src/actions/pool-state.ts
936
+ import { isAddressEqual as isAddressEqual6 } from "viem";
937
+ function getMarketPoolState(context, poolId, options = {}) {
938
+ assertMarketPoolId(poolId);
939
+ return readMarketSnapshot(context, options, async (scope) => {
940
+ const pool = await readMarketPoolAt(scope, poolId);
941
+ requireMarketPoolHook(scope, pool);
942
+ return { pool, ...await readMarketPoolStateAt(scope, poolId) };
943
+ });
944
+ }
945
+ async function readMarketPoolStateAt(scope, poolId) {
946
+ const reader = scope.deployment.poolStateReader;
947
+ if (!reader) throw new MarketFeatureUnavailableError("poolStateReader");
948
+ await assertMarketCode(scope, scope.deployment.poolManager);
949
+ const blockNumber = scope.block.blockNumber;
950
+ let state;
951
+ if (reader.kind === "state-view") {
952
+ await assertMarketCode(scope, reader.contract);
953
+ const target = {
954
+ address: reader.contract.address,
955
+ abi: marketStateViewAbi,
956
+ blockNumber
957
+ };
958
+ const manager = await scope.publicClient.readContract({
959
+ ...target,
960
+ functionName: "poolManager"
961
+ });
962
+ if (!isAddressEqual6(manager, scope.deployment.poolManager.address))
963
+ throw new MarketDeploymentVerificationError(
964
+ "stateView.poolManager",
965
+ scope.deployment.poolManager.address,
966
+ manager
967
+ );
968
+ const [slot0, activeLiquidity] = await Promise.all([
969
+ scope.publicClient.readContract({ ...target, functionName: "getSlot0", args: [poolId] }),
970
+ scope.publicClient.readContract({
971
+ ...target,
972
+ functionName: "getLiquidity",
973
+ args: [poolId]
974
+ })
975
+ ]);
976
+ state = {
977
+ sqrtPriceX96: slot0[0],
978
+ tick: slot0[1],
979
+ protocolFeePacked: slot0[2],
980
+ storedLpFeePips: slot0[3],
981
+ activeLiquidity
982
+ };
983
+ } else {
984
+ const words = await scope.publicClient.readContract({
985
+ address: scope.deployment.poolManager.address,
986
+ abi: marketExtsloadAbi,
987
+ functionName: "extsload",
988
+ args: [marketPoolStorageSlots(poolId)],
989
+ blockNumber
990
+ });
991
+ state = decodeMarketPoolStateWords(words);
992
+ }
993
+ if (state.tick < -887272 || state.tick > 887272)
994
+ throw new MarketDeploymentVerificationError("pool.tick", "v4 tick bounds", state.tick);
995
+ return { source: reader.kind, initialized: state.sqrtPriceX96 !== 0n, ...state };
996
+ }
997
+
998
+ // src/actions/write/preview.ts
999
+ import { erc20Abi, isAddressEqual as isAddressEqual8, zeroAddress as zeroAddress5 } from "viem";
1000
+
1001
+ // src/math/liquidity.ts
1002
+ var Q96 = 1n << 96n;
1003
+ var MIN_SQRT = 4295128739n;
1004
+ var MAX_SQRT = 1461446703485210103287273052203988822378723970342n;
1005
+ var FACTORS = [
1006
+ 0xfffcb933bd6fad37aa2d162d1a594001n,
1007
+ 0xfff97272373d413259a46990580e213an,
1008
+ 0xfff2e50f5f656932ef12357cf3c7fdccn,
1009
+ 0xffe5caca7e10e4e61c3624eaa0941cd0n,
1010
+ 0xffcb9843d60f6159c9db58835c926644n,
1011
+ 0xff973b41fa98c081472e6896dfb254c0n,
1012
+ 0xff2ea16466c96a3843ec78b326b52861n,
1013
+ 0xfe5dee046a99a2a811c461f1969c3053n,
1014
+ 0xfcbe86c7900a88aedcffc83b479aa3a4n,
1015
+ 0xf987a7253ac413176f2b074cf7815e54n,
1016
+ 0xf3392b0822b70005940c7a398e4b70f3n,
1017
+ 0xe7159475a2c29b7443b29c7fa6e889d9n,
1018
+ 0xd097f3bdfd2022b8845ad8f792aa5825n,
1019
+ 0xa9f746462d870fdf8a65dc1f90e061e5n,
1020
+ 0x70d869a156d2a1b890bb3df62baf32f7n,
1021
+ 0x31be135f97d08fd981231505542fcfa6n,
1022
+ 0x9aa508b5b7a84e1c677de54f3e99bc9n,
1023
+ 0x5d6af8dedb81196699c329225ee604n,
1024
+ 0x2216e584f5fa1ea926041bedfe98n,
1025
+ 0x48a170391f7dc42444e8fa2n
1026
+ ];
1027
+ function getMarketSqrtPriceAtTick(tick) {
1028
+ if (!Number.isInteger(tick) || Math.abs(tick) > 887272)
1029
+ throw new InvalidMarketConfigError("tick", "Tick must be an integer in v4 bounds.");
1030
+ const absolute = Math.abs(tick);
1031
+ let ratio = 1n << 128n;
1032
+ for (let i = 0; i < FACTORS.length; i++) {
1033
+ const factor = FACTORS[i];
1034
+ if (factor !== void 0 && (absolute & 1 << i) !== 0) ratio = ratio * factor >> 128n;
1035
+ }
1036
+ if (tick > 0) ratio = ((1n << 256n) - 1n) / ratio;
1037
+ return ratio + (1n << 32n) - 1n >> 32n;
1038
+ }
1039
+ function assertPrice(price) {
1040
+ if (typeof price !== "bigint" || price < MIN_SQRT || price >= MAX_SQRT)
1041
+ throw new InvalidMarketConfigError(
1042
+ "sqrtPriceX96",
1043
+ "Price must be initialized and inside v4 bounds."
1044
+ );
1045
+ }
1046
+ function getMarketTickAtSqrtPrice(sqrtPriceX96) {
1047
+ assertPrice(sqrtPriceX96);
1048
+ let lower = -887272;
1049
+ let upper = 887272;
1050
+ while (lower < upper) {
1051
+ const middle = Math.ceil((lower + upper) / 2);
1052
+ if (getMarketSqrtPriceAtTick(middle) <= sqrtPriceX96) lower = middle;
1053
+ else upper = middle - 1;
1054
+ }
1055
+ return lower;
1056
+ }
1057
+ function getMarketPriceRatio(sqrtPriceX96, decimals0, decimals1) {
1058
+ assertPrice(sqrtPriceX96);
1059
+ for (const decimals of [decimals0, decimals1]) {
1060
+ if (!Number.isInteger(decimals) || decimals < 0 || decimals > 255)
1061
+ throw new InvalidMarketConfigError("decimals", "Decimals must fit uint8.");
1062
+ }
1063
+ return {
1064
+ numerator: sqrtPriceX96 ** 2n * 10n ** BigInt(decimals0),
1065
+ denominator: (1n << 192n) * 10n ** BigInt(decimals1)
1066
+ };
1067
+ }
1068
+ function boundaries(sqrtPriceX96, tickLower, tickUpper) {
1069
+ assertPrice(sqrtPriceX96);
1070
+ const lower = getMarketSqrtPriceAtTick(tickLower);
1071
+ const upper = getMarketSqrtPriceAtTick(tickUpper);
1072
+ if (lower >= upper)
1073
+ throw new InvalidMarketConfigError("ticks", "Lower tick must precede upper tick.");
1074
+ return {
1075
+ lower,
1076
+ upper,
1077
+ current: sqrtPriceX96 < lower ? lower : sqrtPriceX96 > upper ? upper : sqrtPriceX96
1078
+ };
1079
+ }
1080
+ function getMarketAmountsForLiquidity(params) {
1081
+ assertMarketUint(params.liquidity, "liquidity", 128);
1082
+ if (params.rounding !== "up" && params.rounding !== "down")
1083
+ throw new InvalidMarketConfigError("rounding", "Expected up or down.");
1084
+ const { lower, upper, current } = boundaries(
1085
+ params.sqrtPriceX96,
1086
+ params.tickLower,
1087
+ params.tickUpper
1088
+ );
1089
+ const divide = (n, d) => params.rounding === "up" ? (n + d - 1n) / d : n / d;
1090
+ return {
1091
+ amount0: divide(params.liquidity * Q96 * (upper - current), current * upper),
1092
+ amount1: divide(params.liquidity * (current - lower), Q96)
1093
+ };
1094
+ }
1095
+ function getMarketLiquidityForAmounts(params) {
1096
+ assertMarketUint(params.amount0, "amount0");
1097
+ assertMarketUint(params.amount1, "amount1");
1098
+ const { lower, upper, current } = boundaries(
1099
+ params.sqrtPriceX96,
1100
+ params.tickLower,
1101
+ params.tickUpper
1102
+ );
1103
+ const l0 = current === upper ? void 0 : params.amount0 * (current * upper / Q96) / (upper - current);
1104
+ const l1 = current === lower ? void 0 : params.amount1 * Q96 / (current - lower);
1105
+ if (l0 !== void 0) assertMarketUint(l0, "liquidity0", 128);
1106
+ if (l1 !== void 0) assertMarketUint(l1, "liquidity1", 128);
1107
+ return l0 === void 0 ? l1 ?? 0n : l1 === void 0 || l0 < l1 ? l0 : l1;
1108
+ }
1109
+
1110
+ // src/actions/write/guards.ts
1111
+ import { isAddressEqual as isAddressEqual7, zeroAddress as zeroAddress4 } from "viem";
1112
+ function liquidityKey(context, input) {
1113
+ const key = defineMarketPoolKey(input);
1114
+ const hook2 = requireMarketHook(context, key.hooks);
1115
+ if (isAddressEqual7(key.currency0, zeroAddress4) && hook2.kind !== "ramp-eth")
1116
+ throw new MarketFeatureUnavailableError("This Hook supports ERC-20 only");
1117
+ return key;
1118
+ }
1119
+ function expiry(timestamp, seconds = 60) {
1120
+ if (!Number.isInteger(seconds) || seconds < 1 || seconds > 300)
1121
+ throw new InvalidMarketConfigError("validForSeconds", "Lifetime must be 1..300 seconds.");
1122
+ return timestamp + BigInt(seconds);
1123
+ }
1124
+ function recipient(context, key, to) {
1125
+ assertMarketAddress(to, "to");
1126
+ if ([key.hooks, context.deployment.poolManager.address, zeroAddress4].some(
1127
+ (value) => isAddressEqual7(value, to)
1128
+ ))
1129
+ throw new InvalidMarketConfigError("to", "Recipient cannot be zero, the Hook or PoolManager.");
1130
+ return to;
1131
+ }
1132
+ function claimFee(value) {
1133
+ if (!Number.isInteger(value) || value < 0 || value > 2e3)
1134
+ throw new InvalidMarketConfigError("maxFeeBps", "Claim fee tolerance must be 0..2000 bps.");
1135
+ }
1136
+ async function assertWriteDeployment(scope, key, claimOperator = false, management = false) {
1137
+ const hook2 = requireMarketHook(scope, key.hooks);
1138
+ if (management && hook2.capabilities.management !== "verified")
1139
+ throw new MarketFeatureUnavailableError("verified management capability");
1140
+ if (!management && hook2.capabilities.liquidity !== "verified")
1141
+ throw new MarketFeatureUnavailableError("verified liquidity capability");
1142
+ if (!management && isAddressEqual7(key.currency0, zeroAddress4) && hook2.capabilities.nativeLiquidity !== "verified")
1143
+ throw new MarketFeatureUnavailableError("verified nativeLiquidity capability");
1144
+ if (claimOperator && hook2.capabilities.claimOperator !== "verified")
1145
+ throw new MarketFeatureUnavailableError("verified claimOperator capability");
1146
+ for (const contract2 of [
1147
+ hook2,
1148
+ scope.deployment.poolManager,
1149
+ scope.deployment.authority,
1150
+ hook2.claimFeePolicy
1151
+ ])
1152
+ await assertMarketCode(scope, contract2);
1153
+ if (hook2.kind === "rwa-ramp") {
1154
+ if (!hook2.calendar) throw new MarketFeatureUnavailableError("RWA calendar");
1155
+ await assertMarketCode(scope, hook2.calendar);
1156
+ const [calendar, controller] = await Promise.all([
1157
+ scope.publicClient.readContract({
1158
+ address: hook2.address,
1159
+ abi: marketRwaRampAbi,
1160
+ functionName: "marketCalendar",
1161
+ blockNumber: scope.block.blockNumber
1162
+ }),
1163
+ scope.publicClient.readContract({
1164
+ address: hook2.calendar.address,
1165
+ abi: marketMarketCalendarAbi,
1166
+ functionName: "controller",
1167
+ blockNumber: scope.block.blockNumber
1168
+ })
1169
+ ]);
1170
+ if (!isAddressEqual7(calendar, hook2.calendar.address) || !isAddressEqual7(controller, hook2.address))
1171
+ throw new MarketDeploymentVerificationError(
1172
+ "write.calendar",
1173
+ [hook2.calendar.address, hook2.address],
1174
+ [calendar, controller]
1175
+ );
1176
+ }
1177
+ const target = {
1178
+ address: hook2.address,
1179
+ abi: marketRampAbi,
1180
+ blockNumber: scope.block.blockNumber
1181
+ };
1182
+ const actual = await Promise.all([
1183
+ scope.publicClient.readContract({ ...target, functionName: "poolManager" }),
1184
+ scope.publicClient.readContract({ ...target, functionName: "authority" }),
1185
+ scope.publicClient.readContract({ ...target, functionName: "claimFeePolicy" }),
1186
+ scope.publicClient.readContract({
1187
+ address: hook2.claimFeePolicy.address,
1188
+ abi: marketClaimFeePolicyAbi,
1189
+ functionName: "ledger",
1190
+ blockNumber: scope.block.blockNumber
1191
+ })
1192
+ ]);
1193
+ const expected = [
1194
+ scope.deployment.poolManager.address,
1195
+ scope.deployment.authority.address,
1196
+ hook2.claimFeePolicy.address,
1197
+ hook2.address
1198
+ ];
1199
+ for (let index = 0; index < expected.length; index++) {
1200
+ const want = expected[index];
1201
+ const got = actual[index];
1202
+ if (!want || !got || !isAddressEqual7(want, got))
1203
+ throw new MarketDeploymentVerificationError(`write.binding.${index}`, want, got);
1204
+ }
1205
+ }
1206
+
1207
+ // src/actions/write/preview.ts
1208
+ async function previewMarketLiquidity(context, action, input) {
1209
+ const params = immutableClone(input);
1210
+ const key = liquidityKey(context, params.key);
1211
+ const poolId = getMarketPoolId(key);
1212
+ const rangeId = getMarketRangeId(poolId, params.tickLower, params.tickUpper, key.tickSpacing);
1213
+ assertMarketUint(params.liquidity, "liquidity", 128);
1214
+ assertMarketUint(params.deadline, "deadline");
1215
+ if (params.liquidity === 0n)
1216
+ throw new InvalidMarketConfigError("liquidity", "Liquidity must be positive.");
1217
+ if (!Number.isInteger(params.slippageBps) || params.slippageBps < 0 || params.slippageBps >= 1e4)
1218
+ throw new InvalidMarketConfigError(
1219
+ "slippageBps",
1220
+ "Slippage must be an integer from 0 to 9999 bps."
1221
+ );
1222
+ return immutableClone(
1223
+ await readMarketSnapshot(context, {}, async (scope) => {
1224
+ const lifetime = expiry(scope.block.timestamp, params.validForSeconds);
1225
+ if (params.deadline < scope.block.timestamp)
1226
+ throw new InvalidMarketConfigError("deadline", "Deadline has expired.");
1227
+ const state = await readMarketPoolStateAt(scope, poolId);
1228
+ const amounts = getMarketAmountsForLiquidity({
1229
+ ...params,
1230
+ sqrtPriceX96: state.sqrtPriceX96,
1231
+ rounding: action === "deposit" ? "up" : "down"
1232
+ });
1233
+ const limit = (amount) => action === "deposit" ? (amount * BigInt(1e4 + params.slippageBps) + 9999n) / 10000n : amount * BigInt(1e4 - params.slippageBps) / 10000n;
1234
+ const limit0 = limit(amounts.amount0);
1235
+ const limit1 = limit(amounts.amount1);
1236
+ assertMarketUint(limit0, "limit0", 128);
1237
+ assertMarketUint(limit1, "limit1", 128);
1238
+ return {
1239
+ ...params,
1240
+ key,
1241
+ action,
1242
+ rangeId,
1243
+ sqrtPriceX96: state.sqrtPriceX96,
1244
+ ...amounts,
1245
+ limit0,
1246
+ limit1,
1247
+ nativeValue: action === "deposit" && isAddressEqual8(key.currency0, zeroAddress5) ? limit0 : 0n,
1248
+ estimatedNativeRefund: action === "deposit" && isAddressEqual8(key.currency0, zeroAddress5) ? limit0 - amounts.amount0 : 0n,
1249
+ expiresAt: params.deadline < lifetime ? params.deadline : lifetime
1250
+ };
1251
+ })
1252
+ );
1253
+ }
1254
+ function getMarketSpendStatus(context, params) {
1255
+ const key = liquidityKey(context, params.key);
1256
+ const { owner, amount0, amount1 } = params;
1257
+ assertMarketAddress(owner, "owner");
1258
+ assertMarketUint(amount0, "amount0", 128);
1259
+ assertMarketUint(amount1, "amount1", 128);
1260
+ return readMarketSnapshot(context, params, async (scope) => ({
1261
+ owner,
1262
+ spender: key.hooks,
1263
+ tokens: await Promise.all(
1264
+ [
1265
+ { token: key.currency0, requiredAmount: amount0 },
1266
+ { token: key.currency1, requiredAmount: amount1 }
1267
+ ].map(async ({ token, requiredAmount }) => {
1268
+ if (isAddressEqual8(token, zeroAddress5)) {
1269
+ const balance2 = await scope.publicClient.getBalance({
1270
+ address: owner,
1271
+ blockNumber: scope.block.blockNumber
1272
+ });
1273
+ return {
1274
+ token,
1275
+ kind: "native",
1276
+ balance: balance2,
1277
+ allowance: null,
1278
+ requiredAmount,
1279
+ needsApproval: false,
1280
+ sufficientBalance: balance2 >= requiredAmount
1281
+ };
1282
+ }
1283
+ const target = {
1284
+ address: token,
1285
+ abi: erc20Abi,
1286
+ blockNumber: scope.block.blockNumber
1287
+ };
1288
+ const [balance, allowance] = await Promise.all([
1289
+ scope.publicClient.readContract({ ...target, functionName: "balanceOf", args: [owner] }),
1290
+ scope.publicClient.readContract({
1291
+ ...target,
1292
+ functionName: "allowance",
1293
+ args: [owner, key.hooks]
1294
+ })
1295
+ ]);
1296
+ return {
1297
+ token,
1298
+ kind: "erc20",
1299
+ balance,
1300
+ allowance,
1301
+ requiredAmount,
1302
+ needsApproval: allowance < requiredAmount,
1303
+ sufficientBalance: balance >= requiredAmount
1304
+ };
1305
+ })
1306
+ )
1307
+ }));
1308
+ }
1309
+
1310
+ // src/chains.ts
1311
+ function defineMarketChain(input) {
1312
+ const deployment = defineMarketDeployment(input.deployment);
1313
+ if (input.chainId !== deployment.chainId) {
1314
+ throw new InvalidMarketConfigError("chainId", "Chain and deployment chain IDs must match.");
1315
+ }
1316
+ if (!Number.isSafeInteger(input.confirmations) || input.confirmations < 1) {
1317
+ throw new InvalidMarketConfigError("confirmations", "Expected at least one confirmation.");
1318
+ }
1319
+ return Object.freeze({ chainId: input.chainId, deployment, confirmations: input.confirmations });
1320
+ }
1321
+
1322
+ // src/actions/write/transactions.ts
1323
+ import {
1324
+ decodeEventLog,
1325
+ encodeFunctionData as encodeFunctionData2,
1326
+ erc20Abi as erc20Abi2,
1327
+ isAddressEqual as isAddressEqual10,
1328
+ zeroAddress as zeroAddress7
1329
+ } from "viem";
1330
+
1331
+ // src/actions/write/management.ts
1332
+ import {
1333
+ encodeAbiParameters as encodeAbiParameters4,
1334
+ encodeFunctionData,
1335
+ isAddressEqual as isAddressEqual9,
1336
+ keccak256 as keccak2565,
1337
+ zeroAddress as zeroAddress6
1338
+ } from "viem";
1339
+
1340
+ // src/math/calendar.ts
1341
+ function marketDaysInMonth(year, month) {
1342
+ if (!Number.isInteger(year) || year < 1970 || year > 9999 || !Number.isInteger(month) || month < 1 || month > 12)
1343
+ throw new InvalidMarketConfigError("date", "Expected year 1970..9999 and month 1..12.");
1344
+ if (month === 2) return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) ? 29 : 28;
1345
+ return [4, 6, 9, 11].includes(month) ? 30 : 31;
1346
+ }
1347
+ function packMarketDayOverrides(year, month, days) {
1348
+ const maximum = marketDaysInMonth(year, month);
1349
+ if (!Array.isArray(days) || days.length > 10)
1350
+ throw new InvalidMarketConfigError("days", "At most ten overrides per month.");
1351
+ const seen = /* @__PURE__ */ new Set();
1352
+ let packed = 0n;
1353
+ for (const { day, status } of days) {
1354
+ if (!Number.isInteger(day) || day < 1 || day > maximum || seen.has(day) || status !== "closed" && status !== "open")
1355
+ throw new InvalidMarketConfigError("days", "Invalid or duplicate override date/status.");
1356
+ seen.add(day);
1357
+ packed |= (status === "closed" ? 1n : 2n) << BigInt((day - 1) * 2);
1358
+ }
1359
+ return packed;
1360
+ }
1361
+
1362
+ // src/actions/write/management.ts
1363
+ function integer(value, field, min = 0, max = 16777215) {
1364
+ if (!Number.isSafeInteger(value) || value < min || value > max)
1365
+ throw new InvalidMarketConfigError(field, `Expected integer ${min}..${max}.`);
1366
+ }
1367
+ function condition(ok, field) {
1368
+ if (!ok)
1369
+ throw new InvalidMarketConfigError(
1370
+ field,
1371
+ `Invalid management parameter combination: ${field}.`
1372
+ );
1373
+ }
1374
+ function encodeMarketManagement(context, a) {
1375
+ const key = liquidityKey(context, a.key);
1376
+ const hook2 = requireMarketHook(context, key.hooks);
1377
+ const id = getMarketPoolId(key);
1378
+ const target = hook2.address;
1379
+ const ramp = marketRampAbi;
1380
+ const rwa = marketRwaRampAbi;
1381
+ const result = (data, to = target) => ({ key, to, data, value: 0n });
1382
+ const requireRwa = () => {
1383
+ if (hook2.kind !== "rwa-ramp") throw new MarketFeatureUnavailableError("RWA Hook required");
1384
+ };
1385
+ switch (a.kind) {
1386
+ case "pokeFee":
1387
+ integer(a.fee0For1, "fee0For1");
1388
+ integer(a.fee1For0, "fee1For0");
1389
+ integer(a.ttl, "ttl", 1, 259200);
1390
+ condition(a.fee0For1 !== 0 || a.fee1For0 !== 0, "pokeFee");
1391
+ return result(
1392
+ encodeFunctionData({
1393
+ abi: ramp,
1394
+ functionName: "pokeFee",
1395
+ args: [id, a.fee0For1, a.fee1For0, a.ttl]
1396
+ })
1397
+ );
1398
+ case "clearPoke":
1399
+ return result(encodeFunctionData({ abi: ramp, functionName: "clearPoke", args: [id] }));
1400
+ case "setPoolAsymmetry":
1401
+ integer(a.premiumPips, "premiumPips");
1402
+ condition(typeof a.premiumZeroForOne === "boolean", "direction");
1403
+ return result(
1404
+ encodeFunctionData({
1405
+ abi: ramp,
1406
+ functionName: "setPoolAsymmetry",
1407
+ args: [key, a.premiumPips, a.premiumZeroForOne]
1408
+ })
1409
+ );
1410
+ case "setCryptoPoolConfig":
1411
+ if (hook2.kind === "rwa-ramp") throw new MarketFeatureUnavailableError("Crypto Hook required");
1412
+ integer(a.floorPips, "floorPips", 100);
1413
+ integer(a.flatPips, "flatPips", a.floorPips);
1414
+ integer(a.cap, "cap", a.flatPips);
1415
+ return result(
1416
+ encodeFunctionData({
1417
+ abi: ramp,
1418
+ functionName: "setPoolConfig",
1419
+ args: [key, a.floorPips, a.flatPips, a.cap]
1420
+ })
1421
+ );
1422
+ case "setRwaPoolConfig": {
1423
+ requireRwa();
1424
+ integer(a.cap, "cap", 100);
1425
+ const c = a.config;
1426
+ for (const field of ["openFloor", "overnightFloor", "closedFloor"])
1427
+ integer(c[field], field, 100, a.cap);
1428
+ integer(c.spikeMult, "spikeMult", 0, 20);
1429
+ integer(c.closedSpike, "closedSpike");
1430
+ integer(c.descentWindow, "descentWindow", 0, 21600);
1431
+ integer(c.closeFloor, "closeFloor", 0, a.cap);
1432
+ integer(c.closeBefore, "closeBefore", 0, 21600);
1433
+ integer(c.closeAfter, "closeAfter", 0, 21600);
1434
+ condition(
1435
+ c.descentWindow === 0 ? c.spikeMult === 0 && c.closedSpike === 0 : c.overnightFloor * c.spikeMult > c.openFloor && c.closedSpike > c.openFloor,
1436
+ "descentWindow"
1437
+ );
1438
+ condition(
1439
+ c.closeFloor === 0 ? c.closeBefore === 0 && c.closeAfter === 0 : c.closeFloor >= c.openFloor && (c.closeBefore !== 0 || c.closeAfter !== 0),
1440
+ "closeFloor"
1441
+ );
1442
+ return result(
1443
+ encodeFunctionData({
1444
+ abi: rwa.filter(
1445
+ (item) => item.type !== "function" || item.name !== "setPoolConfig" || item.inputs.length === 3
1446
+ ),
1447
+ functionName: "setPoolConfig",
1448
+ args: [key, c, a.cap]
1449
+ })
1450
+ );
1451
+ }
1452
+ case "setSessionHours":
1453
+ requireRwa();
1454
+ integer(a.openSec, "openSec", 32400, 36e3);
1455
+ integer(a.closeSec, "closeSec", 55800, 59400);
1456
+ condition(a.closeSec - a.openSec >= 3600 && a.closeSec - a.openSec <= 43200, "sessionHours");
1457
+ return result(
1458
+ encodeFunctionData({
1459
+ abi: rwa,
1460
+ functionName: "setSessionHours",
1461
+ args: [id, a.openSec, a.closeSec]
1462
+ })
1463
+ );
1464
+ case "setDayOverrides": {
1465
+ requireRwa();
1466
+ const packed = packMarketDayOverrides(a.year, a.month, a.days);
1467
+ return result(
1468
+ encodeFunctionData({
1469
+ abi: rwa,
1470
+ functionName: "setDayOverrides",
1471
+ args: [id, BigInt(a.year * 100 + a.month), packed]
1472
+ })
1473
+ );
1474
+ }
1475
+ case "setDstMode":
1476
+ requireRwa();
1477
+ condition(["auto", "est", "edt"].includes(a.mode), "mode");
1478
+ return result(
1479
+ encodeFunctionData({
1480
+ abi: rwa,
1481
+ functionName: "setDstMode",
1482
+ args: [id, a.mode === "auto" ? 0 : a.mode === "est" ? 1 : 2]
1483
+ })
1484
+ );
1485
+ case "setEarlyClose":
1486
+ requireRwa();
1487
+ integer(a.day, "day", 1, marketDaysInMonth(a.year, a.month));
1488
+ integer(a.closeSec, "closeSec", 0, 86400);
1489
+ return result(
1490
+ encodeFunctionData({
1491
+ abi: rwa,
1492
+ functionName: "setEarlyClose",
1493
+ args: [id, BigInt(a.year), BigInt(a.month), BigInt(a.day), a.closeSec]
1494
+ })
1495
+ );
1496
+ case "setPaused":
1497
+ case "setPoolPaused":
1498
+ integer(a.duration, "duration", 0, 604800);
1499
+ return result(
1500
+ a.kind === "setPaused" ? encodeFunctionData({ abi: ramp, functionName: "setPaused", args: [BigInt(a.duration)] }) : encodeFunctionData({
1501
+ abi: ramp,
1502
+ functionName: "setPoolPaused",
1503
+ args: [key, BigInt(a.duration)]
1504
+ })
1505
+ );
1506
+ case "setClaimFee":
1507
+ claimFee(a.bps);
1508
+ assertMarketAddress(a.recipient, "recipient", a.bps === 0);
1509
+ if (!isAddressEqual9(a.recipient, zeroAddress6)) recipient(context, key, a.recipient);
1510
+ condition(Array.isArray(a.settleFirst), "settleFirst");
1511
+ for (const currency of a.settleFirst)
1512
+ assertMarketAddress(currency, "settleFirst", hook2.kind === "ramp-eth");
1513
+ condition(
1514
+ new Set(a.settleFirst.map((v) => v.toLowerCase())).size === a.settleFirst.length,
1515
+ "settleFirst"
1516
+ );
1517
+ return result(
1518
+ encodeFunctionData({
1519
+ abi: ramp,
1520
+ functionName: "setClaimFee",
1521
+ args: [key, a.settleFirst, a.bps, a.recipient]
1522
+ })
1523
+ );
1524
+ case "setClaimFeeBps":
1525
+ claimFee(a.bps);
1526
+ return result(
1527
+ encodeFunctionData({ abi: ramp, functionName: "setClaimFeeBps", args: [key, a.bps] })
1528
+ );
1529
+ case "sweepClaimFee":
1530
+ assertMarketAddress(a.currency, "currency", hook2.kind === "ramp-eth");
1531
+ return result(
1532
+ encodeFunctionData({ abi: ramp, functionName: "sweepClaimFee", args: [a.currency] })
1533
+ );
1534
+ case "register":
1535
+ return result(
1536
+ encodeFunctionData({ abi: marketPoolRegistryAbi, functionName: "register", args: [key] }),
1537
+ context.deployment.registry.address
1538
+ );
1539
+ case "deregister":
1540
+ case "reregister":
1541
+ return result(
1542
+ encodeFunctionData({ abi: marketPoolRegistryAbi, functionName: a.kind, args: [id] }),
1543
+ context.deployment.registry.address
1544
+ );
1545
+ case "setHook":
1546
+ case "disableHook": {
1547
+ const reader = context.deployment.reader;
1548
+ if (!reader) throw new MarketFeatureUnavailableError("Reader required");
1549
+ if (a.kind === "disableHook")
1550
+ return result(
1551
+ encodeFunctionData({
1552
+ abi: marketRampReaderAbi,
1553
+ functionName: "disableHook",
1554
+ args: [hook2.address]
1555
+ }),
1556
+ reader.address
1557
+ );
1558
+ condition(
1559
+ /^0x[0-9a-fA-F]{64}$/.test(a.expectedCodeHash) && a.expectedCodeHash.toLowerCase() === hook2.runtimeCodeHash.toLowerCase(),
1560
+ "expectedCodeHash"
1561
+ );
1562
+ return result(
1563
+ encodeFunctionData({
1564
+ abi: marketRampReaderAbi,
1565
+ functionName: "setHook",
1566
+ args: [hook2.address, hook2.kind === "rwa-ramp" ? 2 : 1, a.expectedCodeHash]
1567
+ }),
1568
+ reader.address
1569
+ );
1570
+ }
1571
+ default:
1572
+ throw new InvalidMarketConfigError("kind", "Unknown management action.");
1573
+ }
1574
+ }
1575
+ async function inspectMarketManagementAt(scope, a, account, when = 0) {
1576
+ assertMarketAddress(account, "account");
1577
+ integer(when, "when", 0, 2 ** 48 - 1);
1578
+ const call = encodeMarketManagement(scope, a);
1579
+ const hook2 = requireMarketHook(scope, call.key.hooks);
1580
+ if (hook2.capabilities.management !== "verified")
1581
+ throw new MarketFeatureUnavailableError("verified management capability");
1582
+ const registryAction = [
1583
+ "register",
1584
+ "deregister",
1585
+ "reregister",
1586
+ "setHook",
1587
+ "disableHook"
1588
+ ].includes(a.kind);
1589
+ const readerAction = a.kind === "setHook" || a.kind === "disableHook";
1590
+ if (a.kind !== "disableHook" && a.kind !== "deregister" && a.kind !== "reregister")
1591
+ await assertWriteDeployment(scope, call.key, false, true);
1592
+ else await assertMarketCode(scope, scope.deployment.authority);
1593
+ const read = { blockNumber: scope.block.blockNumber };
1594
+ if (registryAction) {
1595
+ await assertMarketCode(scope, scope.deployment.registry);
1596
+ const actual = await scope.publicClient.readContract({
1597
+ ...read,
1598
+ address: scope.deployment.registry.address,
1599
+ abi: marketPoolRegistryAbi,
1600
+ functionName: "authority"
1601
+ });
1602
+ if (!isAddressEqual9(actual, scope.deployment.authority.address))
1603
+ throw new MarketDeploymentVerificationError(
1604
+ "registry.authority",
1605
+ scope.deployment.authority.address,
1606
+ actual
1607
+ );
1608
+ }
1609
+ if (readerAction) {
1610
+ const reader = scope.deployment.reader;
1611
+ if (!reader) throw new MarketFeatureUnavailableError("Reader required");
1612
+ await assertMarketCode(scope, reader);
1613
+ const [registry, authority] = await Promise.all([
1614
+ scope.publicClient.readContract({
1615
+ ...read,
1616
+ address: reader.address,
1617
+ abi: marketRampReaderAbi,
1618
+ functionName: "registry"
1619
+ }),
1620
+ scope.publicClient.readContract({
1621
+ ...read,
1622
+ address: reader.address,
1623
+ abi: marketRampReaderAbi,
1624
+ functionName: "authority"
1625
+ })
1626
+ ]);
1627
+ if (!isAddressEqual9(registry, scope.deployment.registry.address) || !isAddressEqual9(authority, scope.deployment.authority.address))
1628
+ throw new MarketDeploymentVerificationError("reader.bindings", scope.deployment, [
1629
+ registry,
1630
+ authority
1631
+ ]);
1632
+ }
1633
+ const hookRead = { ...read, address: hook2.address, abi: marketRampAbi };
1634
+ if (a.kind === "setCryptoPoolConfig" || a.kind === "setRwaPoolConfig") {
1635
+ const absolute = await scope.publicClient.readContract({
1636
+ ...hookRead,
1637
+ functionName: "ABSOLUTE_MAX_FEE"
1638
+ });
1639
+ condition(a.cap <= absolute, "cap");
1640
+ }
1641
+ if (a.kind === "pokeFee" || a.kind === "setPoolAsymmetry") {
1642
+ const id = getMarketPoolId(call.key);
1643
+ const [floor, cap] = await Promise.all([
1644
+ scope.publicClient.readContract({ ...hookRead, functionName: "pokeFloor", args: [id] }),
1645
+ scope.publicClient.readContract({ ...hookRead, functionName: "maxFee", args: [id] })
1646
+ ]);
1647
+ if (a.kind === "pokeFee")
1648
+ condition(
1649
+ [a.fee0For1, a.fee1For0].every((fee) => fee === 0 || fee >= floor && fee <= cap),
1650
+ "pokeFee.band"
1651
+ );
1652
+ else condition(a.premiumPips <= cap - floor, "premiumPips.band");
1653
+ }
1654
+ if (a.kind === "setEarlyClose" && a.closeSec !== 0) {
1655
+ const id = getMarketPoolId(call.key);
1656
+ const [open, close] = await Promise.all([
1657
+ scope.publicClient.readContract({
1658
+ ...read,
1659
+ address: hook2.address,
1660
+ abi: marketRwaRampAbi,
1661
+ functionName: "openSec",
1662
+ args: [id]
1663
+ }),
1664
+ scope.publicClient.readContract({
1665
+ ...read,
1666
+ address: hook2.address,
1667
+ abi: marketRwaRampAbi,
1668
+ functionName: "closeSec",
1669
+ args: [id]
1670
+ })
1671
+ ]);
1672
+ condition(a.closeSec <= close && a.closeSec - open >= 10800, "earlyClose");
1673
+ }
1674
+ const target = {
1675
+ ...read,
1676
+ address: scope.deployment.authority.address,
1677
+ abi: marketAccessManagerAbi
1678
+ };
1679
+ const [immediate, delay] = a.kind === "sweepClaimFee" ? [true, 0] : await scope.publicClient.readContract({
1680
+ ...target,
1681
+ functionName: "canCall",
1682
+ args: [account, call.to, call.data.slice(0, 10)]
1683
+ });
1684
+ const operationId = keccak2565(
1685
+ encodeAbiParameters4(
1686
+ [{ type: "address" }, { type: "address" }, { type: "bytes" }],
1687
+ [account, call.to, call.data]
1688
+ )
1689
+ );
1690
+ const scheduledAt = await scope.publicClient.readContract({
1691
+ ...target,
1692
+ functionName: "getSchedule",
1693
+ args: [operationId]
1694
+ });
1695
+ return {
1696
+ permission: immediate ? "immediate" : delay > 0 ? "delayed" : "denied",
1697
+ delay,
1698
+ operationId,
1699
+ scheduledAt,
1700
+ direct: { to: call.to, data: call.data, value: 0n },
1701
+ schedule: {
1702
+ to: target.address,
1703
+ value: 0n,
1704
+ data: encodeFunctionData({
1705
+ abi: marketAccessManagerAbi,
1706
+ functionName: "schedule",
1707
+ args: [call.to, call.data, when]
1708
+ })
1709
+ },
1710
+ execute: {
1711
+ to: target.address,
1712
+ value: 0n,
1713
+ data: encodeFunctionData({
1714
+ abi: marketAccessManagerAbi,
1715
+ functionName: "execute",
1716
+ args: [call.to, call.data]
1717
+ })
1718
+ }
1719
+ };
1720
+ }
1721
+ function managementRequest(auth, execution, timestamp) {
1722
+ if (auth.permission === "denied")
1723
+ throw new InvalidMarketConfigError(
1724
+ "permission",
1725
+ "Account is not authorized for this management selector."
1726
+ );
1727
+ if (execution.mode === "direct") {
1728
+ condition(auth.permission === "immediate", "permission.scheduleRequired");
1729
+ return auth.direct;
1730
+ }
1731
+ if (execution.mode === "schedule") {
1732
+ condition(auth.permission === "delayed" && auth.scheduledAt === 0, "schedule");
1733
+ const when = execution.when ?? 0;
1734
+ condition(when === 0 || BigInt(when) >= timestamp + BigInt(auth.delay), "when");
1735
+ return auth.schedule;
1736
+ }
1737
+ if (execution.mode === "execute") {
1738
+ condition(
1739
+ auth.scheduledAt !== 0 && BigInt(auth.scheduledAt) <= timestamp,
1740
+ "schedule.notReadyOrExpired"
1741
+ );
1742
+ return auth.execute;
1743
+ }
1744
+ throw new InvalidMarketConfigError("mode", "Unknown management execution mode.");
1745
+ }
1746
+
1747
+ // src/actions/write/transactions.ts
1748
+ function createMarketWriteActions(publicClient, walletClient, chain) {
1749
+ const context = { publicClient, deployment: chain.deployment };
1750
+ const store = createPreparedTransactionStore();
1751
+ const previews = /* @__PURE__ */ new WeakSet();
1752
+ const sent = /* @__PURE__ */ new Map();
1753
+ const submitting = /* @__PURE__ */ new WeakSet();
1754
+ const submitted = /* @__PURE__ */ new WeakSet();
1755
+ const account = () => resolveLiveWalletAccount(
1756
+ walletClient,
1757
+ chain.chainId,
1758
+ (expected, actual) => new MarketDeploymentVerificationError("wallet.chainId", expected, actual)
1759
+ );
1760
+ async function simulate(request, blockNumber) {
1761
+ try {
1762
+ const result = await publicClient.call({ ...request, blockNumber, batch: false });
1763
+ if (request.data.startsWith("0x095ea7b3") && result.data && result.data !== "0x" && BigInt(result.data) !== 1n)
1764
+ throw new InvalidMarketConfigError("approve", "Token returned false for approve.");
1765
+ } catch (cause) {
1766
+ throw new MarketTransactionError("simulate", cause);
1767
+ }
1768
+ }
1769
+ async function checkNativeBudget(request) {
1770
+ if (request.gas === void 0 || request.maxFeePerGas === void 0) return;
1771
+ const balance = await publicClient.getBalance({ address: request.account });
1772
+ if (balance < request.value + request.gas * request.maxFeePerGas)
1773
+ throw new InvalidMarketConfigError(
1774
+ "nativeBalance",
1775
+ "Insufficient native balance for prepaid value plus gas budget."
1776
+ );
1777
+ }
1778
+ async function fresh(block, expiresAt) {
1779
+ const [latest, original, chainId] = await Promise.all([
1780
+ publicClient.getBlock({ blockTag: "latest" }),
1781
+ publicClient.getBlock({ blockNumber: block.blockNumber }),
1782
+ publicClient.getChainId()
1783
+ ]);
1784
+ if (chainId !== chain.chainId)
1785
+ throw new MarketDeploymentVerificationError("publicClient.chainId", chain.chainId, chainId);
1786
+ if (original.hash !== block.blockHash)
1787
+ throw new MarketDeploymentVerificationError(
1788
+ "preview.blockHash",
1789
+ block.blockHash,
1790
+ original.hash
1791
+ );
1792
+ if (latest.timestamp < block.timestamp || latest.timestamp > expiresAt)
1793
+ throw new InvalidMarketConfigError(
1794
+ "expiry",
1795
+ "Preview or prepared transaction has expired; prepare again."
1796
+ );
1797
+ }
1798
+ async function preview(action, params) {
1799
+ const result = await previewMarketLiquidity(context, action, params);
1800
+ previews.add(result);
1801
+ return result;
1802
+ }
1803
+ async function prepare(input) {
1804
+ const key = liquidityKey(context, input.key);
1805
+ const live = await account();
1806
+ if (input.preview) await fresh(input.preview.block, input.preview.data.expiresAt);
1807
+ let managementContext;
1808
+ const snapshot = await readMarketSnapshot(context, {}, async (scope) => {
1809
+ if (!input.management)
1810
+ await assertWriteDeployment(
1811
+ scope,
1812
+ key,
1813
+ input.action === "setClaimOperator" || input.action === "claimFor"
1814
+ );
1815
+ let request = {
1816
+ account: live.address,
1817
+ to: input.target ?? key.hooks,
1818
+ data: input.data,
1819
+ value: input.action === "deposit" ? input.preview?.data.nativeValue ?? 0n : 0n,
1820
+ chainId: chain.chainId
1821
+ };
1822
+ if (input.management) {
1823
+ const { action, execution } = input.management;
1824
+ const auth = await inspectMarketManagementAt(
1825
+ scope,
1826
+ action,
1827
+ live.address,
1828
+ execution.mode === "schedule" ? execution.when : 0
1829
+ );
1830
+ request = { ...request, ...managementRequest(auth, execution, scope.block.timestamp) };
1831
+ managementContext = {
1832
+ action,
1833
+ execution,
1834
+ target: auth.direct.to,
1835
+ operationId: auth.operationId
1836
+ };
1837
+ }
1838
+ if (input.action === "deposit" && input.preview) {
1839
+ const status = await getMarketSpendStatus(context, {
1840
+ key,
1841
+ owner: live.address,
1842
+ amount0: input.preview.data.limit0,
1843
+ amount1: input.preview.data.limit1,
1844
+ ...scope.block
1845
+ });
1846
+ if (status.data.tokens.some((token) => !token.sufficientBalance || token.needsApproval))
1847
+ throw new InvalidMarketConfigError(
1848
+ "spend",
1849
+ "Insufficient token balance or allowance for deposit maxima."
1850
+ );
1851
+ }
1852
+ await simulate(request, scope.block.blockNumber);
1853
+ if (isAddressEqual10(key.currency0, zeroAddress7)) {
1854
+ const fees = await publicClient.estimateFeesPerGas({ chain: void 0, type: "eip1559" });
1855
+ const estimatedGas = await publicClient.estimateGas({ ...request, ...fees });
1856
+ request = { ...request, ...fees, gas: (estimatedGas * 125n + 99n) / 100n };
1857
+ await checkNativeBudget(request);
1858
+ }
1859
+ return request;
1860
+ });
1861
+ const after = await account();
1862
+ if (!isAddressEqual10(live.address, after.address))
1863
+ throw new InvalidMarketConfigError("account", "Wallet account changed during preparation.");
1864
+ const expiresAt = input.preview?.data.expiresAt ?? expiry(snapshot.block.timestamp, input.validForSeconds);
1865
+ const preparedContext = immutableClone({
1866
+ action: input.action,
1867
+ ...managementContext ? { management: managementContext } : {},
1868
+ key,
1869
+ rangeId: input.rangeId,
1870
+ block: snapshot.block,
1871
+ expiresAt,
1872
+ owner: input.owner ?? live.address,
1873
+ recipient: input.action === "deposit" || input.action === "approve" ? live.address : input.to
1874
+ });
1875
+ return store.create(snapshot.data, input.preview ?? null, preparedContext);
1876
+ }
1877
+ function requirePreview(value, action) {
1878
+ if (!previews.has(value) || value.data.action !== action)
1879
+ throw new InvalidMarketConfigError(
1880
+ "preview",
1881
+ "Use an unchanged preview from this client for the requested action."
1882
+ );
1883
+ return value.data;
1884
+ }
1885
+ async function prepareWithdraw(previewValue, to, maxFeeBps) {
1886
+ const q = requirePreview(previewValue, "withdraw");
1887
+ recipient(context, q.key, to);
1888
+ if (maxFeeBps !== void 0) claimFee(maxFeeBps);
1889
+ const args = [
1890
+ q.key,
1891
+ q.tickLower,
1892
+ q.tickUpper,
1893
+ q.liquidity,
1894
+ to,
1895
+ q.limit0,
1896
+ q.limit1,
1897
+ q.deadline
1898
+ ];
1899
+ return prepare({
1900
+ action: maxFeeBps === void 0 ? "withdraw" : "withdrawAndClaim",
1901
+ key: q.key,
1902
+ to,
1903
+ rangeId: q.rangeId,
1904
+ preview: previewValue,
1905
+ data: maxFeeBps === void 0 ? encodeFunctionData2({ abi: marketRampAbi, functionName: "withdraw", args }) : encodeFunctionData2({
1906
+ abi: marketRampAbi,
1907
+ functionName: "withdrawAndClaim",
1908
+ args: [...args, maxFeeBps]
1909
+ })
1910
+ });
1911
+ }
1912
+ async function send(prepared) {
1913
+ if (!prepared || typeof prepared !== "object" || !store.has(prepared))
1914
+ throw new InvalidMarketConfigError(
1915
+ "prepared",
1916
+ "Transaction was not prepared by this client."
1917
+ );
1918
+ if (submitting.has(prepared) || submitted.has(prepared))
1919
+ throw new InvalidMarketConfigError(
1920
+ "prepared",
1921
+ "Transaction is submitting or already submitted; prepare again for another action."
1922
+ );
1923
+ const request = store.getCanonical(prepared);
1924
+ if (!request || !walletClient)
1925
+ throw new InvalidMarketConfigError("wallet", "A wallet is required.");
1926
+ submitting.add(prepared);
1927
+ try {
1928
+ const live = await account();
1929
+ if (!isAddressEqual10(live.address, request.account))
1930
+ throw new InvalidMarketConfigError("account", "Wallet account changed; prepare again.");
1931
+ await fresh(prepared.context.block, prepared.context.expiresAt);
1932
+ await readMarketSnapshot(context, {}, async (scope) => {
1933
+ const management = prepared.context.management;
1934
+ if (management) {
1935
+ const execution = management.execution;
1936
+ const auth = await inspectMarketManagementAt(
1937
+ scope,
1938
+ management.action,
1939
+ live.address,
1940
+ execution.mode === "schedule" ? execution.when : 0
1941
+ );
1942
+ const canonical = managementRequest(auth, execution, scope.block.timestamp);
1943
+ if (!isAddressEqual10(canonical.to, request.to) || canonical.data !== request.data || auth.operationId !== management.operationId)
1944
+ throw new InvalidMarketConfigError(
1945
+ "management",
1946
+ "Management request changed; prepare again."
1947
+ );
1948
+ } else
1949
+ await assertWriteDeployment(
1950
+ scope,
1951
+ prepared.context.key,
1952
+ prepared.context.action === "setClaimOperator" || prepared.context.action === "claimFor"
1953
+ );
1954
+ });
1955
+ await simulate(request);
1956
+ const finalAccount = await account();
1957
+ if (!isAddressEqual10(finalAccount.address, request.account))
1958
+ throw new InvalidMarketConfigError("account", "Wallet account changed before signing.");
1959
+ await fresh(prepared.context.block, prepared.context.expiresAt);
1960
+ await checkNativeBudget(request);
1961
+ let hash;
1962
+ try {
1963
+ hash = await walletClient.sendTransaction({
1964
+ ...request,
1965
+ account: finalAccount,
1966
+ chain: walletClient.chain ?? null
1967
+ });
1968
+ } catch (cause) {
1969
+ throw new MarketTransactionError("send", cause);
1970
+ }
1971
+ sent.set(hash, prepared);
1972
+ submitted.add(prepared);
1973
+ return hash;
1974
+ } finally {
1975
+ submitting.delete(prepared);
1976
+ }
1977
+ }
1978
+ async function waitForTransaction(hash, options = {}) {
1979
+ const prepared = sent.get(hash);
1980
+ if (!prepared)
1981
+ throw new InvalidMarketConfigError(
1982
+ "hash",
1983
+ "Only hashes sent by this client can be reconciled with its prepared action."
1984
+ );
1985
+ if (await publicClient.getChainId() !== chain.chainId)
1986
+ throw new InvalidMarketConfigError("chainId", "Receipt client is on a different chain.");
1987
+ try {
1988
+ let replacement;
1989
+ const receipt = await publicClient.waitForTransactionReceipt({
1990
+ hash,
1991
+ confirmations: chain.confirmations,
1992
+ timeout: options.timeout,
1993
+ onReplaced: ({ reason, transaction }) => {
1994
+ if (reason !== "repriced")
1995
+ replacement = new MarketTransactionReplacedError(hash, transaction.hash, reason);
1996
+ }
1997
+ });
1998
+ if (replacement) throw replacement;
1999
+ const result = transactionResultFromReceipt(receipt);
2000
+ const managementEvents = [];
2001
+ const management = prepared.context.management;
2002
+ if (receipt.status === "success" && management) {
2003
+ const eventAbi = [
2004
+ ...marketRampAbi,
2005
+ ...marketRwaRampAbi,
2006
+ ...marketPoolRegistryAbi,
2007
+ ...marketRampReaderAbi,
2008
+ ...marketAccessManagerAbi
2009
+ ];
2010
+ for (const log of receipt.logs) {
2011
+ const isAuthority = isAddressEqual10(log.address, chain.deployment.authority.address);
2012
+ if (!isAuthority && !isAddressEqual10(log.address, management.target)) continue;
2013
+ try {
2014
+ const decoded = decodeEventLog({
2015
+ abi: eventAbi,
2016
+ data: log.data,
2017
+ topics: log.topics,
2018
+ strict: true
2019
+ });
2020
+ const args = Object.fromEntries(Object.entries(decoded.args ?? {}));
2021
+ if (isAuthority && args.operationId !== management.operationId) continue;
2022
+ if (!isAuthority && management.execution.mode === "schedule") continue;
2023
+ managementEvents.push({ address: log.address, eventName: decoded.eventName, args });
2024
+ } catch {
2025
+ }
2026
+ }
2027
+ if (management.execution.mode !== "direct") {
2028
+ const eventName = management.execution.mode === "schedule" ? "OperationScheduled" : "OperationExecuted";
2029
+ if (!managementEvents.some(
2030
+ (event) => event.eventName === eventName && isAddressEqual10(event.address, chain.deployment.authority.address)
2031
+ ))
2032
+ throw new InvalidMarketConfigError(
2033
+ "receipt.events",
2034
+ "Missing matching AccessManager operation event."
2035
+ );
2036
+ }
2037
+ }
2038
+ const events = [];
2039
+ const shareEvents = [];
2040
+ if (receipt.status === "success")
2041
+ for (const log of receipt.logs) {
2042
+ if (!isAddressEqual10(log.address, prepared.context.key.hooks)) continue;
2043
+ try {
2044
+ const decoded = decodeEventLog({
2045
+ abi: marketRampAbi,
2046
+ data: log.data,
2047
+ topics: log.topics,
2048
+ strict: true
2049
+ });
2050
+ const expected = prepared.context;
2051
+ if (decoded.eventName === "Transfer") {
2052
+ const a = decoded.args;
2053
+ if ((expected.action === "transferShares" || expected.action === "transferSharesFrom") && a.id === expected.rangeId && isAddressEqual10(a.from, expected.owner) && isAddressEqual10(a.to, expected.recipient) && isAddressEqual10(a.caller, prepared.request.account))
2054
+ shareEvents.push({
2055
+ eventName: "Transfer",
2056
+ caller: a.caller,
2057
+ from: a.from,
2058
+ to: a.to,
2059
+ rangeId: a.id,
2060
+ amount: a.amount
2061
+ });
2062
+ continue;
2063
+ }
2064
+ if (decoded.eventName === "Approval") {
2065
+ const a = decoded.args;
2066
+ if (expected.action === "approveShares" && a.id === expected.rangeId && isAddressEqual10(a.owner, expected.owner) && isAddressEqual10(a.spender, expected.recipient))
2067
+ shareEvents.push({
2068
+ eventName: "Approval",
2069
+ owner: a.owner,
2070
+ spender: a.spender,
2071
+ rangeId: a.id,
2072
+ amount: a.amount
2073
+ });
2074
+ continue;
2075
+ }
2076
+ if (decoded.eventName === "OperatorSet" || decoded.eventName === "ClaimOperatorSet") {
2077
+ const a = decoded.args;
2078
+ if (isAddressEqual10(a.owner, expected.owner) && isAddressEqual10(a.operator, expected.recipient)) {
2079
+ if (decoded.eventName === "OperatorSet" && expected.action === "setShareOperator")
2080
+ shareEvents.push({ eventName: "OperatorSet", ...decoded.args });
2081
+ if (decoded.eventName === "ClaimOperatorSet" && expected.action === "setClaimOperator" && decoded.args.rangeId === expected.rangeId)
2082
+ shareEvents.push({ eventName: "ClaimOperatorSet", ...decoded.args });
2083
+ }
2084
+ continue;
2085
+ }
2086
+ if (decoded.eventName !== "Deposited" && decoded.eventName !== "Withdrawn" && decoded.eventName !== "FeesClaimed")
2087
+ continue;
2088
+ const args = decoded.args;
2089
+ const to = "to" in args ? args.to : args.owner;
2090
+ if (!isAddressEqual10(args.owner, prepared.context.owner) || args.rangeId !== prepared.context.rangeId || !isAddressEqual10(to, prepared.context.recipient))
2091
+ continue;
2092
+ events.push({
2093
+ eventName: decoded.eventName,
2094
+ owner: args.owner,
2095
+ rangeId: args.rangeId,
2096
+ amount0: args.amount0,
2097
+ amount1: args.amount1,
2098
+ liquidity: "liquidity" in args ? args.liquidity : null,
2099
+ to
2100
+ });
2101
+ } catch {
2102
+ }
2103
+ }
2104
+ const requiredEvent = prepared.context.action === "deposit" ? "Deposited" : prepared.context.action === "withdraw" || prepared.context.action === "withdrawAndClaim" ? "Withdrawn" : null;
2105
+ if (receipt.status === "success" && requiredEvent && !events.some((event) => event.eventName === requiredEvent))
2106
+ throw new InvalidMarketConfigError(
2107
+ "receipt.events",
2108
+ "Successful receipt is missing the matching liquidity event."
2109
+ );
2110
+ if (receipt.status === "success" && [
2111
+ "transferShares",
2112
+ "transferSharesFrom",
2113
+ "approveShares",
2114
+ "setShareOperator",
2115
+ "setClaimOperator"
2116
+ ].includes(prepared.context.action) && shareEvents.length === 0)
2117
+ throw new InvalidMarketConfigError(
2118
+ "receipt.events",
2119
+ "Successful receipt is missing the matching share/authorization event."
2120
+ );
2121
+ return {
2122
+ hash: result.hash,
2123
+ status: receipt.status === "success" ? "confirmed" : "reverted",
2124
+ receipt,
2125
+ events,
2126
+ shareEvents,
2127
+ managementEvents
2128
+ };
2129
+ } catch (cause) {
2130
+ if (cause instanceof MarketTransactionReplacedError) throw cause;
2131
+ throw new MarketTransactionError("receipt", cause);
2132
+ }
2133
+ }
2134
+ function shareRange(params) {
2135
+ const key = liquidityKey(context, params.key);
2136
+ return {
2137
+ key,
2138
+ rangeId: getMarketRangeId(
2139
+ getMarketPoolId(key),
2140
+ params.tickLower,
2141
+ params.tickUpper,
2142
+ key.tickSpacing
2143
+ )
2144
+ };
2145
+ }
2146
+ function transferShares(input) {
2147
+ const params = immutableClone(input);
2148
+ const { key, rangeId } = shareRange(params);
2149
+ recipient(context, key, params.to);
2150
+ assertMarketUint(params.amount, "shares", 128);
2151
+ if (params.amount === 0n)
2152
+ throw new InvalidMarketConfigError("shares", "Share transfer amount must be positive.");
2153
+ if (params.owner) assertMarketAddress(params.owner, "owner");
2154
+ return prepare({
2155
+ action: params.owner ? "transferSharesFrom" : "transferShares",
2156
+ key,
2157
+ rangeId,
2158
+ owner: params.owner,
2159
+ to: params.to,
2160
+ validForSeconds: params.validForSeconds,
2161
+ data: params.owner ? encodeFunctionData2({
2162
+ abi: marketRampAbi,
2163
+ functionName: "transferFrom",
2164
+ args: [params.owner, params.to, rangeId, params.amount]
2165
+ }) : encodeFunctionData2({
2166
+ abi: marketRampAbi,
2167
+ functionName: "transfer",
2168
+ args: [params.to, rangeId, params.amount]
2169
+ })
2170
+ });
2171
+ }
2172
+ return {
2173
+ getManagementAuthorization: (input, owner, options = {}) => {
2174
+ const action = immutableClone(input);
2175
+ return readMarketSnapshot(
2176
+ context,
2177
+ {},
2178
+ (scope) => inspectMarketManagementAt(scope, action, owner, options.when)
2179
+ );
2180
+ },
2181
+ prepareManagement: async (input, options = {}) => {
2182
+ const action = immutableClone(input);
2183
+ const execution = immutableClone(options.execution ?? { mode: "direct" });
2184
+ const call = encodeMarketManagement(context, action);
2185
+ return prepare({
2186
+ action: "management",
2187
+ key: call.key,
2188
+ to: call.to,
2189
+ target: call.to,
2190
+ data: call.data,
2191
+ rangeId: null,
2192
+ validForSeconds: options.validForSeconds,
2193
+ management: { action, execution }
2194
+ });
2195
+ },
2196
+ previewDeposit: (params) => preview("deposit", params),
2197
+ previewWithdraw: (params) => preview("withdraw", params),
2198
+ getSpendStatus: (params) => getMarketSpendStatus(context, params),
2199
+ prepareApproval: async (input) => {
2200
+ const params = immutableClone(input);
2201
+ const key = liquidityKey(context, params.key);
2202
+ if (params.currency !== 0 && params.currency !== 1)
2203
+ throw new InvalidMarketConfigError("currency", "Choose currency 0 or 1.");
2204
+ if (params.currency === 0 && isAddressEqual10(key.currency0, zeroAddress7))
2205
+ throw new InvalidMarketConfigError(
2206
+ "currency",
2207
+ "Native currency does not support approval."
2208
+ );
2209
+ assertMarketUint(params.amount, "amount", 128);
2210
+ const live = await account();
2211
+ return prepare({
2212
+ action: "approve",
2213
+ key,
2214
+ to: live.address,
2215
+ target: params.currency === 0 ? key.currency0 : key.currency1,
2216
+ rangeId: null,
2217
+ validForSeconds: params.validForSeconds,
2218
+ data: encodeFunctionData2({
2219
+ abi: erc20Abi2,
2220
+ functionName: "approve",
2221
+ args: [key.hooks, params.amount]
2222
+ })
2223
+ });
2224
+ },
2225
+ prepareDeposit: async (value) => {
2226
+ const q = requirePreview(value, "deposit");
2227
+ const live = await account();
2228
+ return prepare({
2229
+ action: "deposit",
2230
+ key: q.key,
2231
+ to: live.address,
2232
+ rangeId: q.rangeId,
2233
+ preview: value,
2234
+ data: encodeFunctionData2({
2235
+ abi: marketRampAbi,
2236
+ functionName: "deposit",
2237
+ args: [q.key, q.tickLower, q.tickUpper, q.liquidity, q.limit0, q.limit1, q.deadline]
2238
+ })
2239
+ });
2240
+ },
2241
+ prepareWithdraw: (value, to) => prepareWithdraw(value, to),
2242
+ prepareWithdrawAndClaim: (value, to, maxFeeBps) => prepareWithdraw(value, to, maxFeeBps),
2243
+ prepareClaim: (input) => {
2244
+ const params = immutableClone(input);
2245
+ const key = liquidityKey(context, params.key);
2246
+ recipient(context, key, params.to);
2247
+ claimFee(params.maxFeeBps);
2248
+ const rangeId = getMarketRangeId(
2249
+ getMarketPoolId(key),
2250
+ params.tickLower,
2251
+ params.tickUpper,
2252
+ key.tickSpacing
2253
+ );
2254
+ return prepare({
2255
+ action: "claim",
2256
+ key,
2257
+ to: params.to,
2258
+ rangeId,
2259
+ validForSeconds: params.validForSeconds,
2260
+ data: encodeFunctionData2({
2261
+ abi: marketRampAbi,
2262
+ functionName: "claimFees",
2263
+ args: [key, params.tickLower, params.tickUpper, params.to, params.maxFeeBps]
2264
+ })
2265
+ });
2266
+ },
2267
+ prepareTransferShares: (params) => transferShares({ ...params, owner: void 0 }),
2268
+ prepareTransferSharesFrom: (params) => {
2269
+ assertMarketAddress(params.owner, "owner");
2270
+ return transferShares(params);
2271
+ },
2272
+ prepareApproveShares: (input) => {
2273
+ const params = immutableClone(input);
2274
+ const { key, rangeId } = shareRange(params);
2275
+ assertMarketAddress(params.spender, "spender");
2276
+ assertMarketUint(params.amount, "allowance");
2277
+ return prepare({
2278
+ action: "approveShares",
2279
+ key,
2280
+ rangeId,
2281
+ to: params.spender,
2282
+ validForSeconds: params.validForSeconds,
2283
+ data: encodeFunctionData2({
2284
+ abi: marketRampAbi,
2285
+ functionName: "approve",
2286
+ args: [params.spender, rangeId, params.amount]
2287
+ })
2288
+ });
2289
+ },
2290
+ prepareSetShareOperator: (input) => {
2291
+ const params = immutableClone(input);
2292
+ const key = liquidityKey(context, params.key);
2293
+ assertMarketAddress(params.operator, "operator");
2294
+ if (typeof params.approved !== "boolean")
2295
+ throw new InvalidMarketConfigError("approved", "Expected a boolean.");
2296
+ return prepare({
2297
+ action: "setShareOperator",
2298
+ key,
2299
+ rangeId: null,
2300
+ to: params.operator,
2301
+ validForSeconds: params.validForSeconds,
2302
+ data: encodeFunctionData2({
2303
+ abi: marketRampAbi,
2304
+ functionName: "setOperator",
2305
+ args: [params.operator, params.approved]
2306
+ })
2307
+ });
2308
+ },
2309
+ prepareSetClaimOperator: (input) => {
2310
+ const params = immutableClone(input);
2311
+ const { key, rangeId } = shareRange(params);
2312
+ assertMarketAddress(params.operator, "operator");
2313
+ if (typeof params.approved !== "boolean")
2314
+ throw new InvalidMarketConfigError("approved", "Expected a boolean.");
2315
+ return prepare({
2316
+ action: "setClaimOperator",
2317
+ key,
2318
+ rangeId,
2319
+ to: params.operator,
2320
+ validForSeconds: params.validForSeconds,
2321
+ data: encodeFunctionData2({
2322
+ abi: marketRampAbi,
2323
+ functionName: "setClaimOperator",
2324
+ args: [rangeId, params.operator, params.approved]
2325
+ })
2326
+ });
2327
+ },
2328
+ prepareClaimFeesFor: (input) => {
2329
+ const params = immutableClone(input);
2330
+ const { key, rangeId } = shareRange(params);
2331
+ assertMarketAddress(params.owner, "owner");
2332
+ recipient(context, key, params.to);
2333
+ claimFee(params.maxFeeBps);
2334
+ return prepare({
2335
+ action: "claimFor",
2336
+ key,
2337
+ rangeId,
2338
+ owner: params.owner,
2339
+ to: params.to,
2340
+ validForSeconds: params.validForSeconds,
2341
+ data: encodeFunctionData2({
2342
+ abi: marketRampAbi,
2343
+ functionName: "claimFeesFor",
2344
+ args: [
2345
+ key,
2346
+ params.tickLower,
2347
+ params.tickUpper,
2348
+ params.owner,
2349
+ params.to,
2350
+ params.maxFeeBps
2351
+ ]
2352
+ })
2353
+ });
2354
+ },
2355
+ send,
2356
+ waitForTransaction
2357
+ };
2358
+ }
2359
+
2360
+ // src/verify.ts
2361
+ import { isAddressEqual as isAddressEqual11, keccak256 as keccak2566 } from "viem";
2362
+ function assertEqual(field, expected, actual) {
2363
+ if (expected !== actual) throw new MarketDeploymentVerificationError(field, expected, actual);
2364
+ }
2365
+ async function verifyMarketDeployment(publicClient, input, options = {}) {
2366
+ const deployment = defineMarketDeployment(input);
2367
+ try {
2368
+ assertEqual("chainId", deployment.chainId, await publicClient.getChainId());
2369
+ const block = await publicClient.getBlock(
2370
+ options.blockNumber === void 0 ? { blockTag: "latest" } : { blockNumber: options.blockNumber }
2371
+ );
2372
+ if (block.number === null || block.hash === null) {
2373
+ throw new MarketDeploymentVerificationError("block", "mined block", block);
2374
+ }
2375
+ const blockNumber = block.number;
2376
+ const contracts = [
2377
+ deployment.poolManager,
2378
+ deployment.registry,
2379
+ deployment.authority,
2380
+ ...deployment.reader ? [deployment.reader] : [],
2381
+ ...deployment.poolStateReader?.kind === "state-view" ? [deployment.poolStateReader.contract] : [],
2382
+ ...deployment.hooks.flatMap((hook2) => [
2383
+ hook2,
2384
+ hook2.claimFeePolicy,
2385
+ ...hook2.calendar ? [hook2.calendar] : []
2386
+ ])
2387
+ ];
2388
+ for (const contract2 of contracts) {
2389
+ const code = await publicClient.getCode({ address: contract2.address, blockNumber });
2390
+ if (!code || code === "0x") {
2391
+ throw new MarketDeploymentVerificationError(contract2.address, "deployed code", code);
2392
+ }
2393
+ assertEqual(contract2.address, contract2.runtimeCodeHash.toLowerCase(), keccak2566(code));
2394
+ }
2395
+ const assertAddress = (field, expected, actual) => {
2396
+ if (!isAddressEqual11(expected, actual)) {
2397
+ throw new MarketDeploymentVerificationError(field, expected, actual);
2398
+ }
2399
+ };
2400
+ if (deployment.poolStateReader?.kind === "state-view") {
2401
+ assertAddress(
2402
+ "stateView.poolManager",
2403
+ deployment.poolManager.address,
2404
+ await publicClient.readContract({
2405
+ address: deployment.poolStateReader.contract.address,
2406
+ abi: marketStateViewAbi,
2407
+ functionName: "poolManager",
2408
+ blockNumber
2409
+ })
2410
+ );
2411
+ }
2412
+ assertAddress(
2413
+ "registry.authority",
2414
+ deployment.authority.address,
2415
+ await publicClient.readContract({
2416
+ address: deployment.registry.address,
2417
+ abi: marketPoolRegistryAbi,
2418
+ functionName: "authority",
2419
+ blockNumber
2420
+ })
2421
+ );
2422
+ if (deployment.reader) {
2423
+ const reader = {
2424
+ address: deployment.reader.address,
2425
+ abi: marketRampReaderAbi,
2426
+ blockNumber
2427
+ };
2428
+ assertAddress(
2429
+ "reader.registry",
2430
+ deployment.registry.address,
2431
+ await publicClient.readContract({ ...reader, functionName: "registry" })
2432
+ );
2433
+ assertAddress(
2434
+ "reader.authority",
2435
+ deployment.authority.address,
2436
+ await publicClient.readContract({ ...reader, functionName: "authority" })
2437
+ );
2438
+ }
2439
+ for (const hook2 of deployment.hooks) {
2440
+ const target = { address: hook2.address, abi: marketRampAbi, blockNumber };
2441
+ assertAddress(
2442
+ `${hook2.address}.poolManager`,
2443
+ deployment.poolManager.address,
2444
+ await publicClient.readContract({ ...target, functionName: "poolManager" })
2445
+ );
2446
+ assertAddress(
2447
+ `${hook2.address}.authority`,
2448
+ deployment.authority.address,
2449
+ await publicClient.readContract({ ...target, functionName: "authority" })
2450
+ );
2451
+ assertAddress(
2452
+ `${hook2.address}.claimFeePolicy`,
2453
+ hook2.claimFeePolicy.address,
2454
+ await publicClient.readContract({ ...target, functionName: "claimFeePolicy" })
2455
+ );
2456
+ assertAddress(
2457
+ `${hook2.address}.policy.ledger`,
2458
+ hook2.address,
2459
+ await publicClient.readContract({
2460
+ address: hook2.claimFeePolicy.address,
2461
+ abi: marketClaimFeePolicyAbi,
2462
+ functionName: "ledger",
2463
+ blockNumber
2464
+ })
2465
+ );
2466
+ assertEqual(
2467
+ `${hook2.address}.MAX_POKE_DISCOUNT_BPS`,
2468
+ 5e3,
2469
+ await publicClient.readContract({ ...target, functionName: "MAX_POKE_DISCOUNT_BPS" })
2470
+ );
2471
+ if (hook2.calendar) {
2472
+ assertAddress(
2473
+ `${hook2.address}.calendar`,
2474
+ hook2.calendar.address,
2475
+ await publicClient.readContract({
2476
+ address: hook2.address,
2477
+ abi: marketRwaRampAbi,
2478
+ functionName: "marketCalendar",
2479
+ blockNumber
2480
+ })
2481
+ );
2482
+ assertAddress(
2483
+ `${hook2.address}.calendar.controller`,
2484
+ hook2.address,
2485
+ await publicClient.readContract({
2486
+ address: hook2.calendar.address,
2487
+ abi: marketMarketCalendarAbi,
2488
+ functionName: "controller",
2489
+ blockNumber
2490
+ })
2491
+ );
2492
+ }
2493
+ if (deployment.reader) {
2494
+ assertEqual(
2495
+ `${hook2.address}.readerKind`,
2496
+ hook2.kind === "rwa-ramp" ? 2 : 1,
2497
+ await publicClient.readContract({
2498
+ address: deployment.reader.address,
2499
+ abi: marketRampReaderAbi,
2500
+ functionName: "hookKind",
2501
+ args: [hook2.address],
2502
+ blockNumber
2503
+ })
2504
+ );
2505
+ }
2506
+ }
2507
+ const finalBlock = await publicClient.getBlock({ blockNumber });
2508
+ assertEqual("blockHash", block.hash, finalBlock.hash);
2509
+ return Object.freeze({
2510
+ chainId: deployment.chainId,
2511
+ deploymentId: deployment.deploymentId,
2512
+ blockNumber,
2513
+ blockHash: block.hash,
2514
+ scope: "code-and-wiring",
2515
+ checkedContracts: contracts.length
2516
+ });
2517
+ } catch (error) {
2518
+ if (error instanceof MarketDeploymentVerificationError) throw error;
2519
+ throw new MarketReadError(error);
2520
+ }
2521
+ }
2522
+
2523
+ // src/client.ts
2524
+ function createMarketClient(options) {
2525
+ const chain = defineMarketChain(options.chain);
2526
+ const publicClient = options.publicClient;
2527
+ if (publicClient.chain && publicClient.chain.id !== chain.chainId) {
2528
+ throw new InvalidMarketConfigError("publicClient.chain", "Public client chain does not match.");
2529
+ }
2530
+ const context = { publicClient, deployment: chain.deployment };
2531
+ return Object.freeze({
2532
+ chain,
2533
+ getClaimOperator: (params) => getMarketClaimOperator(context, params),
2534
+ getShareAuthorization: (params) => getMarketShareAuthorization(context, params),
2535
+ getFeeSnapshot: (params) => getMarketFeeSnapshot(context, params),
2536
+ estimateClaimableFees: (params) => estimateMarketClaimableFees(context, params),
2537
+ ...createMarketWriteActions(publicClient, options.walletClient, chain),
2538
+ verifyDeployment: (readOptions) => verifyMarketDeployment(publicClient, chain.deployment, readOptions),
2539
+ getPool: (poolId, readOptions) => getMarketPool(context, poolId, readOptions),
2540
+ listPools: (params) => listMarketPools(context, params),
2541
+ getCurrentFees: (poolId, readOptions) => getMarketCurrentFees(context, poolId, readOptions),
2542
+ getFeeBreakdown: (poolId, zeroForOne, readOptions) => getMarketFeeBreakdown(context, poolId, zeroForOne, readOptions),
2543
+ previewFeeAt: (poolId, zeroForOne, timestamp, readOptions) => previewMarketFeeAt(context, poolId, zeroForOne, timestamp, readOptions),
2544
+ getSession: (poolId, readOptions) => getMarketSession(context, poolId, readOptions),
2545
+ getRange: (params) => getMarketRange(context, params),
2546
+ getPosition: (params) => getMarketPosition(context, params),
2547
+ getPoolState: (poolId, readOptions) => getMarketPoolState(context, poolId, readOptions)
2548
+ });
2549
+ }
2550
+
2551
+ // src/test-pools.ts
2552
+ var marketTestPools = [
2553
+ {
2554
+ chainId: 5042,
2555
+ name: "tBTC/tUSDC",
2556
+ testAssets: true,
2557
+ permissionlessMint: true,
2558
+ hookKind: "ramp",
2559
+ poolId: "0x1a325fe4671d6584778464cbe5ea68b111c2a72718f128a9427717298e85e2cd",
2560
+ key: {
2561
+ currency0: "0x442fc5b4d43fb7ec18ff8ac0a8fb9fdd2efec0db",
2562
+ currency1: "0x44e90eb500868af9b0b16406f3ce165c90e1e85e",
2563
+ fee: 8388608,
2564
+ tickSpacing: 1,
2565
+ hooks: "0x928f4c9b7f80dcbe95b606867e76336a956fa080"
2566
+ },
2567
+ base: {
2568
+ symbol: "tBTC",
2569
+ address: "0x442fc5b4d43fb7ec18ff8ac0a8fb9fdd2efec0db",
2570
+ decimals: 8
2571
+ },
2572
+ quote: {
2573
+ symbol: "tUSDC",
2574
+ address: "0x44e90eb500868af9b0b16406f3ce165c90e1e85e",
2575
+ decimals: 6
2576
+ },
2577
+ components: {
2578
+ poolManager: "0x8366a39cc670b4001a1121b8f6a443a643e40951",
2579
+ registry: "0x3386feb5016983790ef05410e888a8b7bf5a722d",
2580
+ reader: "0xbd782f3de07f2c8f27ef3a2cb165f36c5a505e45",
2581
+ accessManager: "0x005710955b542c11fa2259721840329cddf44914"
2582
+ },
2583
+ source: {
2584
+ commit: "cf16bd9376c12ea50de04658b279176d8d56e4f5",
2585
+ path: "docs/test-pools/arc.json",
2586
+ blockNumber: 23523593,
2587
+ blockHash: "0xea3eb1e8cd308955ad999df48212f3b839e3eec7b55cf7702aba213d548f847d"
2588
+ }
2589
+ },
2590
+ {
2591
+ chainId: 56,
2592
+ name: "tBNB/tUSDT",
2593
+ testAssets: true,
2594
+ permissionlessMint: true,
2595
+ hookKind: "ramp",
2596
+ poolId: "0xb1cf54cb728bb02bb40def7d4f088a7274f35ef05b6257cb518d5f10be438bee",
2597
+ key: {
2598
+ currency0: "0x78e708f1f8fe842abaaeaf23ade31e524e153980",
2599
+ currency1: "0x8a5218b1b296ced5c88cd55c256fcb58c32f227d",
2600
+ fee: 8388608,
2601
+ tickSpacing: 1,
2602
+ hooks: "0xa6a75d930f7a920391c4afffe744069233c4e080"
2603
+ },
2604
+ base: {
2605
+ symbol: "tBNB",
2606
+ address: "0x78e708f1f8fe842abaaeaf23ade31e524e153980",
2607
+ decimals: 18
2608
+ },
2609
+ quote: {
2610
+ symbol: "tUSDT",
2611
+ address: "0x8a5218b1b296ced5c88cd55c256fcb58c32f227d",
2612
+ decimals: 18
2613
+ },
2614
+ components: {
2615
+ poolManager: "0x28e2Ea090877bF75740558f6BFB36A5ffeE9e9dF",
2616
+ registry: "0xe75be888ae3d92be2f962f62f78775228eb3cbc9",
2617
+ reader: "0x2fd8d887a67bf61166e5aacae375cda0ad72d292",
2618
+ accessManager: "0x09e9f944a86c5c239eb0dceac85e1f4805d61256"
2619
+ },
2620
+ source: {
2621
+ commit: "cf16bd9376c12ea50de04658b279176d8d56e4f5",
2622
+ path: "docs/test-pools/bsc.json",
2623
+ blockNumber: 124890195,
2624
+ blockHash: "0xba1ae7df7b719fc6d0cf4b49a2278926fc6c62aaf12e2bc49c9788579bba948e"
2625
+ }
2626
+ },
2627
+ {
2628
+ chainId: 56,
2629
+ name: "tQQQ/tUSDT",
2630
+ testAssets: true,
2631
+ permissionlessMint: true,
2632
+ hookKind: "rwa-ramp",
2633
+ poolId: "0x9ccf485776611256dd717db8c53808e370160d8c90668a75c6d456dd07f21423",
2634
+ key: {
2635
+ currency0: "0x51984c455a78c072f9a23453e236bd3729dc3efd",
2636
+ currency1: "0x8a5218b1b296ced5c88cd55c256fcb58c32f227d",
2637
+ fee: 8388608,
2638
+ tickSpacing: 1,
2639
+ hooks: "0x7b144d9583c71a1b20cb26954d2ccd330af46080"
2640
+ },
2641
+ base: {
2642
+ symbol: "tQQQ",
2643
+ address: "0x51984c455a78c072f9a23453e236bd3729dc3efd",
2644
+ decimals: 18
2645
+ },
2646
+ quote: {
2647
+ symbol: "tUSDT",
2648
+ address: "0x8a5218b1b296ced5c88cd55c256fcb58c32f227d",
2649
+ decimals: 18
2650
+ },
2651
+ components: {
2652
+ poolManager: "0x28e2Ea090877bF75740558f6BFB36A5ffeE9e9dF",
2653
+ registry: "0xe75be888ae3d92be2f962f62f78775228eb3cbc9",
2654
+ reader: "0x2fd8d887a67bf61166e5aacae375cda0ad72d292",
2655
+ accessManager: "0x09e9f944a86c5c239eb0dceac85e1f4805d61256"
2656
+ },
2657
+ source: {
2658
+ commit: "cf16bd9376c12ea50de04658b279176d8d56e4f5",
2659
+ path: "docs/test-pools/bsc.json",
2660
+ blockNumber: 124890195,
2661
+ blockHash: "0xba1ae7df7b719fc6d0cf4b49a2278926fc6c62aaf12e2bc49c9788579bba948e"
2662
+ }
2663
+ }
2664
+ ];
2665
+ export {
2666
+ InvalidMarketConfigError,
2667
+ MarketDeploymentVerificationError,
2668
+ MarketFeatureUnavailableError,
2669
+ MarketReadError,
2670
+ MarketSettlingError,
2671
+ MarketTransactionError,
2672
+ MarketTransactionReplacedError,
2673
+ calculateMarketClaimableFees,
2674
+ createMarketClient,
2675
+ defineMarketChain,
2676
+ defineMarketDeployment,
2677
+ defineMarketPoolKey,
2678
+ estimateMarketClaimableFees,
2679
+ getMarketAmountsForLiquidity,
2680
+ getMarketClaimOperator,
2681
+ getMarketCurrentFees,
2682
+ getMarketFeeBreakdown,
2683
+ getMarketFeeSnapshot,
2684
+ getMarketLiquidityForAmounts,
2685
+ getMarketPool,
2686
+ getMarketPoolId,
2687
+ getMarketPoolState,
2688
+ getMarketPosition,
2689
+ getMarketPriceRatio,
2690
+ getMarketRange,
2691
+ getMarketRangeId,
2692
+ getMarketSession,
2693
+ getMarketShareAuthorization,
2694
+ getMarketSpendStatus,
2695
+ getMarketSqrtPriceAtTick,
2696
+ getMarketSwapDirection,
2697
+ getMarketTickAtSqrtPrice,
2698
+ listMarketPools,
2699
+ marketDaysInMonth,
2700
+ marketTestPools,
2701
+ packMarketDayOverrides,
2702
+ previewMarketFeeAt,
2703
+ verifyMarketDeployment
2704
+ };
2705
+ //# sourceMappingURL=index.js.map