@reptilianhq/uniswap-sdk 0.2.2

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.
Files changed (89) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +4 -0
  3. package/README.md +176 -0
  4. package/RELEASING.md +114 -0
  5. package/dist/abis.d.ts +161 -0
  6. package/dist/abis.d.ts.map +1 -0
  7. package/dist/abis.js +21 -0
  8. package/dist/abis.js.map +1 -0
  9. package/dist/batch.d.ts +60 -0
  10. package/dist/batch.d.ts.map +1 -0
  11. package/dist/batch.js +157 -0
  12. package/dist/batch.js.map +1 -0
  13. package/dist/compatibility.d.ts +15 -0
  14. package/dist/compatibility.d.ts.map +1 -0
  15. package/dist/compatibility.js +57 -0
  16. package/dist/compatibility.js.map +1 -0
  17. package/dist/deployments.d.ts +27 -0
  18. package/dist/deployments.d.ts.map +1 -0
  19. package/dist/deployments.js +70 -0
  20. package/dist/deployments.js.map +1 -0
  21. package/dist/depth.d.ts +24 -0
  22. package/dist/depth.d.ts.map +1 -0
  23. package/dist/depth.js +65 -0
  24. package/dist/depth.js.map +1 -0
  25. package/dist/errors.d.ts +25 -0
  26. package/dist/errors.d.ts.map +1 -0
  27. package/dist/errors.js +32 -0
  28. package/dist/errors.js.map +1 -0
  29. package/dist/events.d.ts +23 -0
  30. package/dist/events.d.ts.map +1 -0
  31. package/dist/events.js +27 -0
  32. package/dist/events.js.map +1 -0
  33. package/dist/index.d.ts +4 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +4 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/official-sdk.cjs +9 -0
  38. package/dist/official-sdk.cjs.map +1 -0
  39. package/dist/official-sdk.d.cts +2 -0
  40. package/dist/official-sdk.d.cts.map +1 -0
  41. package/dist/pool.d.ts +30 -0
  42. package/dist/pool.d.ts.map +1 -0
  43. package/dist/pool.js +55 -0
  44. package/dist/pool.js.map +1 -0
  45. package/dist/providers.d.ts +59 -0
  46. package/dist/providers.d.ts.map +1 -0
  47. package/dist/providers.js +110 -0
  48. package/dist/providers.js.map +1 -0
  49. package/dist/reads.d.ts +61 -0
  50. package/dist/reads.d.ts.map +1 -0
  51. package/dist/reads.js +92 -0
  52. package/dist/reads.js.map +1 -0
  53. package/dist/receipts.d.ts +2 -0
  54. package/dist/receipts.d.ts.map +1 -0
  55. package/dist/receipts.js +2 -0
  56. package/dist/receipts.js.map +1 -0
  57. package/dist/transactions.d.ts +2 -0
  58. package/dist/transactions.d.ts.map +1 -0
  59. package/dist/transactions.js +2 -0
  60. package/dist/transactions.js.map +1 -0
  61. package/dist/v3-abis.d.ts +525 -0
  62. package/dist/v3-abis.d.ts.map +1 -0
  63. package/dist/v3-abis.js +43 -0
  64. package/dist/v3-abis.js.map +1 -0
  65. package/dist/v3-receipts.d.ts +28 -0
  66. package/dist/v3-receipts.d.ts.map +1 -0
  67. package/dist/v3-receipts.js +68 -0
  68. package/dist/v3-receipts.js.map +1 -0
  69. package/dist/v3-transactions.d.ts +107 -0
  70. package/dist/v3-transactions.d.ts.map +1 -0
  71. package/dist/v3-transactions.js +323 -0
  72. package/dist/v3-transactions.js.map +1 -0
  73. package/dist/v3.d.ts +6 -0
  74. package/dist/v3.d.ts.map +1 -0
  75. package/dist/v3.js +6 -0
  76. package/dist/v3.js.map +1 -0
  77. package/dist/v4.d.ts +8 -0
  78. package/dist/v4.d.ts.map +1 -0
  79. package/dist/v4.js +5 -0
  80. package/dist/v4.js.map +1 -0
  81. package/docs/FORK_TESTING.md +24 -0
  82. package/examples/read-only-consumer.mjs +59 -0
  83. package/fixtures/receipts/robinhood-mainnet-v3-lifecycle.json +84 -0
  84. package/fixtures/receipts/robinhood-mainnet-v3-mint.json +42 -0
  85. package/package.json +124 -0
  86. package/provenance/mainnet.json +33 -0
  87. package/provenance/testnet.json +33 -0
  88. package/scripts/check-conformance.mjs +191 -0
  89. package/scripts/verify-v3-deployments.mjs +23 -0
