@skate-org/amm-evm-v2 2.0.0-alpha.3 → 2.0.0-alpha.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @skate-org/amm-evm-v2
2
2
 
3
+ ## 2.0.0-alpha.5 — 2026-05-06
4
+
5
+ - **Kernel lens helpers ported from v1.** Adds `simulateSwap`,
6
+ `simulateMint`, `simulateBurn`, `simulateDecreaseLiquidity` —
7
+ static-call wrappers around `KernelManager.lens{Swap,Mint,Burn,DecreaseLiquidity}`.
8
+ Each returns named fields matching the ABI output (e.g.
9
+ `simulateMint` → `{ amount0Used, amount1Used, liquidityAmount, returnData }`)
10
+ and accepts an optional viem client for test injection. Errors flow
11
+ through the read-path (`EvmReadError`) since lens calls don't write
12
+ state. Same DEV/STAGING/PRODUCTION mode handling as the readers.
13
+ - Internal: extracted `resolveKernelClient` to `kernel/_client.ts` so
14
+ readers and lens helpers share the same client-resolution logic.
15
+ - Internal (tests): extracted the `mockKernelClient` helper to
16
+ `test/_helpers.ts`. Reader and lens test suites now share one
17
+ union-ABI mock transport instead of duplicating the implementation.
18
+
19
+ ## 2.0.0-alpha.4 — 2026-05-06
20
+
21
+ Lockstep bump — paired with the `SwapQuote` schema fix in
22
+ `@skate-org/amm-api-v2`. This package's source is unchanged versus
23
+ `2.0.0-alpha.3`.
24
+
3
25
  ## 2.0.0-alpha.3 — 2026-05-06
4
26
 
5
27
  Lockstep bump — paired with the SVM/Sui efficiency pass in
