boing-sdk 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +191 -0
- package/dist/accessList.d.ts +22 -0
- package/dist/accessList.d.ts.map +1 -0
- package/dist/accessList.js +45 -0
- package/dist/bincode.d.ts +92 -0
- package/dist/bincode.d.ts.map +1 -0
- package/dist/bincode.js +154 -0
- package/dist/callAbi.d.ts +119 -0
- package/dist/callAbi.d.ts.map +1 -0
- package/dist/callAbi.js +156 -0
- package/dist/calldata.d.ts +35 -0
- package/dist/calldata.d.ts.map +1 -0
- package/dist/calldata.js +93 -0
- package/dist/canonicalDeployArtifacts.d.ts +154 -0
- package/dist/canonicalDeployArtifacts.d.ts.map +1 -0
- package/dist/canonicalDeployArtifacts.js +271 -0
- package/dist/canonicalTestnet.d.ts +15 -0
- package/dist/canonicalTestnet.d.ts.map +1 -0
- package/dist/canonicalTestnet.js +15 -0
- package/dist/canonicalTestnetDex.d.ts +17 -0
- package/dist/canonicalTestnetDex.d.ts.map +1 -0
- package/dist/canonicalTestnetDex.js +17 -0
- package/dist/chainIds.d.ts +18 -0
- package/dist/chainIds.d.ts.map +1 -0
- package/dist/chainIds.js +56 -0
- package/dist/client.d.ts +223 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +659 -0
- package/dist/connectionMonitor.d.ts +47 -0
- package/dist/connectionMonitor.d.ts.map +1 -0
- package/dist/connectionMonitor.js +93 -0
- package/dist/create2.d.ts +94 -0
- package/dist/create2.d.ts.map +1 -0
- package/dist/create2.js +225 -0
- package/dist/dappDeploy.d.ts +100 -0
- package/dist/dappDeploy.d.ts.map +1 -0
- package/dist/dappDeploy.js +140 -0
- package/dist/dappUiHelpers.d.ts +28 -0
- package/dist/dappUiHelpers.d.ts.map +1 -0
- package/dist/dappUiHelpers.js +69 -0
- package/dist/defaultReferenceFungibleSecuredRuntimeBytecodeHex.d.ts +6 -0
- package/dist/defaultReferenceFungibleSecuredRuntimeBytecodeHex.d.ts.map +1 -0
- package/dist/defaultReferenceFungibleSecuredRuntimeBytecodeHex.js +5 -0
- package/dist/defaultReferenceFungibleSecuredTemplateBytecodeHex.d.ts +6 -0
- package/dist/defaultReferenceFungibleSecuredTemplateBytecodeHex.d.ts.map +1 -0
- package/dist/defaultReferenceFungibleSecuredTemplateBytecodeHex.js +5 -0
- package/dist/defaultReferenceFungibleTemplateBytecodeHex.d.ts +6 -0
- package/dist/defaultReferenceFungibleTemplateBytecodeHex.d.ts.map +1 -0
- package/dist/defaultReferenceFungibleTemplateBytecodeHex.js +5 -0
- package/dist/defaultReferenceNftCollectionTemplateBytecodeHex.d.ts +7 -0
- package/dist/defaultReferenceNftCollectionTemplateBytecodeHex.d.ts.map +1 -0
- package/dist/defaultReferenceNftCollectionTemplateBytecodeHex.js +6 -0
- package/dist/dexIntegration.d.ts +61 -0
- package/dist/dexIntegration.d.ts.map +1 -0
- package/dist/dexIntegration.js +193 -0
- package/dist/erc721Logs.d.ts +21 -0
- package/dist/erc721Logs.d.ts.map +1 -0
- package/dist/erc721Logs.js +69 -0
- package/dist/errors.d.ts +60 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +153 -0
- package/dist/hex.d.ts +27 -0
- package/dist/hex.d.ts.map +1 -0
- package/dist/hex.js +82 -0
- package/dist/index.d.ts +83 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/indexerBatch.d.ts +111 -0
- package/dist/indexerBatch.d.ts.map +1 -0
- package/dist/indexerBatch.js +253 -0
- package/dist/indexerGaps.d.ts +50 -0
- package/dist/indexerGaps.d.ts.map +1 -0
- package/dist/indexerGaps.js +117 -0
- package/dist/indexerSync.d.ts +61 -0
- package/dist/indexerSync.d.ts.map +1 -0
- package/dist/indexerSync.js +100 -0
- package/dist/nativeAmm.d.ts +64 -0
- package/dist/nativeAmm.d.ts.map +1 -0
- package/dist/nativeAmm.js +174 -0
- package/dist/nativeAmmLogs.d.ts +48 -0
- package/dist/nativeAmmLogs.d.ts.map +1 -0
- package/dist/nativeAmmLogs.js +114 -0
- package/dist/nativeAmmLpVault.d.ts +94 -0
- package/dist/nativeAmmLpVault.d.ts.map +1 -0
- package/dist/nativeAmmLpVault.js +205 -0
- package/dist/nativeAmmPool.d.ts +124 -0
- package/dist/nativeAmmPool.d.ts.map +1 -0
- package/dist/nativeAmmPool.js +245 -0
- package/dist/nativeContractSubmit.d.ts +26 -0
- package/dist/nativeContractSubmit.d.ts.map +1 -0
- package/dist/nativeContractSubmit.js +23 -0
- package/dist/nativeDexDirectory.d.ts +83 -0
- package/dist/nativeDexDirectory.d.ts.map +1 -0
- package/dist/nativeDexDirectory.js +147 -0
- package/dist/nativeDexDirectoryApi.d.ts +121 -0
- package/dist/nativeDexDirectoryApi.d.ts.map +1 -0
- package/dist/nativeDexDirectoryApi.js +408 -0
- package/dist/nativeDexFactory.d.ts +25 -0
- package/dist/nativeDexFactory.d.ts.map +1 -0
- package/dist/nativeDexFactory.js +72 -0
- package/dist/nativeDexFactoryLogs.d.ts +19 -0
- package/dist/nativeDexFactoryLogs.d.ts.map +1 -0
- package/dist/nativeDexFactoryLogs.js +61 -0
- package/dist/nativeDexFactoryPool.d.ts +61 -0
- package/dist/nativeDexFactoryPool.d.ts.map +1 -0
- package/dist/nativeDexFactoryPool.js +120 -0
- package/dist/nativeDexIndexerStats.d.ts +96 -0
- package/dist/nativeDexIndexerStats.d.ts.map +1 -0
- package/dist/nativeDexIndexerStats.js +448 -0
- package/dist/nativeDexLedgerRouter.d.ts +67 -0
- package/dist/nativeDexLedgerRouter.d.ts.map +1 -0
- package/dist/nativeDexLedgerRouter.js +108 -0
- package/dist/nativeDexLpPositions.d.ts +39 -0
- package/dist/nativeDexLpPositions.d.ts.map +1 -0
- package/dist/nativeDexLpPositions.js +69 -0
- package/dist/nativeDexNftIndexer.d.ts +26 -0
- package/dist/nativeDexNftIndexer.d.ts.map +1 -0
- package/dist/nativeDexNftIndexer.js +50 -0
- package/dist/nativeDexPoolHistory.d.ts +40 -0
- package/dist/nativeDexPoolHistory.d.ts.map +1 -0
- package/dist/nativeDexPoolHistory.js +110 -0
- package/dist/nativeDexReceiptArchive.d.ts +25 -0
- package/dist/nativeDexReceiptArchive.d.ts.map +1 -0
- package/dist/nativeDexReceiptArchive.js +47 -0
- package/dist/nativeDexRouting.d.ts +160 -0
- package/dist/nativeDexRouting.d.ts.map +1 -0
- package/dist/nativeDexRouting.js +345 -0
- package/dist/nativeDexSeamless.d.ts +86 -0
- package/dist/nativeDexSeamless.d.ts.map +1 -0
- package/dist/nativeDexSeamless.js +131 -0
- package/dist/nativeDexSwap2Router.d.ts +45 -0
- package/dist/nativeDexSwap2Router.d.ts.map +1 -0
- package/dist/nativeDexSwap2Router.js +276 -0
- package/dist/nativeLpShareToken.d.ts +54 -0
- package/dist/nativeLpShareToken.d.ts.map +1 -0
- package/dist/nativeLpShareToken.js +135 -0
- package/dist/nativeTokenSecurity.d.ts +59 -0
- package/dist/nativeTokenSecurity.d.ts.map +1 -0
- package/dist/nativeTokenSecurity.js +59 -0
- package/dist/networkProfile.d.ts +8 -0
- package/dist/networkProfile.d.ts.map +1 -0
- package/dist/networkProfile.js +29 -0
- package/dist/newHeadsWs.d.ts +43 -0
- package/dist/newHeadsWs.d.ts.map +1 -0
- package/dist/newHeadsWs.js +139 -0
- package/dist/preflightGate.d.ts +16 -0
- package/dist/preflightGate.d.ts.map +1 -0
- package/dist/preflightGate.js +29 -0
- package/dist/receiptLogs.d.ts +29 -0
- package/dist/receiptLogs.d.ts.map +1 -0
- package/dist/receiptLogs.js +66 -0
- package/dist/referenceFungibleSecuredDeployBytecode.d.ts +54 -0
- package/dist/referenceFungibleSecuredDeployBytecode.d.ts.map +1 -0
- package/dist/referenceFungibleSecuredDeployBytecode.js +274 -0
- package/dist/referenceNft.d.ts +14 -0
- package/dist/referenceNft.d.ts.map +1 -0
- package/dist/referenceNft.js +34 -0
- package/dist/referenceToken.d.ts +14 -0
- package/dist/referenceToken.d.ts.map +1 -0
- package/dist/referenceToken.js +29 -0
- package/dist/retryAfter.d.ts +6 -0
- package/dist/retryAfter.d.ts.map +1 -0
- package/dist/retryAfter.js +24 -0
- package/dist/rpcCapabilities.d.ts +43 -0
- package/dist/rpcCapabilities.d.ts.map +1 -0
- package/dist/rpcCapabilities.js +159 -0
- package/dist/rpcDoctor.d.ts +27 -0
- package/dist/rpcDoctor.d.ts.map +1 -0
- package/dist/rpcDoctor.js +66 -0
- package/dist/rpcSurfaceUi.d.ts +32 -0
- package/dist/rpcSurfaceUi.d.ts.map +1 -0
- package/dist/rpcSurfaceUi.js +49 -0
- package/dist/submitFlow.d.ts +70 -0
- package/dist/submitFlow.d.ts.map +1 -0
- package/dist/submitFlow.js +121 -0
- package/dist/transactionBuilder.d.ts +55 -0
- package/dist/transactionBuilder.d.ts.map +1 -0
- package/dist/transactionBuilder.js +100 -0
- package/dist/types.d.ts +436 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/walletProvider.d.ts +46 -0
- package/dist/walletProvider.d.ts.map +1 -0
- package/dist/walletProvider.js +126 -0
- package/package.json +44 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native constant-product pool — `contract_call` + access list for Boing Express / JSON-RPC.
|
|
3
|
+
* Matches `Transaction::suggested_parallel_access_list` for `ContractCall` when only sender + pool touch state.
|
|
4
|
+
*
|
|
5
|
+
* Storage layout matches `boing_execution::native_amm`:
|
|
6
|
+
* reserves (`reserve_a_key` / `reserve_b_key`), total LP (`total_lp_supply_key`), per-signer LP (`lp_balance_storage_key`);
|
|
7
|
+
* **v3/v4:** `swap_fee_bps_key` (`k[31] == 0x07`).
|
|
8
|
+
* Amounts are u128 BE in the **low 16 bytes** of each 32-byte word.
|
|
9
|
+
*/
|
|
10
|
+
import { mergeAccessListWithSimulation } from './accessList.js';
|
|
11
|
+
import { ensureHex, validateHex32 } from './hex.js';
|
|
12
|
+
const HEX_RE = /^[0-9a-fA-F]+$/;
|
|
13
|
+
function normalizeCalldataHex(calldataHex) {
|
|
14
|
+
const h = ensureHex(calldataHex.trim());
|
|
15
|
+
const raw = h.slice(2);
|
|
16
|
+
if (raw.length % 2 !== 0) {
|
|
17
|
+
throw new Error('calldata must be even-length hex');
|
|
18
|
+
}
|
|
19
|
+
if (!HEX_RE.test(raw)) {
|
|
20
|
+
throw new Error('calldata: invalid hex');
|
|
21
|
+
}
|
|
22
|
+
return `0x${raw.toLowerCase()}`;
|
|
23
|
+
}
|
|
24
|
+
/** `read` and `write` both include signer + pool (parallel-scheduling minimum for pool-only bytecode). */
|
|
25
|
+
export function buildNativeConstantProductPoolAccessList(senderHex32, poolHex32, options) {
|
|
26
|
+
const s = validateHex32(senderHex32).toLowerCase();
|
|
27
|
+
const p = validateHex32(poolHex32).toLowerCase();
|
|
28
|
+
const extra = options?.additionalAccountsHex32 ?? [];
|
|
29
|
+
if (extra.length === 0) {
|
|
30
|
+
return { read: [s, p], write: [s, p] };
|
|
31
|
+
}
|
|
32
|
+
const seen = new Set([s, p]);
|
|
33
|
+
const sortedExtras = [];
|
|
34
|
+
for (const x of extra) {
|
|
35
|
+
const h = validateHex32(x).toLowerCase();
|
|
36
|
+
if (!seen.has(h)) {
|
|
37
|
+
seen.add(h);
|
|
38
|
+
sortedExtras.push(h);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
sortedExtras.sort();
|
|
42
|
+
const combined = [s, p, ...sortedExtras];
|
|
43
|
+
return { read: combined, write: [...combined] };
|
|
44
|
+
}
|
|
45
|
+
/** Params for `boing_sendTransaction` / Express `contract_call` with explicit access list. */
|
|
46
|
+
export function buildNativeConstantProductContractCallTx(senderHex32, poolHex32, calldataHex, options) {
|
|
47
|
+
return {
|
|
48
|
+
type: 'contract_call',
|
|
49
|
+
contract: validateHex32(poolHex32).toLowerCase(),
|
|
50
|
+
calldata: normalizeCalldataHex(calldataHex),
|
|
51
|
+
access_list: buildNativeConstantProductPoolAccessList(senderHex32, poolHex32, options),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Access list for **`contract_call`** into the native **multihop router**: signer, router, each pool in path order (deduped), then sorted extras (e.g. reference tokens).
|
|
56
|
+
*/
|
|
57
|
+
export function buildNativeDexMultihopRouterAccessList(senderHex32, routerHex32, poolHex32List, options) {
|
|
58
|
+
const s = validateHex32(senderHex32).toLowerCase();
|
|
59
|
+
const r = validateHex32(routerHex32).toLowerCase();
|
|
60
|
+
const seen = new Set([s, r]);
|
|
61
|
+
const ordered = [s, r];
|
|
62
|
+
for (const pool of poolHex32List) {
|
|
63
|
+
const p = validateHex32(pool).toLowerCase();
|
|
64
|
+
if (!seen.has(p)) {
|
|
65
|
+
seen.add(p);
|
|
66
|
+
ordered.push(p);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const extra = options?.additionalAccountsHex32 ?? [];
|
|
70
|
+
const sortedExtras = [];
|
|
71
|
+
for (const x of extra) {
|
|
72
|
+
const h = validateHex32(x).toLowerCase();
|
|
73
|
+
if (!seen.has(h)) {
|
|
74
|
+
seen.add(h);
|
|
75
|
+
sortedExtras.push(h);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
sortedExtras.sort();
|
|
79
|
+
const combined = [...ordered, ...sortedExtras];
|
|
80
|
+
return { read: combined, write: [...combined] };
|
|
81
|
+
}
|
|
82
|
+
/** Multihop router **`contract_call`** with {@link buildNativeDexMultihopRouterAccessList}. */
|
|
83
|
+
export function buildNativeDexMultihopRouterContractCallTx(senderHex32, routerHex32, calldataHex, poolHex32List, options) {
|
|
84
|
+
return {
|
|
85
|
+
type: 'contract_call',
|
|
86
|
+
contract: validateHex32(routerHex32).toLowerCase(),
|
|
87
|
+
calldata: normalizeCalldataHex(calldataHex),
|
|
88
|
+
access_list: buildNativeDexMultihopRouterAccessList(senderHex32, routerHex32, poolHex32List, options),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Widen multihop router access list with `sim.suggested_access_list` (e.g. after `boing_simulateTransaction`).
|
|
93
|
+
*/
|
|
94
|
+
export function mergeNativeDexMultihopRouterAccessListWithSimulation(senderHex32, routerHex32, poolHex32List, sim, options) {
|
|
95
|
+
const base = buildNativeDexMultihopRouterAccessList(senderHex32, routerHex32, poolHex32List, options);
|
|
96
|
+
return mergeAccessListWithSimulation(base.read, base.write, sim);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Widen `read`/`write` with `sim.suggested_access_list` (e.g. after `boing_simulateTransaction`).
|
|
100
|
+
*/
|
|
101
|
+
export function mergeNativePoolAccessListWithSimulation(senderHex32, poolHex32, sim, options) {
|
|
102
|
+
const base = buildNativeConstantProductPoolAccessList(senderHex32, poolHex32, options);
|
|
103
|
+
return mergeAccessListWithSimulation(base.read, base.write, sim);
|
|
104
|
+
}
|
|
105
|
+
/** `boing_getContractStorage` key for reserve A (`native_amm::reserve_a_key`). */
|
|
106
|
+
export const NATIVE_CONSTANT_PRODUCT_RESERVE_A_KEY_HEX = `0x${'00'.repeat(31)}01`;
|
|
107
|
+
/** `boing_getContractStorage` key for reserve B (`native_amm::reserve_b_key`). */
|
|
108
|
+
export const NATIVE_CONSTANT_PRODUCT_RESERVE_B_KEY_HEX = `0x${'00'.repeat(31)}02`;
|
|
109
|
+
/** Total LP supply key (`native_amm::total_lp_supply_key`, `k[31] == 0x03`). */
|
|
110
|
+
export const NATIVE_CONSTANT_PRODUCT_TOTAL_LP_KEY_HEX = `0x${'00'.repeat(31)}03`;
|
|
111
|
+
/** **v2:** On-chain reference-token id for reserve side A (`token_a_key`, `k[31] == 0x04`). */
|
|
112
|
+
export const NATIVE_CONSTANT_PRODUCT_TOKEN_A_KEY_HEX = `0x${'00'.repeat(31)}04`;
|
|
113
|
+
/** **v2:** Reference-token id for side B (`k[31] == 0x05`). */
|
|
114
|
+
export const NATIVE_CONSTANT_PRODUCT_TOKEN_B_KEY_HEX = `0x${'00'.repeat(31)}05`;
|
|
115
|
+
/** **v2:** Non-zero after successful `set_tokens` (`k[31] == 0x06`). */
|
|
116
|
+
export const NATIVE_CONSTANT_PRODUCT_TOKENS_CONFIGURED_KEY_HEX = `0x${'00'.repeat(31)}06`;
|
|
117
|
+
/** **v3/v4:** Swap fee bps on output (`swap_fee_bps_key`, `k[31] == 0x07`). **`0`** = unset until first `add_liquidity` (then defaults to **`NATIVE_CP_SWAP_FEE_BPS`** on-chain). */
|
|
118
|
+
export const NATIVE_CONSTANT_PRODUCT_SWAP_FEE_BPS_KEY_HEX = `0x${'00'.repeat(31)}07`;
|
|
119
|
+
const LP_BALANCE_XOR_U8 = (() => {
|
|
120
|
+
const u8 = new Uint8Array(32);
|
|
121
|
+
u8.set(new TextEncoder().encode('BOING_NATIVEAMM_LPRV1'));
|
|
122
|
+
return u8;
|
|
123
|
+
})();
|
|
124
|
+
/**
|
|
125
|
+
* `boing_getContractStorage` key for the caller's LP balance (`native_amm::lp_balance_storage_key`).
|
|
126
|
+
*/
|
|
127
|
+
export function nativeAmmLpBalanceStorageKeyHex(senderHex32) {
|
|
128
|
+
const raw = validateHex32(senderHex32).slice(2).toLowerCase();
|
|
129
|
+
let out = '';
|
|
130
|
+
for (let i = 0; i < 32; i++) {
|
|
131
|
+
const b = parseInt(raw.slice(i * 2, i * 2 + 2), 16) ^ LP_BALANCE_XOR_U8[i];
|
|
132
|
+
out += b.toString(16).padStart(2, '0');
|
|
133
|
+
}
|
|
134
|
+
return `0x${out}`;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Decode **u128** from a 32-byte Boing contract storage word (`value` from `boing_getContractStorage`):
|
|
138
|
+
* big-endian integer in the **low 16 bytes** (high 16 bytes ignored), matching reference-token amount words.
|
|
139
|
+
*/
|
|
140
|
+
export function decodeBoingStorageWordU128(valueHex) {
|
|
141
|
+
const raw = ensureHex(valueHex).slice(2).toLowerCase();
|
|
142
|
+
if (raw.length === 0)
|
|
143
|
+
return 0n;
|
|
144
|
+
if (raw.length % 2 !== 0) {
|
|
145
|
+
throw new Error('storage word: hex length must be even');
|
|
146
|
+
}
|
|
147
|
+
if (!HEX_RE.test(raw)) {
|
|
148
|
+
throw new Error('storage word: invalid hex');
|
|
149
|
+
}
|
|
150
|
+
const word64 = raw.length > 64 ? raw.slice(-64) : raw.padStart(64, '0');
|
|
151
|
+
const low16BytesHex = word64.slice(32);
|
|
152
|
+
return BigInt(`0x${low16BytesHex}`);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Decode successful native pool **`add_liquidity`** contract return data: **exactly 32 bytes** (64 hex
|
|
156
|
+
* chars), **u128** LP minted in the **low 16 bytes**; high 16 bytes must be zero (canonical amount word).
|
|
157
|
+
*/
|
|
158
|
+
export function decodeNativeAmmAddLiquidityReturnLpMinted(returnDataHex) {
|
|
159
|
+
const raw = ensureHex(returnDataHex).slice(2).toLowerCase();
|
|
160
|
+
if (raw.length % 2 !== 0) {
|
|
161
|
+
throw new Error('add_liquidity return: hex length must be even');
|
|
162
|
+
}
|
|
163
|
+
if (raw.length !== 64) {
|
|
164
|
+
throw new Error('add_liquidity return: expected exactly 32 bytes (64 hex chars)');
|
|
165
|
+
}
|
|
166
|
+
if (!HEX_RE.test(raw)) {
|
|
167
|
+
throw new Error('add_liquidity return: invalid hex');
|
|
168
|
+
}
|
|
169
|
+
if (!raw.slice(0, 32).match(/^0+$/)) {
|
|
170
|
+
throw new Error('add_liquidity return: high 16 bytes must be zero');
|
|
171
|
+
}
|
|
172
|
+
return decodeBoingStorageWordU128(`0x${raw}`);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Decode native AMM `Log2` **data** (96 bytes): three u128 words (low 16 bytes of each 32-byte word), per `NATIVE-AMM-CALLDATA.md` § Logs.
|
|
176
|
+
*/
|
|
177
|
+
export function decodeNativeAmmLogDataU128Triple(dataHex) {
|
|
178
|
+
const raw = ensureHex(dataHex).slice(2).toLowerCase();
|
|
179
|
+
if (!HEX_RE.test(raw)) {
|
|
180
|
+
throw new Error('native AMM log data: invalid hex');
|
|
181
|
+
}
|
|
182
|
+
if (raw.length < 192) {
|
|
183
|
+
throw new Error('native AMM log data: expected at least 96 bytes (192 hex chars)');
|
|
184
|
+
}
|
|
185
|
+
const w = (start) => decodeBoingStorageWordU128(`0x${raw.slice(start, start + 64)}`);
|
|
186
|
+
return [w(0), w(64), w(128)];
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Read both in-ledger reserves for the MVP constant-product pool (`Promise.all` of two storage reads).
|
|
190
|
+
*/
|
|
191
|
+
export async function fetchNativeConstantProductReserves(client, poolHex32) {
|
|
192
|
+
const pool = validateHex32(poolHex32);
|
|
193
|
+
const [wa, wb] = await Promise.all([
|
|
194
|
+
client.getContractStorage(pool, NATIVE_CONSTANT_PRODUCT_RESERVE_A_KEY_HEX),
|
|
195
|
+
client.getContractStorage(pool, NATIVE_CONSTANT_PRODUCT_RESERVE_B_KEY_HEX),
|
|
196
|
+
]);
|
|
197
|
+
return {
|
|
198
|
+
reserveA: decodeBoingStorageWordU128(wa.value),
|
|
199
|
+
reserveB: decodeBoingStorageWordU128(wb.value),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/** Single `boing_getContractStorage` read for **`total_lp_supply_key`**. */
|
|
203
|
+
export async function fetchNativeConstantProductTotalLpSupply(client, poolHex32) {
|
|
204
|
+
const pool = validateHex32(poolHex32);
|
|
205
|
+
const w = await client.getContractStorage(pool, NATIVE_CONSTANT_PRODUCT_TOTAL_LP_KEY_HEX);
|
|
206
|
+
return decodeBoingStorageWordU128(w.value);
|
|
207
|
+
}
|
|
208
|
+
/** **v3/v4:** Raw u128 at **`swap_fee_bps_key`**. Use **`0n`** → default fee **`NATIVE_CP_SWAP_FEE_BPS`** when quoting swaps. */
|
|
209
|
+
export async function fetchNativeConstantProductSwapFeeBps(client, poolHex32) {
|
|
210
|
+
const pool = validateHex32(poolHex32);
|
|
211
|
+
const w = await client.getContractStorage(pool, NATIVE_CONSTANT_PRODUCT_SWAP_FEE_BPS_KEY_HEX);
|
|
212
|
+
return decodeBoingStorageWordU128(w.value);
|
|
213
|
+
}
|
|
214
|
+
/** LP balance for **`signerHex32`** in **`poolHex32`** (XOR-derived storage key). */
|
|
215
|
+
export async function fetchNativeAmmSignerLpBalance(client, poolHex32, signerHex32) {
|
|
216
|
+
const pool = validateHex32(poolHex32);
|
|
217
|
+
const key = nativeAmmLpBalanceStorageKeyHex(signerHex32);
|
|
218
|
+
const w = await client.getContractStorage(pool, key);
|
|
219
|
+
return decodeBoingStorageWordU128(w.value);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* One round-trip batch: reserves + total LP, and optionally the given signer's LP balance (**3** or **4** parallel storage reads).
|
|
223
|
+
*/
|
|
224
|
+
export async function fetchNativeConstantProductPoolSnapshot(client, poolHex32, options) {
|
|
225
|
+
const pool = validateHex32(poolHex32);
|
|
226
|
+
const signer = options?.signerHex32?.trim();
|
|
227
|
+
const reads = [
|
|
228
|
+
client.getContractStorage(pool, NATIVE_CONSTANT_PRODUCT_RESERVE_A_KEY_HEX),
|
|
229
|
+
client.getContractStorage(pool, NATIVE_CONSTANT_PRODUCT_RESERVE_B_KEY_HEX),
|
|
230
|
+
client.getContractStorage(pool, NATIVE_CONSTANT_PRODUCT_TOTAL_LP_KEY_HEX),
|
|
231
|
+
];
|
|
232
|
+
if (signer) {
|
|
233
|
+
reads.push(client.getContractStorage(pool, nativeAmmLpBalanceStorageKeyHex(signer)));
|
|
234
|
+
}
|
|
235
|
+
const out = await Promise.all(reads);
|
|
236
|
+
const snap = {
|
|
237
|
+
reserveA: decodeBoingStorageWordU128(out[0].value),
|
|
238
|
+
reserveB: decodeBoingStorageWordU128(out[1].value),
|
|
239
|
+
totalLpSupply: decodeBoingStorageWordU128(out[2].value),
|
|
240
|
+
};
|
|
241
|
+
if (signer && out[3]) {
|
|
242
|
+
snap.signerLpBalance = decodeBoingStorageWordU128(out[3].value);
|
|
243
|
+
}
|
|
244
|
+
return snap;
|
|
245
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin ergonomic wrapper around `submitContractCallWithSimulationRetry` for a fixed contract + signer.
|
|
3
|
+
*/
|
|
4
|
+
import type { BoingClient } from './client.js';
|
|
5
|
+
import { type SubmitContractCallWithSimulationOptions, type SubmitFlowResult } from './submitFlow.js';
|
|
6
|
+
import type { Ed25519SecretKey32 } from './transactionBuilder.js';
|
|
7
|
+
export interface NativeContractSubmitterConfig {
|
|
8
|
+
client: BoingClient;
|
|
9
|
+
secretKey32: Ed25519SecretKey32;
|
|
10
|
+
senderHex: string;
|
|
11
|
+
contractHex: string;
|
|
12
|
+
/** Default access list for calls (signer + contract is typical). */
|
|
13
|
+
accessList?: {
|
|
14
|
+
read: string[];
|
|
15
|
+
write: string[];
|
|
16
|
+
};
|
|
17
|
+
maxSimulationRetries?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Factory for repeated `ContractCall` submits to one contract with shared signer/client options.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createNativeContractSubmitter(config: NativeContractSubmitterConfig): {
|
|
23
|
+
/** Submit arbitrary calldata with simulate → access-list retry → submit. */
|
|
24
|
+
submitCalldata(calldata: Uint8Array, overrides?: Pick<SubmitContractCallWithSimulationOptions, "accessList" | "maxSimulationRetries">): Promise<SubmitFlowResult>;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=nativeContractSubmit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeContractSubmit.d.ts","sourceRoot":"","sources":["../src/nativeContractSubmit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAEL,KAAK,uCAAuC,EAC5C,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,kBAAkB,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACjD,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,6BAA6B;IAE/E,4EAA4E;6BAEhE,UAAU,cACR,IAAI,CACd,uCAAuC,EACvC,YAAY,GAAG,sBAAsB,CACtC,GACA,OAAO,CAAC,gBAAgB,CAAC;EAY/B"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin ergonomic wrapper around `submitContractCallWithSimulationRetry` for a fixed contract + signer.
|
|
3
|
+
*/
|
|
4
|
+
import { submitContractCallWithSimulationRetry, } from './submitFlow.js';
|
|
5
|
+
/**
|
|
6
|
+
* Factory for repeated `ContractCall` submits to one contract with shared signer/client options.
|
|
7
|
+
*/
|
|
8
|
+
export function createNativeContractSubmitter(config) {
|
|
9
|
+
return {
|
|
10
|
+
/** Submit arbitrary calldata with simulate → access-list retry → submit. */
|
|
11
|
+
async submitCalldata(calldata, overrides) {
|
|
12
|
+
return submitContractCallWithSimulationRetry({
|
|
13
|
+
client: config.client,
|
|
14
|
+
secretKey32: config.secretKey32,
|
|
15
|
+
senderHex: config.senderHex,
|
|
16
|
+
contractHex: config.contractHex,
|
|
17
|
+
calldata,
|
|
18
|
+
accessList: overrides?.accessList ?? config.accessList,
|
|
19
|
+
maxSimulationRetries: overrides?.maxSimulationRetries ?? config.maxSimulationRetries,
|
|
20
|
+
});
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native DEX pair directory — single Boing RPC surface (no external chains).
|
|
3
|
+
*
|
|
4
|
+
* Composes {@link fetchNativeDexIntegrationDefaults}, factory storage reads, and optional
|
|
5
|
+
* **`register_pair`** log backfill into one snapshot; helpers resolve **`(tokenA, tokenB)` → pool**.
|
|
6
|
+
*/
|
|
7
|
+
import type { BoingClient } from './client.js';
|
|
8
|
+
import { type NativeDexIntegrationDefaults, type NativeDexIntegrationOverrides } from './dexIntegration.js';
|
|
9
|
+
import { type FindNativeDexFactoryPoolOptions } from './nativeDexFactoryPool.js';
|
|
10
|
+
import type { NativeDexFactoryRegisterRpcParsed } from './nativeDexFactoryLogs.js';
|
|
11
|
+
/** Snapshot of operator hints + on-chain directory state (Boing RPC only). */
|
|
12
|
+
export type NativeDexDirectorySnapshot = {
|
|
13
|
+
chainId: number | null;
|
|
14
|
+
headHeight: number;
|
|
15
|
+
defaults: NativeDexIntegrationDefaults;
|
|
16
|
+
/** Factory storage **`pairs_count`** when factory address is known; otherwise **`null`**. */
|
|
17
|
+
pairsCount: bigint | null;
|
|
18
|
+
/**
|
|
19
|
+
* Parsed **`register_pair`** logs when {@link FetchNativeDexDirectorySnapshotOptions.registerLogs} was set
|
|
20
|
+
* and a factory address was resolved; otherwise **`null`** (not fetched).
|
|
21
|
+
*/
|
|
22
|
+
registerLogs: NativeDexFactoryRegisterRpcParsed[] | null;
|
|
23
|
+
};
|
|
24
|
+
export type FetchNativeDexDirectorySnapshotOptions = {
|
|
25
|
+
overrides?: NativeDexIntegrationOverrides;
|
|
26
|
+
/**
|
|
27
|
+
* Inclusive block range for **`boing_getLogs`** (**`register_pair`** on the factory).
|
|
28
|
+
* **`toBlock`** defaults to the chain head from the same **`getNetworkInfo`** snapshot.
|
|
29
|
+
*/
|
|
30
|
+
registerLogs?: {
|
|
31
|
+
fromBlock: number;
|
|
32
|
+
toBlock?: number;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Plan the next inclusive **`register_pair`** log scan for an indexer (Boing RPC only).
|
|
37
|
+
* Returns **`null`** when already caught up (**`lastScannedBlockInclusive` ≥ `headHeight`**).
|
|
38
|
+
*/
|
|
39
|
+
export declare function suggestNativeDexRegisterLogCatchUpRange(opts: {
|
|
40
|
+
headHeight: number;
|
|
41
|
+
lastScannedBlockInclusive: number | null;
|
|
42
|
+
}): {
|
|
43
|
+
fromBlock: number;
|
|
44
|
+
toBlock: number;
|
|
45
|
+
} | null;
|
|
46
|
+
/** Canonical map key for an unordered token pair (lowercased **32-byte** hex ids). */
|
|
47
|
+
export declare function nativeDexPairKey(tokenAHex32: string, tokenBHex32: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Build **`pairKey → poolHex`** from register logs. Later log entries win (on-chain re-register / ordering).
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildNativeDexRegisterLogPoolIndex(logs: readonly NativeDexFactoryRegisterRpcParsed[]): ReadonlyMap<string, `0x${string}`>;
|
|
52
|
+
/** Resolve pool for **`(tokenA, tokenB)`** in either order using a register-log index. */
|
|
53
|
+
export declare function pickNativeDexPoolFromRegisterLogs(logs: readonly NativeDexFactoryRegisterRpcParsed[], tokenAHex32: string, tokenBHex32: string): `0x${string}` | null;
|
|
54
|
+
/**
|
|
55
|
+
* Fetch network hints, optional factory pair count, and optional **`register_pair`** logs — **Boing RPC only**.
|
|
56
|
+
*/
|
|
57
|
+
export declare function fetchNativeDexDirectorySnapshot(client: BoingClient, options?: FetchNativeDexDirectorySnapshotOptions): Promise<NativeDexDirectorySnapshot>;
|
|
58
|
+
export type ResolveNativeDexPoolForTokensResult = {
|
|
59
|
+
poolHex: `0x${string}` | null;
|
|
60
|
+
factoryHex: `0x${string}` | null;
|
|
61
|
+
via: 'logs' | 'simulate' | 'none';
|
|
62
|
+
};
|
|
63
|
+
export type ResolveNativeDexPoolForTokensOptions = {
|
|
64
|
+
kind: 'logs';
|
|
65
|
+
overrides?: NativeDexIntegrationOverrides;
|
|
66
|
+
fromBlock: number;
|
|
67
|
+
toBlock?: number;
|
|
68
|
+
} | {
|
|
69
|
+
kind: 'simulate';
|
|
70
|
+
overrides?: NativeDexIntegrationOverrides;
|
|
71
|
+
find: FindNativeDexFactoryPoolOptions;
|
|
72
|
+
} | {
|
|
73
|
+
kind: 'auto';
|
|
74
|
+
overrides?: NativeDexIntegrationOverrides;
|
|
75
|
+
fromBlock: number;
|
|
76
|
+
toBlock?: number;
|
|
77
|
+
find: FindNativeDexFactoryPoolOptions;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Resolve **`tokenA` / `tokenB` → pool** using logs and/or directory simulation (**Boing-only**).
|
|
81
|
+
*/
|
|
82
|
+
export declare function resolveNativeDexPoolForTokens(client: BoingClient, tokenAHex32: string, tokenBHex32: string, options: ResolveNativeDexPoolForTokensOptions): Promise<ResolveNativeDexPoolForTokensResult>;
|
|
83
|
+
//# sourceMappingURL=nativeDexDirectory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeDexDirectory.d.ts","sourceRoot":"","sources":["../src/nativeDexDirectory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native DEX pair directory — single Boing RPC surface (no external chains).
|
|
3
|
+
*
|
|
4
|
+
* Composes {@link fetchNativeDexIntegrationDefaults}, factory storage reads, and optional
|
|
5
|
+
* **`register_pair`** log backfill into one snapshot; helpers resolve **`(tokenA, tokenB)` → pool**.
|
|
6
|
+
*/
|
|
7
|
+
import { fetchNativeDexFactoryRegisterLogs, fetchNativeDexIntegrationDefaults, mergeNativeDexIntegrationDefaults, } from './dexIntegration.js';
|
|
8
|
+
import { validateHex32 } from './hex.js';
|
|
9
|
+
import { fetchNativeDexFactoryPairsCount, findNativeDexFactoryPoolByTokens, } from './nativeDexFactoryPool.js';
|
|
10
|
+
function clampBlock(n, lo, hi) {
|
|
11
|
+
if (n < lo)
|
|
12
|
+
return lo;
|
|
13
|
+
if (n > hi)
|
|
14
|
+
return hi;
|
|
15
|
+
return n;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Plan the next inclusive **`register_pair`** log scan for an indexer (Boing RPC only).
|
|
19
|
+
* Returns **`null`** when already caught up (**`lastScannedBlockInclusive` ≥ `headHeight`**).
|
|
20
|
+
*/
|
|
21
|
+
export function suggestNativeDexRegisterLogCatchUpRange(opts) {
|
|
22
|
+
if (!Number.isInteger(opts.headHeight) || opts.headHeight < 0) {
|
|
23
|
+
throw new RangeError('headHeight must be a non-negative integer');
|
|
24
|
+
}
|
|
25
|
+
if (opts.lastScannedBlockInclusive != null) {
|
|
26
|
+
if (!Number.isInteger(opts.lastScannedBlockInclusive) || opts.lastScannedBlockInclusive < -1) {
|
|
27
|
+
throw new RangeError('lastScannedBlockInclusive must be null or an integer >= -1');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (opts.lastScannedBlockInclusive == null || opts.lastScannedBlockInclusive < 0) {
|
|
31
|
+
return { fromBlock: 0, toBlock: opts.headHeight };
|
|
32
|
+
}
|
|
33
|
+
const next = opts.lastScannedBlockInclusive + 1;
|
|
34
|
+
if (next > opts.headHeight)
|
|
35
|
+
return null;
|
|
36
|
+
return { fromBlock: next, toBlock: opts.headHeight };
|
|
37
|
+
}
|
|
38
|
+
/** Canonical map key for an unordered token pair (lowercased **32-byte** hex ids). */
|
|
39
|
+
export function nativeDexPairKey(tokenAHex32, tokenBHex32) {
|
|
40
|
+
const a = validateHex32(tokenAHex32).toLowerCase();
|
|
41
|
+
const b = validateHex32(tokenBHex32).toLowerCase();
|
|
42
|
+
return a < b ? `${a}:${b}` : `${b}:${a}`;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Build **`pairKey → poolHex`** from register logs. Later log entries win (on-chain re-register / ordering).
|
|
46
|
+
*/
|
|
47
|
+
export function buildNativeDexRegisterLogPoolIndex(logs) {
|
|
48
|
+
const m = new Map();
|
|
49
|
+
for (const row of logs) {
|
|
50
|
+
const k = nativeDexPairKey(row.tokenAHex, row.tokenBHex);
|
|
51
|
+
m.set(k, validateHex32(row.poolHex));
|
|
52
|
+
}
|
|
53
|
+
return m;
|
|
54
|
+
}
|
|
55
|
+
/** Resolve pool for **`(tokenA, tokenB)`** in either order using a register-log index. */
|
|
56
|
+
export function pickNativeDexPoolFromRegisterLogs(logs, tokenAHex32, tokenBHex32) {
|
|
57
|
+
const idx = buildNativeDexRegisterLogPoolIndex(logs);
|
|
58
|
+
return idx.get(nativeDexPairKey(tokenAHex32, tokenBHex32)) ?? null;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Fetch network hints, optional factory pair count, and optional **`register_pair`** logs — **Boing RPC only**.
|
|
62
|
+
*/
|
|
63
|
+
export async function fetchNativeDexDirectorySnapshot(client, options) {
|
|
64
|
+
const info = await client.getNetworkInfo();
|
|
65
|
+
const headHeight = info.head_height;
|
|
66
|
+
const defaults = mergeNativeDexIntegrationDefaults(info, options?.overrides);
|
|
67
|
+
const factoryHex = defaults.nativeDexFactoryAccountHex;
|
|
68
|
+
let pairsCount = null;
|
|
69
|
+
if (factoryHex != null) {
|
|
70
|
+
pairsCount = await fetchNativeDexFactoryPairsCount(client, factoryHex);
|
|
71
|
+
}
|
|
72
|
+
let registerLogs = null;
|
|
73
|
+
const rl = options?.registerLogs;
|
|
74
|
+
if (rl != null && factoryHex != null) {
|
|
75
|
+
const fromBlock = rl.fromBlock;
|
|
76
|
+
const toBlock = clampBlock(rl.toBlock ?? headHeight, 0, headHeight);
|
|
77
|
+
if (fromBlock <= toBlock) {
|
|
78
|
+
registerLogs = await fetchNativeDexFactoryRegisterLogs(client, {
|
|
79
|
+
factoryAccountHex: factoryHex,
|
|
80
|
+
fromBlock,
|
|
81
|
+
toBlock,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
registerLogs = [];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
chainId: info.chain_id ?? null,
|
|
90
|
+
headHeight,
|
|
91
|
+
defaults,
|
|
92
|
+
pairsCount,
|
|
93
|
+
registerLogs,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Resolve **`tokenA` / `tokenB` → pool** using logs and/or directory simulation (**Boing-only**).
|
|
98
|
+
*/
|
|
99
|
+
export async function resolveNativeDexPoolForTokens(client, tokenAHex32, tokenBHex32, options) {
|
|
100
|
+
switch (options.kind) {
|
|
101
|
+
case 'logs': {
|
|
102
|
+
const snap = await fetchNativeDexDirectorySnapshot(client, {
|
|
103
|
+
overrides: options.overrides,
|
|
104
|
+
registerLogs: { fromBlock: options.fromBlock, toBlock: options.toBlock },
|
|
105
|
+
});
|
|
106
|
+
const fac = snap.defaults.nativeDexFactoryAccountHex;
|
|
107
|
+
if (fac == null || snap.registerLogs == null) {
|
|
108
|
+
return { poolHex: null, factoryHex: fac, via: 'none' };
|
|
109
|
+
}
|
|
110
|
+
const poolHex = pickNativeDexPoolFromRegisterLogs(snap.registerLogs, tokenAHex32, tokenBHex32);
|
|
111
|
+
return { poolHex, factoryHex: fac, via: poolHex != null ? 'logs' : 'none' };
|
|
112
|
+
}
|
|
113
|
+
case 'simulate': {
|
|
114
|
+
const d = await fetchNativeDexIntegrationDefaults(client, options.overrides);
|
|
115
|
+
const fac = d.nativeDexFactoryAccountHex;
|
|
116
|
+
if (fac == null) {
|
|
117
|
+
return { poolHex: null, factoryHex: null, via: 'none' };
|
|
118
|
+
}
|
|
119
|
+
const poolHexRaw = await findNativeDexFactoryPoolByTokens(client, fac, tokenAHex32, tokenBHex32, options.find);
|
|
120
|
+
const poolHex = poolHexRaw != null ? validateHex32(poolHexRaw) : null;
|
|
121
|
+
return { poolHex, factoryHex: fac, via: poolHex != null ? 'simulate' : 'none' };
|
|
122
|
+
}
|
|
123
|
+
case 'auto': {
|
|
124
|
+
const snap = await fetchNativeDexDirectorySnapshot(client, {
|
|
125
|
+
overrides: options.overrides,
|
|
126
|
+
registerLogs: { fromBlock: options.fromBlock, toBlock: options.toBlock },
|
|
127
|
+
});
|
|
128
|
+
const fac = snap.defaults.nativeDexFactoryAccountHex;
|
|
129
|
+
if (fac == null) {
|
|
130
|
+
return { poolHex: null, factoryHex: null, via: 'none' };
|
|
131
|
+
}
|
|
132
|
+
if (snap.registerLogs != null) {
|
|
133
|
+
const fromLogs = pickNativeDexPoolFromRegisterLogs(snap.registerLogs, tokenAHex32, tokenBHex32);
|
|
134
|
+
if (fromLogs != null) {
|
|
135
|
+
return { poolHex: fromLogs, factoryHex: fac, via: 'logs' };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const poolHexRaw = await findNativeDexFactoryPoolByTokens(client, fac, tokenAHex32, tokenBHex32, options.find);
|
|
139
|
+
const poolHex = poolHexRaw != null ? validateHex32(poolHexRaw) : null;
|
|
140
|
+
return { poolHex, factoryHex: fac, via: poolHex != null ? 'simulate' : 'none' };
|
|
141
|
+
}
|
|
142
|
+
default: {
|
|
143
|
+
const _exhaustive = options;
|
|
144
|
+
return _exhaustive;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP JSON for the Cloudflare Worker `workers/native-dex-indexer` D1 directory
|
|
3
|
+
* (`GET /v1/directory/meta`, `GET /v1/directory/pools`). Not Boing JSON-RPC.
|
|
4
|
+
*/
|
|
5
|
+
import type { NativeDexIndexerPoolRow } from './nativeDexIndexerStats.js';
|
|
6
|
+
import type { NativeDexMaterializedPoolEvent } from './nativeDexPoolHistory.js';
|
|
7
|
+
/** `api` field value on successful directory responses. */
|
|
8
|
+
export declare const NATIVE_DEX_DIRECTORY_API_ID: "boing-native-dex-directory/v1";
|
|
9
|
+
/** Bumped when D1 schema or meta semantics change in a breaking way for clients. */
|
|
10
|
+
export declare const NATIVE_DEX_DIRECTORY_SCHEMA_VERSION: 2;
|
|
11
|
+
export type NativeDexDirectoryMetaResponse = {
|
|
12
|
+
api: string;
|
|
13
|
+
schemaVersion?: number;
|
|
14
|
+
poolCount: number;
|
|
15
|
+
/** Row count in `directory_pool_events` when the Worker migration is applied. */
|
|
16
|
+
eventCount?: number;
|
|
17
|
+
latestSyncBatch: string | null;
|
|
18
|
+
/** Chain height used for the last event snapshot (migration `0003+`). */
|
|
19
|
+
indexedTipHeight?: number | null;
|
|
20
|
+
/** Block hash at `indexedTipHeight` when the node returned it — for skew checks only; not a reorg rewind signal. */
|
|
21
|
+
indexedTipBlockHash?: string | null;
|
|
22
|
+
/** `header.parent_hash` at the indexed tip block when available. */
|
|
23
|
+
indexedParentBlockHash?: string | null;
|
|
24
|
+
nftOwnerRowCount?: number;
|
|
25
|
+
/** Rows in `directory_receipt_log` when migration `0006` is applied and receipt archiving is enabled. */
|
|
26
|
+
receiptLogCount?: number;
|
|
27
|
+
};
|
|
28
|
+
export type NativeDexDirectoryPoolsPageResponse = {
|
|
29
|
+
api: string;
|
|
30
|
+
limit: number;
|
|
31
|
+
cursor: string | null;
|
|
32
|
+
nextCursor: string | null;
|
|
33
|
+
hasMore: boolean;
|
|
34
|
+
pools: NativeDexIndexerPoolRow[];
|
|
35
|
+
};
|
|
36
|
+
export type NativeDexDirectoryPoolEventsPageResponse = {
|
|
37
|
+
api: string;
|
|
38
|
+
poolHex: string;
|
|
39
|
+
limit: number;
|
|
40
|
+
cursor: string | null;
|
|
41
|
+
nextCursor: string | null;
|
|
42
|
+
hasMore: boolean;
|
|
43
|
+
events: NativeDexMaterializedPoolEvent[];
|
|
44
|
+
};
|
|
45
|
+
export type NativeDexDirectoryUserEventsPageResponse = {
|
|
46
|
+
api: string;
|
|
47
|
+
callerHex: string;
|
|
48
|
+
limit: number;
|
|
49
|
+
cursor: string | null;
|
|
50
|
+
nextCursor: string | null;
|
|
51
|
+
hasMore: boolean;
|
|
52
|
+
events: NativeDexMaterializedPoolEvent[];
|
|
53
|
+
};
|
|
54
|
+
export declare class NativeDexDirectoryHttpError extends Error {
|
|
55
|
+
readonly status: number;
|
|
56
|
+
readonly url: string;
|
|
57
|
+
readonly bodySnippet?: string | undefined;
|
|
58
|
+
constructor(message: string, status: number, url: string, bodySnippet?: string | undefined);
|
|
59
|
+
}
|
|
60
|
+
/** Trim and strip a trailing slash (no path segment — base is worker origin). */
|
|
61
|
+
export declare function normalizeNativeDexDirectoryWorkerBaseUrl(raw: string): string;
|
|
62
|
+
/**
|
|
63
|
+
* Parse `GET /v1/directory/meta` JSON. Returns `null` if shape is invalid.
|
|
64
|
+
*/
|
|
65
|
+
export declare function parseNativeDexDirectoryMetaResponse(data: unknown): NativeDexDirectoryMetaResponse | null;
|
|
66
|
+
/**
|
|
67
|
+
* Parse `GET /v1/directory/pools` JSON. Drops pool objects that fail minimal hex validation.
|
|
68
|
+
*/
|
|
69
|
+
export declare function parseNativeDexDirectoryPoolsPageResponse(data: unknown): NativeDexDirectoryPoolsPageResponse | null;
|
|
70
|
+
/**
|
|
71
|
+
* Parse `GET /v1/history/pool/{pool}/events` JSON. Drops malformed event objects.
|
|
72
|
+
*/
|
|
73
|
+
export declare function parseNativeDexDirectoryPoolEventsPageResponse(data: unknown): NativeDexDirectoryPoolEventsPageResponse | null;
|
|
74
|
+
/**
|
|
75
|
+
* Parse `GET /v1/history/user/{caller}/events` JSON. Drops malformed event objects.
|
|
76
|
+
*/
|
|
77
|
+
export declare function parseNativeDexDirectoryUserEventsPageResponse(data: unknown): NativeDexDirectoryUserEventsPageResponse | null;
|
|
78
|
+
/**
|
|
79
|
+
* `GET {baseUrl}/v1/directory/meta`
|
|
80
|
+
*/
|
|
81
|
+
export declare function fetchNativeDexDirectoryMeta(baseUrl: string, init?: RequestInit): Promise<NativeDexDirectoryMetaResponse>;
|
|
82
|
+
export type FetchNativeDexDirectoryPoolsPageQuery = {
|
|
83
|
+
/** 1–100; default 20 on server if omitted — we pass explicit default 20 when unset. */
|
|
84
|
+
limit?: number;
|
|
85
|
+
cursor?: string | null;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* `GET {baseUrl}/v1/directory/pools?limit=&cursor=`
|
|
89
|
+
*/
|
|
90
|
+
export declare function fetchNativeDexDirectoryPoolsPage(baseUrl: string, query?: FetchNativeDexDirectoryPoolsPageQuery, init?: RequestInit): Promise<NativeDexDirectoryPoolsPageResponse>;
|
|
91
|
+
export type FetchNativeDexDirectoryPoolEventsPageQuery = {
|
|
92
|
+
limit?: number;
|
|
93
|
+
/** Row `id` cursor from prior `nextCursor` (newest-first pages). */
|
|
94
|
+
cursor?: string | null;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* `GET {baseUrl}/v1/history/pool/{poolHex}/events?limit=&cursor=`
|
|
98
|
+
*/
|
|
99
|
+
export declare function fetchNativeDexDirectoryPoolEventsPage(baseUrl: string, poolHex32: string, query?: FetchNativeDexDirectoryPoolEventsPageQuery, init?: RequestInit): Promise<NativeDexDirectoryPoolEventsPageResponse>;
|
|
100
|
+
export type FetchNativeDexDirectoryUserEventsPageQuery = {
|
|
101
|
+
limit?: number;
|
|
102
|
+
cursor?: string | null;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* `GET {baseUrl}/v1/history/user/{callerHex}/events?limit=&cursor=`
|
|
106
|
+
*/
|
|
107
|
+
export declare function fetchNativeDexDirectoryUserEventsPage(baseUrl: string, callerHex32: string, query?: FetchNativeDexDirectoryUserEventsPageQuery, init?: RequestInit): Promise<NativeDexDirectoryUserEventsPageResponse>;
|
|
108
|
+
export type CollectNativeDexDirectoryPoolsOptions = {
|
|
109
|
+
/** Per request `limit` (1–100). Default 100. */
|
|
110
|
+
pageLimit?: number;
|
|
111
|
+
/** Stop after this many pools (truncates last page). Default unlimited. */
|
|
112
|
+
maxPools?: number;
|
|
113
|
+
/** Safety cap on HTTP pages. Default 10_000. */
|
|
114
|
+
maxPages?: number;
|
|
115
|
+
init?: RequestInit;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Walk cursor pages until `hasMore` is false or limits hit.
|
|
119
|
+
*/
|
|
120
|
+
export declare function collectAllNativeDexDirectoryPools(baseUrl: string, opts?: CollectNativeDexDirectoryPoolsOptions): Promise<NativeDexIndexerPoolRow[]>;
|
|
121
|
+
//# sourceMappingURL=nativeDexDirectoryApi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeDexDirectoryApi.d.ts","sourceRoot":"","sources":["../src/nativeDexDirectoryApi.ts"],"names":[],"mappings":"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"}
|