package/dist/events.js ADDED
@@ -0,0 +1,27 @@
1
+ import { decodeEventLog } from 'viem';
2
+ import { v4PoolManagerAbi } from './abis.js';
3
+ import { invalid, UniswapSdkError } from './errors.js';
4
+ import { checkedAddress, poolReference } from './pool.js';
5
+ /** Normalize an Initialize log supplied by an indexer or bounded RPC scan. */
6
+ export function decodeV4PoolInitialization(deployment, log) {
7
+ if (log.removed)
8
+ invalid('Removed logs cannot establish pool discovery');
9
+ if (checkedAddress(log.address) !== checkedAddress(deployment.poolManager))
10
+ invalid('Initialize log came from a different PoolManager');
11
+ const decoded = (() => {
12
+ try {
13
+ return decodeEventLog({ abi: v4PoolManagerAbi, data: log.data, topics: log.topics, strict: true });
14
+ }
15
+ catch (cause) {
16
+ throw new UniswapSdkError('INVALID_ARGUMENT', 'Initialize log cannot be decoded', { cause });
17
+ }
18
+ })();
19
+ if (decoded.eventName !== 'Initialize')
20
+ invalid('Expected an Initialize event');
21
+ const reference = poolReference(deployment, decoded.args);
22
+ if (reference.poolId.toLowerCase() !== decoded.args.id.toLowerCase())
23
+ invalid('Initialize PoolKey does not match its pool ID');
24
+ return { ...reference, sqrtPriceX96: decoded.args.sqrtPriceX96, tick: decoded.args.tick,
25
+ blockNumber: log.blockNumber, transactionHash: log.transactionHash, logIndex: log.logIndex };
26
+ }
27
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA0B,MAAM,MAAM,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAqB,MAAM,WAAW,CAAC;AAE7E,8EAA8E;AAC9E,MAAM,UAAU,0BAA0B,CAAC,UAAwB,EAAE,GAEpE;IACC,IAAI,GAAG,CAAC,OAAO;QAAE,OAAO,CAAC,8CAA8C,CAAC,CAAC;IACzE,IAAI,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,cAAc,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,CAAC,kDAAkD,CAAC,CAAC;IACxI,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE;QACpB,IAAI,CAAC;YACH,OAAO,cAAc,CAAC,EAAE,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACrG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,eAAe,CAAC,kBAAkB,EAAE,kCAAkC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IACL,IAAI,OAAO,CAAC,SAAS,KAAK,YAAY;QAAE,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAChF,MAAM,SAAS,GAAG,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,IAAI,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE;QAAE,OAAO,CAAC,+CAA+C,CAAC,CAAC;IAC/H,OAAO,EAAE,GAAG,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI;QACrF,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,eAAe,EAAE,GAAG,CAAC,eAAe,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;AACjG,CAAC","sourcesContent":["import { decodeEventLog, type Address, type Hex } from 'viem';\nimport { v4PoolManagerAbi } from './abis.js';\nimport { invalid, UniswapSdkError } from './errors.js';\nimport { checkedAddress, poolReference, type V4Deployment } from './pool.js';\n\n/** Normalize an Initialize log supplied by an indexer or bounded RPC scan. */\nexport function decodeV4PoolInitialization(deployment: V4Deployment, log: {\n address: Address; data: Hex; topics: [Hex, ...Hex[]]; blockNumber: bigint; transactionHash: Hex; logIndex: number; removed?: boolean;\n}) {\n if (log.removed) invalid('Removed logs cannot establish pool discovery');\n if (checkedAddress(log.address) !== checkedAddress(deployment.poolManager)) invalid('Initialize log came from a different PoolManager');\n const decoded = (() => {\n try {\n return decodeEventLog({ abi: v4PoolManagerAbi, data: log.data, topics: log.topics, strict: true });\n } catch (cause) {\n throw new UniswapSdkError('INVALID_ARGUMENT', 'Initialize log cannot be decoded', { cause });\n }\n })();\n if (decoded.eventName !== 'Initialize') invalid('Expected an Initialize event');\n const reference = poolReference(deployment, decoded.args);\n if (reference.poolId.toLowerCase() !== decoded.args.id.toLowerCase()) invalid('Initialize PoolKey does not match its pool ID');\n return { ...reference, sqrtPriceX96: decoded.args.sqrtPriceX96, tick: decoded.args.tick,\n blockNumber: log.blockNumber, transactionHash: log.transactionHash, logIndex: log.logIndex };\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export * from './v4.js';
2
+ export { UniswapSdkError, isUniswapSdkError } from './errors.js';
3
+ export * from './v3.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACjE,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './v4.js';
2
+ export { UniswapSdkError, isUniswapSdkError } from './errors.js';
3
+ export * from './v3.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACjE,cAAc,SAAS,CAAC","sourcesContent":["export * from './v4.js';\nexport { UniswapSdkError, isUniswapSdkError } from './errors.js';\nexport * from './v3.js';\n"]}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Pool = void 0;
4
+ // Upstream 2.3.3's ESM export contains extensionless directory imports that
5
+ // native Node cannot resolve. Its public require export works in Node and
6
+ // bundlers. Keep this compatibility seam local instead of forking the SDK.
7
+ var v4_sdk_1 = require("@uniswap/v4-sdk");
8
+ Object.defineProperty(exports, "Pool", { enumerable: true, get: function () { return v4_sdk_1.Pool; } });
9
+ //# sourceMappingURL=official-sdk.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"official-sdk.cjs","sourceRoot":"","sources":["../src/official-sdk.cts"],"names":[],"mappings":";;;AAAA,4EAA4E;AAC5E,0EAA0E;AAC1E,2EAA2E;AAC3E,0CAAuC;AAA9B,8FAAA,IAAI,OAAA","sourcesContent":["// Upstream 2.3.3's ESM export contains extensionless directory imports that\n// native Node cannot resolve. Its public require export works in Node and\n// bundlers. Keep this compatibility seam local instead of forking the SDK.\nexport { Pool } from '@uniswap/v4-sdk';\n"]}
@@ -0,0 +1,2 @@
1
+ export { Pool } from '@uniswap/v4-sdk';
2
+ //# sourceMappingURL=official-sdk.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"official-sdk.d.cts","sourceRoot":"","sources":["../src/official-sdk.cts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/pool.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ import type { Currency } from '@uniswap/sdk-core';
2
+ import { type Address, type Hex } from 'viem';
3
+ export interface V4PoolKey {
4
+ currency0: Address;
5
+ currency1: Address;
6
+ fee: number;
7
+ tickSpacing: number;
8
+ hooks: Address;
9
+ }
10
+ export interface V4Deployment {
11
+ chainId: number;
12
+ poolManager: Address;
13
+ stateView: Address;
14
+ quoter: Address;
15
+ }
16
+ export interface V4PoolReference {
17
+ chainId: number;
18
+ poolManager: Address;
19
+ poolId: Hex;
20
+ key: V4PoolKey;
21
+ }
22
+ export declare function checkedAddress(value: Address): Address;
23
+ export declare function validateDeployment(deployment: V4Deployment): V4Deployment;
24
+ export declare function validatePoolKey(key: V4PoolKey): V4PoolKey;
25
+ /** Official SDK currency normalization; native currencies remain address(0). */
26
+ export declare function poolKeyFromCurrencies(a: Currency, b: Currency, fee: number, tickSpacing: number, hooks: Address): V4PoolKey;
27
+ /** Pool ID does not contain chain or manager identity; retain the full reference. */
28
+ export declare function getV4PoolId(input: V4PoolKey): Hex;
29
+ export declare function poolReference(deployment: V4Deployment, input: V4PoolKey): V4PoolReference;
30
+ //# sourceMappingURL=pool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAsE,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAGlH,MAAM,WAAW,SAAS;IAAG,SAAS,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE;AACvH,MAAM,WAAW,YAAY;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE;AAC5G,MAAM,WAAW,eAAe;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC;IAAC,GAAG,EAAE,SAAS,CAAA;CAAE;AAEvG,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGtD;AACD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,YAAY,GAAG,YAAY,CAKzE;AACD,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,CAOzD;AAED,gFAAgF;AAChF,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,SAAS,CAU3H;AAED,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,GAAG,CAMjD;AACD,wBAAgB,aAAa,CAAC,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,GAAG,eAAe,CAIzF"}
package/dist/pool.js ADDED
@@ -0,0 +1,55 @@
1
+ import { Pool } from './official-sdk.cjs';
2
+ import { encodeAbiParameters, getAddress, isAddress, keccak256, zeroAddress } from 'viem';
3
+ import { invalid, UniswapSdkError } from './errors.js';
4
+ export function checkedAddress(value) {
5
+ if (!isAddress(value))
6
+ invalid('Expected a valid EVM address');
7
+ return getAddress(value);
8
+ }
9
+ export function validateDeployment(deployment) {
10
+ if (!Number.isSafeInteger(deployment.chainId) || deployment.chainId <= 0)
11
+ invalid('chainId must be a positive safe integer');
12
+ const result = { chainId: deployment.chainId, poolManager: checkedAddress(deployment.poolManager), stateView: checkedAddress(deployment.stateView), quoter: checkedAddress(deployment.quoter) };
13
+ if ([result.poolManager, result.stateView, result.quoter].includes(zeroAddress))
14
+ invalid('Deployment contracts cannot be zero addresses');
15
+ return result;
16
+ }
17
+ export function validatePoolKey(key) {
18
+ const result = { ...key, currency0: checkedAddress(key.currency0), currency1: checkedAddress(key.currency1), hooks: checkedAddress(key.hooks) };
19
+ if (BigInt(result.currency0) >= BigInt(result.currency1))
20
+ invalid('PoolKey currencies must be distinct and in canonical address order');
21
+ if (!Number.isInteger(key.fee) || key.fee < 0 || (key.fee > 1_000_000 && key.fee !== 0x800000))
22
+ invalid('fee must be a static fee up to 1000000 or the dynamic fee flag');
23
+ if (key.fee === 0x800000 && result.hooks === zeroAddress)
24
+ invalid('Dynamic fee requires a hook');
25
+ if (!Number.isInteger(key.tickSpacing) || key.tickSpacing < 1 || key.tickSpacing > 32767)
26
+ invalid('tickSpacing must be between 1 and 32767');
27
+ return result;
28
+ }
29
+ /** Official SDK currency normalization; native currencies remain address(0). */
30
+ export function poolKeyFromCurrencies(a, b, fee, tickSpacing, hooks) {
31
+ if (a.chainId !== b.chainId)
32
+ invalid('Pool currencies must belong to the same chain');
33
+ if (a.equals(b))
34
+ invalid('Pool currencies must be distinct');
35
+ try {
36
+ const key = Pool.getPoolKey(a, b, fee, tickSpacing, hooks);
37
+ return validatePoolKey({ ...key, currency0: checkedAddress(key.currency0), currency1: checkedAddress(key.currency1), hooks: checkedAddress(key.hooks) });
38
+ }
39
+ catch (cause) {
40
+ if (cause instanceof UniswapSdkError)
41
+ throw cause;
42
+ throw new UniswapSdkError('INVALID_ARGUMENT', 'Official Uniswap SDK rejected the pool parameters', { cause });
43
+ }
44
+ }
45
+ /** Pool ID does not contain chain or manager identity; retain the full reference. */
46
+ export function getV4PoolId(input) {
47
+ const key = validatePoolKey(input);
48
+ return keccak256(encodeAbiParameters([{ type: 'address' }, { type: 'address' }, { type: 'uint24' }, { type: 'int24' }, { type: 'address' }], [key.currency0, key.currency1, key.fee, key.tickSpacing, key.hooks]));
49
+ }
50
+ export function poolReference(deployment, input) {
51
+ const { chainId, poolManager } = validateDeployment(deployment);
52
+ const key = validatePoolKey(input);
53
+ return { chainId, poolManager, key, poolId: getV4PoolId(key) };
54
+ }
55
+ //# sourceMappingURL=pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool.js","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"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","sourcesContent":["import { Pool } from './official-sdk.cjs';\nimport type { Currency } from '@uniswap/sdk-core';\nimport { encodeAbiParameters, getAddress, isAddress, keccak256, zeroAddress, type Address, type Hex } from 'viem';\nimport { invalid, UniswapSdkError } from './errors.js';\n\nexport interface V4PoolKey { currency0: Address; currency1: Address; fee: number; tickSpacing: number; hooks: Address }\nexport interface V4Deployment { chainId: number; poolManager: Address; stateView: Address; quoter: Address }\nexport interface V4PoolReference { chainId: number; poolManager: Address; poolId: Hex; key: V4PoolKey }\n\nexport function checkedAddress(value: Address): Address {\n if (!isAddress(value)) invalid('Expected a valid EVM address');\n return getAddress(value);\n}\nexport function validateDeployment(deployment: V4Deployment): V4Deployment {\n if (!Number.isSafeInteger(deployment.chainId) || deployment.chainId <= 0) invalid('chainId must be a positive safe integer');\n const result = { chainId: deployment.chainId, poolManager: checkedAddress(deployment.poolManager), stateView: checkedAddress(deployment.stateView), quoter: checkedAddress(deployment.quoter) };\n if ([result.poolManager, result.stateView, result.quoter].includes(zeroAddress)) invalid('Deployment contracts cannot be zero addresses');\n return result;\n}\nexport function validatePoolKey(key: V4PoolKey): V4PoolKey {\n const result = { ...key, currency0: checkedAddress(key.currency0), currency1: checkedAddress(key.currency1), hooks: checkedAddress(key.hooks) };\n if (BigInt(result.currency0) >= BigInt(result.currency1)) invalid('PoolKey currencies must be distinct and in canonical address order');\n if (!Number.isInteger(key.fee) || key.fee < 0 || (key.fee > 1_000_000 && key.fee !== 0x800000)) invalid('fee must be a static fee up to 1000000 or the dynamic fee flag');\n if (key.fee === 0x800000 && result.hooks === zeroAddress) invalid('Dynamic fee requires a hook');\n if (!Number.isInteger(key.tickSpacing) || key.tickSpacing < 1 || key.tickSpacing > 32767) invalid('tickSpacing must be between 1 and 32767');\n return result;\n}\n\n/** Official SDK currency normalization; native currencies remain address(0). */\nexport function poolKeyFromCurrencies(a: Currency, b: Currency, fee: number, tickSpacing: number, hooks: Address): V4PoolKey {\n if (a.chainId !== b.chainId) invalid('Pool currencies must belong to the same chain');\n if (a.equals(b)) invalid('Pool currencies must be distinct');\n try {\n const key = Pool.getPoolKey(a, b, fee, tickSpacing, hooks);\n return validatePoolKey({ ...key, currency0: checkedAddress(key.currency0 as Address), currency1: checkedAddress(key.currency1 as Address), hooks: checkedAddress(key.hooks as Address) });\n } catch (cause) {\n if (cause instanceof UniswapSdkError) throw cause;\n throw new UniswapSdkError('INVALID_ARGUMENT', 'Official Uniswap SDK rejected the pool parameters', { cause });\n }\n}\n\n/** Pool ID does not contain chain or manager identity; retain the full reference. */\nexport function getV4PoolId(input: V4PoolKey): Hex {\n const key = validatePoolKey(input);\n return keccak256(encodeAbiParameters(\n [{ type: 'address' }, { type: 'address' }, { type: 'uint24' }, { type: 'int24' }, { type: 'address' }],\n [key.currency0, key.currency1, key.fee, key.tickSpacing, key.hooks],\n ));\n}\nexport function poolReference(deployment: V4Deployment, input: V4PoolKey): V4PoolReference {\n const { chainId, poolManager } = validateDeployment(deployment);\n const key = validatePoolKey(input);\n return { chainId, poolManager, key, poolId: getV4PoolId(key) };\n}\n"]}
@@ -0,0 +1,59 @@
1
+ import { type Address, type Hex } from 'viem';
2
+ import { type V4PoolReference } from './pool.js';
3
+ /** Structural contract implemented by protocol SDKs; contains no transport or signer. */
4
+ export interface V4ProviderDescriptor {
5
+ schemaVersion: 1;
6
+ providerId: string;
7
+ deploymentId: string;
8
+ substrate: 'uniswap-v4';
9
+ chainId: number;
10
+ poolManager: Address;
11
+ startBlock: bigint;
12
+ hooks: readonly Address[];
13
+ discovery: {
14
+ address: Address;
15
+ eventSignature: string;
16
+ poolIdParameter: string;
17
+ expectedRuntimeCodeHash: Hex;
18
+ };
19
+ poolEvents: readonly V4PoolEvent[];
20
+ }
21
+ export type V4PoolEvent = 'Initialize' | 'Swap' | 'ModifyLiquidity' | 'Donate';
22
+ /** Evidence is historical, not execution authorization. Protocol SDKs verify its meaning. */
23
+ export interface V4ProviderPool extends V4PoolReference {
24
+ providerId: string;
25
+ deploymentId: string;
26
+ membership: {
27
+ sourceAddress: Address;
28
+ eventSignature: string;
29
+ blockNumber: bigint;
30
+ blockHash: Hex;
31
+ transactionHash: Hex;
32
+ logIndex: number;
33
+ };
34
+ }
35
+ export declare function verifyV4ProviderDescriptor(provider: V4ProviderDescriptor): void;
36
+ /** Structural/identity verification only; the protocol SDK verifies registration provenance. */
37
+ export declare function verifyV4ProviderPool(provider: V4ProviderDescriptor, pool: V4ProviderPool): void;
38
+ /** Bounded eth_getLogs-compatible plans. Empty selections return no requests, never a wildcard.
39
+ * Hosts must apply topics upstream, retain canonical membership evidence, and replay discovery
40
+ * blocks when the selection changes. Each query covers its whole first block, including events
41
+ * emitted before the registration log. Hosts own reorg rollback, cursors and finality.
42
+ */
43
+ export declare function buildV4PoolSubscriptions(provider: V4ProviderDescriptor, pools: readonly V4ProviderPool[], options: {
44
+ fromBlock: bigint;
45
+ toBlock: bigint;
46
+ maxPoolIdsPerRequest?: number;
47
+ transport: {
48
+ indexedTopicFiltering: boolean;
49
+ };
50
+ }): {
51
+ providerId: string;
52
+ deploymentId: string;
53
+ chainId: number;
54
+ address: Address;
55
+ fromBlock: bigint;
56
+ toBlock: bigint;
57
+ topics: readonly [Hex, readonly Hex[]];
58
+ }[];
59
+ //# sourceMappingURL=providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+C,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAC3F,OAAO,EAA+B,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAG9E,yFAAyF;AACzF,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,CAAC,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,YAAY,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,OAAO,EAAE,CAAC;IAC1B,SAAS,EAAE;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,uBAAuB,EAAE,GAAG,CAAC;KAC9B,CAAC;IACF,UAAU,EAAE,SAAS,WAAW,EAAE,CAAC;CACpC;AACD,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,MAAM,GAAG,iBAAiB,GAAG,QAAQ,CAAC;AAQ/E,6FAA6F;AAC7F,MAAM,WAAW,cAAe,SAAQ,eAAe;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE;QACV,aAAa,EAAE,OAAO,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,GAAG,CAAC;QACf,eAAe,EAAE,GAAG,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAQD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAW/E;AAED,gGAAgG;AAChG,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAY/F;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,KAAK,EAAE,SAAS,cAAc,EAAE,EAAE,OAAO,EAAE;IAClH,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAClE,SAAS,EAAE;QAAE,qBAAqB,EAAE,OAAO,CAAA;KAAE,CAAC;CAC/C;gBA2B4B,MAAM;kBAAgB,MAAM;aAAW,MAAM;aAAW,OAAO;eAAa,MAAM;aAAW,MAAM;YAAU,SAAS,CAAC,GAAG,EAAE,SAAS,GAAG,EAAE,CAAC;IAWvK"}
@@ -0,0 +1,110 @@
1
+ import { getAddress, keccak256, toBytes, zeroAddress } from 'viem';
2
+ import { checkedAddress, getV4PoolId } from './pool.js';
3
+ import { invalid } from './errors.js';
4
+ const signatures = {
5
+ Initialize: 'Initialize(bytes32,address,address,uint24,int24,address,uint160,int24)',
6
+ Swap: 'Swap(bytes32,address,int128,int128,uint160,uint128,int24,uint24)',
7
+ ModifyLiquidity: 'ModifyLiquidity(bytes32,address,int24,int24,int256,bytes32)',
8
+ Donate: 'Donate(bytes32,address,uint256,uint256)',
9
+ };
10
+ function hash(value) {
11
+ if (!/^0x[\da-f]{64}$/i.test(value) || /^0x0{64}$/i.test(value))
12
+ invalid('Expected a nonzero bytes32 hash');
13
+ }
14
+ function block(value) {
15
+ if (typeof value !== 'bigint' || value < 0n)
16
+ invalid('Expected a nonnegative block number');
17
+ }
18
+ export function verifyV4ProviderDescriptor(provider) {
19
+ if (provider.schemaVersion !== 1 || provider.substrate !== 'uniswap-v4')
20
+ invalid('Unsupported provider composition version or substrate');
21
+ if (!provider.providerId?.trim() || !provider.deploymentId?.trim())
22
+ invalid('Provider and deployment identifiers are required');
23
+ if (!Number.isSafeInteger(provider.chainId) || provider.chainId <= 0)
24
+ invalid('Invalid provider chain ID');
25
+ if (checkedAddress(provider.poolManager) === zeroAddress || checkedAddress(provider.discovery.address) === zeroAddress)
26
+ invalid('Provider contracts cannot be zero addresses');
27
+ block(provider.startBlock);
28
+ hash(provider.discovery.expectedRuntimeCodeHash);
29
+ if (!/^[A-Za-z]\w*\([^)]*\)$/.test(provider.discovery.eventSignature) || !provider.discovery.poolIdParameter)
30
+ invalid('Explicit pool membership discovery is required');
31
+ if (!provider.hooks.length)
32
+ invalid('Provider must enumerate its reviewed hooks');
33
+ provider.hooks.forEach(checkedAddress);
34
+ if (!provider.poolEvents.length || provider.poolEvents.some(event => !Object.hasOwn(signatures, event)))
35
+ invalid('Explicit supported pool events are required');
36
+ }
37
+ /** Structural/identity verification only; the protocol SDK verifies registration provenance. */
38
+ export function verifyV4ProviderPool(provider, pool) {
39
+ verifyV4ProviderDescriptor(provider);
40
+ if (pool.providerId !== provider.providerId || pool.deploymentId !== provider.deploymentId || pool.chainId !== provider.chainId
41
+ || checkedAddress(pool.poolManager) !== checkedAddress(provider.poolManager))
42
+ invalid('Pool belongs to a different provider deployment');
43
+ if (!provider.hooks.some(hook => checkedAddress(hook) === checkedAddress(pool.key.hooks)))
44
+ invalid('Pool uses an unreviewed provider hook');
45
+ if (getV4PoolId(pool.key).toLowerCase() !== pool.poolId.toLowerCase())
46
+ invalid('Pool ID differs from its full key');
47
+ if (checkedAddress(pool.membership.sourceAddress) !== checkedAddress(provider.discovery.address)
48
+ || pool.membership.eventSignature !== provider.discovery.eventSignature)
49
+ invalid('Pool membership uses a different discovery source');
50
+ block(pool.membership.blockNumber);
51
+ if (pool.membership.blockNumber < provider.startBlock)
52
+ invalid('Pool membership predates deployment');
53
+ hash(pool.membership.blockHash);
54
+ hash(pool.membership.transactionHash);
55
+ if (!Number.isSafeInteger(pool.membership.logIndex) || pool.membership.logIndex < 0)
56
+ invalid('Invalid membership log index');
57
+ }
58
+ /** Bounded eth_getLogs-compatible plans. Empty selections return no requests, never a wildcard.
59
+ * Hosts must apply topics upstream, retain canonical membership evidence, and replay discovery
60
+ * blocks when the selection changes. Each query covers its whole first block, including events
61
+ * emitted before the registration log. Hosts own reorg rollback, cursors and finality.
62
+ */
63
+ export function buildV4PoolSubscriptions(provider, pools, options) {
64
+ verifyV4ProviderDescriptor(provider);
65
+ block(options.fromBlock);
66
+ block(options.toBlock);
67
+ if (options.toBlock < options.fromBlock)
68
+ invalid('Invalid subscription block range');
69
+ if (!options.transport.indexedTopicFiltering)
70
+ invalid('Selective v4 indexing requires upstream indexed-topic filtering');
71
+ const size = options.maxPoolIdsPerRequest ?? 64;
72
+ if (!Number.isSafeInteger(size) || size < 1 || size > 256)
73
+ invalid('Pool filter batch size must be between 1 and 256');
74
+ if (pools.length > 4096)
75
+ invalid('At most 4096 selected pools per planning call');
76
+ const selected = new Map();
77
+ for (const pool of pools) {
78
+ verifyV4ProviderPool(provider, pool);
79
+ const id = pool.poolId.toLowerCase();
80
+ const previous = selected.get(id);
81
+ if (previous && (previous.membership.blockHash.toLowerCase() !== pool.membership.blockHash.toLowerCase()
82
+ || previous.membership.blockNumber !== pool.membership.blockNumber
83
+ || previous.membership.transactionHash.toLowerCase() !== pool.membership.transactionHash.toLowerCase()
84
+ || previous.membership.logIndex !== pool.membership.logIndex))
85
+ invalid('Conflicting membership evidence; reconcile canonical history before subscribing');
86
+ selected.set(id, pool);
87
+ }
88
+ const groups = new Map();
89
+ for (const [id, pool] of [...selected].sort(([a], [b]) => a.localeCompare(b))) {
90
+ const start = pool.membership.blockNumber > options.fromBlock ? pool.membership.blockNumber : options.fromBlock;
91
+ if (start > options.toBlock)
92
+ continue;
93
+ const group = groups.get(start) ?? [];
94
+ group.push(id);
95
+ groups.set(start, group);
96
+ }
97
+ const plans = [];
98
+ for (const [fromBlock, ids] of [...groups].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) {
99
+ for (let offset = 0; offset < ids.length; offset += size) {
100
+ for (const event of [...new Set(provider.poolEvents)])
101
+ plans.push({
102
+ providerId: provider.providerId, deploymentId: provider.deploymentId,
103
+ chainId: provider.chainId, address: getAddress(provider.poolManager), fromBlock, toBlock: options.toBlock,
104
+ topics: [keccak256(toBytes(signatures[event])), ids.slice(offset, offset + size)],
105
+ });
106
+ }
107
+ }
108
+ return plans;
109
+ }
110
+ //# sourceMappingURL=providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAddress, keccak256, toBytes, zeroAddress, type Address, type Hex } from 'viem';\nimport { checkedAddress, getV4PoolId, type V4PoolReference } from './pool.js';\nimport { invalid } from './errors.js';\n\n/** Structural contract implemented by protocol SDKs; contains no transport or signer. */\nexport interface V4ProviderDescriptor {\n schemaVersion: 1;\n providerId: string;\n deploymentId: string;\n substrate: 'uniswap-v4';\n chainId: number;\n poolManager: Address;\n startBlock: bigint;\n hooks: readonly Address[];\n discovery: {\n address: Address;\n eventSignature: string;\n poolIdParameter: string;\n expectedRuntimeCodeHash: Hex;\n };\n poolEvents: readonly V4PoolEvent[];\n}\nexport type V4PoolEvent = 'Initialize' | 'Swap' | 'ModifyLiquidity' | 'Donate';\nconst signatures: Record<V4PoolEvent, string> = {\n Initialize: 'Initialize(bytes32,address,address,uint24,int24,address,uint160,int24)',\n Swap: 'Swap(bytes32,address,int128,int128,uint160,uint128,int24,uint24)',\n ModifyLiquidity: 'ModifyLiquidity(bytes32,address,int24,int24,int256,bytes32)',\n Donate: 'Donate(bytes32,address,uint256,uint256)',\n};\n\n/** Evidence is historical, not execution authorization. Protocol SDKs verify its meaning. */\nexport interface V4ProviderPool extends V4PoolReference {\n providerId: string;\n deploymentId: string;\n membership: {\n sourceAddress: Address;\n eventSignature: string;\n blockNumber: bigint;\n blockHash: Hex;\n transactionHash: Hex;\n logIndex: number;\n };\n}\n\nfunction hash(value: Hex) {\n if (!/^0x[\\da-f]{64}$/i.test(value) || /^0x0{64}$/i.test(value)) invalid('Expected a nonzero bytes32 hash');\n}\nfunction block(value: bigint) {\n if (typeof value !== 'bigint' || value < 0n) invalid('Expected a nonnegative block number');\n}\nexport function verifyV4ProviderDescriptor(provider: V4ProviderDescriptor): void {\n if (provider.schemaVersion !== 1 || provider.substrate !== 'uniswap-v4') invalid('Unsupported provider composition version or substrate');\n if (!provider.providerId?.trim() || !provider.deploymentId?.trim()) invalid('Provider and deployment identifiers are required');\n if (!Number.isSafeInteger(provider.chainId) || provider.chainId <= 0) invalid('Invalid provider chain ID');\n if (checkedAddress(provider.poolManager) === zeroAddress || checkedAddress(provider.discovery.address) === zeroAddress) invalid('Provider contracts cannot be zero addresses');\n block(provider.startBlock);\n hash(provider.discovery.expectedRuntimeCodeHash);\n if (!/^[A-Za-z]\\w*\\([^)]*\\)$/.test(provider.discovery.eventSignature) || !provider.discovery.poolIdParameter) invalid('Explicit pool membership discovery is required');\n if (!provider.hooks.length) invalid('Provider must enumerate its reviewed hooks');\n provider.hooks.forEach(checkedAddress);\n if (!provider.poolEvents.length || provider.poolEvents.some(event => !Object.hasOwn(signatures, event))) invalid('Explicit supported pool events are required');\n}\n\n/** Structural/identity verification only; the protocol SDK verifies registration provenance. */\nexport function verifyV4ProviderPool(provider: V4ProviderDescriptor, pool: V4ProviderPool): void {\n verifyV4ProviderDescriptor(provider);\n if (pool.providerId !== provider.providerId || pool.deploymentId !== provider.deploymentId || pool.chainId !== provider.chainId\n || checkedAddress(pool.poolManager) !== checkedAddress(provider.poolManager)) invalid('Pool belongs to a different provider deployment');\n if (!provider.hooks.some(hook => checkedAddress(hook) === checkedAddress(pool.key.hooks))) invalid('Pool uses an unreviewed provider hook');\n if (getV4PoolId(pool.key).toLowerCase() !== pool.poolId.toLowerCase()) invalid('Pool ID differs from its full key');\n if (checkedAddress(pool.membership.sourceAddress) !== checkedAddress(provider.discovery.address)\n || pool.membership.eventSignature !== provider.discovery.eventSignature) invalid('Pool membership uses a different discovery source');\n block(pool.membership.blockNumber);\n if (pool.membership.blockNumber < provider.startBlock) invalid('Pool membership predates deployment');\n hash(pool.membership.blockHash); hash(pool.membership.transactionHash);\n if (!Number.isSafeInteger(pool.membership.logIndex) || pool.membership.logIndex < 0) invalid('Invalid membership log index');\n}\n\n/** Bounded eth_getLogs-compatible plans. Empty selections return no requests, never a wildcard.\n * Hosts must apply topics upstream, retain canonical membership evidence, and replay discovery\n * blocks when the selection changes. Each query covers its whole first block, including events\n * emitted before the registration log. Hosts own reorg rollback, cursors and finality.\n */\nexport function buildV4PoolSubscriptions(provider: V4ProviderDescriptor, pools: readonly V4ProviderPool[], options: {\n fromBlock: bigint; toBlock: bigint; maxPoolIdsPerRequest?: number;\n transport: { indexedTopicFiltering: boolean };\n}) {\n verifyV4ProviderDescriptor(provider);\n block(options.fromBlock); block(options.toBlock);\n if (options.toBlock < options.fromBlock) invalid('Invalid subscription block range');\n if (!options.transport.indexedTopicFiltering) invalid('Selective v4 indexing requires upstream indexed-topic filtering');\n const size = options.maxPoolIdsPerRequest ?? 64;\n if (!Number.isSafeInteger(size) || size < 1 || size > 256) invalid('Pool filter batch size must be between 1 and 256');\n if (pools.length > 4096) invalid('At most 4096 selected pools per planning call');\n const selected = new Map<string, V4ProviderPool>();\n for (const pool of pools) {\n verifyV4ProviderPool(provider, pool);\n const id = pool.poolId.toLowerCase();\n const previous = selected.get(id);\n if (previous && (previous.membership.blockHash.toLowerCase() !== pool.membership.blockHash.toLowerCase()\n || previous.membership.blockNumber !== pool.membership.blockNumber\n || previous.membership.transactionHash.toLowerCase() !== pool.membership.transactionHash.toLowerCase()\n || previous.membership.logIndex !== pool.membership.logIndex)) invalid('Conflicting membership evidence; reconcile canonical history before subscribing');\n selected.set(id, pool);\n }\n const groups = new Map<bigint, Hex[]>();\n for (const [id, pool] of [...selected].sort(([a], [b]) => a.localeCompare(b))) {\n const start = pool.membership.blockNumber > options.fromBlock ? pool.membership.blockNumber : options.fromBlock;\n if (start > options.toBlock) continue;\n const group = groups.get(start) ?? [];\n group.push(id as Hex);\n groups.set(start, group);\n }\n const plans: { providerId: string; deploymentId: string; chainId: number; address: Address; fromBlock: bigint; toBlock: bigint; topics: readonly [Hex, readonly Hex[]] }[] = [];\n for (const [fromBlock, ids] of [...groups].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) {\n for (let offset = 0; offset < ids.length; offset += size) {\n for (const event of [...new Set(provider.poolEvents)]) plans.push({\n providerId: provider.providerId, deploymentId: provider.deploymentId,\n chainId: provider.chainId, address: getAddress(provider.poolManager), fromBlock, toBlock: options.toBlock,\n topics: [keccak256(toBytes(signatures[event])), ids.slice(offset, offset + size)],\n });\n }\n }\n return plans;\n}\n"]}
@@ -0,0 +1,61 @@
1
+ import { type Address, type Hex, type PublicClient } from 'viem';
2
+ import { UniswapSdkError } from './errors.js';
3
+ import { type V4Deployment, type V4PoolKey, type V4PoolReference } from './pool.js';
4
+ export type V4ReadClient = Pick<PublicClient, 'getChainId' | 'getBlockNumber' | 'readContract' | 'simulateContract'>;
5
+ export interface V4Observation extends V4PoolReference {
6
+ blockNumber: bigint;
7
+ }
8
+ export interface V4PoolSnapshot extends V4Observation {
9
+ sqrtPriceX96: bigint;
10
+ tick: number;
11
+ protocolFee: number;
12
+ lpFee: number;
13
+ liquidity: bigint;
14
+ }
15
+ export declare function assertManager(client: V4ReadClient, deployment: V4Deployment, address: Address, blockNumber: bigint): Promise<void>;
16
+ export declare function observationBlock(client: V4ReadClient, deployment: V4Deployment, blockNumber?: bigint): Promise<bigint>;
17
+ /** Wiring check only: not bytecode provenance or custom-hook compatibility. */
18
+ export declare function verifyV4DeploymentWiring(client: V4ReadClient, deployment: V4Deployment, options?: {
19
+ blockNumber?: bigint;
20
+ }): Promise<{
21
+ deployment: V4Deployment;
22
+ blockNumber: bigint;
23
+ }>;
24
+ export declare function readV4Pool(client: V4ReadClient, deployment: V4Deployment, key: V4PoolKey, options?: {
25
+ blockNumber?: bigint;
26
+ }): Promise<V4PoolSnapshot>;
27
+ export interface V4QuoteInput {
28
+ currencyIn: Address;
29
+ amountIn: bigint;
30
+ /** Required even when empty: custom hook encoding belongs to the protocol adapter. */
31
+ hookData: Hex;
32
+ /** eth_call sender; hooks may still see the Quoter as their caller. */
33
+ account: Address;
34
+ }
35
+ export interface V4Quote extends V4Observation {
36
+ currencyIn: Address;
37
+ currencyOut: Address;
38
+ amountIn: bigint;
39
+ amountOut: bigint;
40
+ gasEstimate: bigint;
41
+ account: Address;
42
+ hookData: Hex;
43
+ quoter: Address;
44
+ }
45
+ export declare function quoteV4ExactInput(client: V4ReadClient, deployment: V4Deployment, key: V4PoolKey, input: V4QuoteInput, options?: {
46
+ blockNumber?: bigint;
47
+ }): Promise<V4Quote>;
48
+ export type V4QuoteResult = {
49
+ status: 'success';
50
+ quote: V4Quote;
51
+ } | {
52
+ status: 'failure';
53
+ index: number;
54
+ error: UniswapSdkError;
55
+ };
56
+ /** Bounded concurrency, individual eth_calls preserve sender and isolate failures. */
57
+ export declare function quoteV4Batch(client: V4ReadClient, deployment: V4Deployment, key: V4PoolKey, inputs: readonly V4QuoteInput[], options?: {
58
+ blockNumber?: bigint;
59
+ concurrency?: number;
60
+ }): Promise<V4QuoteResult[]>;
61
+ //# sourceMappingURL=reads.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reads.d.ts","sourceRoot":"","sources":["../src/reads.ts"],"names":[],"mappings":"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"}
package/dist/reads.js ADDED
@@ -0,0 +1,92 @@
1
+ import { v4QuoterAbi, v4StateViewAbi } from './abis.js';
2
+ import { UniswapSdkError, invalid, rpc } from './errors.js';
3
+ import { checkedAddress, poolReference, validateDeployment } from './pool.js';
4
+ export async function assertManager(client, deployment, address, blockNumber) {
5
+ const manager = await rpc(() => client.readContract({ address, abi: v4StateViewAbi, functionName: 'poolManager', blockNumber }));
6
+ if (manager.toLowerCase() !== deployment.poolManager.toLowerCase())
7
+ throw new UniswapSdkError('DEPLOYMENT_MISMATCH', 'Periphery points to a different PoolManager');
8
+ }
9
+ export async function observationBlock(client, deployment, blockNumber) {
10
+ validateDeployment(deployment);
11
+ if (blockNumber !== undefined && (typeof blockNumber !== 'bigint' || blockNumber < 0n))
12
+ invalid('blockNumber must be a nonnegative bigint');
13
+ return rpc(async () => {
14
+ if (await client.getChainId() !== deployment.chainId)
15
+ throw new UniswapSdkError('CHAIN_MISMATCH', 'RPC chain does not match the requested deployment');
16
+ return blockNumber ?? await client.getBlockNumber();
17
+ });
18
+ }
19
+ /** Wiring check only: not bytecode provenance or custom-hook compatibility. */
20
+ export async function verifyV4DeploymentWiring(client, deployment, options = {}) {
21
+ const blockNumber = await observationBlock(client, deployment, options.blockNumber);
22
+ const managers = await rpc(() => Promise.all([
23
+ client.readContract({ address: deployment.stateView, abi: v4StateViewAbi, functionName: 'poolManager', blockNumber }),
24
+ client.readContract({ address: deployment.quoter, abi: v4QuoterAbi, functionName: 'poolManager', blockNumber }),
25
+ ]));
26
+ if (managers.some(manager => manager.toLowerCase() !== deployment.poolManager.toLowerCase()))
27
+ throw new UniswapSdkError('DEPLOYMENT_MISMATCH', 'StateView or Quoter points to a different PoolManager');
28
+ return { deployment: validateDeployment(deployment), blockNumber };
29
+ }
30
+ export async function readV4Pool(client, deployment, key, options = {}) {
31
+ const reference = poolReference(deployment, key);
32
+ const blockNumber = await observationBlock(client, deployment, options.blockNumber);
33
+ await assertManager(client, deployment, deployment.stateView, blockNumber);
34
+ const [slot0, liquidity] = await rpc(() => Promise.all([
35
+ client.readContract({ address: deployment.stateView, abi: v4StateViewAbi, functionName: 'getSlot0', args: [reference.poolId], blockNumber }),
36
+ client.readContract({ address: deployment.stateView, abi: v4StateViewAbi, functionName: 'getLiquidity', args: [reference.poolId], blockNumber }),
37
+ ]));
38
+ if (slot0[0] === 0n)
39
+ throw new UniswapSdkError('POOL_NOT_FOUND', 'Pool is not initialized at the requested block');
40
+ return { ...reference, blockNumber, sqrtPriceX96: slot0[0], tick: slot0[1], protocolFee: slot0[2], lpFee: slot0[3], liquidity };
41
+ }
42
+ export async function quoteV4ExactInput(client, deployment, key, input, options = {}) {
43
+ const reference = poolReference(deployment, key);
44
+ const currencyIn = checkedAddress(input.currencyIn);
45
+ const account = checkedAddress(input.account);
46
+ if (currencyIn !== reference.key.currency0 && currencyIn !== reference.key.currency1)
47
+ invalid('Input currency does not belong to this pool');
48
+ if (typeof input.amountIn !== 'bigint' || input.amountIn <= 0n || input.amountIn >= 1n << 128n)
49
+ invalid('amountIn must be a positive uint128');
50
+ if (typeof input.hookData !== 'string' || !/^0x(?:[0-9a-fA-F]{2})*$/.test(input.hookData))
51
+ invalid('hookData must be explicit even-length hex bytes');
52
+ const blockNumber = await observationBlock(client, deployment, options.blockNumber);
53
+ await assertManager(client, deployment, deployment.quoter, blockNumber);
54
+ const zeroForOne = currencyIn === reference.key.currency0;
55
+ try {
56
+ const { result: [amountOut, gasEstimate] } = await client.simulateContract({
57
+ address: deployment.quoter, abi: v4QuoterAbi, functionName: 'quoteExactInputSingle', account, blockNumber,
58
+ args: [{ poolKey: reference.key, zeroForOne, exactAmount: input.amountIn, hookData: input.hookData }],
59
+ });
60
+ return { ...reference, blockNumber, currencyIn, currencyOut: zeroForOne ? reference.key.currency1 : reference.key.currency0, amountIn: input.amountIn, amountOut, gasEstimate, account, hookData: input.hookData, quoter: deployment.quoter };
61
+ }
62
+ catch (cause) {
63
+ throw new UniswapSdkError('QUOTE_FAILED', 'Quoter simulation failed; no executable quote is available', { cause });
64
+ }
65
+ }
66
+ /** Bounded concurrency, individual eth_calls preserve sender and isolate failures. */
67
+ export async function quoteV4Batch(client, deployment, key, inputs, options = {}) {
68
+ const concurrency = options.concurrency ?? 4;
69
+ if (!Number.isInteger(concurrency) || concurrency < 1 || concurrency > 16)
70
+ invalid('concurrency must be between 1 and 16');
71
+ if (inputs.length > 256)
72
+ invalid('At most 256 quotes may be requested per batch');
73
+ poolReference(deployment, key);
74
+ if (inputs.length === 0)
75
+ return [];
76
+ const blockNumber = await observationBlock(client, deployment, options.blockNumber);
77
+ const results = [];
78
+ for (let offset = 0; offset < inputs.length; offset += concurrency) {
79
+ results.push(...await Promise.all(inputs.slice(offset, offset + concurrency).map(async (input, i) => {
80
+ try {
81
+ return { status: 'success', quote: await quoteV4ExactInput(client, deployment, key, input, { blockNumber }) };
82
+ }
83
+ catch (cause) {
84
+ if (!(cause instanceof UniswapSdkError) || cause.code === 'CHAIN_MISMATCH' || cause.code === 'RPC_ERROR')
85
+ throw cause;
86
+ return { status: 'failure', index: offset + i, error: cause };
87
+ }
88
+ })));
89
+ }
90
+ return results;
91
+ }
92
+ //# sourceMappingURL=reads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reads.js","sourceRoot":"","sources":["../src/reads.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Address, type Hex, type PublicClient } from 'viem';\nimport { v4QuoterAbi, v4StateViewAbi } from './abis.js';\nimport { UniswapSdkError, invalid, rpc } from './errors.js';\nimport { checkedAddress, poolReference, validateDeployment, type V4Deployment, type V4PoolKey, type V4PoolReference } from './pool.js';\n\nexport type V4ReadClient = Pick<PublicClient, 'getChainId' | 'getBlockNumber' | 'readContract' | 'simulateContract'>;\nexport interface V4Observation extends V4PoolReference { blockNumber: bigint }\nexport interface V4PoolSnapshot extends V4Observation { sqrtPriceX96: bigint; tick: number; protocolFee: number; lpFee: number; liquidity: bigint }\n\nexport async function assertManager(client: V4ReadClient, deployment: V4Deployment, address: Address, blockNumber: bigint): Promise<void> {\n const manager = await rpc(() => client.readContract({ address, abi: v4StateViewAbi, functionName: 'poolManager', blockNumber }));\n if (manager.toLowerCase() !== deployment.poolManager.toLowerCase()) throw new UniswapSdkError('DEPLOYMENT_MISMATCH', 'Periphery points to a different PoolManager');\n}\n\nexport async function observationBlock(client: V4ReadClient, deployment: V4Deployment, blockNumber?: bigint): Promise<bigint> {\n validateDeployment(deployment);\n if (blockNumber !== undefined && (typeof blockNumber !== 'bigint' || blockNumber < 0n)) invalid('blockNumber must be a nonnegative bigint');\n return rpc(async () => {\n if (await client.getChainId() !== deployment.chainId) throw new UniswapSdkError('CHAIN_MISMATCH', 'RPC chain does not match the requested deployment');\n return blockNumber ?? await client.getBlockNumber();\n });\n}\n\n/** Wiring check only: not bytecode provenance or custom-hook compatibility. */\nexport async function verifyV4DeploymentWiring(client: V4ReadClient, deployment: V4Deployment, options: { blockNumber?: bigint } = {}) {\n const blockNumber = await observationBlock(client, deployment, options.blockNumber);\n const managers = await rpc(() => Promise.all([\n client.readContract({ address: deployment.stateView, abi: v4StateViewAbi, functionName: 'poolManager', blockNumber }),\n client.readContract({ address: deployment.quoter, abi: v4QuoterAbi, functionName: 'poolManager', blockNumber }),\n ]));\n if (managers.some(manager => manager.toLowerCase() !== deployment.poolManager.toLowerCase())) throw new UniswapSdkError('DEPLOYMENT_MISMATCH', 'StateView or Quoter points to a different PoolManager');\n return { deployment: validateDeployment(deployment), blockNumber };\n}\n\nexport async function readV4Pool(client: V4ReadClient, deployment: V4Deployment, key: V4PoolKey, options: { blockNumber?: bigint } = {}): Promise<V4PoolSnapshot> {\n const reference = poolReference(deployment, key);\n const blockNumber = await observationBlock(client, deployment, options.blockNumber);\n await assertManager(client, deployment, deployment.stateView, blockNumber);\n const [slot0, liquidity] = await rpc(() => Promise.all([\n client.readContract({ address: deployment.stateView, abi: v4StateViewAbi, functionName: 'getSlot0', args: [reference.poolId], blockNumber }),\n client.readContract({ address: deployment.stateView, abi: v4StateViewAbi, functionName: 'getLiquidity', args: [reference.poolId], blockNumber }),\n ]));\n if (slot0[0] === 0n) throw new UniswapSdkError('POOL_NOT_FOUND', 'Pool is not initialized at the requested block');\n return { ...reference, blockNumber, sqrtPriceX96: slot0[0], tick: slot0[1], protocolFee: slot0[2], lpFee: slot0[3], liquidity };\n}\n\nexport interface V4QuoteInput {\n currencyIn: Address;\n amountIn: bigint;\n /** Required even when empty: custom hook encoding belongs to the protocol adapter. */\n hookData: Hex;\n /** eth_call sender; hooks may still see the Quoter as their caller. */\n account: Address;\n}\nexport interface V4Quote extends V4Observation {\n currencyIn: Address; currencyOut: Address; amountIn: bigint; amountOut: bigint; gasEstimate: bigint;\n account: Address; hookData: Hex; quoter: Address;\n}\n\nexport async function quoteV4ExactInput(client: V4ReadClient, deployment: V4Deployment, key: V4PoolKey, input: V4QuoteInput, options: { blockNumber?: bigint } = {}): Promise<V4Quote> {\n const reference = poolReference(deployment, key);\n const currencyIn = checkedAddress(input.currencyIn);\n const account = checkedAddress(input.account);\n if (currencyIn !== reference.key.currency0 && currencyIn !== reference.key.currency1) invalid('Input currency does not belong to this pool');\n if (typeof input.amountIn !== 'bigint' || input.amountIn <= 0n || input.amountIn >= 1n << 128n) invalid('amountIn must be a positive uint128');\n if (typeof input.hookData !== 'string' || !/^0x(?:[0-9a-fA-F]{2})*$/.test(input.hookData)) invalid('hookData must be explicit even-length hex bytes');\n const blockNumber = await observationBlock(client, deployment, options.blockNumber);\n await assertManager(client, deployment, deployment.quoter, blockNumber);\n const zeroForOne = currencyIn === reference.key.currency0;\n try {\n const { result: [amountOut, gasEstimate] } = await client.simulateContract({\n address: deployment.quoter, abi: v4QuoterAbi, functionName: 'quoteExactInputSingle', account, blockNumber,\n args: [{ poolKey: reference.key, zeroForOne, exactAmount: input.amountIn, hookData: input.hookData }],\n });\n return { ...reference, blockNumber, currencyIn, currencyOut: zeroForOne ? reference.key.currency1 : reference.key.currency0, amountIn: input.amountIn, amountOut, gasEstimate, account, hookData: input.hookData, quoter: deployment.quoter };\n } catch (cause) { throw new UniswapSdkError('QUOTE_FAILED', 'Quoter simulation failed; no executable quote is available', { cause }); }\n}\n\nexport type V4QuoteResult = { status: 'success'; quote: V4Quote } | { status: 'failure'; index: number; error: UniswapSdkError };\n\n/** Bounded concurrency, individual eth_calls preserve sender and isolate failures. */\nexport async function quoteV4Batch(client: V4ReadClient, deployment: V4Deployment, key: V4PoolKey, inputs: readonly V4QuoteInput[], options: { blockNumber?: bigint; concurrency?: number } = {}): Promise<V4QuoteResult[]> {\n const concurrency = options.concurrency ?? 4;\n if (!Number.isInteger(concurrency) || concurrency < 1 || concurrency > 16) invalid('concurrency must be between 1 and 16');\n if (inputs.length > 256) invalid('At most 256 quotes may be requested per batch');\n poolReference(deployment, key);\n if (inputs.length === 0) return [];\n const blockNumber = await observationBlock(client, deployment, options.blockNumber);\n const results: V4QuoteResult[] = [];\n for (let offset = 0; offset < inputs.length; offset += concurrency) {\n results.push(...await Promise.all(inputs.slice(offset, offset + concurrency).map(async (input, i): Promise<V4QuoteResult> => {\n try { return { status: 'success', quote: await quoteV4ExactInput(client, deployment, key, input, { blockNumber }) }; }\n catch (cause) {\n if (!(cause instanceof UniswapSdkError) || cause.code === 'CHAIN_MISMATCH' || cause.code === 'RPC_ERROR') throw cause;\n return { status: 'failure', index: offset + i, error: cause };\n }\n })));\n }\n return results;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export * from './v3-receipts.js';
2
+ //# sourceMappingURL=receipts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipts.d.ts","sourceRoot":"","sources":["../src/receipts.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './v3-receipts.js';
2
+ //# sourceMappingURL=receipts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipts.js","sourceRoot":"","sources":["../src/receipts.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC","sourcesContent":["export * from './v3-receipts.js';\n"]}
@@ -0,0 +1,2 @@
1
+ export * from './v3-transactions.js';
2
+ //# sourceMappingURL=transactions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transactions.d.ts","sourceRoot":"","sources":["../src/transactions.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './v3-transactions.js';
2
+ //# sourceMappingURL=transactions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transactions.js","sourceRoot":"","sources":["../src/transactions.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC","sourcesContent":["export * from './v3-transactions.js';\n"]}