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,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build **`0xFD` + init** deploy payloads for the secured reference fungible, matching
|
|
3
|
+
* `boing_execution::reference_fungible_secured_deploy_bytecode` / init layout.
|
|
4
|
+
*
|
|
5
|
+
* Runtime bytes are pinned from `defaultReferenceFungibleSecuredRuntimeBytecodeHex.ts`
|
|
6
|
+
* (regenerated with `embed-reference-fungible-secured-template-hex.mjs`).
|
|
7
|
+
*/
|
|
8
|
+
import { DEFAULT_REFERENCE_FUNGIBLE_SECURED_RUNTIME_BYTECODE_HEX } from './defaultReferenceFungibleSecuredRuntimeBytecodeHex.js';
|
|
9
|
+
import { bytesToHex, hexToBytes } from './hex.js';
|
|
10
|
+
import { normalizeNativeTokenSecurity, } from './nativeTokenSecurity.js';
|
|
11
|
+
const CONTRACT_DEPLOY_INIT_CODE_MARKER = 0xfd;
|
|
12
|
+
const Op = {
|
|
13
|
+
Stop: 0x00,
|
|
14
|
+
Add: 0x01,
|
|
15
|
+
Lt: 0x10,
|
|
16
|
+
Eq: 0x14,
|
|
17
|
+
IsZero: 0x15,
|
|
18
|
+
Caller: 0x33,
|
|
19
|
+
BlockHeight: 0x40,
|
|
20
|
+
MLoad: 0x51,
|
|
21
|
+
MStore: 0x52,
|
|
22
|
+
SLoad: 0x54,
|
|
23
|
+
SStore: 0x55,
|
|
24
|
+
JumpI: 0x57,
|
|
25
|
+
Push32: 0x7f,
|
|
26
|
+
Return: 0xf3,
|
|
27
|
+
};
|
|
28
|
+
/** Mirrors `reference_fungible_secured` flag words (u32). */
|
|
29
|
+
export const FLAG_DENYLIST = 0x01;
|
|
30
|
+
export const FLAG_MAX_TX = 0x02;
|
|
31
|
+
export const FLAG_MAX_WALLET = 0x04;
|
|
32
|
+
export const FLAG_ANTI_BOT = 0x08;
|
|
33
|
+
export const FLAG_COOLDOWN = 0x10;
|
|
34
|
+
export const FLAG_NO_MINT = 0x20;
|
|
35
|
+
export const FLAG_TRANSFER_UNLOCK = 0x40;
|
|
36
|
+
const U128_MAX = (1n << 128n) - 1n;
|
|
37
|
+
const U64_MAX = (1n << 64n) - 1n;
|
|
38
|
+
const DEFAULT_ANTI_BOT_EXTRA_BLOCKS = 100n;
|
|
39
|
+
function keyLastByte(b) {
|
|
40
|
+
const k = new Uint8Array(32);
|
|
41
|
+
k[31] = b & 0xff;
|
|
42
|
+
return k;
|
|
43
|
+
}
|
|
44
|
+
function wordZero() {
|
|
45
|
+
return new Uint8Array(32);
|
|
46
|
+
}
|
|
47
|
+
function wordOne() {
|
|
48
|
+
const w = new Uint8Array(32);
|
|
49
|
+
w[31] = 1;
|
|
50
|
+
return w;
|
|
51
|
+
}
|
|
52
|
+
function wordU32(n) {
|
|
53
|
+
const w = new Uint8Array(32);
|
|
54
|
+
new DataView(w.buffer).setUint32(28, n >>> 0, false);
|
|
55
|
+
return w;
|
|
56
|
+
}
|
|
57
|
+
function wordU64(n) {
|
|
58
|
+
const w = new Uint8Array(32);
|
|
59
|
+
const v = n <= U64_MAX ? n : U64_MAX;
|
|
60
|
+
new DataView(w.buffer).setBigUint64(24, v, false);
|
|
61
|
+
return w;
|
|
62
|
+
}
|
|
63
|
+
function amountWord(amount) {
|
|
64
|
+
const w = new Uint8Array(32);
|
|
65
|
+
let v = amount <= U128_MAX ? amount : U128_MAX;
|
|
66
|
+
for (let i = 31; i >= 16; i--) {
|
|
67
|
+
w[i] = Number(v & 0xffn);
|
|
68
|
+
v >>= 8n;
|
|
69
|
+
}
|
|
70
|
+
return w;
|
|
71
|
+
}
|
|
72
|
+
function push32(w) {
|
|
73
|
+
const out = new Uint8Array(33);
|
|
74
|
+
out[0] = Op.Push32;
|
|
75
|
+
out.set(w, 1);
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
function u8(b) {
|
|
79
|
+
return new Uint8Array([b & 0xff]);
|
|
80
|
+
}
|
|
81
|
+
function concatBytes(...parts) {
|
|
82
|
+
const n = parts.reduce((a, p) => a + p.length, 0);
|
|
83
|
+
const out = new Uint8Array(n);
|
|
84
|
+
let o = 0;
|
|
85
|
+
for (const p of parts) {
|
|
86
|
+
out.set(p, o);
|
|
87
|
+
o += p.length;
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
function emitRuntimeToMemory(runtime) {
|
|
92
|
+
const padLen = (Math.ceil(runtime.length / 32) | 0) * 32;
|
|
93
|
+
const rt = new Uint8Array(padLen);
|
|
94
|
+
rt.set(runtime, 0);
|
|
95
|
+
const chunks = [];
|
|
96
|
+
for (let off = 0; off < padLen; off += 32) {
|
|
97
|
+
chunks.push(push32(rt.subarray(off, off + 32)));
|
|
98
|
+
chunks.push(push32(wordU64(BigInt(off))));
|
|
99
|
+
chunks.push(u8(Op.MStore));
|
|
100
|
+
}
|
|
101
|
+
return concatBytes(...chunks);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Init bytecode only (no `0xFD` prefix), matching `reference_fungible_secured_init_bytecode`.
|
|
105
|
+
*/
|
|
106
|
+
export function referenceFungibleSecuredInitBytecode(config, runtime) {
|
|
107
|
+
const refSecAdminKey = keyLastByte(0xc1);
|
|
108
|
+
const refSecAntiBotEndKey = keyLastByte(0xc7);
|
|
109
|
+
const refSecFlagsKey = keyLastByte(0xc3);
|
|
110
|
+
const refSecMaxTxKey = keyLastByte(0xc4);
|
|
111
|
+
const refSecMaxWalletKey = keyLastByte(0xc5);
|
|
112
|
+
const refSecAntiBotMaxKey = keyLastByte(0xc8);
|
|
113
|
+
const refSecCooldownSecsKey = keyLastByte(0xc9);
|
|
114
|
+
const refSecXferUnlockKey = keyLastByte(0xca);
|
|
115
|
+
const refSecPausedKey = keyLastByte(0xc6);
|
|
116
|
+
const parts = [
|
|
117
|
+
u8(Op.Caller),
|
|
118
|
+
push32(refSecAdminKey),
|
|
119
|
+
u8(Op.SStore),
|
|
120
|
+
u8(Op.BlockHeight),
|
|
121
|
+
push32(wordU64(config.antiBotExtraBlocks)),
|
|
122
|
+
u8(Op.Add),
|
|
123
|
+
push32(refSecAntiBotEndKey),
|
|
124
|
+
u8(Op.SStore),
|
|
125
|
+
push32(wordU32(config.flags >>> 0)),
|
|
126
|
+
push32(refSecFlagsKey),
|
|
127
|
+
u8(Op.SStore),
|
|
128
|
+
push32(amountWord(config.maxTx)),
|
|
129
|
+
push32(refSecMaxTxKey),
|
|
130
|
+
u8(Op.SStore),
|
|
131
|
+
push32(amountWord(config.maxWallet)),
|
|
132
|
+
push32(refSecMaxWalletKey),
|
|
133
|
+
u8(Op.SStore),
|
|
134
|
+
push32(amountWord(config.antiBotMaxAmount)),
|
|
135
|
+
push32(refSecAntiBotMaxKey),
|
|
136
|
+
u8(Op.SStore),
|
|
137
|
+
push32(wordU64(config.cooldownSecs)),
|
|
138
|
+
push32(refSecCooldownSecsKey),
|
|
139
|
+
u8(Op.SStore),
|
|
140
|
+
push32(wordU64(config.transferUnlockHeight)),
|
|
141
|
+
push32(refSecXferUnlockKey),
|
|
142
|
+
u8(Op.SStore),
|
|
143
|
+
push32(config.initialPaused ? wordOne() : wordZero()),
|
|
144
|
+
push32(refSecPausedKey),
|
|
145
|
+
u8(Op.SStore),
|
|
146
|
+
emitRuntimeToMemory(runtime),
|
|
147
|
+
push32(wordU64(BigInt(runtime.length))),
|
|
148
|
+
push32(wordZero()),
|
|
149
|
+
u8(Op.Return),
|
|
150
|
+
u8(Op.Stop),
|
|
151
|
+
];
|
|
152
|
+
return concatBytes(...parts);
|
|
153
|
+
}
|
|
154
|
+
/** Full deploy: `0xFD || init` (init `RETURN`s runtime). */
|
|
155
|
+
export function referenceFungibleSecuredDeployBytecode(config, runtime) {
|
|
156
|
+
const rt = runtime ??
|
|
157
|
+
hexToBytes(DEFAULT_REFERENCE_FUNGIBLE_SECURED_RUNTIME_BYTECODE_HEX);
|
|
158
|
+
const init = referenceFungibleSecuredInitBytecode(config, rt);
|
|
159
|
+
return concatBytes(u8(CONTRACT_DEPLOY_INIT_CODE_MARKER), init);
|
|
160
|
+
}
|
|
161
|
+
export function referenceFungibleSecuredDeployBytecodeHex(config, runtime) {
|
|
162
|
+
return bytesToHex(referenceFungibleSecuredDeployBytecode(config, runtime));
|
|
163
|
+
}
|
|
164
|
+
function parseDecimalU128(label, s) {
|
|
165
|
+
const t = s.trim();
|
|
166
|
+
if (!t)
|
|
167
|
+
return 0n;
|
|
168
|
+
if (!/^[0-9]+$/.test(t)) {
|
|
169
|
+
throw new Error(`${label}: expected non-negative decimal integer, got ${JSON.stringify(s)}`);
|
|
170
|
+
}
|
|
171
|
+
const v = BigInt(t);
|
|
172
|
+
if (v > U128_MAX) {
|
|
173
|
+
throw new Error(`${label}: value exceeds uint128`);
|
|
174
|
+
}
|
|
175
|
+
return v;
|
|
176
|
+
}
|
|
177
|
+
function parseDecimalU64(label, s) {
|
|
178
|
+
const t = s.trim();
|
|
179
|
+
if (!t)
|
|
180
|
+
return 0n;
|
|
181
|
+
if (!/^[0-9]+$/.test(t)) {
|
|
182
|
+
throw new Error(`${label}: expected non-negative decimal integer, got ${JSON.stringify(s)}`);
|
|
183
|
+
}
|
|
184
|
+
const v = BigInt(t);
|
|
185
|
+
if (v > U64_MAX) {
|
|
186
|
+
throw new Error(`${label}: value exceeds uint64`);
|
|
187
|
+
}
|
|
188
|
+
return v;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Map wizard / `boing.native_token_security.v1` fields to secured init storage (on-chain enforcement).
|
|
192
|
+
*
|
|
193
|
+
* - **renounceOwnership**: not applied at deploy (admin is deployer); use admin `0x05` after deploy.
|
|
194
|
+
* - **timelock**: maps to transfer-unlock **block height** = `chainHeight + timelockDelay` (both decimals).
|
|
195
|
+
*/
|
|
196
|
+
export function referenceFungibleSecuredConfigFromNativeTokenSecurity(input, ctx = {}) {
|
|
197
|
+
const n = normalizeNativeTokenSecurity(input);
|
|
198
|
+
let flags = 0;
|
|
199
|
+
let maxTx = 0n;
|
|
200
|
+
let maxWallet = 0n;
|
|
201
|
+
let antiBotExtraBlocks = 0n;
|
|
202
|
+
let antiBotMaxAmount = 0n;
|
|
203
|
+
let cooldownSecs = 0n;
|
|
204
|
+
let transferUnlockHeight = 0n;
|
|
205
|
+
let initialPaused = false;
|
|
206
|
+
if (n.enableBlacklist || n.enableFreezing) {
|
|
207
|
+
flags |= FLAG_DENYLIST;
|
|
208
|
+
}
|
|
209
|
+
if (n.renounceMint) {
|
|
210
|
+
flags |= FLAG_NO_MINT;
|
|
211
|
+
}
|
|
212
|
+
if (n.pauseFunction) {
|
|
213
|
+
initialPaused = true;
|
|
214
|
+
}
|
|
215
|
+
const maxTxV = parseDecimalU128('maxTxAmount', n.maxTxAmount);
|
|
216
|
+
if (maxTxV > 0n) {
|
|
217
|
+
flags |= FLAG_MAX_TX;
|
|
218
|
+
maxTx = maxTxV;
|
|
219
|
+
}
|
|
220
|
+
const wantWalletCap = n.maxWallet || n.antiWhale;
|
|
221
|
+
const pctRaw = n.maxWalletPercentage.trim();
|
|
222
|
+
const supply = ctx.mintFirstTotalSupplyWei;
|
|
223
|
+
if (wantWalletCap) {
|
|
224
|
+
flags |= FLAG_MAX_WALLET;
|
|
225
|
+
if (pctRaw && supply !== undefined && supply > 0n) {
|
|
226
|
+
const pct = parseDecimalU128('maxWalletPercentage', pctRaw);
|
|
227
|
+
if (pct > 100n) {
|
|
228
|
+
throw new Error('maxWalletPercentage: must be 0–100');
|
|
229
|
+
}
|
|
230
|
+
maxWallet = (supply * pct) / 100n;
|
|
231
|
+
}
|
|
232
|
+
else if (maxTxV > 0n) {
|
|
233
|
+
maxWallet = maxTxV;
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
throw new Error('maxWallet / antiWhale: set maxWalletPercentage and mintFirstTotalSupplyWei on the deploy builder, or set maxTxAmount to use as the per-wallet cap');
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (n.antiBot) {
|
|
240
|
+
flags |= FLAG_ANTI_BOT;
|
|
241
|
+
antiBotExtraBlocks = DEFAULT_ANTI_BOT_EXTRA_BLOCKS;
|
|
242
|
+
antiBotMaxAmount = maxTxV > 0n ? maxTxV : U128_MAX;
|
|
243
|
+
}
|
|
244
|
+
const cd = parseDecimalU64('cooldownPeriod', n.cooldownPeriod);
|
|
245
|
+
if (cd > 0n) {
|
|
246
|
+
flags |= FLAG_COOLDOWN;
|
|
247
|
+
cooldownSecs = cd;
|
|
248
|
+
}
|
|
249
|
+
if (n.timelock) {
|
|
250
|
+
const delay = parseDecimalU64('timelockDelay', n.timelockDelay);
|
|
251
|
+
if (ctx.chainHeight === undefined) {
|
|
252
|
+
throw new Error('nativeTokenSecurity.timelock: pass chainContext.chainHeight (from boing_chainHeight) so transfer unlock height can be set on-chain');
|
|
253
|
+
}
|
|
254
|
+
flags |= FLAG_TRANSFER_UNLOCK;
|
|
255
|
+
transferUnlockHeight = ctx.chainHeight + delay;
|
|
256
|
+
if (transferUnlockHeight > U64_MAX) {
|
|
257
|
+
transferUnlockHeight = U64_MAX;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
flags,
|
|
262
|
+
maxTx,
|
|
263
|
+
maxWallet,
|
|
264
|
+
antiBotExtraBlocks,
|
|
265
|
+
antiBotMaxAmount,
|
|
266
|
+
cooldownSecs,
|
|
267
|
+
transferUnlockHeight,
|
|
268
|
+
initialPaused,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
export function buildReferenceFungibleSecuredDeployBytecodeHexFromNativeTokenSecurity(input, ctx = {}) {
|
|
272
|
+
const cfg = referenceFungibleSecuredConfigFromNativeTokenSecurity(input, ctx);
|
|
273
|
+
return referenceFungibleSecuredDeployBytecodeHex(cfg);
|
|
274
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference NFT calldata layout (Boing-defined). See `docs/BOING-REFERENCE-NFT.md`.
|
|
3
|
+
*/
|
|
4
|
+
export declare const SELECTOR_OWNER_OF = 3;
|
|
5
|
+
export declare const SELECTOR_TRANSFER_NFT = 4;
|
|
6
|
+
export declare const SELECTOR_SET_METADATA_HASH = 5;
|
|
7
|
+
/** 96-byte `owner_of(token_id)` reference calldata. */
|
|
8
|
+
export declare function encodeReferenceOwnerOfCalldata(tokenIdHex32: string): Uint8Array;
|
|
9
|
+
/** 96-byte `transfer_nft(to, token_id)` reference calldata. */
|
|
10
|
+
export declare function encodeReferenceTransferNftCalldata(toHexAccount32: string, tokenIdHex32: string): Uint8Array;
|
|
11
|
+
/** 96-byte `set_metadata_hash(token_id, hash)` reference calldata. */
|
|
12
|
+
export declare function encodeReferenceSetMetadataHashCalldata(tokenIdHex32: string, metadataHashHex32: string): Uint8Array;
|
|
13
|
+
export declare function encodeReferenceOwnerOfCalldataHex(tokenIdHex32: string): string;
|
|
14
|
+
//# sourceMappingURL=referenceNft.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"referenceNft.d.ts","sourceRoot":"","sources":["../src/referenceNft.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,eAAO,MAAM,iBAAiB,IAAO,CAAC;AACtC,eAAO,MAAM,qBAAqB,IAAO,CAAC;AAC1C,eAAO,MAAM,0BAA0B,IAAO,CAAC;AAE/C,uDAAuD;AACvD,wBAAgB,8BAA8B,CAAC,YAAY,EAAE,MAAM,GAAG,UAAU,CAK/E;AAED,+DAA+D;AAC/D,wBAAgB,kCAAkC,CAChD,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,GACnB,UAAU,CAMZ;AAED,sEAAsE;AACtE,wBAAgB,sCAAsC,CACpD,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,MAAM,GACxB,UAAU,CAMZ;AAED,wBAAgB,iCAAiC,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE9E"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference NFT calldata layout (Boing-defined). See `docs/BOING-REFERENCE-NFT.md`.
|
|
3
|
+
*/
|
|
4
|
+
import { bytesToHex } from './hex.js';
|
|
5
|
+
import { calldataAccountIdWord, calldataFixedWord32, calldataSelectorLastByte, } from './calldata.js';
|
|
6
|
+
export const SELECTOR_OWNER_OF = 0x03;
|
|
7
|
+
export const SELECTOR_TRANSFER_NFT = 0x04;
|
|
8
|
+
export const SELECTOR_SET_METADATA_HASH = 0x05;
|
|
9
|
+
/** 96-byte `owner_of(token_id)` reference calldata. */
|
|
10
|
+
export function encodeReferenceOwnerOfCalldata(tokenIdHex32) {
|
|
11
|
+
const out = new Uint8Array(96);
|
|
12
|
+
out.set(calldataSelectorLastByte(SELECTOR_OWNER_OF), 0);
|
|
13
|
+
out.set(calldataFixedWord32(tokenIdHex32), 32);
|
|
14
|
+
return out;
|
|
15
|
+
}
|
|
16
|
+
/** 96-byte `transfer_nft(to, token_id)` reference calldata. */
|
|
17
|
+
export function encodeReferenceTransferNftCalldata(toHexAccount32, tokenIdHex32) {
|
|
18
|
+
const out = new Uint8Array(96);
|
|
19
|
+
out.set(calldataSelectorLastByte(SELECTOR_TRANSFER_NFT), 0);
|
|
20
|
+
out.set(calldataAccountIdWord(toHexAccount32), 32);
|
|
21
|
+
out.set(calldataFixedWord32(tokenIdHex32), 64);
|
|
22
|
+
return out;
|
|
23
|
+
}
|
|
24
|
+
/** 96-byte `set_metadata_hash(token_id, hash)` reference calldata. */
|
|
25
|
+
export function encodeReferenceSetMetadataHashCalldata(tokenIdHex32, metadataHashHex32) {
|
|
26
|
+
const out = new Uint8Array(96);
|
|
27
|
+
out.set(calldataSelectorLastByte(SELECTOR_SET_METADATA_HASH), 0);
|
|
28
|
+
out.set(calldataFixedWord32(tokenIdHex32), 32);
|
|
29
|
+
out.set(calldataFixedWord32(metadataHashHex32), 64);
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
export function encodeReferenceOwnerOfCalldataHex(tokenIdHex32) {
|
|
33
|
+
return bytesToHex(encodeReferenceOwnerOfCalldata(tokenIdHex32));
|
|
34
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference fungible calldata layout (Boing-defined). See `docs/BOING-REFERENCE-TOKEN.md`.
|
|
3
|
+
*/
|
|
4
|
+
/** Selector low byte for reference `transfer`. */
|
|
5
|
+
export declare const SELECTOR_TRANSFER = 1;
|
|
6
|
+
/** Selector low byte for reference first-mint style hook. */
|
|
7
|
+
export declare const SELECTOR_MINT_FIRST = 2;
|
|
8
|
+
/** Build 96-byte reference `transfer(to, amount)` calldata. */
|
|
9
|
+
export declare function encodeReferenceTransferCalldata(toHexAccount32: string, amount: bigint): Uint8Array;
|
|
10
|
+
/** Build 96-byte reference `mint_first` calldata. */
|
|
11
|
+
export declare function encodeReferenceMintFirstCalldata(toHexAccount32: string, amount: bigint): Uint8Array;
|
|
12
|
+
/** Hex `0x` + 96-byte reference transfer calldata. */
|
|
13
|
+
export declare function encodeReferenceTransferCalldataHex(toHexAccount32: string, amount: bigint): string;
|
|
14
|
+
//# sourceMappingURL=referenceToken.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"referenceToken.d.ts","sourceRoot":"","sources":["../src/referenceToken.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,kDAAkD;AAClD,eAAO,MAAM,iBAAiB,IAAO,CAAC;AACtC,6DAA6D;AAC7D,eAAO,MAAM,mBAAmB,IAAO,CAAC;AAExC,+DAA+D;AAC/D,wBAAgB,+BAA+B,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAMlG;AAED,qDAAqD;AACrD,wBAAgB,gCAAgC,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAMnG;AAED,sDAAsD;AACtD,wBAAgB,kCAAkC,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjG"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference fungible calldata layout (Boing-defined). See `docs/BOING-REFERENCE-TOKEN.md`.
|
|
3
|
+
*/
|
|
4
|
+
import { bytesToHex } from './hex.js';
|
|
5
|
+
import { calldataAccountIdWord, calldataSelectorLastByte, calldataU128BeWord, } from './calldata.js';
|
|
6
|
+
/** Selector low byte for reference `transfer`. */
|
|
7
|
+
export const SELECTOR_TRANSFER = 0x01;
|
|
8
|
+
/** Selector low byte for reference first-mint style hook. */
|
|
9
|
+
export const SELECTOR_MINT_FIRST = 0x02;
|
|
10
|
+
/** Build 96-byte reference `transfer(to, amount)` calldata. */
|
|
11
|
+
export function encodeReferenceTransferCalldata(toHexAccount32, amount) {
|
|
12
|
+
const out = new Uint8Array(96);
|
|
13
|
+
out.set(calldataSelectorLastByte(SELECTOR_TRANSFER), 0);
|
|
14
|
+
out.set(calldataAccountIdWord(toHexAccount32), 32);
|
|
15
|
+
out.set(calldataU128BeWord(amount), 64);
|
|
16
|
+
return out;
|
|
17
|
+
}
|
|
18
|
+
/** Build 96-byte reference `mint_first` calldata. */
|
|
19
|
+
export function encodeReferenceMintFirstCalldata(toHexAccount32, amount) {
|
|
20
|
+
const out = new Uint8Array(96);
|
|
21
|
+
out.set(calldataSelectorLastByte(SELECTOR_MINT_FIRST), 0);
|
|
22
|
+
out.set(calldataAccountIdWord(toHexAccount32), 32);
|
|
23
|
+
out.set(calldataU128BeWord(amount), 64);
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
26
|
+
/** Hex `0x` + 96-byte reference transfer calldata. */
|
|
27
|
+
export function encodeReferenceTransferCalldataHex(toHexAccount32, amount) {
|
|
28
|
+
return bytesToHex(encodeReferenceTransferCalldata(toHexAccount32, amount));
|
|
29
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse HTTP **`Retry-After`** (RFC 7231): delay in seconds as integer, or an HTTP-date.
|
|
3
|
+
* Returns milliseconds to wait, or **`undefined`** if missing / unparseable.
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseRetryAfterMs(value: string | null): number | undefined;
|
|
6
|
+
//# sourceMappingURL=retryAfter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retryAfter.d.ts","sourceRoot":"","sources":["../src/retryAfter.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAgB1E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Cap parsed delay so a bad header cannot stall the client for hours. */
|
|
2
|
+
const MAX_RETRY_AFTER_MS = 86400000; // 24h
|
|
3
|
+
/**
|
|
4
|
+
* Parse HTTP **`Retry-After`** (RFC 7231): delay in seconds as integer, or an HTTP-date.
|
|
5
|
+
* Returns milliseconds to wait, or **`undefined`** if missing / unparseable.
|
|
6
|
+
*/
|
|
7
|
+
export function parseRetryAfterMs(value) {
|
|
8
|
+
if (value == null)
|
|
9
|
+
return undefined;
|
|
10
|
+
const trimmed = value.trim();
|
|
11
|
+
if (trimmed === '')
|
|
12
|
+
return undefined;
|
|
13
|
+
const asInt = Number.parseInt(trimmed, 10);
|
|
14
|
+
if (!Number.isNaN(asInt) && asInt >= 0 && String(asInt) === trimmed) {
|
|
15
|
+
return Math.min(asInt * 1000, MAX_RETRY_AFTER_MS);
|
|
16
|
+
}
|
|
17
|
+
const when = Date.parse(trimmed);
|
|
18
|
+
if (!Number.isNaN(when)) {
|
|
19
|
+
const delta = when - Date.now();
|
|
20
|
+
if (delta > 0)
|
|
21
|
+
return Math.min(delta, MAX_RETRY_AFTER_MS);
|
|
22
|
+
}
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional `boing_*` JSON-RPC methods: probe availability without assuming a full node build.
|
|
3
|
+
* Uses JSON-RPC **-32601** (method not found) to detect missing handlers — same as integration fallbacks.
|
|
4
|
+
*/
|
|
5
|
+
import type { BoingClient } from './client.js';
|
|
6
|
+
/** Result of probing a single RPC method. */
|
|
7
|
+
export interface BoingRpcMethodProbe {
|
|
8
|
+
/** `true` if the call completed without throwing. */
|
|
9
|
+
available: boolean;
|
|
10
|
+
/** Present when `available` is false. */
|
|
11
|
+
code?: number;
|
|
12
|
+
message?: string;
|
|
13
|
+
}
|
|
14
|
+
/** Named probes useful for indexers, wallets, and debugging version skew. */
|
|
15
|
+
export interface BoingRpcCapabilities {
|
|
16
|
+
boing_chainHeight: BoingRpcMethodProbe;
|
|
17
|
+
boing_getSyncState: BoingRpcMethodProbe;
|
|
18
|
+
boing_getBlockByHeight: BoingRpcMethodProbe;
|
|
19
|
+
boing_getLogs: BoingRpcMethodProbe;
|
|
20
|
+
boing_getTransactionReceipt: BoingRpcMethodProbe;
|
|
21
|
+
boing_getNetworkInfo: BoingRpcMethodProbe;
|
|
22
|
+
}
|
|
23
|
+
/** Result of {@link probeBoingRpcCapabilities}: core probes plus optional discovery fields. */
|
|
24
|
+
export interface BoingRpcProbeBundle {
|
|
25
|
+
/** From `boing_clientVersion` when implemented; **`null`** if **-32601** or unset. */
|
|
26
|
+
clientVersion: string | null;
|
|
27
|
+
/** From `boing_rpcSupportedMethods` when implemented; **`null`** if **-32601** or unset. */
|
|
28
|
+
supportedMethods: string[] | null;
|
|
29
|
+
methods: BoingRpcCapabilities;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Call discovery plus a small set of read-only RPCs with minimal parameters.
|
|
33
|
+
* A method is **available** if it returns (including JSON-RPC `result: null` for unknown tx/block).
|
|
34
|
+
*/
|
|
35
|
+
export declare function probeBoingRpcCapabilities(client: BoingClient): Promise<BoingRpcProbeBundle>;
|
|
36
|
+
/** Count of core probed methods with `available: true`. */
|
|
37
|
+
export declare function countAvailableBoingRpcMethods(bundleOrMethods: BoingRpcProbeBundle | BoingRpcCapabilities): number;
|
|
38
|
+
/**
|
|
39
|
+
* Human-readable diagnosis when **`probeBoingRpcCapabilities`** shows gaps.
|
|
40
|
+
* **`undefined`** when all probed methods are available, or when there is nothing actionable to say.
|
|
41
|
+
*/
|
|
42
|
+
export declare function explainBoingRpcProbeGaps(bundleOrMethods: BoingRpcProbeBundle | BoingRpcCapabilities): string | undefined;
|
|
43
|
+
//# sourceMappingURL=rpcCapabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpcCapabilities.d.ts","sourceRoot":"","sources":["../src/rpcCapabilities.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,SAAS,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,6EAA6E;AAC7E,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,EAAE,mBAAmB,CAAC;IACvC,kBAAkB,EAAE,mBAAmB,CAAC;IACxC,sBAAsB,EAAE,mBAAmB,CAAC;IAC5C,aAAa,EAAE,mBAAmB,CAAC;IACnC,2BAA2B,EAAE,mBAAmB,CAAC;IACjD,oBAAoB,EAAE,mBAAmB,CAAC;CAC3C;AAED,+FAA+F;AAC/F,MAAM,WAAW,mBAAmB;IAClC,sFAAsF;IACtF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,4FAA4F;IAC5F,gBAAgB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,oBAAoB,CAAC;CAC/B;AA8BD;;;GAGG;AACH,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAuEjG;AAED,2DAA2D;AAC3D,wBAAgB,6BAA6B,CAC3C,eAAe,EAAE,mBAAmB,GAAG,oBAAoB,GAC1D,MAAM,CAGR;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,eAAe,EAAE,mBAAmB,GAAG,oBAAoB,GAC1D,MAAM,GAAG,SAAS,CAgDpB"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional `boing_*` JSON-RPC methods: probe availability without assuming a full node build.
|
|
3
|
+
* Uses JSON-RPC **-32601** (method not found) to detect missing handlers — same as integration fallbacks.
|
|
4
|
+
*/
|
|
5
|
+
import { BoingRpcError, isBoingRpcMethodNotFound } from './errors.js';
|
|
6
|
+
function mapProbeError(e) {
|
|
7
|
+
if (isBoingRpcMethodNotFound(e)) {
|
|
8
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
9
|
+
return { available: false, code: -32601, message: msg };
|
|
10
|
+
}
|
|
11
|
+
if (e instanceof BoingRpcError) {
|
|
12
|
+
return { available: false, code: e.code, message: e.message };
|
|
13
|
+
}
|
|
14
|
+
return { available: false, message: e instanceof Error ? e.message : String(e) };
|
|
15
|
+
}
|
|
16
|
+
const ZERO_TX_HEX = `0x${'00'.repeat(32)}`;
|
|
17
|
+
const CAP_KEYS = [
|
|
18
|
+
'boing_chainHeight',
|
|
19
|
+
'boing_getSyncState',
|
|
20
|
+
'boing_getBlockByHeight',
|
|
21
|
+
'boing_getLogs',
|
|
22
|
+
'boing_getTransactionReceipt',
|
|
23
|
+
'boing_getNetworkInfo',
|
|
24
|
+
];
|
|
25
|
+
function unwrapMethods(bundleOrMethods) {
|
|
26
|
+
return 'methods' in bundleOrMethods ? bundleOrMethods.methods : bundleOrMethods;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Call discovery plus a small set of read-only RPCs with minimal parameters.
|
|
30
|
+
* A method is **available** if it returns (including JSON-RPC `result: null` for unknown tx/block).
|
|
31
|
+
*/
|
|
32
|
+
export async function probeBoingRpcCapabilities(client) {
|
|
33
|
+
const methods = {};
|
|
34
|
+
let clientVersion = null;
|
|
35
|
+
let supportedMethods = null;
|
|
36
|
+
await Promise.all([
|
|
37
|
+
(async () => {
|
|
38
|
+
try {
|
|
39
|
+
clientVersion = await client.clientVersion();
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
if (!isBoingRpcMethodNotFound(e))
|
|
43
|
+
throw e;
|
|
44
|
+
}
|
|
45
|
+
})(),
|
|
46
|
+
(async () => {
|
|
47
|
+
try {
|
|
48
|
+
supportedMethods = await client.rpcSupportedMethods();
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
if (!isBoingRpcMethodNotFound(e))
|
|
52
|
+
throw e;
|
|
53
|
+
}
|
|
54
|
+
})(),
|
|
55
|
+
(async () => {
|
|
56
|
+
try {
|
|
57
|
+
await client.chainHeight();
|
|
58
|
+
methods.boing_chainHeight = { available: true };
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
methods.boing_chainHeight = mapProbeError(e);
|
|
62
|
+
}
|
|
63
|
+
})(),
|
|
64
|
+
(async () => {
|
|
65
|
+
try {
|
|
66
|
+
await client.getSyncState();
|
|
67
|
+
methods.boing_getSyncState = { available: true };
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
methods.boing_getSyncState = mapProbeError(e);
|
|
71
|
+
}
|
|
72
|
+
})(),
|
|
73
|
+
(async () => {
|
|
74
|
+
try {
|
|
75
|
+
await client.getBlockByHeight(0, false);
|
|
76
|
+
methods.boing_getBlockByHeight = { available: true };
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
methods.boing_getBlockByHeight = mapProbeError(e);
|
|
80
|
+
}
|
|
81
|
+
})(),
|
|
82
|
+
(async () => {
|
|
83
|
+
try {
|
|
84
|
+
await client.getLogs({ fromBlock: 0, toBlock: 0 });
|
|
85
|
+
methods.boing_getLogs = { available: true };
|
|
86
|
+
}
|
|
87
|
+
catch (e) {
|
|
88
|
+
methods.boing_getLogs = mapProbeError(e);
|
|
89
|
+
}
|
|
90
|
+
})(),
|
|
91
|
+
(async () => {
|
|
92
|
+
try {
|
|
93
|
+
await client.getTransactionReceipt(ZERO_TX_HEX);
|
|
94
|
+
methods.boing_getTransactionReceipt = { available: true };
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
methods.boing_getTransactionReceipt = mapProbeError(e);
|
|
98
|
+
}
|
|
99
|
+
})(),
|
|
100
|
+
(async () => {
|
|
101
|
+
try {
|
|
102
|
+
await client.getNetworkInfo();
|
|
103
|
+
methods.boing_getNetworkInfo = { available: true };
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
methods.boing_getNetworkInfo = mapProbeError(e);
|
|
107
|
+
}
|
|
108
|
+
})(),
|
|
109
|
+
]);
|
|
110
|
+
return { clientVersion, supportedMethods, methods };
|
|
111
|
+
}
|
|
112
|
+
/** Count of core probed methods with `available: true`. */
|
|
113
|
+
export function countAvailableBoingRpcMethods(bundleOrMethods) {
|
|
114
|
+
const m = unwrapMethods(bundleOrMethods);
|
|
115
|
+
return CAP_KEYS.filter((k) => m[k].available).length;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Human-readable diagnosis when **`probeBoingRpcCapabilities`** shows gaps.
|
|
119
|
+
* **`undefined`** when all probed methods are available, or when there is nothing actionable to say.
|
|
120
|
+
*/
|
|
121
|
+
export function explainBoingRpcProbeGaps(bundleOrMethods) {
|
|
122
|
+
const methods = unwrapMethods(bundleOrMethods);
|
|
123
|
+
const supportedListing = 'supportedMethods' in bundleOrMethods ? bundleOrMethods.supportedMethods : undefined;
|
|
124
|
+
const reportedVersion = 'clientVersion' in bundleOrMethods ? bundleOrMethods.clientVersion : undefined;
|
|
125
|
+
if (!methods.boing_chainHeight.available) {
|
|
126
|
+
return ('boing_chainHeight failed — this URL may not be a Boing JSON-RPC server (POST /, JSON-RPC 2.0), or the node is unreachable.');
|
|
127
|
+
}
|
|
128
|
+
const methodNotFound = CAP_KEYS.filter((k) => !methods[k].available && methods[k].code === -32601);
|
|
129
|
+
if (methodNotFound.length > 0) {
|
|
130
|
+
let s = `The server returned -32601 (method not found) for: ${methodNotFound.join(', ')}. ` +
|
|
131
|
+
'The current **boing-node** in the boing.network repo registers these methods on the same HTTP POST / handler as boing_chainHeight. ' +
|
|
132
|
+
'Typical causes: (1) an **older boing-node binary** — rebuild with `cargo build -p boing-node --release` and restart (see docs/RUNBOOK.md); ' +
|
|
133
|
+
'(2) a **reverse proxy** that only forwards a subset of JSON-RPC method names. ' +
|
|
134
|
+
'Full list: docs/RPC-API-SPEC.md.';
|
|
135
|
+
if (supportedListing != null) {
|
|
136
|
+
const sm = new Set(supportedListing);
|
|
137
|
+
const ghost = methodNotFound.filter((k) => sm.has(k));
|
|
138
|
+
if (ghost.length > 0) {
|
|
139
|
+
s += ` Contradiction: boing_rpcSupportedMethods lists ${ghost.join(', ')} but calls failed — likely a filtering proxy.`;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (reportedVersion != null && reportedVersion !== '') {
|
|
143
|
+
s += ` Reported client: ${reportedVersion}.`;
|
|
144
|
+
}
|
|
145
|
+
else if ('clientVersion' in bundleOrMethods &&
|
|
146
|
+
bundleOrMethods.clientVersion === null) {
|
|
147
|
+
s +=
|
|
148
|
+
' **`boing_clientVersion` is also missing (-32601)** — this process does not match a current `boing-node` from this repository (that method is registered alongside `boing_chainHeight`). ';
|
|
149
|
+
}
|
|
150
|
+
s +=
|
|
151
|
+
' Confirm what is listening: from the repo root run **`npm run rpc-endpoint-check`** (no SDK build). On Windows: **`netstat -ano | findstr :8545`** then **`tasklist /FI "PID eq <pid>" /V`**; start the node with **`cargo run -p boing-node -- --validator --rpc-port 8545`** or **`target/release/boing-node`** after **`cargo build -p boing-node --release`.**';
|
|
152
|
+
return s;
|
|
153
|
+
}
|
|
154
|
+
const otherFailed = CAP_KEYS.filter((k) => !methods[k].available && methods[k].code !== -32601);
|
|
155
|
+
if (otherFailed.length > 0) {
|
|
156
|
+
return `Some probed methods failed with errors other than -32601: ${otherFailed.join(', ')}. Inspect methods.*.message in this output.`;
|
|
157
|
+
}
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-shot environment check: preflight HTTP discovery + capability probes + optional required methods.
|
|
3
|
+
*/
|
|
4
|
+
import type { BoingClient } from './client.js';
|
|
5
|
+
import type { BoingRpcPreflightResult } from './types.js';
|
|
6
|
+
import { type BoingRpcProbeBundle } from './rpcCapabilities.js';
|
|
7
|
+
export interface BoingRpcDoctorOptions {
|
|
8
|
+
/** If set, `ok` is false when any of these are missing from `boing_rpcSupportedMethods`. */
|
|
9
|
+
requiredMethods?: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface BoingRpcDoctorResult {
|
|
12
|
+
ok: boolean;
|
|
13
|
+
preflight: BoingRpcPreflightResult;
|
|
14
|
+
capabilityProbe: BoingRpcProbeBundle;
|
|
15
|
+
missingRequiredMethods: string[];
|
|
16
|
+
messages: string[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Run {@link BoingClient.preflightRpc}, {@link probeBoingRpcCapabilities}, and optional required-method checks.
|
|
20
|
+
* `messages` collects short strings suitable for logs or UI (includes `explainBoingRpcProbeGaps` when probes fail).
|
|
21
|
+
*/
|
|
22
|
+
export declare function doctorBoingRpcEnvironment(client: BoingClient, options?: BoingRpcDoctorOptions): Promise<BoingRpcDoctorResult>;
|
|
23
|
+
/** Format {@link BoingRpcDoctorResult} as a multi-line string for stdout. */
|
|
24
|
+
export declare function formatBoingRpcDoctorReport(result: BoingRpcDoctorResult): string;
|
|
25
|
+
/** Map arbitrary errors to a short doctor message (uses {@link explainBoingRpcError} for `BoingRpcError`). */
|
|
26
|
+
export declare function doctorErrorMessage(e: unknown): string;
|
|
27
|
+
//# sourceMappingURL=rpcDoctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpcDoctor.d.ts","sourceRoot":"","sources":["../src/rpcDoctor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAuD,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAErH,MAAM,WAAW,qBAAqB;IACpC,4FAA4F;IAC5F,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,uBAAuB,CAAC;IACnC,eAAe,EAAE,mBAAmB,CAAC;IACrC,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,WAAW,EACnB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CAoC/B;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAa/E;AAED,8GAA8G;AAC9G,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAErD"}
|