package/dist/index.cjs CHANGED
@@ -39,6 +39,10 @@ __export(index_exports, {
39
39
  readTick: () => readTick,
40
40
  readTickBitmap: () => readTickBitmap,
41
41
  readUserPoolBalances: () => readUserPoolBalances,
42
+ simulateBurn: () => simulateBurn,
43
+ simulateDecreaseLiquidity: () => simulateDecreaseLiquidity,
44
+ simulateMint: () => simulateMint,
45
+ simulateSwap: () => simulateSwap,
42
46
  submitAction: () => submitAction,
43
47
  submitApproval: () => submitApproval,
44
48
  submitSwap: () => submitSwap,
@@ -162,11 +166,15 @@ function wrapWriteError(err, functionName) {
162
166
  // src/kernel/reader.ts
163
167
  var import_amm_bindings = require("@skate-org/amm-bindings");
164
168
  var import_amm_core_v23 = require("@skate-org/amm-core-v2");
165
- function resolveClient(mode, client) {
169
+
170
+ // src/kernel/_client.ts
171
+ function resolveKernelClient(mode, client) {
166
172
  return client ?? getKernelPublicClient(mode);
167
173
  }
174
+
175
+ // src/kernel/reader.ts
168
176
  async function readPool(kernelPool, mode, client) {
169
- const c = resolveClient(mode, client);
177
+ const c = resolveKernelClient(mode, client);
170
178
  try {
171
179
  const [slot0, liquidity] = await Promise.all([
172
180
  c.readContract({
@@ -200,7 +208,7 @@ async function readPool(kernelPool, mode, client) {
200
208
  async function readPosition(tokenId, mode, client) {
201
209
  const { mode: baseMode } = (0, import_amm_core_v23.normalizeMode)(mode);
202
210
  const manager = (0, import_amm_core_v23.KernelManagerAddress)(baseMode);
203
- const c = resolveClient(mode, client);
211
+ const c = resolveKernelClient(mode, client);
204
212
  try {
205
213
  const raw = await c.readContract({
206
214
  address: manager,
@@ -227,7 +235,7 @@ async function readPosition(tokenId, mode, client) {
227
235
  }
228
236
  }
229
237
  async function readTickBitmap(kernelPool, wordPos, mode, client) {
230
- const c = resolveClient(mode, client);
238
+ const c = resolveKernelClient(mode, client);
231
239
  try {
232
240
  const word = await c.readContract({
233
241
  address: kernelPool,
@@ -241,7 +249,7 @@ async function readTickBitmap(kernelPool, wordPos, mode, client) {
241
249
  }
242
250
  }
243
251
  async function readTick(kernelPool, tick, mode, client) {
244
- const c = resolveClient(mode, client);
252
+ const c = resolveKernelClient(mode, client);
245
253
  try {
246
254
  const raw = await c.readContract({
247
255
  address: kernelPool,
@@ -264,7 +272,7 @@ async function readTick(kernelPool, tick, mode, client) {
264
272
  }
265
273
  }
266
274
  async function computePositionAmounts(tokenId, mode, client) {
267
- const c = resolveClient(mode, client);
275
+ const c = resolveKernelClient(mode, client);
268
276
  const position = await readPosition(tokenId, mode, c);
269
277
  const { slot0 } = await readPool(position.pool, mode, c);
270
278
  const sqrtLower = (0, import_amm_core_v23.getSqrtRatioAtTick)(position.tickLower);
@@ -319,15 +327,103 @@ function decodeTickBitmapWord(word, wordPos, tickSpacing) {
319
327
  return result;
320
328
  }
321
329
 
322
- // src/periphery/reader.ts
330
+ // src/kernel/lens.ts
323
331
  var import_amm_bindings2 = require("@skate-org/amm-bindings");
324
332
  var import_amm_core_v24 = require("@skate-org/amm-core-v2");
325
- function resolveClient2(chain, mode, client) {
333
+ async function simulateSwap(params, mode, client) {
334
+ const { mode: baseMode } = (0, import_amm_core_v24.normalizeMode)(mode);
335
+ const c = resolveKernelClient(mode, client);
336
+ try {
337
+ const out = await c.simulateContract({
338
+ address: (0, import_amm_core_v24.KernelManagerAddress)(baseMode),
339
+ abi: import_amm_bindings2.KernelManagerABI,
340
+ functionName: "lensSwap",
341
+ args: [
342
+ params.pool,
343
+ params.recipient,
344
+ params.zeroForOne,
345
+ params.amountSpecified,
346
+ params.sqrtPriceLimitX96
347
+ ]
348
+ });
349
+ const [amount0, amount1, sqrtPriceX96After, returnData] = out.result;
350
+ return { amount0, amount1, sqrtPriceX96After, returnData };
351
+ } catch (err) {
352
+ throw wrapReadError(err, "simulateSwap");
353
+ }
354
+ }
355
+ async function simulateMint(params, mode, client) {
356
+ const { mode: baseMode } = (0, import_amm_core_v24.normalizeMode)(mode);
357
+ const c = resolveKernelClient(mode, client);
358
+ try {
359
+ const out = await c.simulateContract({
360
+ address: (0, import_amm_core_v24.KernelManagerAddress)(baseMode),
361
+ abi: import_amm_bindings2.KernelManagerABI,
362
+ functionName: "lensMint",
363
+ args: [
364
+ params.pool,
365
+ params.recipient,
366
+ params.tickLower,
367
+ params.tickUpper,
368
+ params.amount0,
369
+ params.amount1,
370
+ params.data
371
+ ]
372
+ });
373
+ const [amount0Used, amount1Used, liquidityAmount, returnData] = out.result;
374
+ return { amount0Used, amount1Used, liquidityAmount, returnData };
375
+ } catch (err) {
376
+ throw wrapReadError(err, "simulateMint");
377
+ }
378
+ }
379
+ async function simulateBurn(params, mode, client) {
380
+ const { mode: baseMode } = (0, import_amm_core_v24.normalizeMode)(mode);
381
+ const c = resolveKernelClient(mode, client);
382
+ try {
383
+ const out = await c.simulateContract({
384
+ address: (0, import_amm_core_v24.KernelManagerAddress)(baseMode),
385
+ abi: import_amm_bindings2.KernelManagerABI,
386
+ functionName: "lensBurn",
387
+ args: [
388
+ params.pool,
389
+ params.recipient,
390
+ params.tickLower,
391
+ params.tickUpper,
392
+ params.amount
393
+ ]
394
+ });
395
+ const [amount0, amount1, returnData] = out.result;
396
+ return { amount0, amount1, returnData };
397
+ } catch (err) {
398
+ throw wrapReadError(err, "simulateBurn");
399
+ }
400
+ }
401
+ async function simulateDecreaseLiquidity(params, mode, client) {
402
+ const { mode: baseMode } = (0, import_amm_core_v24.normalizeMode)(mode);
403
+ const c = resolveKernelClient(mode, client);
404
+ try {
405
+ const out = await c.simulateContract({
406
+ address: (0, import_amm_core_v24.KernelManagerAddress)(baseMode),
407
+ abi: import_amm_bindings2.KernelManagerABI,
408
+ functionName: "lensDecreaseLiquidity",
409
+ args: [params.tokenId, params.liquidity]
410
+ });
411
+ const [amount0, amount1, returnData] = out.result;
412
+ return { amount0, amount1, returnData };
413
+ } catch (err) {
414
+ throw wrapReadError(err, "simulateDecreaseLiquidity");
415
+ }
416
+ }
417
+
418
+ // src/periphery/reader.ts
419
+ var import_amm_bindings3 = require("@skate-org/amm-bindings");
420
+ var import_amm_core_v25 = require("@skate-org/amm-core-v2");
421
+ function resolveClient(chain, mode, client) {
326
422
  return client ?? getSourcePublicClient(chain, mode);
327
423
  }
328
424
  async function readPeripheryPool(chain, kernelPool, mode, client) {
329
- const { mode: baseMode } = (0, import_amm_core_v24.normalizeMode)(mode);
330
- const details = (0, import_amm_core_v24.getPeripheryDetailsByKernelPoolAndChainId)(
425
+ const { mode: baseMode } = (0, import_amm_core_v25.normalizeMode)(mode);
426
+ const details = (0, import_amm_core_v25.getPeripheryDetailsByKernelPoolAndChainId)(
331
427
  kernelPool,
332
428
  chain,
333
429
  baseMode
@@ -339,7 +435,7 @@ async function readPeripheryPool(chain, kernelPool, mode, client) {
339
435
  );
340
436
  }
341
437
  const address = details.address;
342
- const c = resolveClient2(chain, mode, client);
438
+ const c = resolveClient(chain, mode, client);
343
439
  try {
344
440
  const [
345
441
  balancesAvailableRaw,
@@ -352,37 +448,37 @@ async function readPeripheryPool(chain, kernelPool, mode, client) {
352
448
  ] = await Promise.all([
353
449
  c.readContract({
354
450
  address,
355
- abi: import_amm_bindings2.PeripheryPoolABI,
451
+ abi: import_amm_bindings3.PeripheryPoolABI,
356
452
  functionName: "balancesAvailable"
357
453
  }),
358
454
  c.readContract({
359
455
  address,
360
- abi: import_amm_bindings2.PeripheryPoolABI,
456
+ abi: import_amm_bindings3.PeripheryPoolABI,
361
457
  functionName: "dustAmount0"
362
458
  }),
363
459
  c.readContract({
364
460
  address,
365
- abi: import_amm_bindings2.PeripheryPoolABI,
461
+ abi: import_amm_bindings3.PeripheryPoolABI,
366
462
  functionName: "dustAmount1"
367
463
  }),
368
464
  c.readContract({
369
465
  address,
370
- abi: import_amm_bindings2.PeripheryPoolABI,
466
+ abi: import_amm_bindings3.PeripheryPoolABI,
371
467
  functionName: "token0"
372
468
  }),
373
469
  c.readContract({
374
470
  address,
375
- abi: import_amm_bindings2.PeripheryPoolABI,
471
+ abi: import_amm_bindings3.PeripheryPoolABI,
376
472
  functionName: "token1"
377
473
  }),
378
474
  c.readContract({
379
475
  address,
380
- abi: import_amm_bindings2.PeripheryPoolABI,
476
+ abi: import_amm_bindings3.PeripheryPoolABI,
381
477
  functionName: "fee"
382
478
  }),
383
479
  c.readContract({
384
480
  address,
385
- abi: import_amm_bindings2.PeripheryPoolABI,
481
+ abi: import_amm_bindings3.PeripheryPoolABI,
386
482
  functionName: "kernelPool"
387
483
  })
388
484
  ]);
@@ -405,8 +501,8 @@ async function readPeripheryPool(chain, kernelPool, mode, client) {
405
501
  }
406
502
  }
407
503
  async function readUserPoolBalances(chain, kernelPool, user, mode, client) {
408
- const { mode: baseMode } = (0, import_amm_core_v24.normalizeMode)(mode);
409
- const details = (0, import_amm_core_v24.getPeripheryDetailsByKernelPoolAndChainId)(
504
+ const { mode: baseMode } = (0, import_amm_core_v25.normalizeMode)(mode);
505
+ const details = (0, import_amm_core_v25.getPeripheryDetailsByKernelPoolAndChainId)(
410
506
  kernelPool,
411
507
  chain,
412
508
  baseMode
@@ -417,11 +513,11 @@ async function readUserPoolBalances(chain, kernelPool, user, mode, client) {
417
513
  `no periphery entry for kernelPool=${kernelPool} chain=${chain} mode=${baseMode}`
418
514
  );
419
515
  }
420
- const c = resolveClient2(chain, mode, client);
516
+ const c = resolveClient(chain, mode, client);
421
517
  try {
422
518
  const raw = await c.readContract({
423
519
  address: details.address,
424
- abi: import_amm_bindings2.PeripheryPoolABI,
520
+ abi: import_amm_bindings3.PeripheryPoolABI,
425
521
  functionName: "usersData",
426
522
  args: [user]
427
523
  });
@@ -483,7 +579,7 @@ async function submitApproval(wallet, params, mode) {
483
579
 
484
580
  // src/events/kernel.ts
485
581
  var import_viem2 = require("viem");
486
- var import_amm_bindings3 = require("@skate-org/amm-bindings");
582
+ var import_amm_bindings4 = require("@skate-org/amm-bindings");
487
583
  var KERNEL_EVENT_NAMES = [
488
584
  "Burn",
489
585
  "Collect",
@@ -501,7 +597,7 @@ var KERNEL_EVENT_NAMES = [
501
597
  function parseKernelEventLog(log) {
502
598
  try {
503
599
  const decoded = (0, import_viem2.decodeEventLog)({
504
- abi: import_amm_bindings3.KernelEventEmitterABI,
600
+ abi: import_amm_bindings4.KernelEventEmitterABI,
505
601
  data: log.data,
506
602
  topics: log.topics
507
603
  });
@@ -522,7 +618,7 @@ function parseKernelEventLog(log) {
522
618
 
523
619
  // src/events/periphery.ts
524
620
  var import_viem3 = require("viem");
525
- var import_amm_bindings4 = require("@skate-org/amm-bindings");
621
+ var import_amm_bindings5 = require("@skate-org/amm-bindings");
526
622
  var PERIPHERY_EVENT_NAMES = [
527
623
  "AmountSettled",
528
624
  "Burned",
@@ -538,7 +634,7 @@ var PERIPHERY_EVENT_NAMES = [
538
634
  function parsePeripheryEventLog(log) {
539
635
  try {
540
636
  const decoded = (0, import_viem3.decodeEventLog)({
541
- abi: import_amm_bindings4.PeripheryEventEmitterABI,
637
+ abi: import_amm_bindings5.PeripheryEventEmitterABI,
542
638
  data: log.data,
543
639
  topics: log.topics
544
640
  });
@@ -558,10 +654,10 @@ function parsePeripheryEventLog(log) {
558
654
  }
559
655
 
560
656
  // src/events/watch.ts
561
- var import_amm_bindings5 = require("@skate-org/amm-bindings");
657
+ var import_amm_bindings6 = require("@skate-org/amm-bindings");
562
658
  function watchKernelEvents(client, address, opts) {
563
659
  return client.watchContractEvent({
564
- abi: import_amm_bindings5.KernelEventEmitterABI,
660
+ abi: import_amm_bindings6.KernelEventEmitterABI,
565
661
  address,
566
662
  onLogs: (logs) => {
567
663
  for (const log of logs) {
@@ -576,7 +672,7 @@ function watchKernelEvents(client, address, opts) {
576
672
  }
577
673
  function watchPeripheryEvents(client, address, opts) {
578
674
  return client.watchContractEvent({
579
- abi: import_amm_bindings5.PeripheryEventEmitterABI,
675
+ abi: import_amm_bindings6.PeripheryEventEmitterABI,
580
676
  address,
581
677
  onLogs: (logs) => {
582
678
  for (const log of logs) {
@@ -610,6 +706,10 @@ function watchPeripheryEvents(client, address, opts) {
610
706
  readTick,
611
707
  readTickBitmap,
612
708
  readUserPoolBalances,
709
+ simulateBurn,
710
+ simulateDecreaseLiquidity,
711
+ simulateMint,
712
+ simulateSwap,
613
713
  submitAction,
614
714
  submitApproval,
615
715
  submitSwap,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/chain-clients.ts","../src/devConfig.ts","../src/errors.ts","../src/kernel/reader.ts","../src/kernel/tickBitmap.ts","../src/periphery/reader.ts","../src/periphery/submit.ts","../src/events/kernel.ts","../src/events/periphery.ts","../src/events/watch.ts"],"sourcesContent":["export * from \"./chain-clients\";\nexport * from \"./devConfig\";\n// Public error classes only; wrap* helpers are internal implementation\n// detail shared between readers/submitters and are not re-exported.\nexport { EvmReadError, EvmWriteError } from \"./errors\";\nexport * from \"./kernel\";\nexport * from \"./periphery\";\nexport * from \"./events\";\n","import {\n createPublicClient,\n defineChain,\n http,\n type Chain,\n type PublicClient,\n type Transport,\n} from \"viem\";\nimport { arbitrum } from \"viem/chains\";\nimport {\n BLOCK_EXPLORER,\n CHAIN,\n VM,\n vmTypeFromChain,\n normalizeMode,\n type EnvModeWithConfig,\n} from \"@skate-org/amm-core-v2\";\n\n/**\n * MegaETH chain definition — `@public`.\n *\n * Exported for callers who need to build their own viem `WalletClient` or\n * `PublicClient` against the same chain the SDK uses internally (e.g. wallet\n * integrations that construct a `WalletClient` ahead of calling\n * `submitAction`). Prefer {@link getKernelPublicClient} when you just need a\n * read client.\n *\n * viem ships a `megaeth` chain at id 4326, but with a different default RPC\n * than the one Skate uses for kernel reads. Define locally so we control the\n * RPC URL + block-explorer metadata and don't inherit unrelated op-stack\n * contract addresses.\n */\nexport const megaethChain: Chain = defineChain({\n id: 4326,\n name: \"MegaETH\",\n network: \"megaeth\",\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n rpcUrls: {\n default: { http: [\"https://mainnet.megaeth.com/rpc\"] },\n public: { http: [\"https://mainnet.megaeth.com/rpc\"] },\n },\n blockExplorers: {\n default: { name: \"Blockscout\", url: BLOCK_EXPLORER.MEGAETH },\n },\n});\n\n/**\n * Default public RPC URLs by chain id.\n *\n * Callers can override per-chain via `DevModeConfig.rpcEndpoints` or by\n * passing an explicit `transport` to the factory functions below.\n */\nconst DEFAULT_RPC: Partial<Record<CHAIN, string>> = {\n [CHAIN.MEGAETH]: \"https://mainnet.megaeth.com/rpc\",\n [CHAIN.ARBITRUM]: \"https://arb1.arbitrum.io/rpc\",\n};\n\n/**\n * Map a supported EVM `CHAIN` to a viem `Chain` definition.\n *\n * Only chains we actively support in Phase 2 are listed; unknown chains\n * return `undefined` and the caller throws.\n */\nfunction chainDefFor(chain: CHAIN): Chain | undefined {\n switch (chain) {\n case CHAIN.MEGAETH:\n return megaethChain;\n case CHAIN.ARBITRUM:\n return arbitrum;\n default:\n return undefined;\n }\n}\n\n/**\n * Resolve the RPC URL for a given chain under the precedence:\n * transport override (caller arg) > mode.config.rpcEndpoints[chain] > DEFAULT_RPC[chain]\n * Returns `undefined` if none is set — callers must have already decided whether\n * to use a caller-supplied transport.\n */\nfunction resolveRpcUrl(\n chain: CHAIN,\n mode: EnvModeWithConfig,\n): string | undefined {\n const { config } = normalizeMode(mode);\n return config?.rpcEndpoints?.[chain] ?? DEFAULT_RPC[chain];\n}\n\n/**\n * Return a fresh `PublicClient` bound to the MegaETH kernel chain.\n *\n * MegaETH is the kernel chain for all environment modes (DEV/STAGING/\n * PRODUCTION) in SDK v2. The `mode` parameter is accepted for API\n * symmetry with the rest of the SDK and as a forward-compatible extension\n * point (e.g. a future testnet kernel).\n *\n * Pure — no singletons, no caching. Pass a custom `transport` to override\n * the default RPC (useful for tests and custom RPC providers).\n */\nexport function getKernelPublicClient(\n mode: EnvModeWithConfig,\n transport?: Transport,\n): PublicClient {\n return createPublicClient({\n chain: megaethChain,\n transport: transport ?? http(resolveRpcUrl(CHAIN.MEGAETH, mode)),\n });\n}\n\n/**\n * Return a fresh `PublicClient` for a source EVM chain (e.g. Arbitrum).\n *\n * Throws a descriptive `Error` when:\n * - `chain` is not an EVM chain (per `vmTypeFromChain`); or\n * - no viem chain definition is registered for `chain`; or\n * - no default RPC URL is configured for `chain` and no `transport` override\n * was provided.\n *\n * Pure — no singletons, no caching.\n */\nexport function getSourcePublicClient(\n chain: CHAIN,\n mode: EnvModeWithConfig,\n transport?: Transport,\n): PublicClient {\n if (vmTypeFromChain(chain) !== VM.EVM) {\n throw new Error(\n `getSourcePublicClient: chain ${chain} is not an EVM chain`,\n );\n }\n const chainDef = chainDefFor(chain);\n if (!chainDef) {\n throw new Error(\n `getSourcePublicClient: no chain definition registered for chain ${chain}`,\n );\n }\n const rpc = resolveRpcUrl(chain, mode);\n if (!rpc && !transport) {\n throw new Error(\n `getSourcePublicClient: no default or override RPC configured for chain ${chain}; pass a transport override or set DevModeConfig.rpcEndpoints[${chain}]`,\n );\n }\n return createPublicClient({\n chain: chainDef,\n transport: transport ?? http(rpc),\n });\n}\n","import type { DevModeConfig } from \"@skate-org/amm-core-v2\";\n\n/** Default DEV api endpoint — matches Phase 1's api client default. */\nexport const DEFAULT_DEV_API_ENDPOINT =\n \"https://dev.api.skatechain.org/amm-action-v2\";\n\n/**\n * Convenience factory for the `{ mode: \"DEV\"; config: DevModeConfig }` tuple.\n *\n * Reduces ceremony at call sites that want to override a single field (e.g.,\n * `rpcEndpoints`) without reconstructing the full object:\n *\n * ```ts\n * const mode = createDevConfig({\n * rpcEndpoints: { [CHAIN.MEGAETH]: \"https://my-private-megaeth/rpc\" },\n * });\n * submitAction(wallet, params, mode);\n * ```\n *\n * Pass nothing to use all defaults.\n */\nexport function createDevConfig(\n overrides: Partial<DevModeConfig> = {},\n): { mode: \"DEV\"; config: DevModeConfig } {\n return {\n mode: \"DEV\",\n config: {\n apiEndpoint: overrides.apiEndpoint ?? DEFAULT_DEV_API_ENDPOINT,\n ...(overrides.rpcEndpoints\n ? { rpcEndpoints: overrides.rpcEndpoints }\n : {}),\n },\n };\n}\n","/**\n * Shared error types for the `@skate-org/amm-evm-v2` package.\n *\n * `EvmReadError` / `EvmWriteError` extend `SdkError` (from core) so callers\n * can `instanceof SdkError` to catch any SDK-origin error without needing\n * to know the specific subclass.\n */\n\nimport { SdkError } from \"@skate-org/amm-core-v2\";\n\n/** SDK-level error thrown when an EVM read reverts or decodes badly. */\nexport class EvmReadError extends SdkError {\n override readonly name: string = \"EvmReadError\";\n readonly functionName: string;\n\n constructor(functionName: string, message: string, options?: ErrorOptions) {\n super(`${functionName}: ${message}`, options);\n this.functionName = functionName;\n }\n}\n\n/**\n * SDK-level error thrown when an EVM write (broadcast) fails.\n *\n * Symmetric with {@link EvmReadError}, but covers the write path: viem's\n * `TransactionExecutionError`, `UserRejectedRequestError`,\n * `ChainMismatchError`, `ChainDisconnectedError`, as well as submitter\n * pre-flight guards (e.g. wrong-chain, missing account).\n */\nexport class EvmWriteError extends SdkError {\n override readonly name: string = \"EvmWriteError\";\n readonly functionName: string;\n\n constructor(functionName: string, message: string, options?: ErrorOptions) {\n super(`${functionName}: ${message}`, options);\n this.functionName = functionName;\n }\n}\n\n/**\n * Wrap any error from an EVM read into `EvmReadError`. Viem always wraps\n * revert-path errors in `ContractFunctionExecutionError` (see\n * `viem/utils/errors/getContractError`), so we check both the outer name and\n * the `.cause` chain for `ContractFunctionRevertedError` /\n * `ContractFunctionZeroDataError`.\n *\n * Shared by `kernel/reader.ts` and `periphery/reader.ts` — depends only on\n * `EvmReadError` and generic Error inspection (no reader-module imports), so\n * it is safe from circular-import concerns.\n */\nexport function wrapReadError(\n err: unknown,\n functionName: string,\n): EvmReadError {\n const outerName = (err as { name?: string } | null)?.name;\n const causeName = (err as { cause?: { name?: string } } | null)?.cause?.name;\n const message =\n (err as { shortMessage?: string } | null)?.shortMessage ??\n (err as { message?: string } | null)?.message ??\n String(err);\n const isViemContractError =\n outerName === \"ContractFunctionExecutionError\" ||\n outerName === \"ContractFunctionRevertedError\" ||\n outerName === \"ContractFunctionZeroDataError\" ||\n causeName === \"ContractFunctionRevertedError\" ||\n causeName === \"ContractFunctionZeroDataError\";\n if (isViemContractError) {\n return new EvmReadError(functionName, `reverted: ${message}`, {\n cause: err as Error,\n });\n }\n return new EvmReadError(functionName, message, { cause: err as Error });\n}\n\n/**\n * Wrap any error from an EVM write-path call (typically\n * `WalletClient.sendTransaction`) into `EvmWriteError`.\n *\n * Any thrown error reaching a submitter is treated as a write failure. If\n * we later want to differentiate known viem write errors\n * (`TransactionExecutionError`, `UserRejectedRequestError`,\n * `ChainMismatchError`, `ChainDisconnectedError`) from unknown errors —\n * e.g. to prefix the message or re-throw unknowns raw — that dispatch goes\n * here. Keeping the single-return shape until a concrete caller need\n * surfaces.\n */\nexport function wrapWriteError(\n err: unknown,\n functionName: string,\n): EvmWriteError {\n const message =\n (err as { shortMessage?: string } | null)?.shortMessage ??\n (err as { message?: string } | null)?.message ??\n String(err);\n return new EvmWriteError(functionName, message, { cause: err as Error });\n}\n","import type { PublicClient } from \"viem\";\nimport {\n KernelManagerABI,\n KernelPoolABI,\n} from \"@skate-org/amm-bindings\";\nimport {\n KernelManagerAddress,\n normalizeMode,\n type EnvModeWithConfig,\n getAmount0Delta,\n getAmount1Delta,\n getSqrtRatioAtTick,\n} from \"@skate-org/amm-core-v2\";\nimport { getKernelPublicClient } from \"../chain-clients\";\nimport { wrapReadError } from \"../errors\";\n\n/** Decoded kernel-pool `slot0` state (named fields, per the ABI tuple). */\nexport interface KernelSlot0 {\n sqrtPriceX96: bigint;\n tick: number;\n observationIndex: number;\n observationCardinality: number;\n observationCardinalityNext: number;\n feeProtocol: number;\n unlocked: boolean;\n}\n\n/** Decoded pool state returned by `readPool`. */\nexport interface KernelPoolState {\n slot0: KernelSlot0;\n liquidity: bigint;\n}\n\n/** Decoded NFT position returned by `readPosition`. */\nexport interface KernelNftPosition {\n pool: `0x${string}`;\n tickLower: number;\n tickUpper: number;\n liquidity: bigint;\n feeGrowthInside0LastX128: bigint;\n feeGrowthInside1LastX128: bigint;\n tokensOwed0: bigint;\n tokensOwed1: bigint;\n}\n\n/** Decoded kernel-pool `ticks(tick)` struct. */\nexport interface KernelTick {\n liquidityGross: bigint;\n liquidityNet: bigint;\n feeGrowthOutside0X128: bigint;\n feeGrowthOutside1X128: bigint;\n tickCumulativeOutside: bigint;\n secondsPerLiquidityOutsideX128: bigint;\n secondsOutside: number;\n initialized: boolean;\n}\n\n/**\n * Return the caller-provided client if present, otherwise build a fresh\n * MegaETH kernel client for the given mode.\n */\nfunction resolveClient(\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): PublicClient {\n return client ?? getKernelPublicClient(mode);\n}\n\n/**\n * Read `slot0` and `liquidity` from a kernel pool. Returns both in a single\n * object; the reads are fired in parallel.\n *\n * The `client` optional parameter is the standard test-injection point.\n */\nexport async function readPool(\n kernelPool: `0x${string}`,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<KernelPoolState> {\n const c = resolveClient(mode, client);\n try {\n const [slot0, liquidity] = await Promise.all([\n c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"slot0\",\n }),\n c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"liquidity\",\n }),\n ]);\n // Viem returns named outputs as a positional tuple (array) when every\n // output has a name — normalize to a named-field object here so callers\n // don't depend on viem's tuple/object split.\n const s0 = slot0 as readonly [\n bigint,\n number,\n number,\n number,\n number,\n number,\n boolean,\n ];\n return {\n slot0: {\n sqrtPriceX96: s0[0],\n tick: s0[1],\n observationIndex: s0[2],\n observationCardinality: s0[3],\n observationCardinalityNext: s0[4],\n feeProtocol: s0[5],\n unlocked: s0[6],\n },\n liquidity: liquidity as bigint,\n };\n } catch (err) {\n throw wrapReadError(err, \"readPool\");\n }\n}\n\n/**\n * Read an NFT position by token id from the kernel manager.\n *\n * Calls `KernelManager.nftPositions(tokenId)` — per the ABI this returns a\n * `DataTypes.NFTPosition` tuple including `pool`, `tickLower`, `tickUpper`,\n * `liquidity`, fee growth, and tokens owed.\n */\nexport async function readPosition(\n tokenId: bigint,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<KernelNftPosition> {\n const { mode: baseMode } = normalizeMode(mode);\n const manager = KernelManagerAddress(baseMode);\n const c = resolveClient(mode, client);\n try {\n const raw = (await c.readContract({\n address: manager,\n abi: KernelManagerABI,\n functionName: \"nftPositions\",\n args: [tokenId],\n })) as unknown;\n // Accept either a positional tuple or an already-named object from\n // viem — normalize to a named-field object, mirroring readPool's\n // defensive remap. Viem's decoding of named-components tuples is\n // stable today (object form), but this guards against future\n // restructuring.\n const asTuple = Array.isArray(raw)\n ? (raw as unknown as readonly [\n `0x${string}`,\n number,\n number,\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n ])\n : null;\n if (asTuple) {\n return {\n pool: asTuple[0],\n tickLower: asTuple[1],\n tickUpper: asTuple[2],\n liquidity: asTuple[3],\n feeGrowthInside0LastX128: asTuple[4],\n feeGrowthInside1LastX128: asTuple[5],\n tokensOwed0: asTuple[6],\n tokensOwed1: asTuple[7],\n };\n }\n return raw as KernelNftPosition;\n } catch (err) {\n throw wrapReadError(err, \"readPosition\");\n }\n}\n\n/**\n * Read a kernel-pool tick-bitmap word (`tickBitmap(int16 wordPos)`).\n *\n * Returns the raw `uint256` word as a bigint. A bit-decoder that expands a\n * word into populated tick indexes is intentionally not shipped in 0.2.0 —\n * flag as an open question for Phase 3 if a caller wants it.\n */\nexport async function readTickBitmap(\n kernelPool: `0x${string}`,\n wordPos: number,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<bigint> {\n const c = resolveClient(mode, client);\n try {\n const word = await c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"tickBitmap\",\n args: [wordPos],\n });\n return word as bigint;\n } catch (err) {\n throw wrapReadError(err, \"readTickBitmap\");\n }\n}\n\n/** Read the `ticks(tick)` struct from a kernel pool. */\nexport async function readTick(\n kernelPool: `0x${string}`,\n tick: number,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<KernelTick> {\n const c = resolveClient(mode, client);\n try {\n const raw = (await c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"ticks\",\n args: [tick],\n })) as readonly [\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n number,\n boolean,\n ];\n return {\n liquidityGross: raw[0],\n liquidityNet: raw[1],\n feeGrowthOutside0X128: raw[2],\n feeGrowthOutside1X128: raw[3],\n tickCumulativeOutside: raw[4],\n secondsPerLiquidityOutsideX128: raw[5],\n secondsOutside: raw[6],\n initialized: raw[7],\n };\n } catch (err) {\n throw wrapReadError(err, \"readTick\");\n }\n}\n\n/**\n * Compute `{amount0, amount1}` for an NFT position using the Group 3 math.\n *\n * Reads the position (to learn `pool`, `tickLower`, `tickUpper`,\n * `liquidity`) and the pool's `slot0`, then splits based on whether the\n * current tick is below, inside, or above the position range — mirroring\n * `PositionValue.principal` from Uniswap v3 periphery.\n */\nexport async function computePositionAmounts(\n tokenId: bigint,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<{ amount0: bigint; amount1: bigint }> {\n const c = resolveClient(mode, client);\n const position = await readPosition(tokenId, mode, c);\n const { slot0 } = await readPool(position.pool, mode, c);\n\n const sqrtLower = getSqrtRatioAtTick(position.tickLower);\n const sqrtUpper = getSqrtRatioAtTick(position.tickUpper);\n\n if (slot0.tick < position.tickLower) {\n return {\n amount0: getAmount0Delta(sqrtLower, sqrtUpper, position.liquidity, false),\n amount1: 0n,\n };\n }\n if (slot0.tick >= position.tickUpper) {\n return {\n amount0: 0n,\n amount1: getAmount1Delta(sqrtLower, sqrtUpper, position.liquidity, false),\n };\n }\n return {\n amount0: getAmount0Delta(\n slot0.sqrtPriceX96,\n sqrtUpper,\n position.liquidity,\n false,\n ),\n amount1: getAmount1Delta(\n sqrtLower,\n slot0.sqrtPriceX96,\n position.liquidity,\n false,\n ),\n };\n}\n","/**\n * Decode a single Uniswap-v3 tick-bitmap `uint256` word into the list of\n * real (non-compressed) ticks it marks as initialized.\n *\n * A tick bitmap word covers 256 compressed ticks. For a given `wordPos`\n * (int16) the word spans compressed ticks `wordPos * 256` through\n * `(wordPos + 1) * 256 - 1`, and bit `k` (0..255) corresponds to the\n * compressed tick `wordPos * 256 + k`. The real tick at bit `k` is\n * `(wordPos * 256 + k) * tickSpacing`.\n *\n * Intended composition with the reader:\n *\n * ```ts\n * const word = await readTickBitmap(pool, wordPos, mode);\n * const ticks = decodeTickBitmapWord(word, wordPos, tickSpacing);\n * ```\n *\n * Pure function: no network, no viem, no external deps.\n *\n * @param word The 256-bit bitmap word returned by PoolAbi.tickBitmap(int16).\n * @param wordPos The int16 word position (-128 .. 127 per Uniswap, but\n * we accept any safe-integer int16-shaped value).\n * @param tickSpacing The pool's tickSpacing (positive integer, typically 1,\n * 10, 60, 200, etc.).\n * @returns Real ticks whose bits are set in the word, ascending.\n *\n * @throws {RangeError} if `tickSpacing <= 0` or if `wordPos` is not a safe integer.\n */\nexport function decodeTickBitmapWord(\n word: bigint,\n wordPos: number,\n tickSpacing: number,\n): number[] {\n if (!Number.isSafeInteger(wordPos)) {\n throw new RangeError(\n `decodeTickBitmapWord: wordPos must be a safe integer, got ${wordPos}`,\n );\n }\n if (!Number.isSafeInteger(tickSpacing) || tickSpacing <= 0) {\n throw new RangeError(\n `decodeTickBitmapWord: tickSpacing must be a positive integer, got ${tickSpacing}`,\n );\n }\n const result: number[] = [];\n // wordPos * 256 gives the base compressed-tick of this word. Each set bit k\n // contributes compressed-tick (wordPos * 256 + k), which becomes real tick\n // (wordPos * 256 + k) * tickSpacing.\n const base = wordPos * 256;\n for (let k = 0; k < 256; k++) {\n if (((word >> BigInt(k)) & 1n) === 1n) {\n result.push((base + k) * tickSpacing);\n }\n }\n return result;\n}\n","import type { PublicClient } from \"viem\";\nimport { PeripheryPoolABI } from \"@skate-org/amm-bindings\";\nimport {\n CHAIN,\n getPeripheryDetailsByKernelPoolAndChainId,\n normalizeMode,\n type EnvModeWithConfig,\n type EvmChain,\n} from \"@skate-org/amm-core-v2\";\nimport { getSourcePublicClient } from \"../chain-clients\";\nimport { EvmReadError, wrapReadError } from \"../errors\";\n\n/**\n * Decoded `balancesAvailable()` tuple on a periphery pool — per the\n * `PeripheryPoolABI` this returns `(uint256 amount0Available, uint256 amount1Available)`.\n */\nexport interface PeripheryBalancesAvailable {\n amount0Available: bigint;\n amount1Available: bigint;\n}\n\n/**\n * Decoded periphery-pool state assembled by {@link readPeripheryPool}.\n *\n * The periphery pool does **not** expose a `slot0`-style view — pricing\n * state lives on the kernel pool on MegaETH (see `readPool`). What the\n * periphery pool does expose is: the configured pair\n * (`token0`, `token1`, `fee`, `kernelPool` reference), the escrowed\n * in-pool settlement balances (`balancesAvailable`), and the two\n * `dustAmount{0,1}` accumulators. Together these are enough for a\n * source-chain caller to reason about pending settlement and dust.\n */\nexport interface PeripheryPoolState {\n /** Periphery pool contract address on the source chain. */\n address: `0x${string}`;\n /** Source-chain ERC-20 address for token0. */\n token0: `0x${string}`;\n /** Source-chain ERC-20 address for token1. */\n token1: `0x${string}`;\n /** Fee tier (uint24) the periphery pool was deployed with. */\n fee: number;\n /** Address of the paired kernel pool on MegaETH. */\n kernelPool: `0x${string}`;\n /** Aggregate in-pool balances available for settlement. */\n balancesAvailable: PeripheryBalancesAvailable;\n /** token0 dust accumulator. */\n dustAmount0: bigint;\n /** token1 dust accumulator. */\n dustAmount1: bigint;\n}\n\n/**\n * Return the caller-provided client, or build a fresh source-chain\n * client for `chain` under the given `mode`. Mirrors the kernel reader\n * injection pattern.\n */\nfunction resolveClient(\n chain: CHAIN,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): PublicClient {\n return client ?? getSourcePublicClient(chain, mode);\n}\n\n/**\n * Read the assembled periphery-pool state on a source chain.\n *\n * Resolves the periphery pool address via\n * `getPeripheryDetailsByKernelPoolAndChainId` (from\n * `@skate-org/amm-core-v2`) — **no addresses are hardcoded here**. If the\n * `(kernelPool, chain, mode)` triple has no entry in the aggregated pool\n * catalog, throws with the triple in the message for debuggability.\n *\n * All sub-reads are fired in parallel and normalized to named fields.\n */\nexport async function readPeripheryPool(\n chain: CHAIN,\n kernelPool: `0x${string}`,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<PeripheryPoolState> {\n const { mode: baseMode } = normalizeMode(mode);\n const details = getPeripheryDetailsByKernelPoolAndChainId(\n kernelPool,\n chain as EvmChain,\n baseMode,\n );\n if (!details) {\n throw new EvmReadError(\n \"readPeripheryPool\",\n `no periphery entry for kernelPool=${kernelPool} chain=${chain} mode=${baseMode}`,\n );\n }\n const address = details.address;\n const c = resolveClient(chain, mode, client);\n try {\n const [\n balancesAvailableRaw,\n dust0,\n dust1,\n token0,\n token1,\n fee,\n kPool,\n ] = await Promise.all([\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"balancesAvailable\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"dustAmount0\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"dustAmount1\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"token0\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"token1\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"fee\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"kernelPool\",\n }),\n ]);\n // Viem decodes multi-output tuples with all-named outputs as a\n // positional tuple — normalize to a named-field object.\n const bAvail = balancesAvailableRaw as readonly [bigint, bigint];\n return {\n address,\n token0: token0 as `0x${string}`,\n token1: token1 as `0x${string}`,\n fee: fee as number,\n kernelPool: kPool as `0x${string}`,\n balancesAvailable: {\n amount0Available: bAvail[0],\n amount1Available: bAvail[1],\n },\n dustAmount0: dust0 as bigint,\n dustAmount1: dust1 as bigint,\n };\n } catch (err) {\n throw wrapReadError(err, \"readPeripheryPool\");\n }\n}\n\n/**\n * Decoded `usersData(address)` tuple on a periphery pool — per the\n * `PeripheryPoolABI` this returns `(uint256 amount0, uint256 amount1)`\n * representing the user's per-pool in-flight token balances on the\n * source chain.\n */\nexport interface UserPoolBalances {\n amount0: bigint;\n amount1: bigint;\n}\n\n/**\n * Read a user's per-pool in-flight balances on a source chain.\n *\n * Resolves the periphery pool address via\n * `getPeripheryDetailsByKernelPoolAndChainId` (no hardcoded addresses)\n * and calls `PeripheryPool.usersData(user)` which returns\n * `(uint256 amount0, uint256 amount1)`.\n *\n * Replaces the previous `readEscrowBalance(chain, user, token)` stub,\n * whose `(user, token)` keying did not match any available ABI view —\n * escrow state is keyed per-(pool, user), not per-(user, token).\n */\nexport async function readUserPoolBalances(\n chain: CHAIN,\n kernelPool: `0x${string}`,\n user: `0x${string}`,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<UserPoolBalances> {\n const { mode: baseMode } = normalizeMode(mode);\n const details = getPeripheryDetailsByKernelPoolAndChainId(\n kernelPool,\n chain as EvmChain,\n baseMode,\n );\n if (!details) {\n throw new EvmReadError(\n \"readUserPoolBalances\",\n `no periphery entry for kernelPool=${kernelPool} chain=${chain} mode=${baseMode}`,\n );\n }\n const c = resolveClient(chain, mode, client);\n try {\n const raw = (await c.readContract({\n address: details.address,\n abi: PeripheryPoolABI,\n functionName: \"usersData\",\n args: [user],\n })) as unknown;\n // `usersData` returns `(uint256 amount0, uint256 amount1)`.\n // Viem decodes tuples with all-named outputs as a positional tuple;\n // handle both the positional and (older) object shapes defensively.\n if (Array.isArray(raw)) {\n const tuple = raw as unknown as readonly [bigint, bigint];\n return { amount0: tuple[0], amount1: tuple[1] };\n }\n const asObject = raw as { amount0: bigint; amount1: bigint };\n return { amount0: asObject.amount0, amount1: asObject.amount1 };\n } catch (err) {\n throw wrapReadError(err, \"readUserPoolBalances\");\n }\n}\n","import type { Address, Hex, WalletClient } from \"viem\";\nimport type { CHAIN, EnvModeWithConfig } from \"@skate-org/amm-core-v2\";\nimport { EvmWriteError, wrapWriteError } from \"../errors\";\n\n/**\n * Pre-built source-chain transaction payload accepted by\n * {@link submitAction}.\n *\n * The SDK does **not** fabricate calldata in Group 6 — callers build the\n * payload (e.g. from a quote's `serializedCall`) and this submitter only\n * broadcasts it. This keeps the SDK decoupled from any off-chain\n * routing/quote surface.\n */\nexport type SubmitActionParams = {\n /** Source-chain id the wallet must be connected to. */\n chain: CHAIN;\n /** Destination address of the broadcast tx. */\n to: Address;\n /** Pre-encoded calldata. */\n data: Hex;\n /** Native-value payable amount; defaults to `0n`. */\n value?: bigint;\n};\n\n/**\n * Broadcast a pre-built periphery action tx from the caller's\n * `WalletClient`.\n *\n * Guarantees:\n * - Throws {@link EvmWriteError} immediately if\n * `wallet.chain?.id !== params.chain` — no RPC call is made.\n * - Throws {@link EvmWriteError} if `wallet.account` is not set.\n * - Forwards the payload to `wallet.sendTransaction` and returns the\n * resulting tx hash.\n * - Wraps any thrown viem write-path error\n * (`TransactionExecutionError`, `UserRejectedRequestError`,\n * `ChainMismatchError`, …) into an {@link EvmWriteError} via\n * {@link wrapWriteError}.\n *\n * The `mode` parameter is currently unused at runtime; it is accepted for\n * API symmetry with the readers and as a forward-compat hook for a future\n * mode-specific submission policy (e.g. DEV-only simulation, staging\n * retries). The `_` prefix marks it unused for the TypeScript checker.\n *\n * Non-goals (per plan guardrails):\n * - Does NOT sign — the caller brings a `WalletClient` wired to their\n * signer.\n * - Does NOT switch chains — callers are responsible for\n * `wallet.switchChain(...)`.\n * - Does NOT retry or manage nonces — delegated to the caller's wallet.\n */\nexport async function submitAction(\n wallet: WalletClient,\n params: SubmitActionParams,\n _mode: EnvModeWithConfig,\n): Promise<Hex> {\n if (wallet.chain?.id !== params.chain) {\n throw new EvmWriteError(\n \"submitAction\",\n `wallet chain ${wallet.chain?.id ?? \"undefined\"} != params.chain ${params.chain}`,\n );\n }\n\n try {\n const account = wallet.account;\n if (!account) {\n throw new EvmWriteError(\n \"submitAction\",\n \"wallet has no account; callers must provide a wallet with wallet.account set\",\n );\n }\n return await wallet.sendTransaction({\n to: params.to,\n data: params.data,\n value: params.value ?? 0n,\n chain: wallet.chain,\n account,\n });\n } catch (err) {\n // Preserve our own pre-flight guards verbatim — they are already\n // EvmWriteError instances and don't need re-wrapping.\n if (err instanceof EvmWriteError) throw err;\n throw wrapWriteError(err, \"submitAction\");\n }\n}\n\n/**\n * Broadcast a periphery *swap* action — thin wrapper around\n * {@link submitAction} that re-labels any unknown error as `submitSwap` to\n * aid log-line triage. Behaviourally identical to `submitAction`; shares\n * its pre-flight guards.\n */\nexport async function submitSwap(\n wallet: WalletClient,\n params: SubmitActionParams,\n mode: EnvModeWithConfig,\n): Promise<Hex> {\n try {\n return await submitAction(wallet, params, mode);\n } catch (err) {\n if (err instanceof EvmWriteError) throw err;\n throw wrapWriteError(err, \"submitSwap\");\n }\n}\n\n/**\n * Broadcast a periphery *approval* action (ERC-20 approve to the source\n * chain's periphery contract) — thin wrapper around {@link submitAction}.\n * See {@link submitSwap} for labeling rationale.\n */\nexport async function submitApproval(\n wallet: WalletClient,\n params: SubmitActionParams,\n mode: EnvModeWithConfig,\n): Promise<Hex> {\n try {\n return await submitAction(wallet, params, mode);\n } catch (err) {\n if (err instanceof EvmWriteError) throw err;\n throw wrapWriteError(err, \"submitApproval\");\n }\n}\n","import { decodeEventLog, type Log } from \"viem\";\nimport { KernelEventEmitterABI } from \"@skate-org/amm-bindings\";\nimport { EvmReadError } from \"../errors\";\n\n/**\n * Event names emitted by the Skate kernel's `KernelEventEmitter`, sourced\n * directly from `@skate-org/amm-bindings`.\n */\nexport type KernelEventName =\n | \"Burn\"\n | \"Collect\"\n | \"CollectProtocol\"\n | \"IncreaseObservationCardinalityNext\"\n | \"Initialize\"\n | \"Mint\"\n | \"PeripheryPoolAdded\"\n | \"PeripheryPoolChanged\"\n | \"PoolCreated\"\n | \"PoolDescriptionUpdated\"\n | \"SetFeeProtocol\"\n | \"Swap\";\n\n/** Exhaustive list of known kernel event names — same values as {@link KernelEventName}. */\nexport const KERNEL_EVENT_NAMES: readonly KernelEventName[] = [\n \"Burn\",\n \"Collect\",\n \"CollectProtocol\",\n \"IncreaseObservationCardinalityNext\",\n \"Initialize\",\n \"Mint\",\n \"PeripheryPoolAdded\",\n \"PeripheryPoolChanged\",\n \"PoolCreated\",\n \"PoolDescriptionUpdated\",\n \"SetFeeProtocol\",\n \"Swap\",\n];\n\n/**\n * A decoded kernel event — the event name, its named args, and the original\n * viem `Log` for context (tx hash, block number, etc.).\n */\nexport interface KernelParsedEvent {\n eventName: KernelEventName;\n args: Record<string, unknown>;\n log: Log;\n}\n\n/**\n * Decode a viem `Log` emitted by the Skate kernel's `KernelEventEmitter`.\n *\n * Throws {@link EvmReadError} if the log's topic0 is not a known kernel event\n * or if ABI decoding fails.\n */\nexport function parseKernelEventLog(log: Log): KernelParsedEvent {\n try {\n const decoded = decodeEventLog({\n abi: KernelEventEmitterABI,\n data: log.data,\n topics: log.topics,\n });\n return {\n eventName: decoded.eventName as KernelEventName,\n args: (decoded.args ?? {}) as Record<string, unknown>,\n log,\n };\n } catch (err) {\n const message = (err as { shortMessage?: string; message?: string })\n .shortMessage ??\n (err as { message?: string }).message ??\n String(err);\n throw new EvmReadError(\n \"parseKernelEventLog\",\n `failed to decode log: ${message}`,\n { cause: err as Error },\n );\n }\n}\n","import { decodeEventLog, type Log } from \"viem\";\nimport { PeripheryEventEmitterABI } from \"@skate-org/amm-bindings\";\nimport { EvmReadError } from \"../errors\";\n\n/**\n * Event names emitted by `PeripheryEventEmitter` on the source chain.\n */\nexport type PeripheryEventName =\n | \"AmountSettled\"\n | \"Burned\"\n | \"LiquidityDecreased\"\n | \"LiquidityIncreased\"\n | \"MintSettled\"\n | \"Minted\"\n | \"PoolCreated\"\n | \"PoolDeployed\"\n | \"Swapped\"\n | \"TransferredTo\";\n\n/** Exhaustive list of known periphery event names. */\nexport const PERIPHERY_EVENT_NAMES: readonly PeripheryEventName[] = [\n \"AmountSettled\",\n \"Burned\",\n \"LiquidityDecreased\",\n \"LiquidityIncreased\",\n \"MintSettled\",\n \"Minted\",\n \"PoolCreated\",\n \"PoolDeployed\",\n \"Swapped\",\n \"TransferredTo\",\n];\n\n/** A decoded periphery event — name, named args, and the original viem `Log`. */\nexport interface PeripheryParsedEvent {\n eventName: PeripheryEventName;\n args: Record<string, unknown>;\n log: Log;\n}\n\n/**\n * Decode a viem `Log` emitted by `PeripheryEventEmitter` on a source chain.\n *\n * Throws {@link EvmReadError} if the log's topic0 is not a known periphery\n * event or if ABI decoding fails.\n */\nexport function parsePeripheryEventLog(log: Log): PeripheryParsedEvent {\n try {\n const decoded = decodeEventLog({\n abi: PeripheryEventEmitterABI,\n data: log.data,\n topics: log.topics,\n });\n return {\n eventName: decoded.eventName as PeripheryEventName,\n args: (decoded.args ?? {}) as Record<string, unknown>,\n log,\n };\n } catch (err) {\n const message = (err as { shortMessage?: string; message?: string })\n .shortMessage ??\n (err as { message?: string }).message ??\n String(err);\n throw new EvmReadError(\n \"parsePeripheryEventLog\",\n `failed to decode log: ${message}`,\n { cause: err as Error },\n );\n }\n}\n","import type { Address, Log, PublicClient } from \"viem\";\nimport {\n KernelEventEmitterABI,\n PeripheryEventEmitterABI,\n} from \"@skate-org/amm-bindings\";\nimport {\n parseKernelEventLog,\n type KernelParsedEvent,\n} from \"./kernel\";\nimport {\n parsePeripheryEventLog,\n type PeripheryParsedEvent,\n} from \"./periphery\";\n\nexport interface EventSubscriptionOptions<E> {\n /** Called for each decoded event. */\n onEvent: (event: E) => void;\n /** Called when a log fails to decode (subscription stays alive). */\n onError?: (err: unknown) => void;\n}\n\n/**\n * Subscribe to kernel events emitted by the `KernelEventEmitter` contract\n * at `address`. Returns an unsubscribe function.\n *\n * Decode failures are surfaced via `opts.onError` (if provided) rather than\n * throwing — the subscription continues.\n */\nexport function watchKernelEvents(\n client: PublicClient,\n address: Address,\n opts: EventSubscriptionOptions<KernelParsedEvent>,\n): () => void {\n return client.watchContractEvent({\n abi: KernelEventEmitterABI,\n address,\n onLogs: (logs: Log[]) => {\n for (const log of logs) {\n try {\n opts.onEvent(parseKernelEventLog(log));\n } catch (err) {\n opts.onError?.(err);\n }\n }\n },\n });\n}\n\n/**\n * Subscribe to periphery events emitted by `PeripheryEventEmitter` at\n * `address` on the source chain the `client` is connected to.\n */\nexport function watchPeripheryEvents(\n client: PublicClient,\n address: Address,\n opts: EventSubscriptionOptions<PeripheryParsedEvent>,\n): () => void {\n return client.watchContractEvent({\n abi: PeripheryEventEmitterABI,\n address,\n onLogs: (logs: Log[]) => {\n for (const log of logs) {\n try {\n opts.onEvent(parsePeripheryEventLog(log));\n } catch (err) {\n opts.onError?.(err);\n }\n }\n },\n });\n}\n"],"mappings":"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","names":["import_amm_core_v2","import_amm_core_v2","import_amm_bindings","import_amm_core_v2","resolveClient","import_viem","import_amm_bindings","import_viem","import_amm_bindings","import_amm_bindings"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/chain-clients.ts","../src/devConfig.ts","../src/errors.ts","../src/kernel/reader.ts","../src/kernel/_client.ts","../src/kernel/tickBitmap.ts","../src/kernel/lens.ts","../src/periphery/reader.ts","../src/periphery/submit.ts","../src/events/kernel.ts","../src/events/periphery.ts","../src/events/watch.ts"],"sourcesContent":["export * from \"./chain-clients\";\nexport * from \"./devConfig\";\n// Public error classes only; wrap* helpers are internal implementation\n// detail shared between readers/submitters and are not re-exported.\nexport { EvmReadError, EvmWriteError } from \"./errors\";\nexport * from \"./kernel\";\nexport * from \"./periphery\";\nexport * from \"./events\";\n","import {\n createPublicClient,\n defineChain,\n http,\n type Chain,\n type PublicClient,\n type Transport,\n} from \"viem\";\nimport { arbitrum } from \"viem/chains\";\nimport {\n BLOCK_EXPLORER,\n CHAIN,\n VM,\n vmTypeFromChain,\n normalizeMode,\n type EnvModeWithConfig,\n} from \"@skate-org/amm-core-v2\";\n\n/**\n * MegaETH chain definition — `@public`.\n *\n * Exported for callers who need to build their own viem `WalletClient` or\n * `PublicClient` against the same chain the SDK uses internally (e.g. wallet\n * integrations that construct a `WalletClient` ahead of calling\n * `submitAction`). Prefer {@link getKernelPublicClient} when you just need a\n * read client.\n *\n * viem ships a `megaeth` chain at id 4326, but with a different default RPC\n * than the one Skate uses for kernel reads. Define locally so we control the\n * RPC URL + block-explorer metadata and don't inherit unrelated op-stack\n * contract addresses.\n */\nexport const megaethChain: Chain = defineChain({\n id: 4326,\n name: \"MegaETH\",\n network: \"megaeth\",\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n rpcUrls: {\n default: { http: [\"https://mainnet.megaeth.com/rpc\"] },\n public: { http: [\"https://mainnet.megaeth.com/rpc\"] },\n },\n blockExplorers: {\n default: { name: \"Blockscout\", url: BLOCK_EXPLORER.MEGAETH },\n },\n});\n\n/**\n * Default public RPC URLs by chain id.\n *\n * Callers can override per-chain via `DevModeConfig.rpcEndpoints` or by\n * passing an explicit `transport` to the factory functions below.\n */\nconst DEFAULT_RPC: Partial<Record<CHAIN, string>> = {\n [CHAIN.MEGAETH]: \"https://mainnet.megaeth.com/rpc\",\n [CHAIN.ARBITRUM]: \"https://arb1.arbitrum.io/rpc\",\n};\n\n/**\n * Map a supported EVM `CHAIN` to a viem `Chain` definition.\n *\n * Only chains we actively support in Phase 2 are listed; unknown chains\n * return `undefined` and the caller throws.\n */\nfunction chainDefFor(chain: CHAIN): Chain | undefined {\n switch (chain) {\n case CHAIN.MEGAETH:\n return megaethChain;\n case CHAIN.ARBITRUM:\n return arbitrum;\n default:\n return undefined;\n }\n}\n\n/**\n * Resolve the RPC URL for a given chain under the precedence:\n * transport override (caller arg) > mode.config.rpcEndpoints[chain] > DEFAULT_RPC[chain]\n * Returns `undefined` if none is set — callers must have already decided whether\n * to use a caller-supplied transport.\n */\nfunction resolveRpcUrl(\n chain: CHAIN,\n mode: EnvModeWithConfig,\n): string | undefined {\n const { config } = normalizeMode(mode);\n return config?.rpcEndpoints?.[chain] ?? DEFAULT_RPC[chain];\n}\n\n/**\n * Return a fresh `PublicClient` bound to the MegaETH kernel chain.\n *\n * MegaETH is the kernel chain for all environment modes (DEV/STAGING/\n * PRODUCTION) in SDK v2. The `mode` parameter is accepted for API\n * symmetry with the rest of the SDK and as a forward-compatible extension\n * point (e.g. a future testnet kernel).\n *\n * Pure — no singletons, no caching. Pass a custom `transport` to override\n * the default RPC (useful for tests and custom RPC providers).\n */\nexport function getKernelPublicClient(\n mode: EnvModeWithConfig,\n transport?: Transport,\n): PublicClient {\n return createPublicClient({\n chain: megaethChain,\n transport: transport ?? http(resolveRpcUrl(CHAIN.MEGAETH, mode)),\n });\n}\n\n/**\n * Return a fresh `PublicClient` for a source EVM chain (e.g. Arbitrum).\n *\n * Throws a descriptive `Error` when:\n * - `chain` is not an EVM chain (per `vmTypeFromChain`); or\n * - no viem chain definition is registered for `chain`; or\n * - no default RPC URL is configured for `chain` and no `transport` override\n * was provided.\n *\n * Pure — no singletons, no caching.\n */\nexport function getSourcePublicClient(\n chain: CHAIN,\n mode: EnvModeWithConfig,\n transport?: Transport,\n): PublicClient {\n if (vmTypeFromChain(chain) !== VM.EVM) {\n throw new Error(\n `getSourcePublicClient: chain ${chain} is not an EVM chain`,\n );\n }\n const chainDef = chainDefFor(chain);\n if (!chainDef) {\n throw new Error(\n `getSourcePublicClient: no chain definition registered for chain ${chain}`,\n );\n }\n const rpc = resolveRpcUrl(chain, mode);\n if (!rpc && !transport) {\n throw new Error(\n `getSourcePublicClient: no default or override RPC configured for chain ${chain}; pass a transport override or set DevModeConfig.rpcEndpoints[${chain}]`,\n );\n }\n return createPublicClient({\n chain: chainDef,\n transport: transport ?? http(rpc),\n });\n}\n","import type { DevModeConfig } from \"@skate-org/amm-core-v2\";\n\n/** Default DEV api endpoint — matches Phase 1's api client default. */\nexport const DEFAULT_DEV_API_ENDPOINT =\n \"https://dev.api.skatechain.org/amm-action-v2\";\n\n/**\n * Convenience factory for the `{ mode: \"DEV\"; config: DevModeConfig }` tuple.\n *\n * Reduces ceremony at call sites that want to override a single field (e.g.,\n * `rpcEndpoints`) without reconstructing the full object:\n *\n * ```ts\n * const mode = createDevConfig({\n * rpcEndpoints: { [CHAIN.MEGAETH]: \"https://my-private-megaeth/rpc\" },\n * });\n * submitAction(wallet, params, mode);\n * ```\n *\n * Pass nothing to use all defaults.\n */\nexport function createDevConfig(\n overrides: Partial<DevModeConfig> = {},\n): { mode: \"DEV\"; config: DevModeConfig } {\n return {\n mode: \"DEV\",\n config: {\n apiEndpoint: overrides.apiEndpoint ?? DEFAULT_DEV_API_ENDPOINT,\n ...(overrides.rpcEndpoints\n ? { rpcEndpoints: overrides.rpcEndpoints }\n : {}),\n },\n };\n}\n","/**\n * Shared error types for the `@skate-org/amm-evm-v2` package.\n *\n * `EvmReadError` / `EvmWriteError` extend `SdkError` (from core) so callers\n * can `instanceof SdkError` to catch any SDK-origin error without needing\n * to know the specific subclass.\n */\n\nimport { SdkError } from \"@skate-org/amm-core-v2\";\n\n/** SDK-level error thrown when an EVM read reverts or decodes badly. */\nexport class EvmReadError extends SdkError {\n override readonly name: string = \"EvmReadError\";\n readonly functionName: string;\n\n constructor(functionName: string, message: string, options?: ErrorOptions) {\n super(`${functionName}: ${message}`, options);\n this.functionName = functionName;\n }\n}\n\n/**\n * SDK-level error thrown when an EVM write (broadcast) fails.\n *\n * Symmetric with {@link EvmReadError}, but covers the write path: viem's\n * `TransactionExecutionError`, `UserRejectedRequestError`,\n * `ChainMismatchError`, `ChainDisconnectedError`, as well as submitter\n * pre-flight guards (e.g. wrong-chain, missing account).\n */\nexport class EvmWriteError extends SdkError {\n override readonly name: string = \"EvmWriteError\";\n readonly functionName: string;\n\n constructor(functionName: string, message: string, options?: ErrorOptions) {\n super(`${functionName}: ${message}`, options);\n this.functionName = functionName;\n }\n}\n\n/**\n * Wrap any error from an EVM read into `EvmReadError`. Viem always wraps\n * revert-path errors in `ContractFunctionExecutionError` (see\n * `viem/utils/errors/getContractError`), so we check both the outer name and\n * the `.cause` chain for `ContractFunctionRevertedError` /\n * `ContractFunctionZeroDataError`.\n *\n * Shared by `kernel/reader.ts` and `periphery/reader.ts` — depends only on\n * `EvmReadError` and generic Error inspection (no reader-module imports), so\n * it is safe from circular-import concerns.\n */\nexport function wrapReadError(\n err: unknown,\n functionName: string,\n): EvmReadError {\n const outerName = (err as { name?: string } | null)?.name;\n const causeName = (err as { cause?: { name?: string } } | null)?.cause?.name;\n const message =\n (err as { shortMessage?: string } | null)?.shortMessage ??\n (err as { message?: string } | null)?.message ??\n String(err);\n const isViemContractError =\n outerName === \"ContractFunctionExecutionError\" ||\n outerName === \"ContractFunctionRevertedError\" ||\n outerName === \"ContractFunctionZeroDataError\" ||\n causeName === \"ContractFunctionRevertedError\" ||\n causeName === \"ContractFunctionZeroDataError\";\n if (isViemContractError) {\n return new EvmReadError(functionName, `reverted: ${message}`, {\n cause: err as Error,\n });\n }\n return new EvmReadError(functionName, message, { cause: err as Error });\n}\n\n/**\n * Wrap any error from an EVM write-path call (typically\n * `WalletClient.sendTransaction`) into `EvmWriteError`.\n *\n * Any thrown error reaching a submitter is treated as a write failure. If\n * we later want to differentiate known viem write errors\n * (`TransactionExecutionError`, `UserRejectedRequestError`,\n * `ChainMismatchError`, `ChainDisconnectedError`) from unknown errors —\n * e.g. to prefix the message or re-throw unknowns raw — that dispatch goes\n * here. Keeping the single-return shape until a concrete caller need\n * surfaces.\n */\nexport function wrapWriteError(\n err: unknown,\n functionName: string,\n): EvmWriteError {\n const message =\n (err as { shortMessage?: string } | null)?.shortMessage ??\n (err as { message?: string } | null)?.message ??\n String(err);\n return new EvmWriteError(functionName, message, { cause: err as Error });\n}\n","import type { PublicClient } from \"viem\";\nimport {\n KernelManagerABI,\n KernelPoolABI,\n} from \"@skate-org/amm-bindings\";\nimport {\n KernelManagerAddress,\n normalizeMode,\n type EnvModeWithConfig,\n getAmount0Delta,\n getAmount1Delta,\n getSqrtRatioAtTick,\n} from \"@skate-org/amm-core-v2\";\nimport { wrapReadError } from \"../errors\";\nimport { resolveKernelClient } from \"./_client\";\n\n/** Decoded kernel-pool `slot0` state (named fields, per the ABI tuple). */\nexport interface KernelSlot0 {\n sqrtPriceX96: bigint;\n tick: number;\n observationIndex: number;\n observationCardinality: number;\n observationCardinalityNext: number;\n feeProtocol: number;\n unlocked: boolean;\n}\n\n/** Decoded pool state returned by `readPool`. */\nexport interface KernelPoolState {\n slot0: KernelSlot0;\n liquidity: bigint;\n}\n\n/** Decoded NFT position returned by `readPosition`. */\nexport interface KernelNftPosition {\n pool: `0x${string}`;\n tickLower: number;\n tickUpper: number;\n liquidity: bigint;\n feeGrowthInside0LastX128: bigint;\n feeGrowthInside1LastX128: bigint;\n tokensOwed0: bigint;\n tokensOwed1: bigint;\n}\n\n/** Decoded kernel-pool `ticks(tick)` struct. */\nexport interface KernelTick {\n liquidityGross: bigint;\n liquidityNet: bigint;\n feeGrowthOutside0X128: bigint;\n feeGrowthOutside1X128: bigint;\n tickCumulativeOutside: bigint;\n secondsPerLiquidityOutsideX128: bigint;\n secondsOutside: number;\n initialized: boolean;\n}\n\n/**\n * Read `slot0` and `liquidity` from a kernel pool. Returns both in a single\n * object; the reads are fired in parallel.\n *\n * The `client` optional parameter is the standard test-injection point.\n */\nexport async function readPool(\n kernelPool: `0x${string}`,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<KernelPoolState> {\n const c = resolveKernelClient(mode, client);\n try {\n const [slot0, liquidity] = await Promise.all([\n c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"slot0\",\n }),\n c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"liquidity\",\n }),\n ]);\n // Viem returns named outputs as a positional tuple (array) when every\n // output has a name — normalize to a named-field object here so callers\n // don't depend on viem's tuple/object split.\n const s0 = slot0 as readonly [\n bigint,\n number,\n number,\n number,\n number,\n number,\n boolean,\n ];\n return {\n slot0: {\n sqrtPriceX96: s0[0],\n tick: s0[1],\n observationIndex: s0[2],\n observationCardinality: s0[3],\n observationCardinalityNext: s0[4],\n feeProtocol: s0[5],\n unlocked: s0[6],\n },\n liquidity: liquidity as bigint,\n };\n } catch (err) {\n throw wrapReadError(err, \"readPool\");\n }\n}\n\n/**\n * Read an NFT position by token id from the kernel manager.\n *\n * Calls `KernelManager.nftPositions(tokenId)` — per the ABI this returns a\n * `DataTypes.NFTPosition` tuple including `pool`, `tickLower`, `tickUpper`,\n * `liquidity`, fee growth, and tokens owed.\n */\nexport async function readPosition(\n tokenId: bigint,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<KernelNftPosition> {\n const { mode: baseMode } = normalizeMode(mode);\n const manager = KernelManagerAddress(baseMode);\n const c = resolveKernelClient(mode, client);\n try {\n const raw = (await c.readContract({\n address: manager,\n abi: KernelManagerABI,\n functionName: \"nftPositions\",\n args: [tokenId],\n })) as unknown;\n // Accept either a positional tuple or an already-named object from\n // viem — normalize to a named-field object, mirroring readPool's\n // defensive remap. Viem's decoding of named-components tuples is\n // stable today (object form), but this guards against future\n // restructuring.\n const asTuple = Array.isArray(raw)\n ? (raw as unknown as readonly [\n `0x${string}`,\n number,\n number,\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n ])\n : null;\n if (asTuple) {\n return {\n pool: asTuple[0],\n tickLower: asTuple[1],\n tickUpper: asTuple[2],\n liquidity: asTuple[3],\n feeGrowthInside0LastX128: asTuple[4],\n feeGrowthInside1LastX128: asTuple[5],\n tokensOwed0: asTuple[6],\n tokensOwed1: asTuple[7],\n };\n }\n return raw as KernelNftPosition;\n } catch (err) {\n throw wrapReadError(err, \"readPosition\");\n }\n}\n\n/**\n * Read a kernel-pool tick-bitmap word (`tickBitmap(int16 wordPos)`).\n *\n * Returns the raw `uint256` word as a bigint. A bit-decoder that expands a\n * word into populated tick indexes is intentionally not shipped in 0.2.0 —\n * flag as an open question for Phase 3 if a caller wants it.\n */\nexport async function readTickBitmap(\n kernelPool: `0x${string}`,\n wordPos: number,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<bigint> {\n const c = resolveKernelClient(mode, client);\n try {\n const word = await c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"tickBitmap\",\n args: [wordPos],\n });\n return word as bigint;\n } catch (err) {\n throw wrapReadError(err, \"readTickBitmap\");\n }\n}\n\n/** Read the `ticks(tick)` struct from a kernel pool. */\nexport async function readTick(\n kernelPool: `0x${string}`,\n tick: number,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<KernelTick> {\n const c = resolveKernelClient(mode, client);\n try {\n const raw = (await c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"ticks\",\n args: [tick],\n })) as readonly [\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n number,\n boolean,\n ];\n return {\n liquidityGross: raw[0],\n liquidityNet: raw[1],\n feeGrowthOutside0X128: raw[2],\n feeGrowthOutside1X128: raw[3],\n tickCumulativeOutside: raw[4],\n secondsPerLiquidityOutsideX128: raw[5],\n secondsOutside: raw[6],\n initialized: raw[7],\n };\n } catch (err) {\n throw wrapReadError(err, \"readTick\");\n }\n}\n\n/**\n * Compute `{amount0, amount1}` for an NFT position using the Group 3 math.\n *\n * Reads the position (to learn `pool`, `tickLower`, `tickUpper`,\n * `liquidity`) and the pool's `slot0`, then splits based on whether the\n * current tick is below, inside, or above the position range — mirroring\n * `PositionValue.principal` from Uniswap v3 periphery.\n */\nexport async function computePositionAmounts(\n tokenId: bigint,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<{ amount0: bigint; amount1: bigint }> {\n const c = resolveKernelClient(mode, client);\n const position = await readPosition(tokenId, mode, c);\n const { slot0 } = await readPool(position.pool, mode, c);\n\n const sqrtLower = getSqrtRatioAtTick(position.tickLower);\n const sqrtUpper = getSqrtRatioAtTick(position.tickUpper);\n\n if (slot0.tick < position.tickLower) {\n return {\n amount0: getAmount0Delta(sqrtLower, sqrtUpper, position.liquidity, false),\n amount1: 0n,\n };\n }\n if (slot0.tick >= position.tickUpper) {\n return {\n amount0: 0n,\n amount1: getAmount1Delta(sqrtLower, sqrtUpper, position.liquidity, false),\n };\n }\n return {\n amount0: getAmount0Delta(\n slot0.sqrtPriceX96,\n sqrtUpper,\n position.liquidity,\n false,\n ),\n amount1: getAmount1Delta(\n sqrtLower,\n slot0.sqrtPriceX96,\n position.liquidity,\n false,\n ),\n };\n}\n","import type { PublicClient } from \"viem\";\nimport type { EnvModeWithConfig } from \"@skate-org/amm-core-v2\";\nimport { getKernelPublicClient } from \"../chain-clients\";\n\n/**\n * Return the caller-provided client if present, otherwise build a fresh\n * MegaETH kernel client for the given mode. Shared by readers + lens\n * helpers; intentionally unexported from the package barrel.\n */\nexport function resolveKernelClient(\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): PublicClient {\n return client ?? getKernelPublicClient(mode);\n}\n","/**\n * Decode a single Uniswap-v3 tick-bitmap `uint256` word into the list of\n * real (non-compressed) ticks it marks as initialized.\n *\n * A tick bitmap word covers 256 compressed ticks. For a given `wordPos`\n * (int16) the word spans compressed ticks `wordPos * 256` through\n * `(wordPos + 1) * 256 - 1`, and bit `k` (0..255) corresponds to the\n * compressed tick `wordPos * 256 + k`. The real tick at bit `k` is\n * `(wordPos * 256 + k) * tickSpacing`.\n *\n * Intended composition with the reader:\n *\n * ```ts\n * const word = await readTickBitmap(pool, wordPos, mode);\n * const ticks = decodeTickBitmapWord(word, wordPos, tickSpacing);\n * ```\n *\n * Pure function: no network, no viem, no external deps.\n *\n * @param word The 256-bit bitmap word returned by PoolAbi.tickBitmap(int16).\n * @param wordPos The int16 word position (-128 .. 127 per Uniswap, but\n * we accept any safe-integer int16-shaped value).\n * @param tickSpacing The pool's tickSpacing (positive integer, typically 1,\n * 10, 60, 200, etc.).\n * @returns Real ticks whose bits are set in the word, ascending.\n *\n * @throws {RangeError} if `tickSpacing <= 0` or if `wordPos` is not a safe integer.\n */\nexport function decodeTickBitmapWord(\n word: bigint,\n wordPos: number,\n tickSpacing: number,\n): number[] {\n if (!Number.isSafeInteger(wordPos)) {\n throw new RangeError(\n `decodeTickBitmapWord: wordPos must be a safe integer, got ${wordPos}`,\n );\n }\n if (!Number.isSafeInteger(tickSpacing) || tickSpacing <= 0) {\n throw new RangeError(\n `decodeTickBitmapWord: tickSpacing must be a positive integer, got ${tickSpacing}`,\n );\n }\n const result: number[] = [];\n // wordPos * 256 gives the base compressed-tick of this word. Each set bit k\n // contributes compressed-tick (wordPos * 256 + k), which becomes real tick\n // (wordPos * 256 + k) * tickSpacing.\n const base = wordPos * 256;\n for (let k = 0; k < 256; k++) {\n if (((word >> BigInt(k)) & 1n) === 1n) {\n result.push((base + k) * tickSpacing);\n }\n }\n return result;\n}\n","import type { PublicClient } from \"viem\";\nimport { KernelManagerABI } from \"@skate-org/amm-bindings\";\nimport {\n KernelManagerAddress,\n normalizeMode,\n type EnvModeWithConfig,\n} from \"@skate-org/amm-core-v2\";\nimport { wrapReadError } from \"../errors\";\nimport { resolveKernelClient } from \"./_client\";\n\n/**\n * Kernel lens (simulate) helpers — wrap KernelManager's `lens*` functions as\n * static-call simulations. Lens functions are marked nonpayable in the ABI,\n * but viem's `simulateContract` evaluates them with `eth_call`, so they\n * reuse the same client + RPC plumbing as the readers and never produce a\n * transaction.\n *\n * Errors funnel through `wrapReadError`: lens calls share the read-path\n * error model (revert reasons + RPC failures), and tagging them as \"writes\"\n * would be misleading since no state changes.\n */\n\nexport interface SimulateSwapParams {\n /** Kernel-pool address (EVM) */\n pool: `0x${string}`;\n /** Recipient encoded as bytes32 (use `toBytes32Address` for cross-VM) */\n recipient: `0x${string}`;\n zeroForOne: boolean;\n /** Positive = exactInput, negative = exactOutput, per Uniswap v3 convention */\n amountSpecified: bigint;\n sqrtPriceLimitX96: bigint;\n}\n\nexport interface SimulateSwapResult {\n amount0: bigint;\n amount1: bigint;\n sqrtPriceX96After: bigint;\n returnData: `0x${string}`;\n}\n\nexport async function simulateSwap(\n params: SimulateSwapParams,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<SimulateSwapResult> {\n const { mode: baseMode } = normalizeMode(mode);\n const c = resolveKernelClient(mode, client);\n try {\n const out = await c.simulateContract({\n address: KernelManagerAddress(baseMode),\n abi: KernelManagerABI,\n functionName: \"lensSwap\",\n args: [\n params.pool,\n params.recipient,\n params.zeroForOne,\n params.amountSpecified,\n params.sqrtPriceLimitX96,\n ],\n });\n const [amount0, amount1, sqrtPriceX96After, returnData] = out.result as readonly [\n bigint,\n bigint,\n bigint,\n `0x${string}`,\n ];\n return { amount0, amount1, sqrtPriceX96After, returnData };\n } catch (err) {\n throw wrapReadError(err, \"simulateSwap\");\n }\n}\n\nexport interface SimulateMintParams {\n pool: `0x${string}`;\n /** Recipient encoded as bytes32 */\n recipient: `0x${string}`;\n tickLower: number;\n tickUpper: number;\n amount0: bigint;\n amount1: bigint;\n /** Caller-supplied callback data (passed to `IKernelMintCallback`) */\n data: `0x${string}`;\n}\n\nexport interface SimulateMintResult {\n amount0Used: bigint;\n amount1Used: bigint;\n liquidityAmount: bigint;\n returnData: `0x${string}`;\n}\n\nexport async function simulateMint(\n params: SimulateMintParams,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<SimulateMintResult> {\n const { mode: baseMode } = normalizeMode(mode);\n const c = resolveKernelClient(mode, client);\n try {\n const out = await c.simulateContract({\n address: KernelManagerAddress(baseMode),\n abi: KernelManagerABI,\n functionName: \"lensMint\",\n args: [\n params.pool,\n params.recipient,\n params.tickLower,\n params.tickUpper,\n params.amount0,\n params.amount1,\n params.data,\n ],\n });\n const [amount0Used, amount1Used, liquidityAmount, returnData] = out.result as readonly [\n bigint,\n bigint,\n bigint,\n `0x${string}`,\n ];\n return { amount0Used, amount1Used, liquidityAmount, returnData };\n } catch (err) {\n throw wrapReadError(err, \"simulateMint\");\n }\n}\n\nexport interface SimulateBurnParams {\n pool: `0x${string}`;\n /** Recipient encoded as bytes32 */\n recipient: `0x${string}`;\n tickLower: number;\n tickUpper: number;\n /** Liquidity amount to burn (uint128). */\n amount: bigint;\n}\n\nexport interface SimulateBurnResult {\n amount0: bigint;\n amount1: bigint;\n returnData: `0x${string}`;\n}\n\nexport async function simulateBurn(\n params: SimulateBurnParams,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<SimulateBurnResult> {\n const { mode: baseMode } = normalizeMode(mode);\n const c = resolveKernelClient(mode, client);\n try {\n const out = await c.simulateContract({\n address: KernelManagerAddress(baseMode),\n abi: KernelManagerABI,\n functionName: \"lensBurn\",\n args: [\n params.pool,\n params.recipient,\n params.tickLower,\n params.tickUpper,\n params.amount,\n ],\n });\n const [amount0, amount1, returnData] = out.result as readonly [\n bigint,\n bigint,\n `0x${string}`,\n ];\n return { amount0, amount1, returnData };\n } catch (err) {\n throw wrapReadError(err, \"simulateBurn\");\n }\n}\n\nexport interface SimulateDecreaseLiquidityParams {\n /** NFT position id (v2 positions). */\n tokenId: bigint;\n /** Liquidity amount to remove (uint128). */\n liquidity: bigint;\n}\n\nexport interface SimulateDecreaseLiquidityResult {\n amount0: bigint;\n amount1: bigint;\n returnData: `0x${string}`;\n}\n\nexport async function simulateDecreaseLiquidity(\n params: SimulateDecreaseLiquidityParams,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<SimulateDecreaseLiquidityResult> {\n const { mode: baseMode } = normalizeMode(mode);\n const c = resolveKernelClient(mode, client);\n try {\n const out = await c.simulateContract({\n address: KernelManagerAddress(baseMode),\n abi: KernelManagerABI,\n functionName: \"lensDecreaseLiquidity\",\n args: [params.tokenId, params.liquidity],\n });\n const [amount0, amount1, returnData] = out.result as readonly [\n bigint,\n bigint,\n `0x${string}`,\n ];\n return { amount0, amount1, returnData };\n } catch (err) {\n throw wrapReadError(err, \"simulateDecreaseLiquidity\");\n }\n}\n","import type { PublicClient } from \"viem\";\nimport { PeripheryPoolABI } from \"@skate-org/amm-bindings\";\nimport {\n CHAIN,\n getPeripheryDetailsByKernelPoolAndChainId,\n normalizeMode,\n type EnvModeWithConfig,\n type EvmChain,\n} from \"@skate-org/amm-core-v2\";\nimport { getSourcePublicClient } from \"../chain-clients\";\nimport { EvmReadError, wrapReadError } from \"../errors\";\n\n/**\n * Decoded `balancesAvailable()` tuple on a periphery pool — per the\n * `PeripheryPoolABI` this returns `(uint256 amount0Available, uint256 amount1Available)`.\n */\nexport interface PeripheryBalancesAvailable {\n amount0Available: bigint;\n amount1Available: bigint;\n}\n\n/**\n * Decoded periphery-pool state assembled by {@link readPeripheryPool}.\n *\n * The periphery pool does **not** expose a `slot0`-style view — pricing\n * state lives on the kernel pool on MegaETH (see `readPool`). What the\n * periphery pool does expose is: the configured pair\n * (`token0`, `token1`, `fee`, `kernelPool` reference), the escrowed\n * in-pool settlement balances (`balancesAvailable`), and the two\n * `dustAmount{0,1}` accumulators. Together these are enough for a\n * source-chain caller to reason about pending settlement and dust.\n */\nexport interface PeripheryPoolState {\n /** Periphery pool contract address on the source chain. */\n address: `0x${string}`;\n /** Source-chain ERC-20 address for token0. */\n token0: `0x${string}`;\n /** Source-chain ERC-20 address for token1. */\n token1: `0x${string}`;\n /** Fee tier (uint24) the periphery pool was deployed with. */\n fee: number;\n /** Address of the paired kernel pool on MegaETH. */\n kernelPool: `0x${string}`;\n /** Aggregate in-pool balances available for settlement. */\n balancesAvailable: PeripheryBalancesAvailable;\n /** token0 dust accumulator. */\n dustAmount0: bigint;\n /** token1 dust accumulator. */\n dustAmount1: bigint;\n}\n\n/**\n * Return the caller-provided client, or build a fresh source-chain\n * client for `chain` under the given `mode`. Mirrors the kernel reader\n * injection pattern.\n */\nfunction resolveClient(\n chain: CHAIN,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): PublicClient {\n return client ?? getSourcePublicClient(chain, mode);\n}\n\n/**\n * Read the assembled periphery-pool state on a source chain.\n *\n * Resolves the periphery pool address via\n * `getPeripheryDetailsByKernelPoolAndChainId` (from\n * `@skate-org/amm-core-v2`) — **no addresses are hardcoded here**. If the\n * `(kernelPool, chain, mode)` triple has no entry in the aggregated pool\n * catalog, throws with the triple in the message for debuggability.\n *\n * All sub-reads are fired in parallel and normalized to named fields.\n */\nexport async function readPeripheryPool(\n chain: CHAIN,\n kernelPool: `0x${string}`,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<PeripheryPoolState> {\n const { mode: baseMode } = normalizeMode(mode);\n const details = getPeripheryDetailsByKernelPoolAndChainId(\n kernelPool,\n chain as EvmChain,\n baseMode,\n );\n if (!details) {\n throw new EvmReadError(\n \"readPeripheryPool\",\n `no periphery entry for kernelPool=${kernelPool} chain=${chain} mode=${baseMode}`,\n );\n }\n const address = details.address;\n const c = resolveClient(chain, mode, client);\n try {\n const [\n balancesAvailableRaw,\n dust0,\n dust1,\n token0,\n token1,\n fee,\n kPool,\n ] = await Promise.all([\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"balancesAvailable\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"dustAmount0\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"dustAmount1\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"token0\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"token1\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"fee\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"kernelPool\",\n }),\n ]);\n // Viem decodes multi-output tuples with all-named outputs as a\n // positional tuple — normalize to a named-field object.\n const bAvail = balancesAvailableRaw as readonly [bigint, bigint];\n return {\n address,\n token0: token0 as `0x${string}`,\n token1: token1 as `0x${string}`,\n fee: fee as number,\n kernelPool: kPool as `0x${string}`,\n balancesAvailable: {\n amount0Available: bAvail[0],\n amount1Available: bAvail[1],\n },\n dustAmount0: dust0 as bigint,\n dustAmount1: dust1 as bigint,\n };\n } catch (err) {\n throw wrapReadError(err, \"readPeripheryPool\");\n }\n}\n\n/**\n * Decoded `usersData(address)` tuple on a periphery pool — per the\n * `PeripheryPoolABI` this returns `(uint256 amount0, uint256 amount1)`\n * representing the user's per-pool in-flight token balances on the\n * source chain.\n */\nexport interface UserPoolBalances {\n amount0: bigint;\n amount1: bigint;\n}\n\n/**\n * Read a user's per-pool in-flight balances on a source chain.\n *\n * Resolves the periphery pool address via\n * `getPeripheryDetailsByKernelPoolAndChainId` (no hardcoded addresses)\n * and calls `PeripheryPool.usersData(user)` which returns\n * `(uint256 amount0, uint256 amount1)`.\n *\n * Replaces the previous `readEscrowBalance(chain, user, token)` stub,\n * whose `(user, token)` keying did not match any available ABI view —\n * escrow state is keyed per-(pool, user), not per-(user, token).\n */\nexport async function readUserPoolBalances(\n chain: CHAIN,\n kernelPool: `0x${string}`,\n user: `0x${string}`,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<UserPoolBalances> {\n const { mode: baseMode } = normalizeMode(mode);\n const details = getPeripheryDetailsByKernelPoolAndChainId(\n kernelPool,\n chain as EvmChain,\n baseMode,\n );\n if (!details) {\n throw new EvmReadError(\n \"readUserPoolBalances\",\n `no periphery entry for kernelPool=${kernelPool} chain=${chain} mode=${baseMode}`,\n );\n }\n const c = resolveClient(chain, mode, client);\n try {\n const raw = (await c.readContract({\n address: details.address,\n abi: PeripheryPoolABI,\n functionName: \"usersData\",\n args: [user],\n })) as unknown;\n // `usersData` returns `(uint256 amount0, uint256 amount1)`.\n // Viem decodes tuples with all-named outputs as a positional tuple;\n // handle both the positional and (older) object shapes defensively.\n if (Array.isArray(raw)) {\n const tuple = raw as unknown as readonly [bigint, bigint];\n return { amount0: tuple[0], amount1: tuple[1] };\n }\n const asObject = raw as { amount0: bigint; amount1: bigint };\n return { amount0: asObject.amount0, amount1: asObject.amount1 };\n } catch (err) {\n throw wrapReadError(err, \"readUserPoolBalances\");\n }\n}\n","import type { Address, Hex, WalletClient } from \"viem\";\nimport type { CHAIN, EnvModeWithConfig } from \"@skate-org/amm-core-v2\";\nimport { EvmWriteError, wrapWriteError } from \"../errors\";\n\n/**\n * Pre-built source-chain transaction payload accepted by\n * {@link submitAction}.\n *\n * The SDK does **not** fabricate calldata in Group 6 — callers build the\n * payload (e.g. from a quote's `serializedCall`) and this submitter only\n * broadcasts it. This keeps the SDK decoupled from any off-chain\n * routing/quote surface.\n */\nexport type SubmitActionParams = {\n /** Source-chain id the wallet must be connected to. */\n chain: CHAIN;\n /** Destination address of the broadcast tx. */\n to: Address;\n /** Pre-encoded calldata. */\n data: Hex;\n /** Native-value payable amount; defaults to `0n`. */\n value?: bigint;\n};\n\n/**\n * Broadcast a pre-built periphery action tx from the caller's\n * `WalletClient`.\n *\n * Guarantees:\n * - Throws {@link EvmWriteError} immediately if\n * `wallet.chain?.id !== params.chain` — no RPC call is made.\n * - Throws {@link EvmWriteError} if `wallet.account` is not set.\n * - Forwards the payload to `wallet.sendTransaction` and returns the\n * resulting tx hash.\n * - Wraps any thrown viem write-path error\n * (`TransactionExecutionError`, `UserRejectedRequestError`,\n * `ChainMismatchError`, …) into an {@link EvmWriteError} via\n * {@link wrapWriteError}.\n *\n * The `mode` parameter is currently unused at runtime; it is accepted for\n * API symmetry with the readers and as a forward-compat hook for a future\n * mode-specific submission policy (e.g. DEV-only simulation, staging\n * retries). The `_` prefix marks it unused for the TypeScript checker.\n *\n * Non-goals (per plan guardrails):\n * - Does NOT sign — the caller brings a `WalletClient` wired to their\n * signer.\n * - Does NOT switch chains — callers are responsible for\n * `wallet.switchChain(...)`.\n * - Does NOT retry or manage nonces — delegated to the caller's wallet.\n */\nexport async function submitAction(\n wallet: WalletClient,\n params: SubmitActionParams,\n _mode: EnvModeWithConfig,\n): Promise<Hex> {\n if (wallet.chain?.id !== params.chain) {\n throw new EvmWriteError(\n \"submitAction\",\n `wallet chain ${wallet.chain?.id ?? \"undefined\"} != params.chain ${params.chain}`,\n );\n }\n\n try {\n const account = wallet.account;\n if (!account) {\n throw new EvmWriteError(\n \"submitAction\",\n \"wallet has no account; callers must provide a wallet with wallet.account set\",\n );\n }\n return await wallet.sendTransaction({\n to: params.to,\n data: params.data,\n value: params.value ?? 0n,\n chain: wallet.chain,\n account,\n });\n } catch (err) {\n // Preserve our own pre-flight guards verbatim — they are already\n // EvmWriteError instances and don't need re-wrapping.\n if (err instanceof EvmWriteError) throw err;\n throw wrapWriteError(err, \"submitAction\");\n }\n}\n\n/**\n * Broadcast a periphery *swap* action — thin wrapper around\n * {@link submitAction} that re-labels any unknown error as `submitSwap` to\n * aid log-line triage. Behaviourally identical to `submitAction`; shares\n * its pre-flight guards.\n */\nexport async function submitSwap(\n wallet: WalletClient,\n params: SubmitActionParams,\n mode: EnvModeWithConfig,\n): Promise<Hex> {\n try {\n return await submitAction(wallet, params, mode);\n } catch (err) {\n if (err instanceof EvmWriteError) throw err;\n throw wrapWriteError(err, \"submitSwap\");\n }\n}\n\n/**\n * Broadcast a periphery *approval* action (ERC-20 approve to the source\n * chain's periphery contract) — thin wrapper around {@link submitAction}.\n * See {@link submitSwap} for labeling rationale.\n */\nexport async function submitApproval(\n wallet: WalletClient,\n params: SubmitActionParams,\n mode: EnvModeWithConfig,\n): Promise<Hex> {\n try {\n return await submitAction(wallet, params, mode);\n } catch (err) {\n if (err instanceof EvmWriteError) throw err;\n throw wrapWriteError(err, \"submitApproval\");\n }\n}\n","import { decodeEventLog, type Log } from \"viem\";\nimport { KernelEventEmitterABI } from \"@skate-org/amm-bindings\";\nimport { EvmReadError } from \"../errors\";\n\n/**\n * Event names emitted by the Skate kernel's `KernelEventEmitter`, sourced\n * directly from `@skate-org/amm-bindings`.\n */\nexport type KernelEventName =\n | \"Burn\"\n | \"Collect\"\n | \"CollectProtocol\"\n | \"IncreaseObservationCardinalityNext\"\n | \"Initialize\"\n | \"Mint\"\n | \"PeripheryPoolAdded\"\n | \"PeripheryPoolChanged\"\n | \"PoolCreated\"\n | \"PoolDescriptionUpdated\"\n | \"SetFeeProtocol\"\n | \"Swap\";\n\n/** Exhaustive list of known kernel event names — same values as {@link KernelEventName}. */\nexport const KERNEL_EVENT_NAMES: readonly KernelEventName[] = [\n \"Burn\",\n \"Collect\",\n \"CollectProtocol\",\n \"IncreaseObservationCardinalityNext\",\n \"Initialize\",\n \"Mint\",\n \"PeripheryPoolAdded\",\n \"PeripheryPoolChanged\",\n \"PoolCreated\",\n \"PoolDescriptionUpdated\",\n \"SetFeeProtocol\",\n \"Swap\",\n];\n\n/**\n * A decoded kernel event — the event name, its named args, and the original\n * viem `Log` for context (tx hash, block number, etc.).\n */\nexport interface KernelParsedEvent {\n eventName: KernelEventName;\n args: Record<string, unknown>;\n log: Log;\n}\n\n/**\n * Decode a viem `Log` emitted by the Skate kernel's `KernelEventEmitter`.\n *\n * Throws {@link EvmReadError} if the log's topic0 is not a known kernel event\n * or if ABI decoding fails.\n */\nexport function parseKernelEventLog(log: Log): KernelParsedEvent {\n try {\n const decoded = decodeEventLog({\n abi: KernelEventEmitterABI,\n data: log.data,\n topics: log.topics,\n });\n return {\n eventName: decoded.eventName as KernelEventName,\n args: (decoded.args ?? {}) as Record<string, unknown>,\n log,\n };\n } catch (err) {\n const message = (err as { shortMessage?: string; message?: string })\n .shortMessage ??\n (err as { message?: string }).message ??\n String(err);\n throw new EvmReadError(\n \"parseKernelEventLog\",\n `failed to decode log: ${message}`,\n { cause: err as Error },\n );\n }\n}\n","import { decodeEventLog, type Log } from \"viem\";\nimport { PeripheryEventEmitterABI } from \"@skate-org/amm-bindings\";\nimport { EvmReadError } from \"../errors\";\n\n/**\n * Event names emitted by `PeripheryEventEmitter` on the source chain.\n */\nexport type PeripheryEventName =\n | \"AmountSettled\"\n | \"Burned\"\n | \"LiquidityDecreased\"\n | \"LiquidityIncreased\"\n | \"MintSettled\"\n | \"Minted\"\n | \"PoolCreated\"\n | \"PoolDeployed\"\n | \"Swapped\"\n | \"TransferredTo\";\n\n/** Exhaustive list of known periphery event names. */\nexport const PERIPHERY_EVENT_NAMES: readonly PeripheryEventName[] = [\n \"AmountSettled\",\n \"Burned\",\n \"LiquidityDecreased\",\n \"LiquidityIncreased\",\n \"MintSettled\",\n \"Minted\",\n \"PoolCreated\",\n \"PoolDeployed\",\n \"Swapped\",\n \"TransferredTo\",\n];\n\n/** A decoded periphery event — name, named args, and the original viem `Log`. */\nexport interface PeripheryParsedEvent {\n eventName: PeripheryEventName;\n args: Record<string, unknown>;\n log: Log;\n}\n\n/**\n * Decode a viem `Log` emitted by `PeripheryEventEmitter` on a source chain.\n *\n * Throws {@link EvmReadError} if the log's topic0 is not a known periphery\n * event or if ABI decoding fails.\n */\nexport function parsePeripheryEventLog(log: Log): PeripheryParsedEvent {\n try {\n const decoded = decodeEventLog({\n abi: PeripheryEventEmitterABI,\n data: log.data,\n topics: log.topics,\n });\n return {\n eventName: decoded.eventName as PeripheryEventName,\n args: (decoded.args ?? {}) as Record<string, unknown>,\n log,\n };\n } catch (err) {\n const message = (err as { shortMessage?: string; message?: string })\n .shortMessage ??\n (err as { message?: string }).message ??\n String(err);\n throw new EvmReadError(\n \"parsePeripheryEventLog\",\n `failed to decode log: ${message}`,\n { cause: err as Error },\n );\n }\n}\n","import type { Address, Log, PublicClient } from \"viem\";\nimport {\n KernelEventEmitterABI,\n PeripheryEventEmitterABI,\n} from \"@skate-org/amm-bindings\";\nimport {\n parseKernelEventLog,\n type KernelParsedEvent,\n} from \"./kernel\";\nimport {\n parsePeripheryEventLog,\n type PeripheryParsedEvent,\n} from \"./periphery\";\n\nexport interface EventSubscriptionOptions<E> {\n /** Called for each decoded event. */\n onEvent: (event: E) => void;\n /** Called when a log fails to decode (subscription stays alive). */\n onError?: (err: unknown) => void;\n}\n\n/**\n * Subscribe to kernel events emitted by the `KernelEventEmitter` contract\n * at `address`. Returns an unsubscribe function.\n *\n * Decode failures are surfaced via `opts.onError` (if provided) rather than\n * throwing — the subscription continues.\n */\nexport function watchKernelEvents(\n client: PublicClient,\n address: Address,\n opts: EventSubscriptionOptions<KernelParsedEvent>,\n): () => void {\n return client.watchContractEvent({\n abi: KernelEventEmitterABI,\n address,\n onLogs: (logs: Log[]) => {\n for (const log of logs) {\n try {\n opts.onEvent(parseKernelEventLog(log));\n } catch (err) {\n opts.onError?.(err);\n }\n }\n },\n });\n}\n\n/**\n * Subscribe to periphery events emitted by `PeripheryEventEmitter` at\n * `address` on the source chain the `client` is connected to.\n */\nexport function watchPeripheryEvents(\n client: PublicClient,\n address: Address,\n opts: EventSubscriptionOptions<PeripheryParsedEvent>,\n): () => void {\n return client.watchContractEvent({\n abi: PeripheryEventEmitterABI,\n address,\n onLogs: (logs: Log[]) => {\n for (const log of logs) {\n try {\n opts.onEvent(parsePeripheryEventLog(log));\n } catch (err) {\n opts.onError?.(err);\n }\n }\n },\n });\n}\n"],"mappings":"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","names":["import_amm_core_v2","import_amm_core_v2","import_amm_bindings","import_amm_core_v2","import_amm_bindings","import_amm_core_v2","import_viem","import_amm_bindings","import_viem","import_amm_bindings","import_amm_bindings"]}
package/dist/index.js CHANGED
@@ -132,11 +132,15 @@ import {
132
132
  getAmount1Delta,
133
133
  getSqrtRatioAtTick
134
134
  } from "@skate-org/amm-core-v2";
135
- function resolveClient(mode, client) {
135
+
136
+ // src/kernel/_client.ts
137
+ function resolveKernelClient(mode, client) {
136
138
  return client ?? getKernelPublicClient(mode);
137
139
  }
140
+
141
+ // src/kernel/reader.ts
138
142
  async function readPool(kernelPool, mode, client) {
139
- const c = resolveClient(mode, client);
143
+ const c = resolveKernelClient(mode, client);
140
144
  try {
141
145
  const [slot0, liquidity] = await Promise.all([
142
146
  c.readContract({
@@ -170,7 +174,7 @@ async function readPool(kernelPool, mode, client) {
170
174
  async function readPosition(tokenId, mode, client) {
171
175
  const { mode: baseMode } = normalizeMode2(mode);
172
176
  const manager = KernelManagerAddress(baseMode);
173
- const c = resolveClient(mode, client);
177
+ const c = resolveKernelClient(mode, client);
174
178
  try {
175
179
  const raw = await c.readContract({
176
180
  address: manager,
@@ -197,7 +201,7 @@ async function readPosition(tokenId, mode, client) {
197
201
  }
198
202
  }
199
203
  async function readTickBitmap(kernelPool, wordPos, mode, client) {
200
- const c = resolveClient(mode, client);
204
+ const c = resolveKernelClient(mode, client);
201
205
  try {
202
206
  const word = await c.readContract({
203
207
  address: kernelPool,
@@ -211,7 +215,7 @@ async function readTickBitmap(kernelPool, wordPos, mode, client) {
211
215
  }
212
216
  }
213
217
  async function readTick(kernelPool, tick, mode, client) {
214
- const c = resolveClient(mode, client);
218
+ const c = resolveKernelClient(mode, client);
215
219
  try {
216
220
  const raw = await c.readContract({
217
221
  address: kernelPool,
@@ -234,7 +238,7 @@ async function readTick(kernelPool, tick, mode, client) {
234
238
  }
235
239
  }
236
240
  async function computePositionAmounts(tokenId, mode, client) {
237
- const c = resolveClient(mode, client);
241
+ const c = resolveKernelClient(mode, client);
238
242
  const position = await readPosition(tokenId, mode, c);
239
243
  const { slot0 } = await readPool(position.pool, mode, c);
240
244
  const sqrtLower = getSqrtRatioAtTick(position.tickLower);
@@ -289,17 +293,108 @@ function decodeTickBitmapWord(word, wordPos, tickSpacing) {
289
293
  return result;
290
294
  }
291
295
 
296
+ // src/kernel/lens.ts
297
+ import { KernelManagerABI as KernelManagerABI2 } from "@skate-org/amm-bindings";
298
+ import {
299
+ KernelManagerAddress as KernelManagerAddress2,
300
+ normalizeMode as normalizeMode3
301
+ } from "@skate-org/amm-core-v2";
302
+ async function simulateSwap(params, mode, client) {
303
+ const { mode: baseMode } = normalizeMode3(mode);
304
+ const c = resolveKernelClient(mode, client);
305
+ try {
306
+ const out = await c.simulateContract({
307
+ address: KernelManagerAddress2(baseMode),
308
+ abi: KernelManagerABI2,
309
+ functionName: "lensSwap",
310
+ args: [
311
+ params.pool,
312
+ params.recipient,
313
+ params.zeroForOne,
314
+ params.amountSpecified,
315
+ params.sqrtPriceLimitX96
316
+ ]
317
+ });
318
+ const [amount0, amount1, sqrtPriceX96After, returnData] = out.result;
319
+ return { amount0, amount1, sqrtPriceX96After, returnData };
320
+ } catch (err) {
321
+ throw wrapReadError(err, "simulateSwap");
322
+ }
323
+ }
324
+ async function simulateMint(params, mode, client) {
325
+ const { mode: baseMode } = normalizeMode3(mode);
326
+ const c = resolveKernelClient(mode, client);
327
+ try {
328
+ const out = await c.simulateContract({
329
+ address: KernelManagerAddress2(baseMode),
330
+ abi: KernelManagerABI2,
331
+ functionName: "lensMint",
332
+ args: [
333
+ params.pool,
334
+ params.recipient,
335
+ params.tickLower,
336
+ params.tickUpper,
337
+ params.amount0,
338
+ params.amount1,
339
+ params.data
340
+ ]
341
+ });
342
+ const [amount0Used, amount1Used, liquidityAmount, returnData] = out.result;
343
+ return { amount0Used, amount1Used, liquidityAmount, returnData };
344
+ } catch (err) {
345
+ throw wrapReadError(err, "simulateMint");
346
+ }
347
+ }
348
+ async function simulateBurn(params, mode, client) {
349
+ const { mode: baseMode } = normalizeMode3(mode);
350
+ const c = resolveKernelClient(mode, client);
351
+ try {
352
+ const out = await c.simulateContract({
353
+ address: KernelManagerAddress2(baseMode),
354
+ abi: KernelManagerABI2,
355
+ functionName: "lensBurn",
356
+ args: [
357
+ params.pool,
358
+ params.recipient,
359
+ params.tickLower,
360
+ params.tickUpper,
361
+ params.amount
362
+ ]
363
+ });
364
+ const [amount0, amount1, returnData] = out.result;
365
+ return { amount0, amount1, returnData };
366
+ } catch (err) {
367
+ throw wrapReadError(err, "simulateBurn");
368
+ }
369
+ }
370
+ async function simulateDecreaseLiquidity(params, mode, client) {
371
+ const { mode: baseMode } = normalizeMode3(mode);
372
+ const c = resolveKernelClient(mode, client);
373
+ try {
374
+ const out = await c.simulateContract({
375
+ address: KernelManagerAddress2(baseMode),
376
+ abi: KernelManagerABI2,
377
+ functionName: "lensDecreaseLiquidity",
378
+ args: [params.tokenId, params.liquidity]
379
+ });
380
+ const [amount0, amount1, returnData] = out.result;
381
+ return { amount0, amount1, returnData };
382
+ } catch (err) {
383
+ throw wrapReadError(err, "simulateDecreaseLiquidity");
384
+ }
385
+ }
386
+
292
387
  // src/periphery/reader.ts
293
388
  import { PeripheryPoolABI } from "@skate-org/amm-bindings";
294
389
  import {
295
390
  getPeripheryDetailsByKernelPoolAndChainId,
296
- normalizeMode as normalizeMode3
391
+ normalizeMode as normalizeMode4
297
392
  } from "@skate-org/amm-core-v2";
298
- function resolveClient2(chain, mode, client) {
393
+ function resolveClient(chain, mode, client) {
299
394
  return client ?? getSourcePublicClient(chain, mode);
300
395
  }
301
396
  async function readPeripheryPool(chain, kernelPool, mode, client) {
302
- const { mode: baseMode } = normalizeMode3(mode);
397
+ const { mode: baseMode } = normalizeMode4(mode);
303
398
  const details = getPeripheryDetailsByKernelPoolAndChainId(
304
399
  kernelPool,
305
400
  chain,
@@ -312,7 +407,7 @@ async function readPeripheryPool(chain, kernelPool, mode, client) {
312
407
  );
313
408
  }
314
409
  const address = details.address;
315
- const c = resolveClient2(chain, mode, client);
410
+ const c = resolveClient(chain, mode, client);
316
411
  try {
317
412
  const [
318
413
  balancesAvailableRaw,
@@ -378,7 +473,7 @@ async function readPeripheryPool(chain, kernelPool, mode, client) {
378
473
  }
379
474
  }
380
475
  async function readUserPoolBalances(chain, kernelPool, user, mode, client) {
381
- const { mode: baseMode } = normalizeMode3(mode);
476
+ const { mode: baseMode } = normalizeMode4(mode);
382
477
  const details = getPeripheryDetailsByKernelPoolAndChainId(
383
478
  kernelPool,
384
479
  chain,
@@ -390,7 +485,7 @@ async function readUserPoolBalances(chain, kernelPool, user, mode, client) {
390
485
  `no periphery entry for kernelPool=${kernelPool} chain=${chain} mode=${baseMode}`
391
486
  );
392
487
  }
393
- const c = resolveClient2(chain, mode, client);
488
+ const c = resolveClient(chain, mode, client);
394
489
  try {
395
490
  const raw = await c.readContract({
396
491
  address: details.address,
@@ -585,6 +680,10 @@ export {
585
680
  readTick,
586
681
  readTickBitmap,
587
682
  readUserPoolBalances,
683
+ simulateBurn,
684
+ simulateDecreaseLiquidity,
685
+ simulateMint,
686
+ simulateSwap,
588
687
  submitAction,
589
688
  submitApproval,
590
689
  submitSwap,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/chain-clients.ts","../src/devConfig.ts","../src/errors.ts","../src/kernel/reader.ts","../src/kernel/tickBitmap.ts","../src/periphery/reader.ts","../src/periphery/submit.ts","../src/events/kernel.ts","../src/events/periphery.ts","../src/events/watch.ts"],"sourcesContent":["import {\n createPublicClient,\n defineChain,\n http,\n type Chain,\n type PublicClient,\n type Transport,\n} from \"viem\";\nimport { arbitrum } from \"viem/chains\";\nimport {\n BLOCK_EXPLORER,\n CHAIN,\n VM,\n vmTypeFromChain,\n normalizeMode,\n type EnvModeWithConfig,\n} from \"@skate-org/amm-core-v2\";\n\n/**\n * MegaETH chain definition — `@public`.\n *\n * Exported for callers who need to build their own viem `WalletClient` or\n * `PublicClient` against the same chain the SDK uses internally (e.g. wallet\n * integrations that construct a `WalletClient` ahead of calling\n * `submitAction`). Prefer {@link getKernelPublicClient} when you just need a\n * read client.\n *\n * viem ships a `megaeth` chain at id 4326, but with a different default RPC\n * than the one Skate uses for kernel reads. Define locally so we control the\n * RPC URL + block-explorer metadata and don't inherit unrelated op-stack\n * contract addresses.\n */\nexport const megaethChain: Chain = defineChain({\n id: 4326,\n name: \"MegaETH\",\n network: \"megaeth\",\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n rpcUrls: {\n default: { http: [\"https://mainnet.megaeth.com/rpc\"] },\n public: { http: [\"https://mainnet.megaeth.com/rpc\"] },\n },\n blockExplorers: {\n default: { name: \"Blockscout\", url: BLOCK_EXPLORER.MEGAETH },\n },\n});\n\n/**\n * Default public RPC URLs by chain id.\n *\n * Callers can override per-chain via `DevModeConfig.rpcEndpoints` or by\n * passing an explicit `transport` to the factory functions below.\n */\nconst DEFAULT_RPC: Partial<Record<CHAIN, string>> = {\n [CHAIN.MEGAETH]: \"https://mainnet.megaeth.com/rpc\",\n [CHAIN.ARBITRUM]: \"https://arb1.arbitrum.io/rpc\",\n};\n\n/**\n * Map a supported EVM `CHAIN` to a viem `Chain` definition.\n *\n * Only chains we actively support in Phase 2 are listed; unknown chains\n * return `undefined` and the caller throws.\n */\nfunction chainDefFor(chain: CHAIN): Chain | undefined {\n switch (chain) {\n case CHAIN.MEGAETH:\n return megaethChain;\n case CHAIN.ARBITRUM:\n return arbitrum;\n default:\n return undefined;\n }\n}\n\n/**\n * Resolve the RPC URL for a given chain under the precedence:\n * transport override (caller arg) > mode.config.rpcEndpoints[chain] > DEFAULT_RPC[chain]\n * Returns `undefined` if none is set — callers must have already decided whether\n * to use a caller-supplied transport.\n */\nfunction resolveRpcUrl(\n chain: CHAIN,\n mode: EnvModeWithConfig,\n): string | undefined {\n const { config } = normalizeMode(mode);\n return config?.rpcEndpoints?.[chain] ?? DEFAULT_RPC[chain];\n}\n\n/**\n * Return a fresh `PublicClient` bound to the MegaETH kernel chain.\n *\n * MegaETH is the kernel chain for all environment modes (DEV/STAGING/\n * PRODUCTION) in SDK v2. The `mode` parameter is accepted for API\n * symmetry with the rest of the SDK and as a forward-compatible extension\n * point (e.g. a future testnet kernel).\n *\n * Pure — no singletons, no caching. Pass a custom `transport` to override\n * the default RPC (useful for tests and custom RPC providers).\n */\nexport function getKernelPublicClient(\n mode: EnvModeWithConfig,\n transport?: Transport,\n): PublicClient {\n return createPublicClient({\n chain: megaethChain,\n transport: transport ?? http(resolveRpcUrl(CHAIN.MEGAETH, mode)),\n });\n}\n\n/**\n * Return a fresh `PublicClient` for a source EVM chain (e.g. Arbitrum).\n *\n * Throws a descriptive `Error` when:\n * - `chain` is not an EVM chain (per `vmTypeFromChain`); or\n * - no viem chain definition is registered for `chain`; or\n * - no default RPC URL is configured for `chain` and no `transport` override\n * was provided.\n *\n * Pure — no singletons, no caching.\n */\nexport function getSourcePublicClient(\n chain: CHAIN,\n mode: EnvModeWithConfig,\n transport?: Transport,\n): PublicClient {\n if (vmTypeFromChain(chain) !== VM.EVM) {\n throw new Error(\n `getSourcePublicClient: chain ${chain} is not an EVM chain`,\n );\n }\n const chainDef = chainDefFor(chain);\n if (!chainDef) {\n throw new Error(\n `getSourcePublicClient: no chain definition registered for chain ${chain}`,\n );\n }\n const rpc = resolveRpcUrl(chain, mode);\n if (!rpc && !transport) {\n throw new Error(\n `getSourcePublicClient: no default or override RPC configured for chain ${chain}; pass a transport override or set DevModeConfig.rpcEndpoints[${chain}]`,\n );\n }\n return createPublicClient({\n chain: chainDef,\n transport: transport ?? http(rpc),\n });\n}\n","import type { DevModeConfig } from \"@skate-org/amm-core-v2\";\n\n/** Default DEV api endpoint — matches Phase 1's api client default. */\nexport const DEFAULT_DEV_API_ENDPOINT =\n \"https://dev.api.skatechain.org/amm-action-v2\";\n\n/**\n * Convenience factory for the `{ mode: \"DEV\"; config: DevModeConfig }` tuple.\n *\n * Reduces ceremony at call sites that want to override a single field (e.g.,\n * `rpcEndpoints`) without reconstructing the full object:\n *\n * ```ts\n * const mode = createDevConfig({\n * rpcEndpoints: { [CHAIN.MEGAETH]: \"https://my-private-megaeth/rpc\" },\n * });\n * submitAction(wallet, params, mode);\n * ```\n *\n * Pass nothing to use all defaults.\n */\nexport function createDevConfig(\n overrides: Partial<DevModeConfig> = {},\n): { mode: \"DEV\"; config: DevModeConfig } {\n return {\n mode: \"DEV\",\n config: {\n apiEndpoint: overrides.apiEndpoint ?? DEFAULT_DEV_API_ENDPOINT,\n ...(overrides.rpcEndpoints\n ? { rpcEndpoints: overrides.rpcEndpoints }\n : {}),\n },\n };\n}\n","/**\n * Shared error types for the `@skate-org/amm-evm-v2` package.\n *\n * `EvmReadError` / `EvmWriteError` extend `SdkError` (from core) so callers\n * can `instanceof SdkError` to catch any SDK-origin error without needing\n * to know the specific subclass.\n */\n\nimport { SdkError } from \"@skate-org/amm-core-v2\";\n\n/** SDK-level error thrown when an EVM read reverts or decodes badly. */\nexport class EvmReadError extends SdkError {\n override readonly name: string = \"EvmReadError\";\n readonly functionName: string;\n\n constructor(functionName: string, message: string, options?: ErrorOptions) {\n super(`${functionName}: ${message}`, options);\n this.functionName = functionName;\n }\n}\n\n/**\n * SDK-level error thrown when an EVM write (broadcast) fails.\n *\n * Symmetric with {@link EvmReadError}, but covers the write path: viem's\n * `TransactionExecutionError`, `UserRejectedRequestError`,\n * `ChainMismatchError`, `ChainDisconnectedError`, as well as submitter\n * pre-flight guards (e.g. wrong-chain, missing account).\n */\nexport class EvmWriteError extends SdkError {\n override readonly name: string = \"EvmWriteError\";\n readonly functionName: string;\n\n constructor(functionName: string, message: string, options?: ErrorOptions) {\n super(`${functionName}: ${message}`, options);\n this.functionName = functionName;\n }\n}\n\n/**\n * Wrap any error from an EVM read into `EvmReadError`. Viem always wraps\n * revert-path errors in `ContractFunctionExecutionError` (see\n * `viem/utils/errors/getContractError`), so we check both the outer name and\n * the `.cause` chain for `ContractFunctionRevertedError` /\n * `ContractFunctionZeroDataError`.\n *\n * Shared by `kernel/reader.ts` and `periphery/reader.ts` — depends only on\n * `EvmReadError` and generic Error inspection (no reader-module imports), so\n * it is safe from circular-import concerns.\n */\nexport function wrapReadError(\n err: unknown,\n functionName: string,\n): EvmReadError {\n const outerName = (err as { name?: string } | null)?.name;\n const causeName = (err as { cause?: { name?: string } } | null)?.cause?.name;\n const message =\n (err as { shortMessage?: string } | null)?.shortMessage ??\n (err as { message?: string } | null)?.message ??\n String(err);\n const isViemContractError =\n outerName === \"ContractFunctionExecutionError\" ||\n outerName === \"ContractFunctionRevertedError\" ||\n outerName === \"ContractFunctionZeroDataError\" ||\n causeName === \"ContractFunctionRevertedError\" ||\n causeName === \"ContractFunctionZeroDataError\";\n if (isViemContractError) {\n return new EvmReadError(functionName, `reverted: ${message}`, {\n cause: err as Error,\n });\n }\n return new EvmReadError(functionName, message, { cause: err as Error });\n}\n\n/**\n * Wrap any error from an EVM write-path call (typically\n * `WalletClient.sendTransaction`) into `EvmWriteError`.\n *\n * Any thrown error reaching a submitter is treated as a write failure. If\n * we later want to differentiate known viem write errors\n * (`TransactionExecutionError`, `UserRejectedRequestError`,\n * `ChainMismatchError`, `ChainDisconnectedError`) from unknown errors —\n * e.g. to prefix the message or re-throw unknowns raw — that dispatch goes\n * here. Keeping the single-return shape until a concrete caller need\n * surfaces.\n */\nexport function wrapWriteError(\n err: unknown,\n functionName: string,\n): EvmWriteError {\n const message =\n (err as { shortMessage?: string } | null)?.shortMessage ??\n (err as { message?: string } | null)?.message ??\n String(err);\n return new EvmWriteError(functionName, message, { cause: err as Error });\n}\n","import type { PublicClient } from \"viem\";\nimport {\n KernelManagerABI,\n KernelPoolABI,\n} from \"@skate-org/amm-bindings\";\nimport {\n KernelManagerAddress,\n normalizeMode,\n type EnvModeWithConfig,\n getAmount0Delta,\n getAmount1Delta,\n getSqrtRatioAtTick,\n} from \"@skate-org/amm-core-v2\";\nimport { getKernelPublicClient } from \"../chain-clients\";\nimport { wrapReadError } from \"../errors\";\n\n/** Decoded kernel-pool `slot0` state (named fields, per the ABI tuple). */\nexport interface KernelSlot0 {\n sqrtPriceX96: bigint;\n tick: number;\n observationIndex: number;\n observationCardinality: number;\n observationCardinalityNext: number;\n feeProtocol: number;\n unlocked: boolean;\n}\n\n/** Decoded pool state returned by `readPool`. */\nexport interface KernelPoolState {\n slot0: KernelSlot0;\n liquidity: bigint;\n}\n\n/** Decoded NFT position returned by `readPosition`. */\nexport interface KernelNftPosition {\n pool: `0x${string}`;\n tickLower: number;\n tickUpper: number;\n liquidity: bigint;\n feeGrowthInside0LastX128: bigint;\n feeGrowthInside1LastX128: bigint;\n tokensOwed0: bigint;\n tokensOwed1: bigint;\n}\n\n/** Decoded kernel-pool `ticks(tick)` struct. */\nexport interface KernelTick {\n liquidityGross: bigint;\n liquidityNet: bigint;\n feeGrowthOutside0X128: bigint;\n feeGrowthOutside1X128: bigint;\n tickCumulativeOutside: bigint;\n secondsPerLiquidityOutsideX128: bigint;\n secondsOutside: number;\n initialized: boolean;\n}\n\n/**\n * Return the caller-provided client if present, otherwise build a fresh\n * MegaETH kernel client for the given mode.\n */\nfunction resolveClient(\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): PublicClient {\n return client ?? getKernelPublicClient(mode);\n}\n\n/**\n * Read `slot0` and `liquidity` from a kernel pool. Returns both in a single\n * object; the reads are fired in parallel.\n *\n * The `client` optional parameter is the standard test-injection point.\n */\nexport async function readPool(\n kernelPool: `0x${string}`,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<KernelPoolState> {\n const c = resolveClient(mode, client);\n try {\n const [slot0, liquidity] = await Promise.all([\n c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"slot0\",\n }),\n c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"liquidity\",\n }),\n ]);\n // Viem returns named outputs as a positional tuple (array) when every\n // output has a name — normalize to a named-field object here so callers\n // don't depend on viem's tuple/object split.\n const s0 = slot0 as readonly [\n bigint,\n number,\n number,\n number,\n number,\n number,\n boolean,\n ];\n return {\n slot0: {\n sqrtPriceX96: s0[0],\n tick: s0[1],\n observationIndex: s0[2],\n observationCardinality: s0[3],\n observationCardinalityNext: s0[4],\n feeProtocol: s0[5],\n unlocked: s0[6],\n },\n liquidity: liquidity as bigint,\n };\n } catch (err) {\n throw wrapReadError(err, \"readPool\");\n }\n}\n\n/**\n * Read an NFT position by token id from the kernel manager.\n *\n * Calls `KernelManager.nftPositions(tokenId)` — per the ABI this returns a\n * `DataTypes.NFTPosition` tuple including `pool`, `tickLower`, `tickUpper`,\n * `liquidity`, fee growth, and tokens owed.\n */\nexport async function readPosition(\n tokenId: bigint,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<KernelNftPosition> {\n const { mode: baseMode } = normalizeMode(mode);\n const manager = KernelManagerAddress(baseMode);\n const c = resolveClient(mode, client);\n try {\n const raw = (await c.readContract({\n address: manager,\n abi: KernelManagerABI,\n functionName: \"nftPositions\",\n args: [tokenId],\n })) as unknown;\n // Accept either a positional tuple or an already-named object from\n // viem — normalize to a named-field object, mirroring readPool's\n // defensive remap. Viem's decoding of named-components tuples is\n // stable today (object form), but this guards against future\n // restructuring.\n const asTuple = Array.isArray(raw)\n ? (raw as unknown as readonly [\n `0x${string}`,\n number,\n number,\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n ])\n : null;\n if (asTuple) {\n return {\n pool: asTuple[0],\n tickLower: asTuple[1],\n tickUpper: asTuple[2],\n liquidity: asTuple[3],\n feeGrowthInside0LastX128: asTuple[4],\n feeGrowthInside1LastX128: asTuple[5],\n tokensOwed0: asTuple[6],\n tokensOwed1: asTuple[7],\n };\n }\n return raw as KernelNftPosition;\n } catch (err) {\n throw wrapReadError(err, \"readPosition\");\n }\n}\n\n/**\n * Read a kernel-pool tick-bitmap word (`tickBitmap(int16 wordPos)`).\n *\n * Returns the raw `uint256` word as a bigint. A bit-decoder that expands a\n * word into populated tick indexes is intentionally not shipped in 0.2.0 —\n * flag as an open question for Phase 3 if a caller wants it.\n */\nexport async function readTickBitmap(\n kernelPool: `0x${string}`,\n wordPos: number,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<bigint> {\n const c = resolveClient(mode, client);\n try {\n const word = await c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"tickBitmap\",\n args: [wordPos],\n });\n return word as bigint;\n } catch (err) {\n throw wrapReadError(err, \"readTickBitmap\");\n }\n}\n\n/** Read the `ticks(tick)` struct from a kernel pool. */\nexport async function readTick(\n kernelPool: `0x${string}`,\n tick: number,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<KernelTick> {\n const c = resolveClient(mode, client);\n try {\n const raw = (await c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"ticks\",\n args: [tick],\n })) as readonly [\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n number,\n boolean,\n ];\n return {\n liquidityGross: raw[0],\n liquidityNet: raw[1],\n feeGrowthOutside0X128: raw[2],\n feeGrowthOutside1X128: raw[3],\n tickCumulativeOutside: raw[4],\n secondsPerLiquidityOutsideX128: raw[5],\n secondsOutside: raw[6],\n initialized: raw[7],\n };\n } catch (err) {\n throw wrapReadError(err, \"readTick\");\n }\n}\n\n/**\n * Compute `{amount0, amount1}` for an NFT position using the Group 3 math.\n *\n * Reads the position (to learn `pool`, `tickLower`, `tickUpper`,\n * `liquidity`) and the pool's `slot0`, then splits based on whether the\n * current tick is below, inside, or above the position range — mirroring\n * `PositionValue.principal` from Uniswap v3 periphery.\n */\nexport async function computePositionAmounts(\n tokenId: bigint,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<{ amount0: bigint; amount1: bigint }> {\n const c = resolveClient(mode, client);\n const position = await readPosition(tokenId, mode, c);\n const { slot0 } = await readPool(position.pool, mode, c);\n\n const sqrtLower = getSqrtRatioAtTick(position.tickLower);\n const sqrtUpper = getSqrtRatioAtTick(position.tickUpper);\n\n if (slot0.tick < position.tickLower) {\n return {\n amount0: getAmount0Delta(sqrtLower, sqrtUpper, position.liquidity, false),\n amount1: 0n,\n };\n }\n if (slot0.tick >= position.tickUpper) {\n return {\n amount0: 0n,\n amount1: getAmount1Delta(sqrtLower, sqrtUpper, position.liquidity, false),\n };\n }\n return {\n amount0: getAmount0Delta(\n slot0.sqrtPriceX96,\n sqrtUpper,\n position.liquidity,\n false,\n ),\n amount1: getAmount1Delta(\n sqrtLower,\n slot0.sqrtPriceX96,\n position.liquidity,\n false,\n ),\n };\n}\n","/**\n * Decode a single Uniswap-v3 tick-bitmap `uint256` word into the list of\n * real (non-compressed) ticks it marks as initialized.\n *\n * A tick bitmap word covers 256 compressed ticks. For a given `wordPos`\n * (int16) the word spans compressed ticks `wordPos * 256` through\n * `(wordPos + 1) * 256 - 1`, and bit `k` (0..255) corresponds to the\n * compressed tick `wordPos * 256 + k`. The real tick at bit `k` is\n * `(wordPos * 256 + k) * tickSpacing`.\n *\n * Intended composition with the reader:\n *\n * ```ts\n * const word = await readTickBitmap(pool, wordPos, mode);\n * const ticks = decodeTickBitmapWord(word, wordPos, tickSpacing);\n * ```\n *\n * Pure function: no network, no viem, no external deps.\n *\n * @param word The 256-bit bitmap word returned by PoolAbi.tickBitmap(int16).\n * @param wordPos The int16 word position (-128 .. 127 per Uniswap, but\n * we accept any safe-integer int16-shaped value).\n * @param tickSpacing The pool's tickSpacing (positive integer, typically 1,\n * 10, 60, 200, etc.).\n * @returns Real ticks whose bits are set in the word, ascending.\n *\n * @throws {RangeError} if `tickSpacing <= 0` or if `wordPos` is not a safe integer.\n */\nexport function decodeTickBitmapWord(\n word: bigint,\n wordPos: number,\n tickSpacing: number,\n): number[] {\n if (!Number.isSafeInteger(wordPos)) {\n throw new RangeError(\n `decodeTickBitmapWord: wordPos must be a safe integer, got ${wordPos}`,\n );\n }\n if (!Number.isSafeInteger(tickSpacing) || tickSpacing <= 0) {\n throw new RangeError(\n `decodeTickBitmapWord: tickSpacing must be a positive integer, got ${tickSpacing}`,\n );\n }\n const result: number[] = [];\n // wordPos * 256 gives the base compressed-tick of this word. Each set bit k\n // contributes compressed-tick (wordPos * 256 + k), which becomes real tick\n // (wordPos * 256 + k) * tickSpacing.\n const base = wordPos * 256;\n for (let k = 0; k < 256; k++) {\n if (((word >> BigInt(k)) & 1n) === 1n) {\n result.push((base + k) * tickSpacing);\n }\n }\n return result;\n}\n","import type { PublicClient } from \"viem\";\nimport { PeripheryPoolABI } from \"@skate-org/amm-bindings\";\nimport {\n CHAIN,\n getPeripheryDetailsByKernelPoolAndChainId,\n normalizeMode,\n type EnvModeWithConfig,\n type EvmChain,\n} from \"@skate-org/amm-core-v2\";\nimport { getSourcePublicClient } from \"../chain-clients\";\nimport { EvmReadError, wrapReadError } from \"../errors\";\n\n/**\n * Decoded `balancesAvailable()` tuple on a periphery pool — per the\n * `PeripheryPoolABI` this returns `(uint256 amount0Available, uint256 amount1Available)`.\n */\nexport interface PeripheryBalancesAvailable {\n amount0Available: bigint;\n amount1Available: bigint;\n}\n\n/**\n * Decoded periphery-pool state assembled by {@link readPeripheryPool}.\n *\n * The periphery pool does **not** expose a `slot0`-style view — pricing\n * state lives on the kernel pool on MegaETH (see `readPool`). What the\n * periphery pool does expose is: the configured pair\n * (`token0`, `token1`, `fee`, `kernelPool` reference), the escrowed\n * in-pool settlement balances (`balancesAvailable`), and the two\n * `dustAmount{0,1}` accumulators. Together these are enough for a\n * source-chain caller to reason about pending settlement and dust.\n */\nexport interface PeripheryPoolState {\n /** Periphery pool contract address on the source chain. */\n address: `0x${string}`;\n /** Source-chain ERC-20 address for token0. */\n token0: `0x${string}`;\n /** Source-chain ERC-20 address for token1. */\n token1: `0x${string}`;\n /** Fee tier (uint24) the periphery pool was deployed with. */\n fee: number;\n /** Address of the paired kernel pool on MegaETH. */\n kernelPool: `0x${string}`;\n /** Aggregate in-pool balances available for settlement. */\n balancesAvailable: PeripheryBalancesAvailable;\n /** token0 dust accumulator. */\n dustAmount0: bigint;\n /** token1 dust accumulator. */\n dustAmount1: bigint;\n}\n\n/**\n * Return the caller-provided client, or build a fresh source-chain\n * client for `chain` under the given `mode`. Mirrors the kernel reader\n * injection pattern.\n */\nfunction resolveClient(\n chain: CHAIN,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): PublicClient {\n return client ?? getSourcePublicClient(chain, mode);\n}\n\n/**\n * Read the assembled periphery-pool state on a source chain.\n *\n * Resolves the periphery pool address via\n * `getPeripheryDetailsByKernelPoolAndChainId` (from\n * `@skate-org/amm-core-v2`) — **no addresses are hardcoded here**. If the\n * `(kernelPool, chain, mode)` triple has no entry in the aggregated pool\n * catalog, throws with the triple in the message for debuggability.\n *\n * All sub-reads are fired in parallel and normalized to named fields.\n */\nexport async function readPeripheryPool(\n chain: CHAIN,\n kernelPool: `0x${string}`,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<PeripheryPoolState> {\n const { mode: baseMode } = normalizeMode(mode);\n const details = getPeripheryDetailsByKernelPoolAndChainId(\n kernelPool,\n chain as EvmChain,\n baseMode,\n );\n if (!details) {\n throw new EvmReadError(\n \"readPeripheryPool\",\n `no periphery entry for kernelPool=${kernelPool} chain=${chain} mode=${baseMode}`,\n );\n }\n const address = details.address;\n const c = resolveClient(chain, mode, client);\n try {\n const [\n balancesAvailableRaw,\n dust0,\n dust1,\n token0,\n token1,\n fee,\n kPool,\n ] = await Promise.all([\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"balancesAvailable\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"dustAmount0\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"dustAmount1\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"token0\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"token1\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"fee\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"kernelPool\",\n }),\n ]);\n // Viem decodes multi-output tuples with all-named outputs as a\n // positional tuple — normalize to a named-field object.\n const bAvail = balancesAvailableRaw as readonly [bigint, bigint];\n return {\n address,\n token0: token0 as `0x${string}`,\n token1: token1 as `0x${string}`,\n fee: fee as number,\n kernelPool: kPool as `0x${string}`,\n balancesAvailable: {\n amount0Available: bAvail[0],\n amount1Available: bAvail[1],\n },\n dustAmount0: dust0 as bigint,\n dustAmount1: dust1 as bigint,\n };\n } catch (err) {\n throw wrapReadError(err, \"readPeripheryPool\");\n }\n}\n\n/**\n * Decoded `usersData(address)` tuple on a periphery pool — per the\n * `PeripheryPoolABI` this returns `(uint256 amount0, uint256 amount1)`\n * representing the user's per-pool in-flight token balances on the\n * source chain.\n */\nexport interface UserPoolBalances {\n amount0: bigint;\n amount1: bigint;\n}\n\n/**\n * Read a user's per-pool in-flight balances on a source chain.\n *\n * Resolves the periphery pool address via\n * `getPeripheryDetailsByKernelPoolAndChainId` (no hardcoded addresses)\n * and calls `PeripheryPool.usersData(user)` which returns\n * `(uint256 amount0, uint256 amount1)`.\n *\n * Replaces the previous `readEscrowBalance(chain, user, token)` stub,\n * whose `(user, token)` keying did not match any available ABI view —\n * escrow state is keyed per-(pool, user), not per-(user, token).\n */\nexport async function readUserPoolBalances(\n chain: CHAIN,\n kernelPool: `0x${string}`,\n user: `0x${string}`,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<UserPoolBalances> {\n const { mode: baseMode } = normalizeMode(mode);\n const details = getPeripheryDetailsByKernelPoolAndChainId(\n kernelPool,\n chain as EvmChain,\n baseMode,\n );\n if (!details) {\n throw new EvmReadError(\n \"readUserPoolBalances\",\n `no periphery entry for kernelPool=${kernelPool} chain=${chain} mode=${baseMode}`,\n );\n }\n const c = resolveClient(chain, mode, client);\n try {\n const raw = (await c.readContract({\n address: details.address,\n abi: PeripheryPoolABI,\n functionName: \"usersData\",\n args: [user],\n })) as unknown;\n // `usersData` returns `(uint256 amount0, uint256 amount1)`.\n // Viem decodes tuples with all-named outputs as a positional tuple;\n // handle both the positional and (older) object shapes defensively.\n if (Array.isArray(raw)) {\n const tuple = raw as unknown as readonly [bigint, bigint];\n return { amount0: tuple[0], amount1: tuple[1] };\n }\n const asObject = raw as { amount0: bigint; amount1: bigint };\n return { amount0: asObject.amount0, amount1: asObject.amount1 };\n } catch (err) {\n throw wrapReadError(err, \"readUserPoolBalances\");\n }\n}\n","import type { Address, Hex, WalletClient } from \"viem\";\nimport type { CHAIN, EnvModeWithConfig } from \"@skate-org/amm-core-v2\";\nimport { EvmWriteError, wrapWriteError } from \"../errors\";\n\n/**\n * Pre-built source-chain transaction payload accepted by\n * {@link submitAction}.\n *\n * The SDK does **not** fabricate calldata in Group 6 — callers build the\n * payload (e.g. from a quote's `serializedCall`) and this submitter only\n * broadcasts it. This keeps the SDK decoupled from any off-chain\n * routing/quote surface.\n */\nexport type SubmitActionParams = {\n /** Source-chain id the wallet must be connected to. */\n chain: CHAIN;\n /** Destination address of the broadcast tx. */\n to: Address;\n /** Pre-encoded calldata. */\n data: Hex;\n /** Native-value payable amount; defaults to `0n`. */\n value?: bigint;\n};\n\n/**\n * Broadcast a pre-built periphery action tx from the caller's\n * `WalletClient`.\n *\n * Guarantees:\n * - Throws {@link EvmWriteError} immediately if\n * `wallet.chain?.id !== params.chain` — no RPC call is made.\n * - Throws {@link EvmWriteError} if `wallet.account` is not set.\n * - Forwards the payload to `wallet.sendTransaction` and returns the\n * resulting tx hash.\n * - Wraps any thrown viem write-path error\n * (`TransactionExecutionError`, `UserRejectedRequestError`,\n * `ChainMismatchError`, …) into an {@link EvmWriteError} via\n * {@link wrapWriteError}.\n *\n * The `mode` parameter is currently unused at runtime; it is accepted for\n * API symmetry with the readers and as a forward-compat hook for a future\n * mode-specific submission policy (e.g. DEV-only simulation, staging\n * retries). The `_` prefix marks it unused for the TypeScript checker.\n *\n * Non-goals (per plan guardrails):\n * - Does NOT sign — the caller brings a `WalletClient` wired to their\n * signer.\n * - Does NOT switch chains — callers are responsible for\n * `wallet.switchChain(...)`.\n * - Does NOT retry or manage nonces — delegated to the caller's wallet.\n */\nexport async function submitAction(\n wallet: WalletClient,\n params: SubmitActionParams,\n _mode: EnvModeWithConfig,\n): Promise<Hex> {\n if (wallet.chain?.id !== params.chain) {\n throw new EvmWriteError(\n \"submitAction\",\n `wallet chain ${wallet.chain?.id ?? \"undefined\"} != params.chain ${params.chain}`,\n );\n }\n\n try {\n const account = wallet.account;\n if (!account) {\n throw new EvmWriteError(\n \"submitAction\",\n \"wallet has no account; callers must provide a wallet with wallet.account set\",\n );\n }\n return await wallet.sendTransaction({\n to: params.to,\n data: params.data,\n value: params.value ?? 0n,\n chain: wallet.chain,\n account,\n });\n } catch (err) {\n // Preserve our own pre-flight guards verbatim — they are already\n // EvmWriteError instances and don't need re-wrapping.\n if (err instanceof EvmWriteError) throw err;\n throw wrapWriteError(err, \"submitAction\");\n }\n}\n\n/**\n * Broadcast a periphery *swap* action — thin wrapper around\n * {@link submitAction} that re-labels any unknown error as `submitSwap` to\n * aid log-line triage. Behaviourally identical to `submitAction`; shares\n * its pre-flight guards.\n */\nexport async function submitSwap(\n wallet: WalletClient,\n params: SubmitActionParams,\n mode: EnvModeWithConfig,\n): Promise<Hex> {\n try {\n return await submitAction(wallet, params, mode);\n } catch (err) {\n if (err instanceof EvmWriteError) throw err;\n throw wrapWriteError(err, \"submitSwap\");\n }\n}\n\n/**\n * Broadcast a periphery *approval* action (ERC-20 approve to the source\n * chain's periphery contract) — thin wrapper around {@link submitAction}.\n * See {@link submitSwap} for labeling rationale.\n */\nexport async function submitApproval(\n wallet: WalletClient,\n params: SubmitActionParams,\n mode: EnvModeWithConfig,\n): Promise<Hex> {\n try {\n return await submitAction(wallet, params, mode);\n } catch (err) {\n if (err instanceof EvmWriteError) throw err;\n throw wrapWriteError(err, \"submitApproval\");\n }\n}\n","import { decodeEventLog, type Log } from \"viem\";\nimport { KernelEventEmitterABI } from \"@skate-org/amm-bindings\";\nimport { EvmReadError } from \"../errors\";\n\n/**\n * Event names emitted by the Skate kernel's `KernelEventEmitter`, sourced\n * directly from `@skate-org/amm-bindings`.\n */\nexport type KernelEventName =\n | \"Burn\"\n | \"Collect\"\n | \"CollectProtocol\"\n | \"IncreaseObservationCardinalityNext\"\n | \"Initialize\"\n | \"Mint\"\n | \"PeripheryPoolAdded\"\n | \"PeripheryPoolChanged\"\n | \"PoolCreated\"\n | \"PoolDescriptionUpdated\"\n | \"SetFeeProtocol\"\n | \"Swap\";\n\n/** Exhaustive list of known kernel event names — same values as {@link KernelEventName}. */\nexport const KERNEL_EVENT_NAMES: readonly KernelEventName[] = [\n \"Burn\",\n \"Collect\",\n \"CollectProtocol\",\n \"IncreaseObservationCardinalityNext\",\n \"Initialize\",\n \"Mint\",\n \"PeripheryPoolAdded\",\n \"PeripheryPoolChanged\",\n \"PoolCreated\",\n \"PoolDescriptionUpdated\",\n \"SetFeeProtocol\",\n \"Swap\",\n];\n\n/**\n * A decoded kernel event — the event name, its named args, and the original\n * viem `Log` for context (tx hash, block number, etc.).\n */\nexport interface KernelParsedEvent {\n eventName: KernelEventName;\n args: Record<string, unknown>;\n log: Log;\n}\n\n/**\n * Decode a viem `Log` emitted by the Skate kernel's `KernelEventEmitter`.\n *\n * Throws {@link EvmReadError} if the log's topic0 is not a known kernel event\n * or if ABI decoding fails.\n */\nexport function parseKernelEventLog(log: Log): KernelParsedEvent {\n try {\n const decoded = decodeEventLog({\n abi: KernelEventEmitterABI,\n data: log.data,\n topics: log.topics,\n });\n return {\n eventName: decoded.eventName as KernelEventName,\n args: (decoded.args ?? {}) as Record<string, unknown>,\n log,\n };\n } catch (err) {\n const message = (err as { shortMessage?: string; message?: string })\n .shortMessage ??\n (err as { message?: string }).message ??\n String(err);\n throw new EvmReadError(\n \"parseKernelEventLog\",\n `failed to decode log: ${message}`,\n { cause: err as Error },\n );\n }\n}\n","import { decodeEventLog, type Log } from \"viem\";\nimport { PeripheryEventEmitterABI } from \"@skate-org/amm-bindings\";\nimport { EvmReadError } from \"../errors\";\n\n/**\n * Event names emitted by `PeripheryEventEmitter` on the source chain.\n */\nexport type PeripheryEventName =\n | \"AmountSettled\"\n | \"Burned\"\n | \"LiquidityDecreased\"\n | \"LiquidityIncreased\"\n | \"MintSettled\"\n | \"Minted\"\n | \"PoolCreated\"\n | \"PoolDeployed\"\n | \"Swapped\"\n | \"TransferredTo\";\n\n/** Exhaustive list of known periphery event names. */\nexport const PERIPHERY_EVENT_NAMES: readonly PeripheryEventName[] = [\n \"AmountSettled\",\n \"Burned\",\n \"LiquidityDecreased\",\n \"LiquidityIncreased\",\n \"MintSettled\",\n \"Minted\",\n \"PoolCreated\",\n \"PoolDeployed\",\n \"Swapped\",\n \"TransferredTo\",\n];\n\n/** A decoded periphery event — name, named args, and the original viem `Log`. */\nexport interface PeripheryParsedEvent {\n eventName: PeripheryEventName;\n args: Record<string, unknown>;\n log: Log;\n}\n\n/**\n * Decode a viem `Log` emitted by `PeripheryEventEmitter` on a source chain.\n *\n * Throws {@link EvmReadError} if the log's topic0 is not a known periphery\n * event or if ABI decoding fails.\n */\nexport function parsePeripheryEventLog(log: Log): PeripheryParsedEvent {\n try {\n const decoded = decodeEventLog({\n abi: PeripheryEventEmitterABI,\n data: log.data,\n topics: log.topics,\n });\n return {\n eventName: decoded.eventName as PeripheryEventName,\n args: (decoded.args ?? {}) as Record<string, unknown>,\n log,\n };\n } catch (err) {\n const message = (err as { shortMessage?: string; message?: string })\n .shortMessage ??\n (err as { message?: string }).message ??\n String(err);\n throw new EvmReadError(\n \"parsePeripheryEventLog\",\n `failed to decode log: ${message}`,\n { cause: err as Error },\n );\n }\n}\n","import type { Address, Log, PublicClient } from \"viem\";\nimport {\n KernelEventEmitterABI,\n PeripheryEventEmitterABI,\n} from \"@skate-org/amm-bindings\";\nimport {\n parseKernelEventLog,\n type KernelParsedEvent,\n} from \"./kernel\";\nimport {\n parsePeripheryEventLog,\n type PeripheryParsedEvent,\n} from \"./periphery\";\n\nexport interface EventSubscriptionOptions<E> {\n /** Called for each decoded event. */\n onEvent: (event: E) => void;\n /** Called when a log fails to decode (subscription stays alive). */\n onError?: (err: unknown) => void;\n}\n\n/**\n * Subscribe to kernel events emitted by the `KernelEventEmitter` contract\n * at `address`. Returns an unsubscribe function.\n *\n * Decode failures are surfaced via `opts.onError` (if provided) rather than\n * throwing — the subscription continues.\n */\nexport function watchKernelEvents(\n client: PublicClient,\n address: Address,\n opts: EventSubscriptionOptions<KernelParsedEvent>,\n): () => void {\n return client.watchContractEvent({\n abi: KernelEventEmitterABI,\n address,\n onLogs: (logs: Log[]) => {\n for (const log of logs) {\n try {\n opts.onEvent(parseKernelEventLog(log));\n } catch (err) {\n opts.onError?.(err);\n }\n }\n },\n });\n}\n\n/**\n * Subscribe to periphery events emitted by `PeripheryEventEmitter` at\n * `address` on the source chain the `client` is connected to.\n */\nexport function watchPeripheryEvents(\n client: PublicClient,\n address: Address,\n opts: EventSubscriptionOptions<PeripheryParsedEvent>,\n): () => void {\n return client.watchContractEvent({\n abi: PeripheryEventEmitterABI,\n address,\n onLogs: (logs: Log[]) => {\n for (const log of logs) {\n try {\n opts.onEvent(parsePeripheryEventLog(log));\n } catch (err) {\n opts.onError?.(err);\n }\n }\n },\n });\n}\n"],"mappings":"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","names":["normalizeMode","normalizeMode","normalizeMode","resolveClient","normalizeMode","decodeEventLog","decodeEventLog","KernelEventEmitterABI","PeripheryEventEmitterABI","KernelEventEmitterABI","PeripheryEventEmitterABI"]}
1
+ {"version":3,"sources":["../src/chain-clients.ts","../src/devConfig.ts","../src/errors.ts","../src/kernel/reader.ts","../src/kernel/_client.ts","../src/kernel/tickBitmap.ts","../src/kernel/lens.ts","../src/periphery/reader.ts","../src/periphery/submit.ts","../src/events/kernel.ts","../src/events/periphery.ts","../src/events/watch.ts"],"sourcesContent":["import {\n createPublicClient,\n defineChain,\n http,\n type Chain,\n type PublicClient,\n type Transport,\n} from \"viem\";\nimport { arbitrum } from \"viem/chains\";\nimport {\n BLOCK_EXPLORER,\n CHAIN,\n VM,\n vmTypeFromChain,\n normalizeMode,\n type EnvModeWithConfig,\n} from \"@skate-org/amm-core-v2\";\n\n/**\n * MegaETH chain definition — `@public`.\n *\n * Exported for callers who need to build their own viem `WalletClient` or\n * `PublicClient` against the same chain the SDK uses internally (e.g. wallet\n * integrations that construct a `WalletClient` ahead of calling\n * `submitAction`). Prefer {@link getKernelPublicClient} when you just need a\n * read client.\n *\n * viem ships a `megaeth` chain at id 4326, but with a different default RPC\n * than the one Skate uses for kernel reads. Define locally so we control the\n * RPC URL + block-explorer metadata and don't inherit unrelated op-stack\n * contract addresses.\n */\nexport const megaethChain: Chain = defineChain({\n id: 4326,\n name: \"MegaETH\",\n network: \"megaeth\",\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n rpcUrls: {\n default: { http: [\"https://mainnet.megaeth.com/rpc\"] },\n public: { http: [\"https://mainnet.megaeth.com/rpc\"] },\n },\n blockExplorers: {\n default: { name: \"Blockscout\", url: BLOCK_EXPLORER.MEGAETH },\n },\n});\n\n/**\n * Default public RPC URLs by chain id.\n *\n * Callers can override per-chain via `DevModeConfig.rpcEndpoints` or by\n * passing an explicit `transport` to the factory functions below.\n */\nconst DEFAULT_RPC: Partial<Record<CHAIN, string>> = {\n [CHAIN.MEGAETH]: \"https://mainnet.megaeth.com/rpc\",\n [CHAIN.ARBITRUM]: \"https://arb1.arbitrum.io/rpc\",\n};\n\n/**\n * Map a supported EVM `CHAIN` to a viem `Chain` definition.\n *\n * Only chains we actively support in Phase 2 are listed; unknown chains\n * return `undefined` and the caller throws.\n */\nfunction chainDefFor(chain: CHAIN): Chain | undefined {\n switch (chain) {\n case CHAIN.MEGAETH:\n return megaethChain;\n case CHAIN.ARBITRUM:\n return arbitrum;\n default:\n return undefined;\n }\n}\n\n/**\n * Resolve the RPC URL for a given chain under the precedence:\n * transport override (caller arg) > mode.config.rpcEndpoints[chain] > DEFAULT_RPC[chain]\n * Returns `undefined` if none is set — callers must have already decided whether\n * to use a caller-supplied transport.\n */\nfunction resolveRpcUrl(\n chain: CHAIN,\n mode: EnvModeWithConfig,\n): string | undefined {\n const { config } = normalizeMode(mode);\n return config?.rpcEndpoints?.[chain] ?? DEFAULT_RPC[chain];\n}\n\n/**\n * Return a fresh `PublicClient` bound to the MegaETH kernel chain.\n *\n * MegaETH is the kernel chain for all environment modes (DEV/STAGING/\n * PRODUCTION) in SDK v2. The `mode` parameter is accepted for API\n * symmetry with the rest of the SDK and as a forward-compatible extension\n * point (e.g. a future testnet kernel).\n *\n * Pure — no singletons, no caching. Pass a custom `transport` to override\n * the default RPC (useful for tests and custom RPC providers).\n */\nexport function getKernelPublicClient(\n mode: EnvModeWithConfig,\n transport?: Transport,\n): PublicClient {\n return createPublicClient({\n chain: megaethChain,\n transport: transport ?? http(resolveRpcUrl(CHAIN.MEGAETH, mode)),\n });\n}\n\n/**\n * Return a fresh `PublicClient` for a source EVM chain (e.g. Arbitrum).\n *\n * Throws a descriptive `Error` when:\n * - `chain` is not an EVM chain (per `vmTypeFromChain`); or\n * - no viem chain definition is registered for `chain`; or\n * - no default RPC URL is configured for `chain` and no `transport` override\n * was provided.\n *\n * Pure — no singletons, no caching.\n */\nexport function getSourcePublicClient(\n chain: CHAIN,\n mode: EnvModeWithConfig,\n transport?: Transport,\n): PublicClient {\n if (vmTypeFromChain(chain) !== VM.EVM) {\n throw new Error(\n `getSourcePublicClient: chain ${chain} is not an EVM chain`,\n );\n }\n const chainDef = chainDefFor(chain);\n if (!chainDef) {\n throw new Error(\n `getSourcePublicClient: no chain definition registered for chain ${chain}`,\n );\n }\n const rpc = resolveRpcUrl(chain, mode);\n if (!rpc && !transport) {\n throw new Error(\n `getSourcePublicClient: no default or override RPC configured for chain ${chain}; pass a transport override or set DevModeConfig.rpcEndpoints[${chain}]`,\n );\n }\n return createPublicClient({\n chain: chainDef,\n transport: transport ?? http(rpc),\n });\n}\n","import type { DevModeConfig } from \"@skate-org/amm-core-v2\";\n\n/** Default DEV api endpoint — matches Phase 1's api client default. */\nexport const DEFAULT_DEV_API_ENDPOINT =\n \"https://dev.api.skatechain.org/amm-action-v2\";\n\n/**\n * Convenience factory for the `{ mode: \"DEV\"; config: DevModeConfig }` tuple.\n *\n * Reduces ceremony at call sites that want to override a single field (e.g.,\n * `rpcEndpoints`) without reconstructing the full object:\n *\n * ```ts\n * const mode = createDevConfig({\n * rpcEndpoints: { [CHAIN.MEGAETH]: \"https://my-private-megaeth/rpc\" },\n * });\n * submitAction(wallet, params, mode);\n * ```\n *\n * Pass nothing to use all defaults.\n */\nexport function createDevConfig(\n overrides: Partial<DevModeConfig> = {},\n): { mode: \"DEV\"; config: DevModeConfig } {\n return {\n mode: \"DEV\",\n config: {\n apiEndpoint: overrides.apiEndpoint ?? DEFAULT_DEV_API_ENDPOINT,\n ...(overrides.rpcEndpoints\n ? { rpcEndpoints: overrides.rpcEndpoints }\n : {}),\n },\n };\n}\n","/**\n * Shared error types for the `@skate-org/amm-evm-v2` package.\n *\n * `EvmReadError` / `EvmWriteError` extend `SdkError` (from core) so callers\n * can `instanceof SdkError` to catch any SDK-origin error without needing\n * to know the specific subclass.\n */\n\nimport { SdkError } from \"@skate-org/amm-core-v2\";\n\n/** SDK-level error thrown when an EVM read reverts or decodes badly. */\nexport class EvmReadError extends SdkError {\n override readonly name: string = \"EvmReadError\";\n readonly functionName: string;\n\n constructor(functionName: string, message: string, options?: ErrorOptions) {\n super(`${functionName}: ${message}`, options);\n this.functionName = functionName;\n }\n}\n\n/**\n * SDK-level error thrown when an EVM write (broadcast) fails.\n *\n * Symmetric with {@link EvmReadError}, but covers the write path: viem's\n * `TransactionExecutionError`, `UserRejectedRequestError`,\n * `ChainMismatchError`, `ChainDisconnectedError`, as well as submitter\n * pre-flight guards (e.g. wrong-chain, missing account).\n */\nexport class EvmWriteError extends SdkError {\n override readonly name: string = \"EvmWriteError\";\n readonly functionName: string;\n\n constructor(functionName: string, message: string, options?: ErrorOptions) {\n super(`${functionName}: ${message}`, options);\n this.functionName = functionName;\n }\n}\n\n/**\n * Wrap any error from an EVM read into `EvmReadError`. Viem always wraps\n * revert-path errors in `ContractFunctionExecutionError` (see\n * `viem/utils/errors/getContractError`), so we check both the outer name and\n * the `.cause` chain for `ContractFunctionRevertedError` /\n * `ContractFunctionZeroDataError`.\n *\n * Shared by `kernel/reader.ts` and `periphery/reader.ts` — depends only on\n * `EvmReadError` and generic Error inspection (no reader-module imports), so\n * it is safe from circular-import concerns.\n */\nexport function wrapReadError(\n err: unknown,\n functionName: string,\n): EvmReadError {\n const outerName = (err as { name?: string } | null)?.name;\n const causeName = (err as { cause?: { name?: string } } | null)?.cause?.name;\n const message =\n (err as { shortMessage?: string } | null)?.shortMessage ??\n (err as { message?: string } | null)?.message ??\n String(err);\n const isViemContractError =\n outerName === \"ContractFunctionExecutionError\" ||\n outerName === \"ContractFunctionRevertedError\" ||\n outerName === \"ContractFunctionZeroDataError\" ||\n causeName === \"ContractFunctionRevertedError\" ||\n causeName === \"ContractFunctionZeroDataError\";\n if (isViemContractError) {\n return new EvmReadError(functionName, `reverted: ${message}`, {\n cause: err as Error,\n });\n }\n return new EvmReadError(functionName, message, { cause: err as Error });\n}\n\n/**\n * Wrap any error from an EVM write-path call (typically\n * `WalletClient.sendTransaction`) into `EvmWriteError`.\n *\n * Any thrown error reaching a submitter is treated as a write failure. If\n * we later want to differentiate known viem write errors\n * (`TransactionExecutionError`, `UserRejectedRequestError`,\n * `ChainMismatchError`, `ChainDisconnectedError`) from unknown errors —\n * e.g. to prefix the message or re-throw unknowns raw — that dispatch goes\n * here. Keeping the single-return shape until a concrete caller need\n * surfaces.\n */\nexport function wrapWriteError(\n err: unknown,\n functionName: string,\n): EvmWriteError {\n const message =\n (err as { shortMessage?: string } | null)?.shortMessage ??\n (err as { message?: string } | null)?.message ??\n String(err);\n return new EvmWriteError(functionName, message, { cause: err as Error });\n}\n","import type { PublicClient } from \"viem\";\nimport {\n KernelManagerABI,\n KernelPoolABI,\n} from \"@skate-org/amm-bindings\";\nimport {\n KernelManagerAddress,\n normalizeMode,\n type EnvModeWithConfig,\n getAmount0Delta,\n getAmount1Delta,\n getSqrtRatioAtTick,\n} from \"@skate-org/amm-core-v2\";\nimport { wrapReadError } from \"../errors\";\nimport { resolveKernelClient } from \"./_client\";\n\n/** Decoded kernel-pool `slot0` state (named fields, per the ABI tuple). */\nexport interface KernelSlot0 {\n sqrtPriceX96: bigint;\n tick: number;\n observationIndex: number;\n observationCardinality: number;\n observationCardinalityNext: number;\n feeProtocol: number;\n unlocked: boolean;\n}\n\n/** Decoded pool state returned by `readPool`. */\nexport interface KernelPoolState {\n slot0: KernelSlot0;\n liquidity: bigint;\n}\n\n/** Decoded NFT position returned by `readPosition`. */\nexport interface KernelNftPosition {\n pool: `0x${string}`;\n tickLower: number;\n tickUpper: number;\n liquidity: bigint;\n feeGrowthInside0LastX128: bigint;\n feeGrowthInside1LastX128: bigint;\n tokensOwed0: bigint;\n tokensOwed1: bigint;\n}\n\n/** Decoded kernel-pool `ticks(tick)` struct. */\nexport interface KernelTick {\n liquidityGross: bigint;\n liquidityNet: bigint;\n feeGrowthOutside0X128: bigint;\n feeGrowthOutside1X128: bigint;\n tickCumulativeOutside: bigint;\n secondsPerLiquidityOutsideX128: bigint;\n secondsOutside: number;\n initialized: boolean;\n}\n\n/**\n * Read `slot0` and `liquidity` from a kernel pool. Returns both in a single\n * object; the reads are fired in parallel.\n *\n * The `client` optional parameter is the standard test-injection point.\n */\nexport async function readPool(\n kernelPool: `0x${string}`,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<KernelPoolState> {\n const c = resolveKernelClient(mode, client);\n try {\n const [slot0, liquidity] = await Promise.all([\n c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"slot0\",\n }),\n c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"liquidity\",\n }),\n ]);\n // Viem returns named outputs as a positional tuple (array) when every\n // output has a name — normalize to a named-field object here so callers\n // don't depend on viem's tuple/object split.\n const s0 = slot0 as readonly [\n bigint,\n number,\n number,\n number,\n number,\n number,\n boolean,\n ];\n return {\n slot0: {\n sqrtPriceX96: s0[0],\n tick: s0[1],\n observationIndex: s0[2],\n observationCardinality: s0[3],\n observationCardinalityNext: s0[4],\n feeProtocol: s0[5],\n unlocked: s0[6],\n },\n liquidity: liquidity as bigint,\n };\n } catch (err) {\n throw wrapReadError(err, \"readPool\");\n }\n}\n\n/**\n * Read an NFT position by token id from the kernel manager.\n *\n * Calls `KernelManager.nftPositions(tokenId)` — per the ABI this returns a\n * `DataTypes.NFTPosition` tuple including `pool`, `tickLower`, `tickUpper`,\n * `liquidity`, fee growth, and tokens owed.\n */\nexport async function readPosition(\n tokenId: bigint,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<KernelNftPosition> {\n const { mode: baseMode } = normalizeMode(mode);\n const manager = KernelManagerAddress(baseMode);\n const c = resolveKernelClient(mode, client);\n try {\n const raw = (await c.readContract({\n address: manager,\n abi: KernelManagerABI,\n functionName: \"nftPositions\",\n args: [tokenId],\n })) as unknown;\n // Accept either a positional tuple or an already-named object from\n // viem — normalize to a named-field object, mirroring readPool's\n // defensive remap. Viem's decoding of named-components tuples is\n // stable today (object form), but this guards against future\n // restructuring.\n const asTuple = Array.isArray(raw)\n ? (raw as unknown as readonly [\n `0x${string}`,\n number,\n number,\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n ])\n : null;\n if (asTuple) {\n return {\n pool: asTuple[0],\n tickLower: asTuple[1],\n tickUpper: asTuple[2],\n liquidity: asTuple[3],\n feeGrowthInside0LastX128: asTuple[4],\n feeGrowthInside1LastX128: asTuple[5],\n tokensOwed0: asTuple[6],\n tokensOwed1: asTuple[7],\n };\n }\n return raw as KernelNftPosition;\n } catch (err) {\n throw wrapReadError(err, \"readPosition\");\n }\n}\n\n/**\n * Read a kernel-pool tick-bitmap word (`tickBitmap(int16 wordPos)`).\n *\n * Returns the raw `uint256` word as a bigint. A bit-decoder that expands a\n * word into populated tick indexes is intentionally not shipped in 0.2.0 —\n * flag as an open question for Phase 3 if a caller wants it.\n */\nexport async function readTickBitmap(\n kernelPool: `0x${string}`,\n wordPos: number,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<bigint> {\n const c = resolveKernelClient(mode, client);\n try {\n const word = await c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"tickBitmap\",\n args: [wordPos],\n });\n return word as bigint;\n } catch (err) {\n throw wrapReadError(err, \"readTickBitmap\");\n }\n}\n\n/** Read the `ticks(tick)` struct from a kernel pool. */\nexport async function readTick(\n kernelPool: `0x${string}`,\n tick: number,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<KernelTick> {\n const c = resolveKernelClient(mode, client);\n try {\n const raw = (await c.readContract({\n address: kernelPool,\n abi: KernelPoolABI,\n functionName: \"ticks\",\n args: [tick],\n })) as readonly [\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n bigint,\n number,\n boolean,\n ];\n return {\n liquidityGross: raw[0],\n liquidityNet: raw[1],\n feeGrowthOutside0X128: raw[2],\n feeGrowthOutside1X128: raw[3],\n tickCumulativeOutside: raw[4],\n secondsPerLiquidityOutsideX128: raw[5],\n secondsOutside: raw[6],\n initialized: raw[7],\n };\n } catch (err) {\n throw wrapReadError(err, \"readTick\");\n }\n}\n\n/**\n * Compute `{amount0, amount1}` for an NFT position using the Group 3 math.\n *\n * Reads the position (to learn `pool`, `tickLower`, `tickUpper`,\n * `liquidity`) and the pool's `slot0`, then splits based on whether the\n * current tick is below, inside, or above the position range — mirroring\n * `PositionValue.principal` from Uniswap v3 periphery.\n */\nexport async function computePositionAmounts(\n tokenId: bigint,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<{ amount0: bigint; amount1: bigint }> {\n const c = resolveKernelClient(mode, client);\n const position = await readPosition(tokenId, mode, c);\n const { slot0 } = await readPool(position.pool, mode, c);\n\n const sqrtLower = getSqrtRatioAtTick(position.tickLower);\n const sqrtUpper = getSqrtRatioAtTick(position.tickUpper);\n\n if (slot0.tick < position.tickLower) {\n return {\n amount0: getAmount0Delta(sqrtLower, sqrtUpper, position.liquidity, false),\n amount1: 0n,\n };\n }\n if (slot0.tick >= position.tickUpper) {\n return {\n amount0: 0n,\n amount1: getAmount1Delta(sqrtLower, sqrtUpper, position.liquidity, false),\n };\n }\n return {\n amount0: getAmount0Delta(\n slot0.sqrtPriceX96,\n sqrtUpper,\n position.liquidity,\n false,\n ),\n amount1: getAmount1Delta(\n sqrtLower,\n slot0.sqrtPriceX96,\n position.liquidity,\n false,\n ),\n };\n}\n","import type { PublicClient } from \"viem\";\nimport type { EnvModeWithConfig } from \"@skate-org/amm-core-v2\";\nimport { getKernelPublicClient } from \"../chain-clients\";\n\n/**\n * Return the caller-provided client if present, otherwise build a fresh\n * MegaETH kernel client for the given mode. Shared by readers + lens\n * helpers; intentionally unexported from the package barrel.\n */\nexport function resolveKernelClient(\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): PublicClient {\n return client ?? getKernelPublicClient(mode);\n}\n","/**\n * Decode a single Uniswap-v3 tick-bitmap `uint256` word into the list of\n * real (non-compressed) ticks it marks as initialized.\n *\n * A tick bitmap word covers 256 compressed ticks. For a given `wordPos`\n * (int16) the word spans compressed ticks `wordPos * 256` through\n * `(wordPos + 1) * 256 - 1`, and bit `k` (0..255) corresponds to the\n * compressed tick `wordPos * 256 + k`. The real tick at bit `k` is\n * `(wordPos * 256 + k) * tickSpacing`.\n *\n * Intended composition with the reader:\n *\n * ```ts\n * const word = await readTickBitmap(pool, wordPos, mode);\n * const ticks = decodeTickBitmapWord(word, wordPos, tickSpacing);\n * ```\n *\n * Pure function: no network, no viem, no external deps.\n *\n * @param word The 256-bit bitmap word returned by PoolAbi.tickBitmap(int16).\n * @param wordPos The int16 word position (-128 .. 127 per Uniswap, but\n * we accept any safe-integer int16-shaped value).\n * @param tickSpacing The pool's tickSpacing (positive integer, typically 1,\n * 10, 60, 200, etc.).\n * @returns Real ticks whose bits are set in the word, ascending.\n *\n * @throws {RangeError} if `tickSpacing <= 0` or if `wordPos` is not a safe integer.\n */\nexport function decodeTickBitmapWord(\n word: bigint,\n wordPos: number,\n tickSpacing: number,\n): number[] {\n if (!Number.isSafeInteger(wordPos)) {\n throw new RangeError(\n `decodeTickBitmapWord: wordPos must be a safe integer, got ${wordPos}`,\n );\n }\n if (!Number.isSafeInteger(tickSpacing) || tickSpacing <= 0) {\n throw new RangeError(\n `decodeTickBitmapWord: tickSpacing must be a positive integer, got ${tickSpacing}`,\n );\n }\n const result: number[] = [];\n // wordPos * 256 gives the base compressed-tick of this word. Each set bit k\n // contributes compressed-tick (wordPos * 256 + k), which becomes real tick\n // (wordPos * 256 + k) * tickSpacing.\n const base = wordPos * 256;\n for (let k = 0; k < 256; k++) {\n if (((word >> BigInt(k)) & 1n) === 1n) {\n result.push((base + k) * tickSpacing);\n }\n }\n return result;\n}\n","import type { PublicClient } from \"viem\";\nimport { KernelManagerABI } from \"@skate-org/amm-bindings\";\nimport {\n KernelManagerAddress,\n normalizeMode,\n type EnvModeWithConfig,\n} from \"@skate-org/amm-core-v2\";\nimport { wrapReadError } from \"../errors\";\nimport { resolveKernelClient } from \"./_client\";\n\n/**\n * Kernel lens (simulate) helpers — wrap KernelManager's `lens*` functions as\n * static-call simulations. Lens functions are marked nonpayable in the ABI,\n * but viem's `simulateContract` evaluates them with `eth_call`, so they\n * reuse the same client + RPC plumbing as the readers and never produce a\n * transaction.\n *\n * Errors funnel through `wrapReadError`: lens calls share the read-path\n * error model (revert reasons + RPC failures), and tagging them as \"writes\"\n * would be misleading since no state changes.\n */\n\nexport interface SimulateSwapParams {\n /** Kernel-pool address (EVM) */\n pool: `0x${string}`;\n /** Recipient encoded as bytes32 (use `toBytes32Address` for cross-VM) */\n recipient: `0x${string}`;\n zeroForOne: boolean;\n /** Positive = exactInput, negative = exactOutput, per Uniswap v3 convention */\n amountSpecified: bigint;\n sqrtPriceLimitX96: bigint;\n}\n\nexport interface SimulateSwapResult {\n amount0: bigint;\n amount1: bigint;\n sqrtPriceX96After: bigint;\n returnData: `0x${string}`;\n}\n\nexport async function simulateSwap(\n params: SimulateSwapParams,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<SimulateSwapResult> {\n const { mode: baseMode } = normalizeMode(mode);\n const c = resolveKernelClient(mode, client);\n try {\n const out = await c.simulateContract({\n address: KernelManagerAddress(baseMode),\n abi: KernelManagerABI,\n functionName: \"lensSwap\",\n args: [\n params.pool,\n params.recipient,\n params.zeroForOne,\n params.amountSpecified,\n params.sqrtPriceLimitX96,\n ],\n });\n const [amount0, amount1, sqrtPriceX96After, returnData] = out.result as readonly [\n bigint,\n bigint,\n bigint,\n `0x${string}`,\n ];\n return { amount0, amount1, sqrtPriceX96After, returnData };\n } catch (err) {\n throw wrapReadError(err, \"simulateSwap\");\n }\n}\n\nexport interface SimulateMintParams {\n pool: `0x${string}`;\n /** Recipient encoded as bytes32 */\n recipient: `0x${string}`;\n tickLower: number;\n tickUpper: number;\n amount0: bigint;\n amount1: bigint;\n /** Caller-supplied callback data (passed to `IKernelMintCallback`) */\n data: `0x${string}`;\n}\n\nexport interface SimulateMintResult {\n amount0Used: bigint;\n amount1Used: bigint;\n liquidityAmount: bigint;\n returnData: `0x${string}`;\n}\n\nexport async function simulateMint(\n params: SimulateMintParams,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<SimulateMintResult> {\n const { mode: baseMode } = normalizeMode(mode);\n const c = resolveKernelClient(mode, client);\n try {\n const out = await c.simulateContract({\n address: KernelManagerAddress(baseMode),\n abi: KernelManagerABI,\n functionName: \"lensMint\",\n args: [\n params.pool,\n params.recipient,\n params.tickLower,\n params.tickUpper,\n params.amount0,\n params.amount1,\n params.data,\n ],\n });\n const [amount0Used, amount1Used, liquidityAmount, returnData] = out.result as readonly [\n bigint,\n bigint,\n bigint,\n `0x${string}`,\n ];\n return { amount0Used, amount1Used, liquidityAmount, returnData };\n } catch (err) {\n throw wrapReadError(err, \"simulateMint\");\n }\n}\n\nexport interface SimulateBurnParams {\n pool: `0x${string}`;\n /** Recipient encoded as bytes32 */\n recipient: `0x${string}`;\n tickLower: number;\n tickUpper: number;\n /** Liquidity amount to burn (uint128). */\n amount: bigint;\n}\n\nexport interface SimulateBurnResult {\n amount0: bigint;\n amount1: bigint;\n returnData: `0x${string}`;\n}\n\nexport async function simulateBurn(\n params: SimulateBurnParams,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<SimulateBurnResult> {\n const { mode: baseMode } = normalizeMode(mode);\n const c = resolveKernelClient(mode, client);\n try {\n const out = await c.simulateContract({\n address: KernelManagerAddress(baseMode),\n abi: KernelManagerABI,\n functionName: \"lensBurn\",\n args: [\n params.pool,\n params.recipient,\n params.tickLower,\n params.tickUpper,\n params.amount,\n ],\n });\n const [amount0, amount1, returnData] = out.result as readonly [\n bigint,\n bigint,\n `0x${string}`,\n ];\n return { amount0, amount1, returnData };\n } catch (err) {\n throw wrapReadError(err, \"simulateBurn\");\n }\n}\n\nexport interface SimulateDecreaseLiquidityParams {\n /** NFT position id (v2 positions). */\n tokenId: bigint;\n /** Liquidity amount to remove (uint128). */\n liquidity: bigint;\n}\n\nexport interface SimulateDecreaseLiquidityResult {\n amount0: bigint;\n amount1: bigint;\n returnData: `0x${string}`;\n}\n\nexport async function simulateDecreaseLiquidity(\n params: SimulateDecreaseLiquidityParams,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<SimulateDecreaseLiquidityResult> {\n const { mode: baseMode } = normalizeMode(mode);\n const c = resolveKernelClient(mode, client);\n try {\n const out = await c.simulateContract({\n address: KernelManagerAddress(baseMode),\n abi: KernelManagerABI,\n functionName: \"lensDecreaseLiquidity\",\n args: [params.tokenId, params.liquidity],\n });\n const [amount0, amount1, returnData] = out.result as readonly [\n bigint,\n bigint,\n `0x${string}`,\n ];\n return { amount0, amount1, returnData };\n } catch (err) {\n throw wrapReadError(err, \"simulateDecreaseLiquidity\");\n }\n}\n","import type { PublicClient } from \"viem\";\nimport { PeripheryPoolABI } from \"@skate-org/amm-bindings\";\nimport {\n CHAIN,\n getPeripheryDetailsByKernelPoolAndChainId,\n normalizeMode,\n type EnvModeWithConfig,\n type EvmChain,\n} from \"@skate-org/amm-core-v2\";\nimport { getSourcePublicClient } from \"../chain-clients\";\nimport { EvmReadError, wrapReadError } from \"../errors\";\n\n/**\n * Decoded `balancesAvailable()` tuple on a periphery pool — per the\n * `PeripheryPoolABI` this returns `(uint256 amount0Available, uint256 amount1Available)`.\n */\nexport interface PeripheryBalancesAvailable {\n amount0Available: bigint;\n amount1Available: bigint;\n}\n\n/**\n * Decoded periphery-pool state assembled by {@link readPeripheryPool}.\n *\n * The periphery pool does **not** expose a `slot0`-style view — pricing\n * state lives on the kernel pool on MegaETH (see `readPool`). What the\n * periphery pool does expose is: the configured pair\n * (`token0`, `token1`, `fee`, `kernelPool` reference), the escrowed\n * in-pool settlement balances (`balancesAvailable`), and the two\n * `dustAmount{0,1}` accumulators. Together these are enough for a\n * source-chain caller to reason about pending settlement and dust.\n */\nexport interface PeripheryPoolState {\n /** Periphery pool contract address on the source chain. */\n address: `0x${string}`;\n /** Source-chain ERC-20 address for token0. */\n token0: `0x${string}`;\n /** Source-chain ERC-20 address for token1. */\n token1: `0x${string}`;\n /** Fee tier (uint24) the periphery pool was deployed with. */\n fee: number;\n /** Address of the paired kernel pool on MegaETH. */\n kernelPool: `0x${string}`;\n /** Aggregate in-pool balances available for settlement. */\n balancesAvailable: PeripheryBalancesAvailable;\n /** token0 dust accumulator. */\n dustAmount0: bigint;\n /** token1 dust accumulator. */\n dustAmount1: bigint;\n}\n\n/**\n * Return the caller-provided client, or build a fresh source-chain\n * client for `chain` under the given `mode`. Mirrors the kernel reader\n * injection pattern.\n */\nfunction resolveClient(\n chain: CHAIN,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): PublicClient {\n return client ?? getSourcePublicClient(chain, mode);\n}\n\n/**\n * Read the assembled periphery-pool state on a source chain.\n *\n * Resolves the periphery pool address via\n * `getPeripheryDetailsByKernelPoolAndChainId` (from\n * `@skate-org/amm-core-v2`) — **no addresses are hardcoded here**. If the\n * `(kernelPool, chain, mode)` triple has no entry in the aggregated pool\n * catalog, throws with the triple in the message for debuggability.\n *\n * All sub-reads are fired in parallel and normalized to named fields.\n */\nexport async function readPeripheryPool(\n chain: CHAIN,\n kernelPool: `0x${string}`,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<PeripheryPoolState> {\n const { mode: baseMode } = normalizeMode(mode);\n const details = getPeripheryDetailsByKernelPoolAndChainId(\n kernelPool,\n chain as EvmChain,\n baseMode,\n );\n if (!details) {\n throw new EvmReadError(\n \"readPeripheryPool\",\n `no periphery entry for kernelPool=${kernelPool} chain=${chain} mode=${baseMode}`,\n );\n }\n const address = details.address;\n const c = resolveClient(chain, mode, client);\n try {\n const [\n balancesAvailableRaw,\n dust0,\n dust1,\n token0,\n token1,\n fee,\n kPool,\n ] = await Promise.all([\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"balancesAvailable\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"dustAmount0\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"dustAmount1\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"token0\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"token1\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"fee\",\n }),\n c.readContract({\n address,\n abi: PeripheryPoolABI,\n functionName: \"kernelPool\",\n }),\n ]);\n // Viem decodes multi-output tuples with all-named outputs as a\n // positional tuple — normalize to a named-field object.\n const bAvail = balancesAvailableRaw as readonly [bigint, bigint];\n return {\n address,\n token0: token0 as `0x${string}`,\n token1: token1 as `0x${string}`,\n fee: fee as number,\n kernelPool: kPool as `0x${string}`,\n balancesAvailable: {\n amount0Available: bAvail[0],\n amount1Available: bAvail[1],\n },\n dustAmount0: dust0 as bigint,\n dustAmount1: dust1 as bigint,\n };\n } catch (err) {\n throw wrapReadError(err, \"readPeripheryPool\");\n }\n}\n\n/**\n * Decoded `usersData(address)` tuple on a periphery pool — per the\n * `PeripheryPoolABI` this returns `(uint256 amount0, uint256 amount1)`\n * representing the user's per-pool in-flight token balances on the\n * source chain.\n */\nexport interface UserPoolBalances {\n amount0: bigint;\n amount1: bigint;\n}\n\n/**\n * Read a user's per-pool in-flight balances on a source chain.\n *\n * Resolves the periphery pool address via\n * `getPeripheryDetailsByKernelPoolAndChainId` (no hardcoded addresses)\n * and calls `PeripheryPool.usersData(user)` which returns\n * `(uint256 amount0, uint256 amount1)`.\n *\n * Replaces the previous `readEscrowBalance(chain, user, token)` stub,\n * whose `(user, token)` keying did not match any available ABI view —\n * escrow state is keyed per-(pool, user), not per-(user, token).\n */\nexport async function readUserPoolBalances(\n chain: CHAIN,\n kernelPool: `0x${string}`,\n user: `0x${string}`,\n mode: EnvModeWithConfig,\n client?: PublicClient,\n): Promise<UserPoolBalances> {\n const { mode: baseMode } = normalizeMode(mode);\n const details = getPeripheryDetailsByKernelPoolAndChainId(\n kernelPool,\n chain as EvmChain,\n baseMode,\n );\n if (!details) {\n throw new EvmReadError(\n \"readUserPoolBalances\",\n `no periphery entry for kernelPool=${kernelPool} chain=${chain} mode=${baseMode}`,\n );\n }\n const c = resolveClient(chain, mode, client);\n try {\n const raw = (await c.readContract({\n address: details.address,\n abi: PeripheryPoolABI,\n functionName: \"usersData\",\n args: [user],\n })) as unknown;\n // `usersData` returns `(uint256 amount0, uint256 amount1)`.\n // Viem decodes tuples with all-named outputs as a positional tuple;\n // handle both the positional and (older) object shapes defensively.\n if (Array.isArray(raw)) {\n const tuple = raw as unknown as readonly [bigint, bigint];\n return { amount0: tuple[0], amount1: tuple[1] };\n }\n const asObject = raw as { amount0: bigint; amount1: bigint };\n return { amount0: asObject.amount0, amount1: asObject.amount1 };\n } catch (err) {\n throw wrapReadError(err, \"readUserPoolBalances\");\n }\n}\n","import type { Address, Hex, WalletClient } from \"viem\";\nimport type { CHAIN, EnvModeWithConfig } from \"@skate-org/amm-core-v2\";\nimport { EvmWriteError, wrapWriteError } from \"../errors\";\n\n/**\n * Pre-built source-chain transaction payload accepted by\n * {@link submitAction}.\n *\n * The SDK does **not** fabricate calldata in Group 6 — callers build the\n * payload (e.g. from a quote's `serializedCall`) and this submitter only\n * broadcasts it. This keeps the SDK decoupled from any off-chain\n * routing/quote surface.\n */\nexport type SubmitActionParams = {\n /** Source-chain id the wallet must be connected to. */\n chain: CHAIN;\n /** Destination address of the broadcast tx. */\n to: Address;\n /** Pre-encoded calldata. */\n data: Hex;\n /** Native-value payable amount; defaults to `0n`. */\n value?: bigint;\n};\n\n/**\n * Broadcast a pre-built periphery action tx from the caller's\n * `WalletClient`.\n *\n * Guarantees:\n * - Throws {@link EvmWriteError} immediately if\n * `wallet.chain?.id !== params.chain` — no RPC call is made.\n * - Throws {@link EvmWriteError} if `wallet.account` is not set.\n * - Forwards the payload to `wallet.sendTransaction` and returns the\n * resulting tx hash.\n * - Wraps any thrown viem write-path error\n * (`TransactionExecutionError`, `UserRejectedRequestError`,\n * `ChainMismatchError`, …) into an {@link EvmWriteError} via\n * {@link wrapWriteError}.\n *\n * The `mode` parameter is currently unused at runtime; it is accepted for\n * API symmetry with the readers and as a forward-compat hook for a future\n * mode-specific submission policy (e.g. DEV-only simulation, staging\n * retries). The `_` prefix marks it unused for the TypeScript checker.\n *\n * Non-goals (per plan guardrails):\n * - Does NOT sign — the caller brings a `WalletClient` wired to their\n * signer.\n * - Does NOT switch chains — callers are responsible for\n * `wallet.switchChain(...)`.\n * - Does NOT retry or manage nonces — delegated to the caller's wallet.\n */\nexport async function submitAction(\n wallet: WalletClient,\n params: SubmitActionParams,\n _mode: EnvModeWithConfig,\n): Promise<Hex> {\n if (wallet.chain?.id !== params.chain) {\n throw new EvmWriteError(\n \"submitAction\",\n `wallet chain ${wallet.chain?.id ?? \"undefined\"} != params.chain ${params.chain}`,\n );\n }\n\n try {\n const account = wallet.account;\n if (!account) {\n throw new EvmWriteError(\n \"submitAction\",\n \"wallet has no account; callers must provide a wallet with wallet.account set\",\n );\n }\n return await wallet.sendTransaction({\n to: params.to,\n data: params.data,\n value: params.value ?? 0n,\n chain: wallet.chain,\n account,\n });\n } catch (err) {\n // Preserve our own pre-flight guards verbatim — they are already\n // EvmWriteError instances and don't need re-wrapping.\n if (err instanceof EvmWriteError) throw err;\n throw wrapWriteError(err, \"submitAction\");\n }\n}\n\n/**\n * Broadcast a periphery *swap* action — thin wrapper around\n * {@link submitAction} that re-labels any unknown error as `submitSwap` to\n * aid log-line triage. Behaviourally identical to `submitAction`; shares\n * its pre-flight guards.\n */\nexport async function submitSwap(\n wallet: WalletClient,\n params: SubmitActionParams,\n mode: EnvModeWithConfig,\n): Promise<Hex> {\n try {\n return await submitAction(wallet, params, mode);\n } catch (err) {\n if (err instanceof EvmWriteError) throw err;\n throw wrapWriteError(err, \"submitSwap\");\n }\n}\n\n/**\n * Broadcast a periphery *approval* action (ERC-20 approve to the source\n * chain's periphery contract) — thin wrapper around {@link submitAction}.\n * See {@link submitSwap} for labeling rationale.\n */\nexport async function submitApproval(\n wallet: WalletClient,\n params: SubmitActionParams,\n mode: EnvModeWithConfig,\n): Promise<Hex> {\n try {\n return await submitAction(wallet, params, mode);\n } catch (err) {\n if (err instanceof EvmWriteError) throw err;\n throw wrapWriteError(err, \"submitApproval\");\n }\n}\n","import { decodeEventLog, type Log } from \"viem\";\nimport { KernelEventEmitterABI } from \"@skate-org/amm-bindings\";\nimport { EvmReadError } from \"../errors\";\n\n/**\n * Event names emitted by the Skate kernel's `KernelEventEmitter`, sourced\n * directly from `@skate-org/amm-bindings`.\n */\nexport type KernelEventName =\n | \"Burn\"\n | \"Collect\"\n | \"CollectProtocol\"\n | \"IncreaseObservationCardinalityNext\"\n | \"Initialize\"\n | \"Mint\"\n | \"PeripheryPoolAdded\"\n | \"PeripheryPoolChanged\"\n | \"PoolCreated\"\n | \"PoolDescriptionUpdated\"\n | \"SetFeeProtocol\"\n | \"Swap\";\n\n/** Exhaustive list of known kernel event names — same values as {@link KernelEventName}. */\nexport const KERNEL_EVENT_NAMES: readonly KernelEventName[] = [\n \"Burn\",\n \"Collect\",\n \"CollectProtocol\",\n \"IncreaseObservationCardinalityNext\",\n \"Initialize\",\n \"Mint\",\n \"PeripheryPoolAdded\",\n \"PeripheryPoolChanged\",\n \"PoolCreated\",\n \"PoolDescriptionUpdated\",\n \"SetFeeProtocol\",\n \"Swap\",\n];\n\n/**\n * A decoded kernel event — the event name, its named args, and the original\n * viem `Log` for context (tx hash, block number, etc.).\n */\nexport interface KernelParsedEvent {\n eventName: KernelEventName;\n args: Record<string, unknown>;\n log: Log;\n}\n\n/**\n * Decode a viem `Log` emitted by the Skate kernel's `KernelEventEmitter`.\n *\n * Throws {@link EvmReadError} if the log's topic0 is not a known kernel event\n * or if ABI decoding fails.\n */\nexport function parseKernelEventLog(log: Log): KernelParsedEvent {\n try {\n const decoded = decodeEventLog({\n abi: KernelEventEmitterABI,\n data: log.data,\n topics: log.topics,\n });\n return {\n eventName: decoded.eventName as KernelEventName,\n args: (decoded.args ?? {}) as Record<string, unknown>,\n log,\n };\n } catch (err) {\n const message = (err as { shortMessage?: string; message?: string })\n .shortMessage ??\n (err as { message?: string }).message ??\n String(err);\n throw new EvmReadError(\n \"parseKernelEventLog\",\n `failed to decode log: ${message}`,\n { cause: err as Error },\n );\n }\n}\n","import { decodeEventLog, type Log } from \"viem\";\nimport { PeripheryEventEmitterABI } from \"@skate-org/amm-bindings\";\nimport { EvmReadError } from \"../errors\";\n\n/**\n * Event names emitted by `PeripheryEventEmitter` on the source chain.\n */\nexport type PeripheryEventName =\n | \"AmountSettled\"\n | \"Burned\"\n | \"LiquidityDecreased\"\n | \"LiquidityIncreased\"\n | \"MintSettled\"\n | \"Minted\"\n | \"PoolCreated\"\n | \"PoolDeployed\"\n | \"Swapped\"\n | \"TransferredTo\";\n\n/** Exhaustive list of known periphery event names. */\nexport const PERIPHERY_EVENT_NAMES: readonly PeripheryEventName[] = [\n \"AmountSettled\",\n \"Burned\",\n \"LiquidityDecreased\",\n \"LiquidityIncreased\",\n \"MintSettled\",\n \"Minted\",\n \"PoolCreated\",\n \"PoolDeployed\",\n \"Swapped\",\n \"TransferredTo\",\n];\n\n/** A decoded periphery event — name, named args, and the original viem `Log`. */\nexport interface PeripheryParsedEvent {\n eventName: PeripheryEventName;\n args: Record<string, unknown>;\n log: Log;\n}\n\n/**\n * Decode a viem `Log` emitted by `PeripheryEventEmitter` on a source chain.\n *\n * Throws {@link EvmReadError} if the log's topic0 is not a known periphery\n * event or if ABI decoding fails.\n */\nexport function parsePeripheryEventLog(log: Log): PeripheryParsedEvent {\n try {\n const decoded = decodeEventLog({\n abi: PeripheryEventEmitterABI,\n data: log.data,\n topics: log.topics,\n });\n return {\n eventName: decoded.eventName as PeripheryEventName,\n args: (decoded.args ?? {}) as Record<string, unknown>,\n log,\n };\n } catch (err) {\n const message = (err as { shortMessage?: string; message?: string })\n .shortMessage ??\n (err as { message?: string }).message ??\n String(err);\n throw new EvmReadError(\n \"parsePeripheryEventLog\",\n `failed to decode log: ${message}`,\n { cause: err as Error },\n );\n }\n}\n","import type { Address, Log, PublicClient } from \"viem\";\nimport {\n KernelEventEmitterABI,\n PeripheryEventEmitterABI,\n} from \"@skate-org/amm-bindings\";\nimport {\n parseKernelEventLog,\n type KernelParsedEvent,\n} from \"./kernel\";\nimport {\n parsePeripheryEventLog,\n type PeripheryParsedEvent,\n} from \"./periphery\";\n\nexport interface EventSubscriptionOptions<E> {\n /** Called for each decoded event. */\n onEvent: (event: E) => void;\n /** Called when a log fails to decode (subscription stays alive). */\n onError?: (err: unknown) => void;\n}\n\n/**\n * Subscribe to kernel events emitted by the `KernelEventEmitter` contract\n * at `address`. Returns an unsubscribe function.\n *\n * Decode failures are surfaced via `opts.onError` (if provided) rather than\n * throwing — the subscription continues.\n */\nexport function watchKernelEvents(\n client: PublicClient,\n address: Address,\n opts: EventSubscriptionOptions<KernelParsedEvent>,\n): () => void {\n return client.watchContractEvent({\n abi: KernelEventEmitterABI,\n address,\n onLogs: (logs: Log[]) => {\n for (const log of logs) {\n try {\n opts.onEvent(parseKernelEventLog(log));\n } catch (err) {\n opts.onError?.(err);\n }\n }\n },\n });\n}\n\n/**\n * Subscribe to periphery events emitted by `PeripheryEventEmitter` at\n * `address` on the source chain the `client` is connected to.\n */\nexport function watchPeripheryEvents(\n client: PublicClient,\n address: Address,\n opts: EventSubscriptionOptions<PeripheryParsedEvent>,\n): () => void {\n return client.watchContractEvent({\n abi: PeripheryEventEmitterABI,\n address,\n onLogs: (logs: Log[]) => {\n for (const log of logs) {\n try {\n opts.onEvent(parsePeripheryEventLog(log));\n } catch (err) {\n opts.onError?.(err);\n }\n }\n },\n });\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP,SAAS,gBAAgB;AACzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAgBA,IAAM,eAAsB,YAAY;AAAA,EAC7C,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,SAAS;AAAA,EACT,gBAAgB,EAAE,MAAM,SAAS,QAAQ,OAAO,UAAU,GAAG;AAAA,EAC7D,SAAS;AAAA,IACP,SAAS,EAAE,MAAM,CAAC,iCAAiC,EAAE;AAAA,IACrD,QAAQ,EAAE,MAAM,CAAC,iCAAiC,EAAE;AAAA,EACtD;AAAA,EACA,gBAAgB;AAAA,IACd,SAAS,EAAE,MAAM,cAAc,KAAK,eAAe,QAAQ;AAAA,EAC7D;AACF,CAAC;AAQD,IAAM,cAA8C;AAAA,EAClD,CAAC,MAAM,OAAO,GAAG;AAAA,EACjB,CAAC,MAAM,QAAQ,GAAG;AACpB;AAQA,SAAS,YAAY,OAAiC;AACpD,UAAQ,OAAO;AAAA,IACb,KAAK,MAAM;AACT,aAAO;AAAA,IACT,KAAK,MAAM;AACT,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAQA,SAAS,cACP,OACA,MACoB;AACpB,QAAM,EAAE,OAAO,IAAI,cAAc,IAAI;AACrC,SAAO,QAAQ,eAAe,KAAK,KAAK,YAAY,KAAK;AAC3D;AAaO,SAAS,sBACd,MACA,WACc;AACd,SAAO,mBAAmB;AAAA,IACxB,OAAO;AAAA,IACP,WAAW,aAAa,KAAK,cAAc,MAAM,SAAS,IAAI,CAAC;AAAA,EACjE,CAAC;AACH;AAaO,SAAS,sBACd,OACA,MACA,WACc;AACd,MAAI,gBAAgB,KAAK,MAAM,GAAG,KAAK;AACrC,UAAM,IAAI;AAAA,MACR,gCAAgC,KAAK;AAAA,IACvC;AAAA,EACF;AACA,QAAM,WAAW,YAAY,KAAK;AAClC,MAAI,CAAC,UAAU;AACb,UAAM,IAAI;AAAA,MACR,mEAAmE,KAAK;AAAA,IAC1E;AAAA,EACF;AACA,QAAM,MAAM,cAAc,OAAO,IAAI;AACrC,MAAI,CAAC,OAAO,CAAC,WAAW;AACtB,UAAM,IAAI;AAAA,MACR,0EAA0E,KAAK,iEAAiE,KAAK;AAAA,IACvJ;AAAA,EACF;AACA,SAAO,mBAAmB;AAAA,IACxB,OAAO;AAAA,IACP,WAAW,aAAa,KAAK,GAAG;AAAA,EAClC,CAAC;AACH;;;AC/IO,IAAM,2BACX;AAiBK,SAAS,gBACd,YAAoC,CAAC,GACG;AACxC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,aAAa,UAAU,eAAe;AAAA,MACtC,GAAI,UAAU,eACV,EAAE,cAAc,UAAU,aAAa,IACvC,CAAC;AAAA,IACP;AAAA,EACF;AACF;;;ACzBA,SAAS,gBAAgB;AAGlB,IAAM,eAAN,cAA2B,SAAS;AAAA,EACvB,OAAe;AAAA,EACxB;AAAA,EAET,YAAY,cAAsB,SAAiB,SAAwB;AACzE,UAAM,GAAG,YAAY,KAAK,OAAO,IAAI,OAAO;AAC5C,SAAK,eAAe;AAAA,EACtB;AACF;AAUO,IAAM,gBAAN,cAA4B,SAAS;AAAA,EACxB,OAAe;AAAA,EACxB;AAAA,EAET,YAAY,cAAsB,SAAiB,SAAwB;AACzE,UAAM,GAAG,YAAY,KAAK,OAAO,IAAI,OAAO;AAC5C,SAAK,eAAe;AAAA,EACtB;AACF;AAaO,SAAS,cACd,KACA,cACc;AACd,QAAM,YAAa,KAAkC;AACrD,QAAM,YAAa,KAA8C,OAAO;AACxE,QAAM,UACH,KAA0C,gBAC1C,KAAqC,WACtC,OAAO,GAAG;AACZ,QAAM,sBACJ,cAAc,oCACd,cAAc,mCACd,cAAc,mCACd,cAAc,mCACd,cAAc;AAChB,MAAI,qBAAqB;AACvB,WAAO,IAAI,aAAa,cAAc,aAAa,OAAO,IAAI;AAAA,MAC5D,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,SAAO,IAAI,aAAa,cAAc,SAAS,EAAE,OAAO,IAAa,CAAC;AACxE;AAcO,SAAS,eACd,KACA,cACe;AACf,QAAM,UACH,KAA0C,gBAC1C,KAAqC,WACtC,OAAO,GAAG;AACZ,SAAO,IAAI,cAAc,cAAc,SAAS,EAAE,OAAO,IAAa,CAAC;AACzE;;;AC9FA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA,iBAAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACHA,SAAS,oBACd,MACA,QACc;AACd,SAAO,UAAU,sBAAsB,IAAI;AAC7C;;;ADiDA,eAAsB,SACpB,YACA,MACA,QAC0B;AAC1B,QAAM,IAAI,oBAAoB,MAAM,MAAM;AAC1C,MAAI;AACF,UAAM,CAAC,OAAO,SAAS,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC3C,EAAE,aAAa;AAAA,QACb,SAAS;AAAA,QACT,KAAK;AAAA,QACL,cAAc;AAAA,MAChB,CAAC;AAAA,MACD,EAAE,aAAa;AAAA,QACb,SAAS;AAAA,QACT,KAAK;AAAA,QACL,cAAc;AAAA,MAChB,CAAC;AAAA,IACH,CAAC;AAID,UAAM,KAAK;AASX,WAAO;AAAA,MACL,OAAO;AAAA,QACL,cAAc,GAAG,CAAC;AAAA,QAClB,MAAM,GAAG,CAAC;AAAA,QACV,kBAAkB,GAAG,CAAC;AAAA,QACtB,wBAAwB,GAAG,CAAC;AAAA,QAC5B,4BAA4B,GAAG,CAAC;AAAA,QAChC,aAAa,GAAG,CAAC;AAAA,QACjB,UAAU,GAAG,CAAC;AAAA,MAChB;AAAA,MACA;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,cAAc,KAAK,UAAU;AAAA,EACrC;AACF;AASA,eAAsB,aACpB,SACA,MACA,QAC4B;AAC5B,QAAM,EAAE,MAAM,SAAS,IAAIC,eAAc,IAAI;AAC7C,QAAM,UAAU,qBAAqB,QAAQ;AAC7C,QAAM,IAAI,oBAAoB,MAAM,MAAM;AAC1C,MAAI;AACF,UAAM,MAAO,MAAM,EAAE,aAAa;AAAA,MAChC,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAMD,UAAM,UAAU,MAAM,QAAQ,GAAG,IAC5B,MAUD;AACJ,QAAI,SAAS;AACX,aAAO;AAAA,QACL,MAAM,QAAQ,CAAC;AAAA,QACf,WAAW,QAAQ,CAAC;AAAA,QACpB,WAAW,QAAQ,CAAC;AAAA,QACpB,WAAW,QAAQ,CAAC;AAAA,QACpB,0BAA0B,QAAQ,CAAC;AAAA,QACnC,0BAA0B,QAAQ,CAAC;AAAA,QACnC,aAAa,QAAQ,CAAC;AAAA,QACtB,aAAa,QAAQ,CAAC;AAAA,MACxB;AAAA,IACF;AACA,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,UAAM,cAAc,KAAK,cAAc;AAAA,EACzC;AACF;AASA,eAAsB,eACpB,YACA,SACA,MACA,QACiB;AACjB,QAAM,IAAI,oBAAoB,MAAM,MAAM;AAC1C,MAAI;AACF,UAAM,OAAO,MAAM,EAAE,aAAa;AAAA,MAChC,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AACD,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,UAAM,cAAc,KAAK,gBAAgB;AAAA,EAC3C;AACF;AAGA,eAAsB,SACpB,YACA,MACA,MACA,QACqB;AACrB,QAAM,IAAI,oBAAoB,MAAM,MAAM;AAC1C,MAAI;AACF,UAAM,MAAO,MAAM,EAAE,aAAa;AAAA,MAChC,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,IAAI;AAAA,IACb,CAAC;AAUD,WAAO;AAAA,MACL,gBAAgB,IAAI,CAAC;AAAA,MACrB,cAAc,IAAI,CAAC;AAAA,MACnB,uBAAuB,IAAI,CAAC;AAAA,MAC5B,uBAAuB,IAAI,CAAC;AAAA,MAC5B,uBAAuB,IAAI,CAAC;AAAA,MAC5B,gCAAgC,IAAI,CAAC;AAAA,MACrC,gBAAgB,IAAI,CAAC;AAAA,MACrB,aAAa,IAAI,CAAC;AAAA,IACpB;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,cAAc,KAAK,UAAU;AAAA,EACrC;AACF;AAUA,eAAsB,uBACpB,SACA,MACA,QAC+C;AAC/C,QAAM,IAAI,oBAAoB,MAAM,MAAM;AAC1C,QAAM,WAAW,MAAM,aAAa,SAAS,MAAM,CAAC;AACpD,QAAM,EAAE,MAAM,IAAI,MAAM,SAAS,SAAS,MAAM,MAAM,CAAC;AAEvD,QAAM,YAAY,mBAAmB,SAAS,SAAS;AACvD,QAAM,YAAY,mBAAmB,SAAS,SAAS;AAEvD,MAAI,MAAM,OAAO,SAAS,WAAW;AACnC,WAAO;AAAA,MACL,SAAS,gBAAgB,WAAW,WAAW,SAAS,WAAW,KAAK;AAAA,MACxE,SAAS;AAAA,IACX;AAAA,EACF;AACA,MAAI,MAAM,QAAQ,SAAS,WAAW;AACpC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,gBAAgB,WAAW,WAAW,SAAS,WAAW,KAAK;AAAA,IAC1E;AAAA,EACF;AACA,SAAO;AAAA,IACL,SAAS;AAAA,MACP,MAAM;AAAA,MACN;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP;AAAA,MACA,MAAM;AAAA,MACN,SAAS;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF;;;AE5PO,SAAS,qBACd,MACA,SACA,aACU;AACV,MAAI,CAAC,OAAO,cAAc,OAAO,GAAG;AAClC,UAAM,IAAI;AAAA,MACR,6DAA6D,OAAO;AAAA,IACtE;AAAA,EACF;AACA,MAAI,CAAC,OAAO,cAAc,WAAW,KAAK,eAAe,GAAG;AAC1D,UAAM,IAAI;AAAA,MACR,qEAAqE,WAAW;AAAA,IAClF;AAAA,EACF;AACA,QAAM,SAAmB,CAAC;AAI1B,QAAM,OAAO,UAAU;AACvB,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,SAAM,QAAQ,OAAO,CAAC,IAAK,QAAQ,IAAI;AACrC,aAAO,MAAM,OAAO,KAAK,WAAW;AAAA,IACtC;AAAA,EACF;AACA,SAAO;AACT;;;ACrDA,SAAS,oBAAAC,yBAAwB;AACjC;AAAA,EACE,wBAAAC;AAAA,EACA,iBAAAC;AAAA,OAEK;AAkCP,eAAsB,aACpB,QACA,MACA,QAC6B;AAC7B,QAAM,EAAE,MAAM,SAAS,IAAIC,eAAc,IAAI;AAC7C,QAAM,IAAI,oBAAoB,MAAM,MAAM;AAC1C,MAAI;AACF,UAAM,MAAM,MAAM,EAAE,iBAAiB;AAAA,MACnC,SAASC,sBAAqB,QAAQ;AAAA,MACtC,KAAKC;AAAA,MACL,cAAc;AAAA,MACd,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AACD,UAAM,CAAC,SAAS,SAAS,mBAAmB,UAAU,IAAI,IAAI;AAM9D,WAAO,EAAE,SAAS,SAAS,mBAAmB,WAAW;AAAA,EAC3D,SAAS,KAAK;AACZ,UAAM,cAAc,KAAK,cAAc;AAAA,EACzC;AACF;AAqBA,eAAsB,aACpB,QACA,MACA,QAC6B;AAC7B,QAAM,EAAE,MAAM,SAAS,IAAIF,eAAc,IAAI;AAC7C,QAAM,IAAI,oBAAoB,MAAM,MAAM;AAC1C,MAAI;AACF,UAAM,MAAM,MAAM,EAAE,iBAAiB;AAAA,MACnC,SAASC,sBAAqB,QAAQ;AAAA,MACtC,KAAKC;AAAA,MACL,cAAc;AAAA,MACd,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AACD,UAAM,CAAC,aAAa,aAAa,iBAAiB,UAAU,IAAI,IAAI;AAMpE,WAAO,EAAE,aAAa,aAAa,iBAAiB,WAAW;AAAA,EACjE,SAAS,KAAK;AACZ,UAAM,cAAc,KAAK,cAAc;AAAA,EACzC;AACF;AAkBA,eAAsB,aACpB,QACA,MACA,QAC6B;AAC7B,QAAM,EAAE,MAAM,SAAS,IAAIF,eAAc,IAAI;AAC7C,QAAM,IAAI,oBAAoB,MAAM,MAAM;AAC1C,MAAI;AACF,UAAM,MAAM,MAAM,EAAE,iBAAiB;AAAA,MACnC,SAASC,sBAAqB,QAAQ;AAAA,MACtC,KAAKC;AAAA,MACL,cAAc;AAAA,MACd,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AACD,UAAM,CAAC,SAAS,SAAS,UAAU,IAAI,IAAI;AAK3C,WAAO,EAAE,SAAS,SAAS,WAAW;AAAA,EACxC,SAAS,KAAK;AACZ,UAAM,cAAc,KAAK,cAAc;AAAA,EACzC;AACF;AAeA,eAAsB,0BACpB,QACA,MACA,QAC0C;AAC1C,QAAM,EAAE,MAAM,SAAS,IAAIF,eAAc,IAAI;AAC7C,QAAM,IAAI,oBAAoB,MAAM,MAAM;AAC1C,MAAI;AACF,UAAM,MAAM,MAAM,EAAE,iBAAiB;AAAA,MACnC,SAASC,sBAAqB,QAAQ;AAAA,MACtC,KAAKC;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,OAAO,SAAS,OAAO,SAAS;AAAA,IACzC,CAAC;AACD,UAAM,CAAC,SAAS,SAAS,UAAU,IAAI,IAAI;AAK3C,WAAO,EAAE,SAAS,SAAS,WAAW;AAAA,EACxC,SAAS,KAAK;AACZ,UAAM,cAAc,KAAK,2BAA2B;AAAA,EACtD;AACF;;;AC/MA,SAAS,wBAAwB;AACjC;AAAA,EAEE;AAAA,EACA,iBAAAC;AAAA,OAGK;AAgDP,SAAS,cACP,OACA,MACA,QACc;AACd,SAAO,UAAU,sBAAsB,OAAO,IAAI;AACpD;AAaA,eAAsB,kBACpB,OACA,YACA,MACA,QAC6B;AAC7B,QAAM,EAAE,MAAM,SAAS,IAAIC,eAAc,IAAI;AAC7C,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,MACA,qCAAqC,UAAU,UAAU,KAAK,SAAS,QAAQ;AAAA,IACjF;AAAA,EACF;AACA,QAAM,UAAU,QAAQ;AACxB,QAAM,IAAI,cAAc,OAAO,MAAM,MAAM;AAC3C,MAAI;AACF,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,MAAM,QAAQ,IAAI;AAAA,MACpB,EAAE,aAAa;AAAA,QACb;AAAA,QACA,KAAK;AAAA,QACL,cAAc;AAAA,MAChB,CAAC;AAAA,MACD,EAAE,aAAa;AAAA,QACb;AAAA,QACA,KAAK;AAAA,QACL,cAAc;AAAA,MAChB,CAAC;AAAA,MACD,EAAE,aAAa;AAAA,QACb;AAAA,QACA,KAAK;AAAA,QACL,cAAc;AAAA,MAChB,CAAC;AAAA,MACD,EAAE,aAAa;AAAA,QACb;AAAA,QACA,KAAK;AAAA,QACL,cAAc;AAAA,MAChB,CAAC;AAAA,MACD,EAAE,aAAa;AAAA,QACb;AAAA,QACA,KAAK;AAAA,QACL,cAAc;AAAA,MAChB,CAAC;AAAA,MACD,EAAE,aAAa;AAAA,QACb;AAAA,QACA,KAAK;AAAA,QACL,cAAc;AAAA,MAChB,CAAC;AAAA,MACD,EAAE,aAAa;AAAA,QACb;AAAA,QACA,KAAK;AAAA,QACL,cAAc;AAAA,MAChB,CAAC;AAAA,IACH,CAAC;AAGD,UAAM,SAAS;AACf,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ,mBAAmB;AAAA,QACjB,kBAAkB,OAAO,CAAC;AAAA,QAC1B,kBAAkB,OAAO,CAAC;AAAA,MAC5B;AAAA,MACA,aAAa;AAAA,MACb,aAAa;AAAA,IACf;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,cAAc,KAAK,mBAAmB;AAAA,EAC9C;AACF;AAyBA,eAAsB,qBACpB,OACA,YACA,MACA,MACA,QAC2B;AAC3B,QAAM,EAAE,MAAM,SAAS,IAAIA,eAAc,IAAI;AAC7C,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,MACA,qCAAqC,UAAU,UAAU,KAAK,SAAS,QAAQ;AAAA,IACjF;AAAA,EACF;AACA,QAAM,IAAI,cAAc,OAAO,MAAM,MAAM;AAC3C,MAAI;AACF,UAAM,MAAO,MAAM,EAAE,aAAa;AAAA,MAChC,SAAS,QAAQ;AAAA,MACjB,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,IAAI;AAAA,IACb,CAAC;AAID,QAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,YAAM,QAAQ;AACd,aAAO,EAAE,SAAS,MAAM,CAAC,GAAG,SAAS,MAAM,CAAC,EAAE;AAAA,IAChD;AACA,UAAM,WAAW;AACjB,WAAO,EAAE,SAAS,SAAS,SAAS,SAAS,SAAS,QAAQ;AAAA,EAChE,SAAS,KAAK;AACZ,UAAM,cAAc,KAAK,sBAAsB;AAAA,EACjD;AACF;;;AC7KA,eAAsB,aACpB,QACA,QACA,OACc;AACd,MAAI,OAAO,OAAO,OAAO,OAAO,OAAO;AACrC,UAAM,IAAI;AAAA,MACR;AAAA,MACA,gBAAgB,OAAO,OAAO,MAAM,WAAW,oBAAoB,OAAO,KAAK;AAAA,IACjF;AAAA,EACF;AAEA,MAAI;AACF,UAAM,UAAU,OAAO;AACvB,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO,MAAM,OAAO,gBAAgB;AAAA,MAClC,IAAI,OAAO;AAAA,MACX,MAAM,OAAO;AAAA,MACb,OAAO,OAAO,SAAS;AAAA,MACvB,OAAO,OAAO;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH,SAAS,KAAK;AAGZ,QAAI,eAAe,cAAe,OAAM;AACxC,UAAM,eAAe,KAAK,cAAc;AAAA,EAC1C;AACF;AAQA,eAAsB,WACpB,QACA,QACA,MACc;AACd,MAAI;AACF,WAAO,MAAM,aAAa,QAAQ,QAAQ,IAAI;AAAA,EAChD,SAAS,KAAK;AACZ,QAAI,eAAe,cAAe,OAAM;AACxC,UAAM,eAAe,KAAK,YAAY;AAAA,EACxC;AACF;AAOA,eAAsB,eACpB,QACA,QACA,MACc;AACd,MAAI;AACF,WAAO,MAAM,aAAa,QAAQ,QAAQ,IAAI;AAAA,EAChD,SAAS,KAAK;AACZ,QAAI,eAAe,cAAe,OAAM;AACxC,UAAM,eAAe,KAAK,gBAAgB;AAAA,EAC5C;AACF;;;ACzHA,SAAS,sBAAgC;AACzC,SAAS,6BAA6B;AAsB/B,IAAM,qBAAiD;AAAA,EAC5D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAkBO,SAAS,oBAAoB,KAA6B;AAC/D,MAAI;AACF,UAAM,UAAU,eAAe;AAAA,MAC7B,KAAK;AAAA,MACL,MAAM,IAAI;AAAA,MACV,QAAQ,IAAI;AAAA,IACd,CAAC;AACD,WAAO;AAAA,MACL,WAAW,QAAQ;AAAA,MACnB,MAAO,QAAQ,QAAQ,CAAC;AAAA,MACxB;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,UAAW,IACd,gBACA,IAA6B,WAC9B,OAAO,GAAG;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,MACA,yBAAyB,OAAO;AAAA,MAChC,EAAE,OAAO,IAAa;AAAA,IACxB;AAAA,EACF;AACF;;;AC7EA,SAAS,kBAAAC,uBAAgC;AACzC,SAAS,gCAAgC;AAmBlC,IAAM,wBAAuD;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAeO,SAAS,uBAAuB,KAAgC;AACrE,MAAI;AACF,UAAM,UAAUC,gBAAe;AAAA,MAC7B,KAAK;AAAA,MACL,MAAM,IAAI;AAAA,MACV,QAAQ,IAAI;AAAA,IACd,CAAC;AACD,WAAO;AAAA,MACL,WAAW,QAAQ;AAAA,MACnB,MAAO,QAAQ,QAAQ,CAAC;AAAA,MACxB;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,UAAW,IACd,gBACA,IAA6B,WAC9B,OAAO,GAAG;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,MACA,yBAAyB,OAAO;AAAA,MAChC,EAAE,OAAO,IAAa;AAAA,IACxB;AAAA,EACF;AACF;;;ACpEA;AAAA,EACE,yBAAAC;AAAA,EACA,4BAAAC;AAAA,OACK;AAwBA,SAAS,kBACd,QACA,SACA,MACY;AACZ,SAAO,OAAO,mBAAmB;AAAA,IAC/B,KAAKC;AAAA,IACL;AAAA,IACA,QAAQ,CAAC,SAAgB;AACvB,iBAAW,OAAO,MAAM;AACtB,YAAI;AACF,eAAK,QAAQ,oBAAoB,GAAG,CAAC;AAAA,QACvC,SAAS,KAAK;AACZ,eAAK,UAAU,GAAG;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAMO,SAAS,qBACd,QACA,SACA,MACY;AACZ,SAAO,OAAO,mBAAmB;AAAA,IAC/B,KAAKC;AAAA,IACL;AAAA,IACA,QAAQ,CAAC,SAAgB;AACvB,iBAAW,OAAO,MAAM;AACtB,YAAI;AACF,eAAK,QAAQ,uBAAuB,GAAG,CAAC;AAAA,QAC1C,SAAS,KAAK;AACZ,eAAK,UAAU,GAAG;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;","names":["normalizeMode","normalizeMode","KernelManagerABI","KernelManagerAddress","normalizeMode","normalizeMode","KernelManagerAddress","KernelManagerABI","normalizeMode","normalizeMode","decodeEventLog","decodeEventLog","KernelEventEmitterABI","PeripheryEventEmitterABI","KernelEventEmitterABI","PeripheryEventEmitterABI"]}
@@ -0,0 +1,9 @@
1
+ import type { PublicClient } from "viem";
2
+ import type { EnvModeWithConfig } from "@skate-org/amm-core-v2";
3
+ /**
4
+ * Return the caller-provided client if present, otherwise build a fresh
5
+ * MegaETH kernel client for the given mode. Shared by readers + lens
6
+ * helpers; intentionally unexported from the package barrel.
7
+ */
8
+ export declare function resolveKernelClient(mode: EnvModeWithConfig, client?: PublicClient): PublicClient;
9
+ //# sourceMappingURL=_client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_client.d.ts","sourceRoot":"","sources":["../../src/kernel/_client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGhE;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,YAAY,CAEd"}
@@ -1,3 +1,4 @@
1
1
  export * from "./reader";
2
2
  export * from "./tickBitmap";
3
+ export * from "./lens";
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/kernel/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/kernel/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC"}
@@ -0,0 +1,76 @@
1
+ import type { PublicClient } from "viem";
2
+ import { type EnvModeWithConfig } from "@skate-org/amm-core-v2";
3
+ /**
4
+ * Kernel lens (simulate) helpers — wrap KernelManager's `lens*` functions as
5
+ * static-call simulations. Lens functions are marked nonpayable in the ABI,
6
+ * but viem's `simulateContract` evaluates them with `eth_call`, so they
7
+ * reuse the same client + RPC plumbing as the readers and never produce a
8
+ * transaction.
9
+ *
10
+ * Errors funnel through `wrapReadError`: lens calls share the read-path
11
+ * error model (revert reasons + RPC failures), and tagging them as "writes"
12
+ * would be misleading since no state changes.
13
+ */
14
+ export interface SimulateSwapParams {
15
+ /** Kernel-pool address (EVM) */
16
+ pool: `0x${string}`;
17
+ /** Recipient encoded as bytes32 (use `toBytes32Address` for cross-VM) */
18
+ recipient: `0x${string}`;
19
+ zeroForOne: boolean;
20
+ /** Positive = exactInput, negative = exactOutput, per Uniswap v3 convention */
21
+ amountSpecified: bigint;
22
+ sqrtPriceLimitX96: bigint;
23
+ }
24
+ export interface SimulateSwapResult {
25
+ amount0: bigint;
26
+ amount1: bigint;
27
+ sqrtPriceX96After: bigint;
28
+ returnData: `0x${string}`;
29
+ }
30
+ export declare function simulateSwap(params: SimulateSwapParams, mode: EnvModeWithConfig, client?: PublicClient): Promise<SimulateSwapResult>;
31
+ export interface SimulateMintParams {
32
+ pool: `0x${string}`;
33
+ /** Recipient encoded as bytes32 */
34
+ recipient: `0x${string}`;
35
+ tickLower: number;
36
+ tickUpper: number;
37
+ amount0: bigint;
38
+ amount1: bigint;
39
+ /** Caller-supplied callback data (passed to `IKernelMintCallback`) */
40
+ data: `0x${string}`;
41
+ }
42
+ export interface SimulateMintResult {
43
+ amount0Used: bigint;
44
+ amount1Used: bigint;
45
+ liquidityAmount: bigint;
46
+ returnData: `0x${string}`;
47
+ }
48
+ export declare function simulateMint(params: SimulateMintParams, mode: EnvModeWithConfig, client?: PublicClient): Promise<SimulateMintResult>;
49
+ export interface SimulateBurnParams {
50
+ pool: `0x${string}`;
51
+ /** Recipient encoded as bytes32 */
52
+ recipient: `0x${string}`;
53
+ tickLower: number;
54
+ tickUpper: number;
55
+ /** Liquidity amount to burn (uint128). */
56
+ amount: bigint;
57
+ }
58
+ export interface SimulateBurnResult {
59
+ amount0: bigint;
60
+ amount1: bigint;
61
+ returnData: `0x${string}`;
62
+ }
63
+ export declare function simulateBurn(params: SimulateBurnParams, mode: EnvModeWithConfig, client?: PublicClient): Promise<SimulateBurnResult>;
64
+ export interface SimulateDecreaseLiquidityParams {
65
+ /** NFT position id (v2 positions). */
66
+ tokenId: bigint;
67
+ /** Liquidity amount to remove (uint128). */
68
+ liquidity: bigint;
69
+ }
70
+ export interface SimulateDecreaseLiquidityResult {
71
+ amount0: bigint;
72
+ amount1: bigint;
73
+ returnData: `0x${string}`;
74
+ }
75
+ export declare function simulateDecreaseLiquidity(params: SimulateDecreaseLiquidityParams, mode: EnvModeWithConfig, client?: PublicClient): Promise<SimulateDecreaseLiquidityResult>;
76
+ //# sourceMappingURL=lens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lens.d.ts","sourceRoot":"","sources":["../../src/kernel/lens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEzC,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAC;AAIhC;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IACpB,yEAAyE;IACzE,SAAS,EAAE,KAAK,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;CAC3B;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,EAC1B,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,kBAAkB,CAAC,CA0B7B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IACpB,mCAAmC;IACnC,SAAS,EAAE,KAAK,MAAM,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;CAC3B;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,EAC1B,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,kBAAkB,CAAC,CA4B7B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IACpB,mCAAmC;IACnC,SAAS,EAAE,KAAK,MAAM,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;CAC3B;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,EAC1B,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,kBAAkB,CAAC,CAyB7B;AAED,MAAM,WAAW,+BAA+B;IAC9C,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;CAC3B;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,+BAA+B,EACvC,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,+BAA+B,CAAC,CAmB1C"}
@@ -1 +1 @@
1
- {"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/kernel/reader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAKzC,OAAO,EAGL,KAAK,iBAAiB,EAIvB,MAAM,wBAAwB,CAAC;AAIhC,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,0BAA0B,EAAE,MAAM,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,uDAAuD;AACvD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB,EAAE,MAAM,CAAC;IACjC,wBAAwB,EAAE,MAAM,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,gDAAgD;AAChD,MAAM,WAAW,UAAU;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,8BAA8B,EAAE,MAAM,CAAC;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;CACtB;AAaD;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,KAAK,MAAM,EAAE,EACzB,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,eAAe,CAAC,CA0C1B;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,iBAAiB,CAAC,CA4C5B;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,KAAK,MAAM,EAAE,EACzB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC,CAajB;AAED,wDAAwD;AACxD,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,KAAK,MAAM,EAAE,EACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,UAAU,CAAC,CA+BrB;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAkC/C"}
1
+ {"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/kernel/reader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAKzC,OAAO,EAGL,KAAK,iBAAiB,EAIvB,MAAM,wBAAwB,CAAC;AAIhC,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,0BAA0B,EAAE,MAAM,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,uDAAuD;AACvD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB,EAAE,MAAM,CAAC;IACjC,wBAAwB,EAAE,MAAM,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,gDAAgD;AAChD,MAAM,WAAW,UAAU;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,8BAA8B,EAAE,MAAM,CAAC;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,KAAK,MAAM,EAAE,EACzB,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,eAAe,CAAC,CA0C1B;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,iBAAiB,CAAC,CA4C5B;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,KAAK,MAAM,EAAE,EACzB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC,CAajB;AAED,wDAAwD;AACxD,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,KAAK,MAAM,EAAE,EACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,UAAU,CAAC,CA+BrB;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAkC/C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skate-org/amm-evm-v2",
3
- "version": "2.0.0-alpha.3",
3
+ "version": "2.0.0-alpha.5",
4
4
  "description": "Skate AMM v2 SDK — EVM clients, kernel/periphery readers, uniswap-v3 math, submitters",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -26,7 +26,7 @@
26
26
  "dependencies": {
27
27
  "@skate-org/amm-bindings": "^1.0.0",
28
28
  "viem": "^2.21.0",
29
- "@skate-org/amm-core-v2": "2.0.0-alpha.3"
29
+ "@skate-org/amm-core-v2": "2.0.0-alpha.5"
30
30
  },
31
31
  "publishConfig": {
32
32
  "access": "public",