@orbinum/sdk 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +570 -22
- package/dist/index.d.mts +1792 -987
- package/dist/index.d.ts +1792 -987
- package/dist/index.js +2229 -491
- package/dist/index.mjs +2214 -490
- package/package.json +5 -1
package/dist/index.js
CHANGED
|
@@ -20,30 +20,41 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
AccountId: () => import_substrate_bindings3.AccountId,
|
|
23
24
|
AccountMappingModule: () => AccountMappingModule,
|
|
24
25
|
AccountMappingPrecompile: () => AccountMappingPrecompile,
|
|
25
|
-
|
|
26
|
+
Blake2256: () => import_substrate_bindings3.Blake2256,
|
|
26
27
|
CircuitId: () => CircuitId,
|
|
27
28
|
CryptoPrecompiles: () => CryptoPrecompiles,
|
|
28
29
|
EncryptedMemo: () => EncryptedMemo,
|
|
29
30
|
EvmClient: () => EvmClient,
|
|
31
|
+
EvmExplorer: () => EvmExplorer,
|
|
32
|
+
IndexerClient: () => IndexerClient,
|
|
30
33
|
KNOWN_PRECOMPILES: () => KNOWN_PRECOMPILES,
|
|
31
|
-
|
|
34
|
+
Keccak256: () => import_substrate_bindings3.Keccak256,
|
|
32
35
|
NoteBuilder: () => NoteBuilder,
|
|
33
36
|
OrbinumClient: () => OrbinumClient,
|
|
37
|
+
OrbinumClientProvider: () => OrbinumClientProvider,
|
|
34
38
|
PRECOMPILE_ADDR: () => PRECOMPILE_ADDR,
|
|
35
39
|
PrivacyKeyManager: () => PrivacyKeyManager,
|
|
40
|
+
PrivacyModule: () => PrivacyModule,
|
|
36
41
|
SLIP0044_NAMESPACE: () => SLIP0044_NAMESPACE,
|
|
37
42
|
ShieldedPoolModule: () => ShieldedPoolModule,
|
|
38
43
|
ShieldedPoolPrecompile: () => ShieldedPoolPrecompile,
|
|
44
|
+
SignatureScheme: () => SignatureScheme,
|
|
45
|
+
Storage: () => import_substrate_bindings3.Storage,
|
|
39
46
|
SubstrateClient: () => SubstrateClient,
|
|
47
|
+
ZkVerifierModule: () => ZkVerifierModule,
|
|
40
48
|
accountIdHexToSs58: () => accountIdHexToSs58,
|
|
41
49
|
addressToAccountIdHex: () => addressToAccountIdHex,
|
|
50
|
+
base58: () => import_base.base58,
|
|
42
51
|
bigintTo32Be: () => bigintTo32Be,
|
|
43
52
|
bigintTo32Le: () => bigintTo32Le,
|
|
44
53
|
bigintTo32LeArr: () => bigintTo32LeArr,
|
|
45
54
|
bytesToBigintLE: () => bytesToBigintLE,
|
|
46
55
|
computePathIndices: () => computePathIndices,
|
|
56
|
+
connectInjectedExtension: () => import_pjs_signer.connectInjectedExtension,
|
|
57
|
+
decodePrecompileCalldata: () => decodePrecompileCalldata,
|
|
47
58
|
decryptJson: () => decryptJson,
|
|
48
59
|
deriveOwnerPk: () => deriveOwnerPk,
|
|
49
60
|
deriveSpendingKeyFromSignature: () => deriveSpendingKeyFromSignature,
|
|
@@ -54,13 +65,19 @@ __export(index_exports, {
|
|
|
54
65
|
ensureHexPrefix: () => ensureHexPrefix,
|
|
55
66
|
evmAddressToAccountId: () => evmAddressToAccountId,
|
|
56
67
|
evmToImplicitSubstrate: () => evmToImplicitSubstrate,
|
|
68
|
+
evmToMappedAccountHex: () => evmToMappedAccountHex,
|
|
57
69
|
evmToSubstrate: () => evmToSubstrate,
|
|
58
70
|
formatBalance: () => formatBalance,
|
|
59
71
|
formatORB: () => formatORB,
|
|
72
|
+
fromBase64: () => fromBase64,
|
|
60
73
|
fromHex: () => fromHex,
|
|
74
|
+
getInjectedExtensions: () => import_pjs_signer.getInjectedExtensions,
|
|
61
75
|
getPolkadotSigner: () => import_signer.getPolkadotSigner,
|
|
62
76
|
getPolkadotSignerFromPjs: () => import_pjs_signer.getPolkadotSignerFromPjs,
|
|
63
77
|
getPrecompileLabel: () => getPrecompileLabel,
|
|
78
|
+
getSs58AddressInfo: () => import_polkadot_api4.getSs58AddressInfo,
|
|
79
|
+
hexToBigint: () => hexToBigint,
|
|
80
|
+
hexToNumber: () => hexToNumber,
|
|
64
81
|
implicitSubstrateToEvm: () => implicitSubstrateToEvm,
|
|
65
82
|
isEvmAddress: () => isEvmAddress,
|
|
66
83
|
isImplicitEvmAccount: () => isImplicitEvmAccount,
|
|
@@ -68,11 +85,19 @@ __export(index_exports, {
|
|
|
68
85
|
isSubstrateAddress: () => isSubstrateAddress,
|
|
69
86
|
isUnifiedAddress: () => isUnifiedAddress,
|
|
70
87
|
leHexToBigint: () => leHexToBigint,
|
|
88
|
+
mapExtrinsicArgs: () => mapExtrinsicArgs,
|
|
89
|
+
mapZkEventData: () => mapZkEventData,
|
|
71
90
|
normalizeEvmAddress: () => normalizeEvmAddress,
|
|
91
|
+
shortHash: () => shortHash,
|
|
72
92
|
substrateSs58ToAccountIdHex: () => substrateSs58ToAccountIdHex,
|
|
73
93
|
substrateToEvm: () => substrateToEvm,
|
|
94
|
+
toBase64: () => toBase64,
|
|
74
95
|
toHex: () => toHex,
|
|
96
|
+
toTxResult: () => toTxResult,
|
|
97
|
+
truncateMiddle: () => truncateMiddle,
|
|
75
98
|
tryDecryptNote: () => tryDecryptNote,
|
|
99
|
+
u128: () => import_substrate_bindings3.u128,
|
|
100
|
+
u64: () => import_substrate_bindings3.u64,
|
|
76
101
|
vaultReplacer: () => vaultReplacer,
|
|
77
102
|
vaultReviver: () => vaultReviver
|
|
78
103
|
});
|
|
@@ -81,10 +106,45 @@ module.exports = __toCommonJS(index_exports);
|
|
|
81
106
|
// src/substrate/SubstrateClient.ts
|
|
82
107
|
var import_polkadot_api = require("polkadot-api");
|
|
83
108
|
var import_ws_provider = require("polkadot-api/ws-provider");
|
|
109
|
+
var import_metadata_builders = require("@polkadot-api/metadata-builders");
|
|
110
|
+
var import_substrate_bindings = require("@polkadot-api/substrate-bindings");
|
|
111
|
+
var import_substrate_bindings2 = require("@polkadot-api/substrate-bindings");
|
|
112
|
+
var import_tx_utils = require("@polkadot-api/tx-utils");
|
|
113
|
+
|
|
114
|
+
// src/utils/hex.ts
|
|
115
|
+
function toHex(bytes) {
|
|
116
|
+
return "0x" + Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
117
|
+
}
|
|
118
|
+
function fromHex(hex) {
|
|
119
|
+
const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
120
|
+
if (clean.length % 2 !== 0) {
|
|
121
|
+
throw new Error(`Invalid hex string \u2014 odd length: "${hex}"`);
|
|
122
|
+
}
|
|
123
|
+
const bytes = new Uint8Array(clean.length / 2);
|
|
124
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
125
|
+
const byte = parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
126
|
+
if (isNaN(byte)) throw new Error(`Invalid hex character at position ${i * 2}`);
|
|
127
|
+
bytes[i] = byte;
|
|
128
|
+
}
|
|
129
|
+
return bytes;
|
|
130
|
+
}
|
|
131
|
+
function ensureHexPrefix(hex) {
|
|
132
|
+
return hex.startsWith("0x") ? hex : `0x${hex}`;
|
|
133
|
+
}
|
|
134
|
+
function hexToNumber(hex) {
|
|
135
|
+
return parseInt(hex, 16);
|
|
136
|
+
}
|
|
137
|
+
function hexToBigint(hex) {
|
|
138
|
+
return BigInt(hex);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// src/substrate/SubstrateClient.ts
|
|
84
142
|
var SubstrateClient = class _SubstrateClient {
|
|
85
143
|
constructor(_papi) {
|
|
86
144
|
this._papi = _papi;
|
|
87
145
|
}
|
|
146
|
+
_dynamicBuilder = null;
|
|
147
|
+
_extDecoder = null;
|
|
88
148
|
/**
|
|
89
149
|
* Connects to the Orbinum node via WebSocket.
|
|
90
150
|
* Throws if the node does not respond within `timeoutMs`.
|
|
@@ -110,13 +170,145 @@ var SubstrateClient = class _SubstrateClient {
|
|
|
110
170
|
async request(method, params = []) {
|
|
111
171
|
return this._papi._request(method, params);
|
|
112
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Returns basic chain information from the node.
|
|
175
|
+
* Combines `system_name`, `system_chain`, `system_properties`, and `state_getRuntimeVersion`.
|
|
176
|
+
*/
|
|
177
|
+
async getChainInfo() {
|
|
178
|
+
const [chainName, version, props] = await Promise.all([
|
|
179
|
+
this.request("system_chain", []),
|
|
180
|
+
this.request("state_getRuntimeVersion", []),
|
|
181
|
+
this.request(
|
|
182
|
+
"system_properties",
|
|
183
|
+
[]
|
|
184
|
+
)
|
|
185
|
+
]);
|
|
186
|
+
const rawSymbol = props.tokenSymbol;
|
|
187
|
+
const rawDecimals = props.tokenDecimals;
|
|
188
|
+
return {
|
|
189
|
+
name: chainName,
|
|
190
|
+
version: String(version.specVersion),
|
|
191
|
+
ss58Prefix: version.ss58Prefix ?? 42,
|
|
192
|
+
symbol: Array.isArray(rawSymbol) ? rawSymbol[0] ?? "ORB" : rawSymbol ?? "ORB",
|
|
193
|
+
decimals: Array.isArray(rawDecimals) ? rawDecimals[0] ?? 18 : rawDecimals ?? 18
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Returns the node's peer count and sync status.
|
|
198
|
+
*/
|
|
199
|
+
async getHealth() {
|
|
200
|
+
return this.request("system_health", []);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Returns the node's software version string.
|
|
204
|
+
*/
|
|
205
|
+
async getNodeVersion() {
|
|
206
|
+
return this.request("system_version", []);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Returns the genesis hash hex.
|
|
210
|
+
*/
|
|
211
|
+
async getGenesisHash() {
|
|
212
|
+
return this.request("chain_getBlockHash", [0]);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Returns the block hash for a given block number.
|
|
216
|
+
* Returns null when the block does not exist or has been pruned.
|
|
217
|
+
*/
|
|
218
|
+
async getBlockHash(blockNumber) {
|
|
219
|
+
const hash = await this.request("chain_getBlockHash", [blockNumber]);
|
|
220
|
+
if (!hash || /^0x0+$/.test(hash) || hash === "0x" + "00".repeat(32)) return null;
|
|
221
|
+
return hash;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Fetches a block by hash or number, enriched with timestamp and block author.
|
|
225
|
+
*
|
|
226
|
+
* Uses `chain_getBlock` (works for all non-pruned blocks, unlike PAPI chainHead
|
|
227
|
+
* which only pins recent blocks). Timestamp is read from `Timestamp.Now` storage
|
|
228
|
+
* with a fallback via the `timestamp.set` extrinsic argument. Author is decoded
|
|
229
|
+
* from PreRuntime digest logs using the chain's SS58 prefix.
|
|
230
|
+
*
|
|
231
|
+
* @param hashOrNumber - A `0x`-prefixed block hash or a block number (number or decimal string).
|
|
232
|
+
* @returns `BlockInfo` or `null` if the block is not found.
|
|
233
|
+
*/
|
|
234
|
+
async getBlock(hashOrNumber) {
|
|
235
|
+
try {
|
|
236
|
+
let blockHash;
|
|
237
|
+
if (typeof hashOrNumber === "number" || /^\d+$/.test(String(hashOrNumber))) {
|
|
238
|
+
const num = typeof hashOrNumber === "number" ? hashOrNumber : parseInt(hashOrNumber, 10);
|
|
239
|
+
const h = await this.getBlockHash(num);
|
|
240
|
+
if (!h) return null;
|
|
241
|
+
blockHash = h;
|
|
242
|
+
} else {
|
|
243
|
+
blockHash = hashOrNumber;
|
|
244
|
+
}
|
|
245
|
+
const raw = await this.request("chain_getBlock", [blockHash]);
|
|
246
|
+
if (!raw?.block) return null;
|
|
247
|
+
const { header, extrinsics } = raw.block;
|
|
248
|
+
const builder = await this.getDynamicBuilder().catch(() => null);
|
|
249
|
+
const ss58Prefix = builder?.ss58Prefix ?? 42;
|
|
250
|
+
let timestampMs = null;
|
|
251
|
+
if (builder) {
|
|
252
|
+
try {
|
|
253
|
+
const tsStore = builder.buildStorage("Timestamp", "Now");
|
|
254
|
+
const tsRaw = await this.request("state_getStorage", [
|
|
255
|
+
tsStore.keys.enc(),
|
|
256
|
+
blockHash
|
|
257
|
+
]);
|
|
258
|
+
if (tsRaw) {
|
|
259
|
+
timestampMs = Number(tsStore.value.dec(fromHex(tsRaw)));
|
|
260
|
+
}
|
|
261
|
+
} catch {
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (!timestampMs) {
|
|
265
|
+
const tsHex = extrinsics.find((hex) => {
|
|
266
|
+
try {
|
|
267
|
+
const b = fromHex(hex);
|
|
268
|
+
return b.length > 6 && b[4] === 3 && b[5] === 0;
|
|
269
|
+
} catch {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
if (tsHex) {
|
|
274
|
+
try {
|
|
275
|
+
const b = fromHex(tsHex);
|
|
276
|
+
const view = new DataView(b.buffer, b.byteOffset + 6, 8);
|
|
277
|
+
const lo = view.getUint32(0, true);
|
|
278
|
+
const hi = view.getUint32(4, true);
|
|
279
|
+
const ms = lo + hi * 4294967296;
|
|
280
|
+
if (ms > 0) timestampMs = ms;
|
|
281
|
+
} catch {
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
const author = _SubstrateClient.extractAuthorFromLogs(header.digest.logs, ss58Prefix);
|
|
286
|
+
return { header, extrinsics, timestampMs, author };
|
|
287
|
+
} catch {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
113
291
|
/**
|
|
114
292
|
* Returns the underlying PolkadotClient instance.
|
|
115
|
-
* Use for
|
|
293
|
+
* Use for raw metadata access and advanced SCALE operations.
|
|
116
294
|
*/
|
|
117
295
|
get polkadotClient() {
|
|
118
296
|
return this._papi;
|
|
119
297
|
}
|
|
298
|
+
/**
|
|
299
|
+
* Observable that emits a new entry each time a best-block is reported by the node.
|
|
300
|
+
* Delegates to PAPI's `blocks$`.
|
|
301
|
+
*/
|
|
302
|
+
get blocks$() {
|
|
303
|
+
return this._papi.blocks$;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Returns the block header for a given tag or block hash.
|
|
307
|
+
* Delegates to PAPI's `getBlockHeader`.
|
|
308
|
+
*/
|
|
309
|
+
getBlockHeader(...args) {
|
|
310
|
+
return this._papi.getBlockHeader(...args);
|
|
311
|
+
}
|
|
120
312
|
/**
|
|
121
313
|
* Returns the PAPI UnsafeApi for dynamic, metadata-driven transaction building.
|
|
122
314
|
* The first access triggers a metadata fetch from the node.
|
|
@@ -161,34 +353,148 @@ var SubstrateClient = class _SubstrateClient {
|
|
|
161
353
|
destroy() {
|
|
162
354
|
this._papi.destroy();
|
|
163
355
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
356
|
+
/**
|
|
357
|
+
* Fetches and decodes all events for a given block hash.
|
|
358
|
+
* Queries `System.Events` storage via SCALE codec built from on-chain metadata.
|
|
359
|
+
*
|
|
360
|
+
* @param blockHash - The `0x`-prefixed block hash string.
|
|
361
|
+
* @returns Array of `EventRecord` or `null` if unavailable.
|
|
362
|
+
*/
|
|
363
|
+
async queryBlockEvents(blockHash) {
|
|
364
|
+
try {
|
|
365
|
+
const builder = await this.getDynamicBuilder();
|
|
366
|
+
const { keys, value } = builder.buildStorage("System", "Events");
|
|
367
|
+
const raw = await this.request("state_getStorage", [
|
|
368
|
+
keys.enc(),
|
|
369
|
+
blockHash
|
|
370
|
+
]);
|
|
371
|
+
if (!raw) return null;
|
|
372
|
+
const decoded = value.dec(fromHex(raw));
|
|
373
|
+
return _SubstrateClient._toEventRecords(decoded);
|
|
374
|
+
} catch {
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
174
377
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
378
|
+
// ─── Internal helpers ─────────────────────────────────────────────────────
|
|
379
|
+
async getDynamicBuilder() {
|
|
380
|
+
if (this._dynamicBuilder) return this._dynamicBuilder;
|
|
381
|
+
const rawMetadata = await this._papi.getMetadata("best");
|
|
382
|
+
const metadata = (0, import_substrate_bindings.decAnyMetadata)(rawMetadata);
|
|
383
|
+
const unified = (0, import_substrate_bindings.unifyMetadata)(metadata);
|
|
384
|
+
const lookup = (0, import_metadata_builders.getLookupFn)(unified);
|
|
385
|
+
this._dynamicBuilder = (0, import_metadata_builders.getDynamicBuilder)(lookup);
|
|
386
|
+
return this._dynamicBuilder;
|
|
387
|
+
}
|
|
388
|
+
async getExtrinsicDecoder() {
|
|
389
|
+
if (this._extDecoder) return this._extDecoder;
|
|
390
|
+
const rawMetadata = await this._papi.getMetadata("best");
|
|
391
|
+
this._extDecoder = (0, import_tx_utils.getExtrinsicDecoder)(rawMetadata);
|
|
392
|
+
return this._extDecoder;
|
|
393
|
+
}
|
|
394
|
+
static _buildDataProxy(value) {
|
|
395
|
+
const formatValue = (v) => {
|
|
396
|
+
if (v instanceof Uint8Array) return fromHex(v).toString();
|
|
397
|
+
if (typeof v === "bigint") return v.toString();
|
|
398
|
+
return String(v);
|
|
399
|
+
};
|
|
400
|
+
const jsonifyValue = (v) => {
|
|
401
|
+
if (v === null || v === void 0) return v;
|
|
402
|
+
if (typeof v === "bigint") return v.toString();
|
|
403
|
+
if (v instanceof Uint8Array)
|
|
404
|
+
return Array.from(v).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
405
|
+
if (Array.isArray(v)) return v.map(jsonifyValue);
|
|
406
|
+
if (typeof v === "object") {
|
|
407
|
+
return Object.fromEntries(
|
|
408
|
+
Object.entries(v).filter(([, val]) => typeof val !== "function").map(([k, val]) => [k, jsonifyValue(val)])
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
return v;
|
|
412
|
+
};
|
|
413
|
+
const entries = Array.isArray(value) ? value : value !== null && typeof value === "object" ? Object.values(value) : [value];
|
|
414
|
+
const items = entries.map((v) => ({
|
|
415
|
+
toString: () => formatValue(v),
|
|
416
|
+
toJSON: () => jsonifyValue(v),
|
|
417
|
+
toHuman: () => jsonifyValue(v),
|
|
418
|
+
...v !== null && typeof v === "object" ? v : {}
|
|
419
|
+
}));
|
|
420
|
+
return Object.assign(items, {
|
|
421
|
+
toJSON: () => jsonifyValue(value),
|
|
422
|
+
toHuman: () => jsonifyValue(value)
|
|
423
|
+
});
|
|
180
424
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
425
|
+
/**
|
|
426
|
+
* Extracts the block author (validator/collator) from raw digest log hex strings.
|
|
427
|
+
* Looks for a PreRuntime log (tag byte = 6) and decodes the first 32 bytes of the
|
|
428
|
+
* SCALE-compact payload as an SS58 address using the given prefix.
|
|
429
|
+
*
|
|
430
|
+
* Can be used standalone with raw logs from `chain_getBlock` responses.
|
|
431
|
+
*/
|
|
432
|
+
static extractAuthorFromLogs(logs, ss58Prefix) {
|
|
433
|
+
try {
|
|
434
|
+
for (const hex of logs) {
|
|
435
|
+
const bytes = fromHex(hex);
|
|
436
|
+
if (bytes.length < 6 || bytes[0] !== 6) continue;
|
|
437
|
+
const firstLenByte = bytes[5];
|
|
438
|
+
const mode = firstLenByte & 3;
|
|
439
|
+
let payloadStart;
|
|
440
|
+
let payloadLen;
|
|
441
|
+
if (mode === 0) {
|
|
442
|
+
payloadLen = firstLenByte >> 2;
|
|
443
|
+
payloadStart = 6;
|
|
444
|
+
} else if (mode === 1) {
|
|
445
|
+
if (bytes.length < 7) continue;
|
|
446
|
+
payloadLen = firstLenByte >> 2 | bytes[6] << 6;
|
|
447
|
+
payloadStart = 7;
|
|
448
|
+
} else if (mode === 2) {
|
|
449
|
+
if (bytes.length < 9) continue;
|
|
450
|
+
payloadLen = (firstLenByte >> 2 | bytes[6] << 6 | bytes[7] << 14 | bytes[8] << 22) >>> 0;
|
|
451
|
+
payloadStart = 9;
|
|
452
|
+
} else {
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
const payload = bytes.slice(payloadStart, payloadStart + payloadLen);
|
|
456
|
+
if (payload.length >= 32) {
|
|
457
|
+
try {
|
|
458
|
+
return (0, import_substrate_bindings2.AccountId)(ss58Prefix).dec(payload.slice(0, 32));
|
|
459
|
+
} catch {
|
|
460
|
+
return toHex(payload.slice(0, 32));
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
} catch {
|
|
465
|
+
}
|
|
466
|
+
return null;
|
|
467
|
+
}
|
|
468
|
+
static _toEventRecords(decoded) {
|
|
469
|
+
return decoded.flatMap((e) => {
|
|
470
|
+
try {
|
|
471
|
+
const raw = e;
|
|
472
|
+
const isApply = raw.phase.type === "ApplyExtrinsic";
|
|
473
|
+
const extIdx = isApply ? raw.phase.value : 0;
|
|
474
|
+
const section = raw.event.type.charAt(0).toLowerCase() + raw.event.type.slice(1);
|
|
475
|
+
const method = raw.event.value.type;
|
|
476
|
+
const record = {
|
|
477
|
+
phase: {
|
|
478
|
+
isApplyExtrinsic: isApply,
|
|
479
|
+
asApplyExtrinsic: {
|
|
480
|
+
eq: (n) => n === extIdx,
|
|
481
|
+
toString: () => String(extIdx),
|
|
482
|
+
toNumber: () => extIdx
|
|
483
|
+
}
|
|
484
|
+
},
|
|
485
|
+
event: {
|
|
486
|
+
section,
|
|
487
|
+
method,
|
|
488
|
+
data: _SubstrateClient._buildDataProxy(raw.event.value.value)
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
return [record];
|
|
492
|
+
} catch {
|
|
493
|
+
return [];
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
};
|
|
192
498
|
|
|
193
499
|
// src/evm/EvmClient.ts
|
|
194
500
|
var EvmClient = class {
|
|
@@ -285,77 +591,582 @@ var EvmClient = class {
|
|
|
285
591
|
* Returns a transaction receipt by hash, or null if not yet mined.
|
|
286
592
|
*/
|
|
287
593
|
async getTransactionReceipt(txHash) {
|
|
288
|
-
|
|
594
|
+
const res = await fetch(this.rpcUrl, {
|
|
595
|
+
method: "POST",
|
|
596
|
+
headers: { "Content-Type": "application/json" },
|
|
597
|
+
body: JSON.stringify({
|
|
598
|
+
id: 1,
|
|
599
|
+
jsonrpc: "2.0",
|
|
600
|
+
method: "eth_getTransactionReceipt",
|
|
601
|
+
params: [txHash]
|
|
602
|
+
})
|
|
603
|
+
});
|
|
604
|
+
if (!res.ok) throw new Error(`EVM HTTP ${res.status}: ${res.statusText}`);
|
|
605
|
+
const json = await res.json();
|
|
606
|
+
if (json.error) {
|
|
607
|
+
throw new Error(`EVM RPC [${json.error.code}]: ${json.error.message}`);
|
|
608
|
+
}
|
|
609
|
+
return json.result ?? null;
|
|
289
610
|
}
|
|
290
611
|
};
|
|
291
612
|
|
|
292
|
-
// src/
|
|
293
|
-
var
|
|
294
|
-
|
|
295
|
-
|
|
613
|
+
// src/utils/format.ts
|
|
614
|
+
var LOCALE_DECIMAL_SEP = new Intl.NumberFormat(void 0).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? ".";
|
|
615
|
+
function formatIntegerLocale(intPart) {
|
|
616
|
+
try {
|
|
617
|
+
return BigInt(intPart || "0").toLocaleString(void 0);
|
|
618
|
+
} catch {
|
|
619
|
+
return (intPart || "0").replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
296
620
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
621
|
+
}
|
|
622
|
+
function normalizeDecimalForDisplay(raw, maxFractionDigits) {
|
|
623
|
+
let value = raw.trim();
|
|
624
|
+
if (!value) return null;
|
|
625
|
+
let sign = "";
|
|
626
|
+
if (value.startsWith("-")) {
|
|
627
|
+
sign = "-";
|
|
628
|
+
value = value.slice(1);
|
|
629
|
+
}
|
|
630
|
+
if (!/^\d*(\.\d*)?$/.test(value)) return null;
|
|
631
|
+
let [integerPart = "0", fractionPart = ""] = value.split(".");
|
|
632
|
+
integerPart = integerPart.replace(/^0+(?=\d)/, "") || "0";
|
|
633
|
+
const limit = Math.max(0, maxFractionDigits);
|
|
634
|
+
fractionPart = fractionPart.slice(0, limit).replace(/0+$/, "");
|
|
635
|
+
const formattedInt = formatIntegerLocale(integerPart);
|
|
636
|
+
return fractionPart ? `${sign}${formattedInt}${LOCALE_DECIMAL_SEP}${fractionPart}` : `${sign}${formattedInt}`;
|
|
637
|
+
}
|
|
638
|
+
function bigintFormatUnits(value, decimals) {
|
|
639
|
+
const negative = value < 0n;
|
|
640
|
+
const abs = negative ? -value : value;
|
|
641
|
+
const divider = 10n ** BigInt(decimals);
|
|
642
|
+
const intPart = abs / divider;
|
|
643
|
+
const fracPart = abs % divider;
|
|
644
|
+
const fracStr = fracPart.toString().padStart(decimals, "0");
|
|
645
|
+
return (negative ? "-" : "") + intPart.toString() + "." + fracStr;
|
|
646
|
+
}
|
|
647
|
+
function isCanonicalDecimal(value) {
|
|
648
|
+
return /^-?(?:\d+\.\d*|\d*\.\d+)$/.test(value);
|
|
649
|
+
}
|
|
650
|
+
function isBigIntLikeInteger(value) {
|
|
651
|
+
return /^-?\d+$/.test(value) || /^0[xX][0-9a-fA-F]+$/.test(value);
|
|
652
|
+
}
|
|
653
|
+
function formatBalance(raw, options = {}) {
|
|
654
|
+
const opts = typeof options === "number" ? { decimals: options } : options;
|
|
655
|
+
const { decimals = 18, symbol = "ORB", showSymbol = true, precision = 6 } = opts;
|
|
656
|
+
const zero = showSymbol ? `0 ${symbol}` : "0";
|
|
657
|
+
if (raw === null || raw === void 0) return zero;
|
|
658
|
+
if (typeof raw === "number" && !Number.isFinite(raw)) return zero;
|
|
659
|
+
const rawStr = String(raw).trim();
|
|
660
|
+
if (!rawStr) return zero;
|
|
661
|
+
if (isCanonicalDecimal(rawStr)) {
|
|
662
|
+
const formatted = normalizeDecimalForDisplay(rawStr, precision);
|
|
663
|
+
if (!formatted || formatted === "0" || formatted === "-0") return zero;
|
|
664
|
+
return showSymbol ? `${formatted} ${symbol}` : formatted;
|
|
665
|
+
}
|
|
666
|
+
if (!isBigIntLikeInteger(rawStr)) return zero;
|
|
667
|
+
try {
|
|
668
|
+
const n = BigInt(rawStr);
|
|
669
|
+
const decimalStr = bigintFormatUnits(n, decimals);
|
|
670
|
+
const formatted = normalizeDecimalForDisplay(decimalStr, precision);
|
|
671
|
+
if (!formatted || formatted === "0" || formatted === "-0") return zero;
|
|
672
|
+
return showSymbol ? `${formatted} ${symbol}` : formatted;
|
|
673
|
+
} catch {
|
|
674
|
+
return zero;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
function formatORB(raw, precision = 6) {
|
|
678
|
+
return formatBalance(raw, { decimals: 18, symbol: "ORB", showSymbol: true, precision });
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// src/evm-explorer/EvmExplorer.ts
|
|
682
|
+
var EvmExplorer = class _EvmExplorer {
|
|
683
|
+
constructor(evm) {
|
|
684
|
+
this.evm = evm;
|
|
685
|
+
}
|
|
686
|
+
// --- Blocks ---
|
|
687
|
+
async getLatestBlocks(count = 10) {
|
|
688
|
+
const latest = await this.evm.getBlockNumber();
|
|
689
|
+
const nums = Array.from({ length: Math.min(count, latest + 1) }, (_, i) => latest - i);
|
|
690
|
+
const results = await Promise.all(
|
|
691
|
+
nums.map(
|
|
692
|
+
(n) => this.evm.request("eth_getBlockByNumber", [
|
|
693
|
+
`0x${n.toString(16)}`,
|
|
694
|
+
false
|
|
695
|
+
]).catch(() => null)
|
|
696
|
+
)
|
|
304
697
|
);
|
|
305
|
-
return
|
|
306
|
-
root: raw.root,
|
|
307
|
-
treeSize: raw.tree_size,
|
|
308
|
-
depth: raw.depth
|
|
309
|
-
};
|
|
698
|
+
return results.filter((b) => b !== null && !!b.hash).map((b) => this.parseBlock(b));
|
|
310
699
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
async getProof(leafIndex) {
|
|
315
|
-
const raw = await this.substrate.request("shieldedPool_getMerkleProof", [
|
|
316
|
-
leafIndex
|
|
317
|
-
]);
|
|
318
|
-
return {
|
|
319
|
-
root: raw.root,
|
|
320
|
-
leafIndex: raw.leaf_index,
|
|
321
|
-
siblings: raw.siblings
|
|
322
|
-
};
|
|
700
|
+
async getBlock(hashOrNumber) {
|
|
701
|
+
const b = await this.fetchBlock(hashOrNumber, false);
|
|
702
|
+
return b ? this.parseBlock(b) : null;
|
|
323
703
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
704
|
+
async getBlockTransactions(hashOrNumber) {
|
|
705
|
+
try {
|
|
706
|
+
const b = await this.fetchBlock(hashOrNumber, true);
|
|
707
|
+
if (!b || !b.transactions.length) return [];
|
|
708
|
+
const txs = b.transactions;
|
|
709
|
+
const receipts = await this.evm.batchRequest(txs.map((tx) => ({ method: "eth_getTransactionReceipt", params: [tx.hash] }))).catch(() => txs.map(() => null));
|
|
710
|
+
return txs.map((tx, i) => this.parseTx(tx, receipts[i] ?? null));
|
|
711
|
+
} catch {
|
|
712
|
+
return [];
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
// --- Transactions ---
|
|
716
|
+
async getTransaction(hash) {
|
|
717
|
+
try {
|
|
718
|
+
const [tx, receipt] = await Promise.all([
|
|
719
|
+
this.evm.request("eth_getTransactionByHash", [hash]),
|
|
720
|
+
this.evm.request("eth_getTransactionReceipt", [hash]).catch(() => null)
|
|
721
|
+
]);
|
|
722
|
+
if (!tx) return null;
|
|
723
|
+
return this.parseTx(tx, receipt);
|
|
724
|
+
} catch {
|
|
725
|
+
return null;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
async getTransactionsByAddress(address, maxBlocks = 300) {
|
|
729
|
+
const addr = address.toLowerCase();
|
|
730
|
+
const latest = await this.evm.getBlockNumber();
|
|
731
|
+
const from = Math.max(0, latest - maxBlocks + 1);
|
|
732
|
+
const blockNums = Array.from({ length: latest - from + 1 }, (_, i) => latest - i);
|
|
733
|
+
const blocks = await Promise.all(
|
|
734
|
+
blockNums.map(
|
|
735
|
+
(n) => this.evm.request("eth_getBlockByNumber", [
|
|
736
|
+
`0x${n.toString(16)}`,
|
|
737
|
+
true
|
|
738
|
+
]).catch(() => null)
|
|
739
|
+
)
|
|
740
|
+
);
|
|
741
|
+
const matchingTxs = [];
|
|
742
|
+
for (const block of blocks) {
|
|
743
|
+
if (!block?.transactions) continue;
|
|
744
|
+
const blockTimestamp = block.timestamp ? hexToNumber(block.timestamp) : null;
|
|
745
|
+
for (const tx of block.transactions) {
|
|
746
|
+
if (tx.from?.toLowerCase() === addr || tx.to?.toLowerCase() === addr) {
|
|
747
|
+
matchingTxs.push({ tx, timestamp: blockTimestamp });
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
if (!matchingTxs.length) return [];
|
|
752
|
+
const receipts = await this.evm.batchRequest(
|
|
753
|
+
matchingTxs.map(({ tx }) => ({
|
|
754
|
+
method: "eth_getTransactionReceipt",
|
|
755
|
+
params: [tx.hash]
|
|
756
|
+
}))
|
|
757
|
+
).catch(() => matchingTxs.map(() => null));
|
|
758
|
+
const results = matchingTxs.map(({ tx, timestamp }, i) => {
|
|
759
|
+
const receipt = receipts[i] ?? null;
|
|
760
|
+
return {
|
|
761
|
+
hash: tx.hash,
|
|
762
|
+
blockNumber: hexToNumber(tx.blockNumber),
|
|
763
|
+
timestamp,
|
|
764
|
+
from: tx.from,
|
|
765
|
+
to: tx.to,
|
|
766
|
+
value: tx.value ?? "0x0",
|
|
767
|
+
input: tx.input ?? "0x",
|
|
768
|
+
gasUsed: receipt ? hexToNumber(receipt.gasUsed) : hexToNumber(tx.gas),
|
|
769
|
+
gasPrice: tx.gasPrice ?? "0x0",
|
|
770
|
+
status: receipt ? receipt.status === "0x1" : true,
|
|
771
|
+
isContractCreation: !tx.to,
|
|
772
|
+
contractAddress: receipt?.contractAddress ?? null
|
|
773
|
+
};
|
|
774
|
+
});
|
|
775
|
+
results.sort((a, b) => b.blockNumber - a.blockNumber);
|
|
776
|
+
return results;
|
|
777
|
+
}
|
|
778
|
+
// --- Address ---
|
|
779
|
+
async getAddressInfo(address) {
|
|
780
|
+
const latest = await this.evm.getBlockNumber().catch(() => 0);
|
|
781
|
+
const fromBlock = `0x${Math.max(0, latest - 5e3).toString(16)}`;
|
|
782
|
+
const [balance, nonce, code, logs] = await Promise.all([
|
|
783
|
+
this.evm.request("eth_getBalance", [address, "latest"]).catch(() => null),
|
|
784
|
+
this.evm.getTransactionCount(address).catch(() => 0),
|
|
785
|
+
this.evm.request("eth_getCode", [address, "latest"]).catch(() => null),
|
|
786
|
+
this.evm.request("eth_getLogs", [{ fromBlock, toBlock: "latest", address }]).catch(() => [])
|
|
331
787
|
]);
|
|
788
|
+
const codeHex = code ?? "0x";
|
|
789
|
+
const isContract = codeHex !== "0x" && codeHex.length > 2;
|
|
790
|
+
const codeBytes = isContract ? Math.floor((codeHex.length - 2) / 2) : 0;
|
|
791
|
+
const recentLogs = (logs ?? []).slice(-50).map((l) => ({
|
|
792
|
+
address: l.address,
|
|
793
|
+
topics: l.topics,
|
|
794
|
+
data: l.data,
|
|
795
|
+
blockNumber: hexToNumber(l.blockNumber),
|
|
796
|
+
transactionHash: l.transactionHash,
|
|
797
|
+
logIndex: hexToNumber(l.logIndex)
|
|
798
|
+
}));
|
|
332
799
|
return {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
800
|
+
address,
|
|
801
|
+
isContract,
|
|
802
|
+
balance: balance ?? "0x0",
|
|
803
|
+
nonce: typeof nonce === "number" ? nonce : hexToNumber(nonce ?? "0x0"),
|
|
804
|
+
codeSize: codeBytes,
|
|
805
|
+
code: isContract ? codeHex.length > 202 ? `${codeHex.slice(0, 202)}\u2026` : codeHex : "0x",
|
|
806
|
+
recentLogs
|
|
336
807
|
};
|
|
337
808
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
809
|
+
async getBalance(address) {
|
|
810
|
+
try {
|
|
811
|
+
const val = await this.evm.getBalance(address);
|
|
812
|
+
return formatBalance(val, { showSymbol: false, precision: 18 });
|
|
813
|
+
} catch {
|
|
814
|
+
return "0";
|
|
815
|
+
}
|
|
344
816
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
817
|
+
async getNonce(address) {
|
|
818
|
+
try {
|
|
819
|
+
return await this.evm.getTransactionCount(address);
|
|
820
|
+
} catch {
|
|
821
|
+
return 0;
|
|
822
|
+
}
|
|
351
823
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
824
|
+
async getIsContract(address) {
|
|
825
|
+
try {
|
|
826
|
+
const code = await this.evm.request("eth_getCode", [address, "latest"]);
|
|
827
|
+
return code !== "0x" && code !== "0x0" && code.length > 2;
|
|
828
|
+
} catch {
|
|
829
|
+
return false;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
// --- Tokens ---
|
|
833
|
+
async getTokenInfo(address) {
|
|
834
|
+
const addr = address.toLowerCase();
|
|
835
|
+
const [name, symbol, decimals, totalSupply] = await this.evm.batchRequest([
|
|
836
|
+
{ method: "eth_call", params: [{ to: addr, data: "0x06fdde03" }, "latest"] },
|
|
837
|
+
{ method: "eth_call", params: [{ to: addr, data: "0x95d89b41" }, "latest"] },
|
|
838
|
+
{ method: "eth_call", params: [{ to: addr, data: "0x313ce567" }, "latest"] },
|
|
839
|
+
{ method: "eth_call", params: [{ to: addr, data: "0x18160ddd" }, "latest"] }
|
|
840
|
+
]).catch(() => [null, null, null, null]);
|
|
841
|
+
const isErc20 = !!(totalSupply && totalSupply !== "0x" && symbol && decimals);
|
|
842
|
+
if (!isErc20 && !name && !symbol) return null;
|
|
843
|
+
return {
|
|
844
|
+
address: addr,
|
|
845
|
+
name: name ? _EvmExplorer.decodeAbiString(name) : "",
|
|
846
|
+
symbol: symbol ? _EvmExplorer.decodeAbiString(symbol) : "",
|
|
847
|
+
decimals: decimals ? Number(_EvmExplorer.decodeAbiUint(decimals)) : 18,
|
|
848
|
+
totalSupply: totalSupply ?? "0x0",
|
|
849
|
+
isErc20
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
async getTokenTransfers(address, holderAddress) {
|
|
853
|
+
const TRANSFER = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
|
|
854
|
+
const latest = await this.evm.getBlockNumber().catch(() => 0);
|
|
855
|
+
const fromBlock = `0x${Math.max(0, latest - 5e3).toString(16)}`;
|
|
856
|
+
let logs;
|
|
857
|
+
if (holderAddress) {
|
|
858
|
+
const padded = `0x${holderAddress.replace(/^0x/, "").toLowerCase().padStart(64, "0")}`;
|
|
859
|
+
const [sent, received] = await Promise.all([
|
|
860
|
+
this.evm.request("eth_getLogs", [{ fromBlock, toBlock: "latest", address, topics: [TRANSFER, padded] }]).catch(() => []),
|
|
861
|
+
this.evm.request("eth_getLogs", [{ fromBlock, toBlock: "latest", address, topics: [TRANSFER, null, padded] }]).catch(() => [])
|
|
862
|
+
]);
|
|
863
|
+
const merged = [...sent ?? [], ...received ?? []];
|
|
864
|
+
merged.sort((a, b) => hexToNumber(b.blockNumber) - hexToNumber(a.blockNumber));
|
|
865
|
+
logs = merged.slice(0, 100);
|
|
866
|
+
} else {
|
|
867
|
+
const all = await this.evm.request("eth_getLogs", [{ fromBlock, toBlock: "latest", address, topics: [TRANSFER] }]).catch(() => []);
|
|
868
|
+
logs = (all ?? []).slice(-100).reverse();
|
|
869
|
+
}
|
|
870
|
+
return logs.map((l) => ({
|
|
871
|
+
transactionHash: l.transactionHash,
|
|
872
|
+
blockNumber: hexToNumber(l.blockNumber),
|
|
873
|
+
from: `0x${(l.topics[1] ?? "").slice(-40)}`,
|
|
874
|
+
to: `0x${(l.topics[2] ?? "").slice(-40)}`,
|
|
875
|
+
value: l.data,
|
|
876
|
+
logIndex: hexToNumber(l.logIndex)
|
|
877
|
+
}));
|
|
878
|
+
}
|
|
879
|
+
async getTokenBalance(tokenAddress, holderAddress) {
|
|
880
|
+
const padded = holderAddress.replace(/^0x/, "").toLowerCase().padStart(64, "0");
|
|
881
|
+
const result = await this.ethCall(tokenAddress, `0x70a08231${padded}`);
|
|
882
|
+
return result ?? "0x0";
|
|
883
|
+
}
|
|
884
|
+
// --- Private: parsers ---
|
|
885
|
+
parseBlock(b) {
|
|
886
|
+
return {
|
|
887
|
+
hash: b.hash,
|
|
888
|
+
number: hexToNumber(b.number),
|
|
889
|
+
timestamp: hexToNumber(b.timestamp),
|
|
890
|
+
transactions: b.transactions.map((tx) => typeof tx === "string" ? tx : tx.hash),
|
|
891
|
+
gasUsed: hexToNumber(b.gasUsed).toString(),
|
|
892
|
+
gasLimit: hexToNumber(b.gasLimit).toString(),
|
|
893
|
+
miner: b.miner,
|
|
894
|
+
parentHash: b.parentHash
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
parseTx(tx, receipt) {
|
|
898
|
+
const parsed = {
|
|
899
|
+
hash: tx.hash,
|
|
900
|
+
blockNumber: tx.blockNumber ? hexToNumber(tx.blockNumber) : 0,
|
|
901
|
+
from: tx.from,
|
|
902
|
+
to: tx.to ?? null,
|
|
903
|
+
value: tx.value,
|
|
904
|
+
gasUsed: receipt ? hexToNumber(receipt.gasUsed).toString() : "0",
|
|
905
|
+
gasPrice: _EvmExplorer.hexToDecimalStr(tx.gasPrice),
|
|
906
|
+
nonce: hexToNumber(tx.nonce),
|
|
907
|
+
input: tx.input ?? "0x",
|
|
908
|
+
status: receipt ? hexToNumber(receipt.status) : 0,
|
|
909
|
+
contractAddress: receipt?.contractAddress ?? null,
|
|
910
|
+
timestamp: null
|
|
911
|
+
};
|
|
912
|
+
if (tx.blockHash) parsed.blockHash = tx.blockHash;
|
|
913
|
+
return parsed;
|
|
914
|
+
}
|
|
915
|
+
// --- Private: fetch helpers ---
|
|
916
|
+
async fetchBlock(hashOrNumber, withTxObjects) {
|
|
917
|
+
try {
|
|
918
|
+
if (typeof hashOrNumber === "number" || /^\d+$/.test(String(hashOrNumber))) {
|
|
919
|
+
const hexN = `0x${parseInt(String(hashOrNumber), 10).toString(16)}`;
|
|
920
|
+
return await this.evm.request("eth_getBlockByNumber", [
|
|
921
|
+
hexN,
|
|
922
|
+
withTxObjects
|
|
923
|
+
]);
|
|
924
|
+
}
|
|
925
|
+
return await this.evm.request("eth_getBlockByHash", [
|
|
926
|
+
hashOrNumber,
|
|
927
|
+
withTxObjects
|
|
928
|
+
]);
|
|
929
|
+
} catch {
|
|
930
|
+
return null;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
async ethCall(to, data) {
|
|
934
|
+
try {
|
|
935
|
+
return await this.evm.call(to, data);
|
|
936
|
+
} catch {
|
|
937
|
+
return null;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
// --- Private static: ABI decoders ---
|
|
941
|
+
static decodeAbiString(hex) {
|
|
942
|
+
if (!hex || hex === "0x") return "";
|
|
943
|
+
const data = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
944
|
+
if (data.length < 128) return "";
|
|
945
|
+
const length = parseInt(data.slice(64, 128), 16);
|
|
946
|
+
if (!length) return "";
|
|
947
|
+
const strHex = data.slice(128, 128 + length * 2);
|
|
948
|
+
try {
|
|
949
|
+
const bytes = new Uint8Array(strHex.match(/../g)?.map((b) => parseInt(b, 16)) ?? []);
|
|
950
|
+
return new TextDecoder("utf-8", { fatal: false }).decode(bytes).replace(/\0/g, "");
|
|
951
|
+
} catch {
|
|
952
|
+
return "";
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
static decodeAbiUint(hex) {
|
|
956
|
+
if (!hex || hex === "0x") return 0n;
|
|
957
|
+
const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
958
|
+
return BigInt(`0x${clean || "0"}`);
|
|
959
|
+
}
|
|
960
|
+
static hexToDecimalStr(hex) {
|
|
961
|
+
try {
|
|
962
|
+
return BigInt(hex).toString();
|
|
963
|
+
} catch {
|
|
964
|
+
return "0";
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
|
|
969
|
+
// src/indexer/IndexerClient.ts
|
|
970
|
+
var IndexerClient = class {
|
|
971
|
+
baseUrl;
|
|
972
|
+
timeoutMs;
|
|
973
|
+
constructor(config) {
|
|
974
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
975
|
+
this.timeoutMs = config.timeoutMs ?? 1e4;
|
|
976
|
+
}
|
|
977
|
+
// ─── Internal helpers ──────────────────────────────────────────────────────
|
|
978
|
+
async _fetchResponse(path) {
|
|
979
|
+
const controller = new AbortController();
|
|
980
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
981
|
+
try {
|
|
982
|
+
return await fetch(`${this.baseUrl}${path}`, { signal: controller.signal });
|
|
983
|
+
} finally {
|
|
984
|
+
clearTimeout(timer);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
async get(path) {
|
|
988
|
+
const res = await this._fetchResponse(path);
|
|
989
|
+
if (!res.ok) {
|
|
990
|
+
throw new Error(`IndexerClient: HTTP ${res.status} for ${path}`);
|
|
991
|
+
}
|
|
992
|
+
return res.json();
|
|
993
|
+
}
|
|
994
|
+
async getOrNull(path) {
|
|
995
|
+
const res = await this._fetchResponse(path);
|
|
996
|
+
if (res.status === 404) return null;
|
|
997
|
+
if (!res.ok) {
|
|
998
|
+
throw new Error(`IndexerClient: HTTP ${res.status} for ${path}`);
|
|
999
|
+
}
|
|
1000
|
+
return res.json();
|
|
1001
|
+
}
|
|
1002
|
+
buildQuery(params) {
|
|
1003
|
+
const entries = Object.entries(params).filter(([, v]) => v !== void 0);
|
|
1004
|
+
if (entries.length === 0) return "";
|
|
1005
|
+
const qs = entries.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`).join("&");
|
|
1006
|
+
return `?${qs}`;
|
|
1007
|
+
}
|
|
1008
|
+
// ─── Commitments ───────────────────────────────────────────────────────────
|
|
1009
|
+
/** Returns the total count of shielded commitments. */
|
|
1010
|
+
async getCommitmentsCount() {
|
|
1011
|
+
const res = await this.get("/shielded/commitments/count");
|
|
1012
|
+
return res.total;
|
|
1013
|
+
}
|
|
1014
|
+
/** Returns a paginated list of shielded commitments. */
|
|
1015
|
+
async getCommitments(params) {
|
|
1016
|
+
const qs = this.buildQuery({
|
|
1017
|
+
page: params?.page,
|
|
1018
|
+
limit: params?.limit,
|
|
1019
|
+
since_leaf_index: params?.sinceLeafIndex
|
|
1020
|
+
});
|
|
1021
|
+
return this.get(`/shielded/commitments${qs}`);
|
|
1022
|
+
}
|
|
1023
|
+
/** Returns a single commitment by its hex string, or null if not found. */
|
|
1024
|
+
async getCommitmentByHex(hex) {
|
|
1025
|
+
return this.getOrNull(
|
|
1026
|
+
`/shielded/commitments/${encodeURIComponent(hex)}`
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
1029
|
+
// ─── Nullifiers ────────────────────────────────────────────────────────────
|
|
1030
|
+
/** Returns a paginated list of spent nullifiers. */
|
|
1031
|
+
async getNullifiers(params) {
|
|
1032
|
+
const qs = this.buildQuery({ page: params?.page, limit: params?.limit });
|
|
1033
|
+
return this.get(`/shielded/nullifiers${qs}`);
|
|
1034
|
+
}
|
|
1035
|
+
/** Returns the spent/unspent status of a nullifier. */
|
|
1036
|
+
async getNullifierStatus(hex) {
|
|
1037
|
+
return this.get(
|
|
1038
|
+
`/shielded/nullifier/${encodeURIComponent(hex)}/status`
|
|
1039
|
+
);
|
|
1040
|
+
}
|
|
1041
|
+
// ─── Private transfers ─────────────────────────────────────────────────────
|
|
1042
|
+
/** Returns a paginated list of private transfer events. */
|
|
1043
|
+
async getTransfers(params) {
|
|
1044
|
+
const qs = this.buildQuery({ page: params?.page, limit: params?.limit });
|
|
1045
|
+
return this.get(`/shielded/transfers${qs}`);
|
|
1046
|
+
}
|
|
1047
|
+
// ─── Unshields ─────────────────────────────────────────────────────────────
|
|
1048
|
+
/** Returns a paginated list of unshield events. */
|
|
1049
|
+
async getUnshields(params) {
|
|
1050
|
+
const qs = this.buildQuery({ page: params?.page, limit: params?.limit });
|
|
1051
|
+
return this.get(`/shielded/unshields${qs}`);
|
|
1052
|
+
}
|
|
1053
|
+
// ─── Merkle roots ──────────────────────────────────────────────────────────
|
|
1054
|
+
/** Returns a paginated list of Merkle root checkpoints. */
|
|
1055
|
+
async getMerkleRoots(params) {
|
|
1056
|
+
const qs = this.buildQuery({ page: params?.page, limit: params?.limit });
|
|
1057
|
+
return this.get(`/shielded/merkle-roots${qs}`);
|
|
1058
|
+
}
|
|
1059
|
+
/** Returns the latest Merkle root, or null if none exists. */
|
|
1060
|
+
async getLatestMerkleRoot() {
|
|
1061
|
+
return this.getOrNull("/shielded/merkle-roots/latest");
|
|
1062
|
+
}
|
|
1063
|
+
// ─── Address activity ──────────────────────────────────────────────────────
|
|
1064
|
+
/** Returns a paginated list of extrinsics signed by the given address. */
|
|
1065
|
+
async getAddressExtrinsics(address, params) {
|
|
1066
|
+
const qs = this.buildQuery({ page: params?.page, limit: params?.limit });
|
|
1067
|
+
return this.get(
|
|
1068
|
+
`/address/${encodeURIComponent(address.toLowerCase())}/extrinsics${qs}`
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
/** Returns a paginated list of EVM transactions filtered by address and/or block number. */
|
|
1072
|
+
async getEvmTransactions(params) {
|
|
1073
|
+
const qs = this.buildQuery({
|
|
1074
|
+
page: params?.page,
|
|
1075
|
+
limit: params?.limit,
|
|
1076
|
+
address: params?.address?.toLowerCase(),
|
|
1077
|
+
blockNumber: params?.blockNumber
|
|
1078
|
+
});
|
|
1079
|
+
return this.get(`/evm/transactions${qs}`);
|
|
1080
|
+
}
|
|
1081
|
+
/** Returns a single EVM transaction by hash, or null if not found. */
|
|
1082
|
+
async getEvmTransactionByHash(hash) {
|
|
1083
|
+
return this.getOrNull(
|
|
1084
|
+
`/evm/transactions/${encodeURIComponent(hash.toLowerCase())}`
|
|
1085
|
+
);
|
|
1086
|
+
}
|
|
1087
|
+
// ─── Blocks ────────────────────────────────────────────────────────────────
|
|
1088
|
+
/** Returns a paginated list of indexed blocks. */
|
|
1089
|
+
async getBlocks(params) {
|
|
1090
|
+
const qs = this.buildQuery({ page: params?.page, limit: params?.limit });
|
|
1091
|
+
return this.get(`/blocks${qs}`);
|
|
1092
|
+
}
|
|
1093
|
+
/** Returns a single block by number or hash, or null if not found. */
|
|
1094
|
+
async getBlock(numberOrHash) {
|
|
1095
|
+
return this.getOrNull(`/blocks/${encodeURIComponent(String(numberOrHash))}`);
|
|
1096
|
+
}
|
|
1097
|
+
// ─── Address commitments ───────────────────────────────────────────────────
|
|
1098
|
+
/** Returns a paginated list of shielded commitments initiated by an address. */
|
|
1099
|
+
async getAddressCommitments(address, params) {
|
|
1100
|
+
const qs = this.buildQuery({ page: params?.page, limit: params?.limit });
|
|
1101
|
+
return this.get(
|
|
1102
|
+
`/address/${encodeURIComponent(address.toLowerCase())}/shielded${qs}`
|
|
1103
|
+
);
|
|
1104
|
+
}
|
|
1105
|
+
/**
|
|
1106
|
+
* Returns a paginated list of all shielded activity (commitments, unshields,
|
|
1107
|
+
* private transfers) associated with the given address.
|
|
1108
|
+
* Each item is tagged with a `kind` discriminant.
|
|
1109
|
+
*/
|
|
1110
|
+
async getAddressShieldedActivity(address, params) {
|
|
1111
|
+
const qs = this.buildQuery({ page: params?.page, limit: params?.limit });
|
|
1112
|
+
return this.get(
|
|
1113
|
+
`/shielded/address/${encodeURIComponent(address.toLowerCase())}${qs}`
|
|
1114
|
+
);
|
|
1115
|
+
}
|
|
1116
|
+
// ─── Stats & Health ────────────────────────────────────────────────────────
|
|
1117
|
+
/** Returns aggregated indexer statistics. */
|
|
1118
|
+
async getStats() {
|
|
1119
|
+
return this.get("/stats");
|
|
1120
|
+
}
|
|
1121
|
+
/** Returns true if the indexer health endpoint responds OK. */
|
|
1122
|
+
async isHealthy() {
|
|
1123
|
+
try {
|
|
1124
|
+
const controller = new AbortController();
|
|
1125
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
1126
|
+
try {
|
|
1127
|
+
const res = await fetch(`${this.baseUrl}/health`, {
|
|
1128
|
+
signal: controller.signal
|
|
1129
|
+
});
|
|
1130
|
+
return res.ok;
|
|
1131
|
+
} finally {
|
|
1132
|
+
clearTimeout(timer);
|
|
1133
|
+
}
|
|
1134
|
+
} catch {
|
|
1135
|
+
return false;
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
};
|
|
1139
|
+
|
|
1140
|
+
// src/shielded-pool/ShieldedPoolModule.ts
|
|
355
1141
|
var import_polkadot_api2 = require("polkadot-api");
|
|
356
1142
|
|
|
1143
|
+
// src/utils/tx.ts
|
|
1144
|
+
function toTxResult(payload) {
|
|
1145
|
+
const base = {
|
|
1146
|
+
txHash: payload.txHash,
|
|
1147
|
+
blockHash: payload.block.hash,
|
|
1148
|
+
blockNumber: payload.block.number,
|
|
1149
|
+
ok: payload.ok
|
|
1150
|
+
};
|
|
1151
|
+
if (!payload.ok) {
|
|
1152
|
+
return { ...base, error: payload.dispatchError.type };
|
|
1153
|
+
}
|
|
1154
|
+
return base;
|
|
1155
|
+
}
|
|
1156
|
+
function callUnsafeTx(txEntry, ...args) {
|
|
1157
|
+
return txEntry(...args);
|
|
1158
|
+
}
|
|
1159
|
+
function resolveTx(unsafe, pallet, call) {
|
|
1160
|
+
const u = unsafe;
|
|
1161
|
+
const p = u["tx"]?.[pallet];
|
|
1162
|
+
if (p === void 0) throw new Error(`Pallet "${pallet}" not found in runtime metadata`);
|
|
1163
|
+
const entry = p[call];
|
|
1164
|
+
if (entry === void 0)
|
|
1165
|
+
throw new Error(`Call "${pallet}.${call}" not found in runtime metadata`);
|
|
1166
|
+
return entry;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
357
1169
|
// src/shielded-pool/EncryptedMemo.ts
|
|
358
|
-
var import_sha2 = require("@noble/hashes/sha2.js");
|
|
359
1170
|
var import_chacha = require("@noble/ciphers/chacha.js");
|
|
360
1171
|
var import_utils = require("@noble/ciphers/utils.js");
|
|
361
1172
|
|
|
@@ -412,11 +1223,10 @@ function leHexToBigint(hex) {
|
|
|
412
1223
|
return bytesToBigintLE(bytes);
|
|
413
1224
|
}
|
|
414
1225
|
|
|
415
|
-
// src/shielded-pool/
|
|
1226
|
+
// src/shielded-pool/helpers.ts
|
|
1227
|
+
var import_sha2 = require("@noble/hashes/sha2.js");
|
|
416
1228
|
var KEY_DOMAIN = new TextEncoder().encode("orbinum-note-encryption-v1");
|
|
417
|
-
var NONCE_SIZE = 12;
|
|
418
1229
|
var MEMO_PLAINTEXT_SIZE = 76;
|
|
419
|
-
var ENCRYPTED_MEMO_SIZE = 104;
|
|
420
1230
|
function serializeMemo(value, ownerPk, blinding, assetId) {
|
|
421
1231
|
const buf = new Uint8Array(MEMO_PLAINTEXT_SIZE);
|
|
422
1232
|
const view = new DataView(buf.buffer);
|
|
@@ -433,6 +1243,22 @@ function deriveEncryptionKey(viewingKey, commitment) {
|
|
|
433
1243
|
h.update(KEY_DOMAIN);
|
|
434
1244
|
return h.digest();
|
|
435
1245
|
}
|
|
1246
|
+
function toBase64(buf) {
|
|
1247
|
+
const bytes = buf instanceof Uint8Array ? buf : new Uint8Array(buf);
|
|
1248
|
+
let str = "";
|
|
1249
|
+
for (const b of bytes) str += String.fromCharCode(b);
|
|
1250
|
+
return btoa(str);
|
|
1251
|
+
}
|
|
1252
|
+
function fromBase64(b64) {
|
|
1253
|
+
const bin = atob(b64);
|
|
1254
|
+
const out = new Uint8Array(bin.length);
|
|
1255
|
+
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
1256
|
+
return out;
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
// src/shielded-pool/EncryptedMemo.ts
|
|
1260
|
+
var NONCE_SIZE = 12;
|
|
1261
|
+
var ENCRYPTED_MEMO_SIZE = 104;
|
|
436
1262
|
var EncryptedMemo = {
|
|
437
1263
|
/**
|
|
438
1264
|
* Build and encrypt a memo for a note.
|
|
@@ -578,34 +1404,9 @@ var NoteBuilder = class {
|
|
|
578
1404
|
};
|
|
579
1405
|
|
|
580
1406
|
// src/shielded-pool/ShieldedPoolModule.ts
|
|
581
|
-
function toTxResult(payload) {
|
|
582
|
-
const base = {
|
|
583
|
-
txHash: payload.txHash,
|
|
584
|
-
blockHash: payload.block.hash,
|
|
585
|
-
blockNumber: payload.block.number,
|
|
586
|
-
ok: payload.ok
|
|
587
|
-
};
|
|
588
|
-
if (!payload.ok) {
|
|
589
|
-
return { ...base, error: payload.dispatchError.type };
|
|
590
|
-
}
|
|
591
|
-
return base;
|
|
592
|
-
}
|
|
593
|
-
function callUnsafeTx(txEntry, ...args) {
|
|
594
|
-
return txEntry(...args);
|
|
595
|
-
}
|
|
596
|
-
function resolveTx(unsafe, pallet, call) {
|
|
597
|
-
const u = unsafe;
|
|
598
|
-
const p = u["tx"]?.[pallet];
|
|
599
|
-
if (p === void 0) throw new Error(`Pallet "${pallet}" not found in runtime metadata`);
|
|
600
|
-
const entry = p[call];
|
|
601
|
-
if (entry === void 0)
|
|
602
|
-
throw new Error(`Call "${pallet}.${call}" not found in runtime metadata`);
|
|
603
|
-
return entry;
|
|
604
|
-
}
|
|
605
1407
|
var ShieldedPoolModule = class {
|
|
606
|
-
constructor(substrate
|
|
1408
|
+
constructor(substrate) {
|
|
607
1409
|
this.substrate = substrate;
|
|
608
|
-
this.merkle = merkle;
|
|
609
1410
|
}
|
|
610
1411
|
// ─── Extrinsics ────────────────────────────────────────────────────────────
|
|
611
1412
|
/**
|
|
@@ -697,44 +1498,26 @@ var ShieldedPoolModule = class {
|
|
|
697
1498
|
);
|
|
698
1499
|
return toTxResult(await tx.signAndSubmit(signer));
|
|
699
1500
|
}
|
|
700
|
-
// ─── Queries ───────────────────────────────────────────────────────────────
|
|
701
|
-
/** Returns whether a nullifier has already been spent. */
|
|
702
|
-
async isNullifierSpent(nullifierHex) {
|
|
703
|
-
const raw = await this.substrate.request(
|
|
704
|
-
"privacy_getNullifierStatus",
|
|
705
|
-
[nullifierHex]
|
|
706
|
-
);
|
|
707
|
-
return raw.is_spent;
|
|
708
|
-
}
|
|
709
|
-
/** Returns the full nullifier status object. */
|
|
710
|
-
async getNullifierStatus(nullifierHex) {
|
|
711
|
-
const raw = await this.substrate.request(
|
|
712
|
-
"privacy_getNullifierStatus",
|
|
713
|
-
[nullifierHex]
|
|
714
|
-
);
|
|
715
|
-
return { nullifier: raw.nullifier, isSpent: raw.is_spent };
|
|
716
|
-
}
|
|
717
|
-
/** Returns the total locked balance in the pool for a given asset. */
|
|
718
|
-
async getPoolBalance(assetId) {
|
|
719
|
-
const raw = await this.substrate.request(
|
|
720
|
-
"shieldedPool_getPoolBalance",
|
|
721
|
-
[assetId]
|
|
722
|
-
);
|
|
723
|
-
return { assetId, balance: BigInt(raw.balance) };
|
|
724
|
-
}
|
|
725
1501
|
/**
|
|
726
|
-
*
|
|
727
|
-
*
|
|
1502
|
+
* Deposits multiple notes into the shielded pool in a single extrinsic.
|
|
1503
|
+
* Extrinsic: shieldedPool.shieldBatch(operations) — max 20 items.
|
|
728
1504
|
*/
|
|
729
|
-
async
|
|
730
|
-
const
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
1505
|
+
async shieldBatch(params, signer) {
|
|
1506
|
+
const operations = params.items.map((item) => ({
|
|
1507
|
+
assetId: item.assetId,
|
|
1508
|
+
amount: item.amount.toString(),
|
|
1509
|
+
commitment: import_polkadot_api2.Binary.fromHex(item.commitment),
|
|
1510
|
+
encryptedMemo: import_polkadot_api2.Binary.fromBytes(item.encryptedMemo ?? EncryptedMemo.dummy())
|
|
1511
|
+
}));
|
|
1512
|
+
const entry = resolveTx(this.substrate.unsafe, "shieldedPool", "shieldBatch");
|
|
1513
|
+
const tx = callUnsafeTx(entry, operations);
|
|
1514
|
+
return toTxResult(await tx.signAndSubmit(signer));
|
|
735
1515
|
}
|
|
736
1516
|
};
|
|
737
1517
|
|
|
1518
|
+
// src/account-mapping/AccountMappingModule.ts
|
|
1519
|
+
var import_polkadot_api3 = require("polkadot-api");
|
|
1520
|
+
|
|
738
1521
|
// src/utils/address.ts
|
|
739
1522
|
var import_util_crypto = require("@polkadot/util-crypto");
|
|
740
1523
|
function normalizeEvmAddress(addr) {
|
|
@@ -765,6 +1548,10 @@ function evmToImplicitSubstrate(evmAddr) {
|
|
|
765
1548
|
}
|
|
766
1549
|
return "0x" + clean.toLowerCase() + "0".repeat(24);
|
|
767
1550
|
}
|
|
1551
|
+
function evmToMappedAccountHex(address) {
|
|
1552
|
+
if (!isEvmAddress(address)) return null;
|
|
1553
|
+
return evmToImplicitSubstrate(address);
|
|
1554
|
+
}
|
|
768
1555
|
function isImplicitEvmAccount(accountHex) {
|
|
769
1556
|
const clean = accountHex.startsWith("0x") ? accountHex.slice(2) : accountHex;
|
|
770
1557
|
if (clean.length !== 64) return false;
|
|
@@ -867,69 +1654,40 @@ function addressToAccountIdHex(addr) {
|
|
|
867
1654
|
return substrateSs58ToAccountIdHex(addr);
|
|
868
1655
|
}
|
|
869
1656
|
|
|
870
|
-
// src/
|
|
871
|
-
|
|
872
|
-
|
|
1657
|
+
// src/account-mapping/helpers.ts
|
|
1658
|
+
function mapRawScheme(raw) {
|
|
1659
|
+
if (raw === "Eip191" || raw === "eip191") return "Eip191";
|
|
1660
|
+
if (raw === "Ed25519" || raw === "ed25519") return "Ed25519";
|
|
1661
|
+
return raw;
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
// src/account-mapping/AccountMappingModule.ts
|
|
1665
|
+
var AccountMappingModule = class {
|
|
1666
|
+
constructor(substrate) {
|
|
873
1667
|
this.substrate = substrate;
|
|
874
|
-
this.evm = evm;
|
|
875
|
-
}
|
|
876
|
-
// ─── Node info ─────────────────────────────────────────────────────────────
|
|
877
|
-
/**
|
|
878
|
-
* Returns basic chain information from the node.
|
|
879
|
-
*/
|
|
880
|
-
async getChainInfo() {
|
|
881
|
-
const [name, version] = await Promise.all([
|
|
882
|
-
this.substrate.request("system_name", []),
|
|
883
|
-
this.substrate.request("state_getRuntimeVersion", [])
|
|
884
|
-
]);
|
|
885
|
-
return {
|
|
886
|
-
name,
|
|
887
|
-
version: String(version.specVersion),
|
|
888
|
-
ss58Prefix: version.ss58Prefix ?? 42
|
|
889
|
-
};
|
|
890
|
-
}
|
|
891
|
-
/**
|
|
892
|
-
* Returns the node's peer count and sync status.
|
|
893
|
-
*/
|
|
894
|
-
async getHealth() {
|
|
895
|
-
return this.substrate.request("system_health", []);
|
|
896
|
-
}
|
|
897
|
-
/**
|
|
898
|
-
* Returns the node's software version string.
|
|
899
|
-
*/
|
|
900
|
-
async getNodeVersion() {
|
|
901
|
-
return this.substrate.request("system_version", []);
|
|
902
|
-
}
|
|
903
|
-
/**
|
|
904
|
-
* Returns the genesis hash hex.
|
|
905
|
-
*/
|
|
906
|
-
async getGenesisHash() {
|
|
907
|
-
return this.substrate.request("chain_getBlockHash", [0]);
|
|
908
1668
|
}
|
|
909
|
-
// ───
|
|
1669
|
+
// ─── Address resolution ─────────────────────────────────────────────────────
|
|
910
1670
|
/**
|
|
911
|
-
*
|
|
912
|
-
*
|
|
1671
|
+
* Returns the explicitly mapped (or fallback) Substrate AccountId32 hex for
|
|
1672
|
+
* an EVM address. `mapped` is set only when `map_account` was called.
|
|
1673
|
+
* `fallback` is always the EeSuffix rule: `H160 ++ [0x00; 12]`.
|
|
913
1674
|
*/
|
|
914
|
-
async
|
|
1675
|
+
async getAccountAddresses(accountId) {
|
|
915
1676
|
try {
|
|
916
1677
|
const raw = await this.substrate.request(
|
|
917
|
-
"
|
|
918
|
-
[
|
|
1678
|
+
"accountMapping_getAccountAddresses",
|
|
1679
|
+
[accountId]
|
|
919
1680
|
);
|
|
920
|
-
return {
|
|
921
|
-
substrateAddress: raw.substrate_address ?? null,
|
|
922
|
-
evmAddress: raw.evm_address ? normalizeEvmAddress(raw.evm_address) : null,
|
|
923
|
-
alias: raw.alias ?? null
|
|
924
|
-
};
|
|
1681
|
+
return { mapped: raw.mapped ?? null, fallback: raw.fallback ?? null };
|
|
925
1682
|
} catch {
|
|
926
|
-
return null;
|
|
1683
|
+
return { mapped: null, fallback: null };
|
|
927
1684
|
}
|
|
928
1685
|
}
|
|
929
1686
|
/**
|
|
930
|
-
* Returns the mapped Substrate
|
|
1687
|
+
* Returns the explicitly mapped Substrate AccountId32 hex for a given EVM
|
|
1688
|
+
* address, or null if no explicit mapping exists.
|
|
931
1689
|
*/
|
|
932
|
-
async
|
|
1690
|
+
async getMappedAccount(evmAddress) {
|
|
933
1691
|
try {
|
|
934
1692
|
return await this.substrate.request("accountMapping_getMappedAccount", [
|
|
935
1693
|
normalizeEvmAddress(evmAddress)
|
|
@@ -938,139 +1696,43 @@ var ChainModule = class {
|
|
|
938
1696
|
return null;
|
|
939
1697
|
}
|
|
940
1698
|
}
|
|
1699
|
+
// ─── Alias queries ──────────────────────────────────────────────────────────
|
|
941
1700
|
/**
|
|
942
|
-
*
|
|
1701
|
+
* Resolves "@alias" to basic info (owner, optional EVM address, link count).
|
|
1702
|
+
* Accepts the alias with or without the leading "@".
|
|
943
1703
|
*/
|
|
944
|
-
async
|
|
1704
|
+
async resolveAlias(alias) {
|
|
945
1705
|
try {
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
1706
|
+
const raw = await this.substrate.request(
|
|
1707
|
+
"accountMapping_resolveAlias",
|
|
1708
|
+
[alias]
|
|
1709
|
+
);
|
|
1710
|
+
if (!raw) return null;
|
|
1711
|
+
return {
|
|
1712
|
+
owner: raw.substrate_account,
|
|
1713
|
+
evmAddress: raw.evm_address ? normalizeEvmAddress(raw.evm_address) : null,
|
|
1714
|
+
chainLinksCount: raw.chain_links_count
|
|
1715
|
+
};
|
|
949
1716
|
} catch {
|
|
950
1717
|
return null;
|
|
951
1718
|
}
|
|
952
1719
|
}
|
|
953
|
-
// ─── EVM helpers ───────────────────────────────────────────────────────────
|
|
954
1720
|
/**
|
|
955
|
-
* Returns
|
|
956
|
-
* to have been provided in `OrbinumClientConfig`.
|
|
1721
|
+
* Returns the alias registered for the given Substrate AccountId32 hex, or null.
|
|
957
1722
|
*/
|
|
958
|
-
async
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
1723
|
+
async getAliasOf(accountId) {
|
|
1724
|
+
try {
|
|
1725
|
+
return await this.substrate.request("accountMapping_getAliasOf", [
|
|
1726
|
+
accountId
|
|
1727
|
+
]);
|
|
1728
|
+
} catch {
|
|
1729
|
+
return null;
|
|
1730
|
+
}
|
|
962
1731
|
}
|
|
1732
|
+
// ─── Full identity ──────────────────────────────────────────────────────────
|
|
963
1733
|
/**
|
|
964
|
-
*
|
|
965
|
-
|
|
966
|
-
async getEvmBlockNumber() {
|
|
967
|
-
if (!this.evm) throw new Error("No EVM RPC URL configured.");
|
|
968
|
-
return this.evm.getBlockNumber();
|
|
969
|
-
}
|
|
970
|
-
};
|
|
971
|
-
|
|
972
|
-
// src/account-mapping/AccountMappingModule.ts
|
|
973
|
-
var import_polkadot_api3 = require("polkadot-api");
|
|
974
|
-
function toTxResult2(payload) {
|
|
975
|
-
const base = {
|
|
976
|
-
txHash: payload.txHash,
|
|
977
|
-
blockHash: payload.block.hash,
|
|
978
|
-
blockNumber: payload.block.number,
|
|
979
|
-
ok: payload.ok
|
|
980
|
-
};
|
|
981
|
-
if (!payload.ok) {
|
|
982
|
-
return { ...base, error: payload.dispatchError.type };
|
|
983
|
-
}
|
|
984
|
-
return base;
|
|
985
|
-
}
|
|
986
|
-
function callUnsafeTx2(txEntry, ...args) {
|
|
987
|
-
return txEntry(...args);
|
|
988
|
-
}
|
|
989
|
-
function resolveTx2(unsafe, pallet, call) {
|
|
990
|
-
const u = unsafe;
|
|
991
|
-
const p = u["tx"]?.[pallet];
|
|
992
|
-
if (p === void 0) throw new Error(`Pallet "${pallet}" not found in runtime metadata`);
|
|
993
|
-
const entry = p[call];
|
|
994
|
-
if (entry === void 0)
|
|
995
|
-
throw new Error(`Call "${pallet}.${call}" not found in runtime metadata`);
|
|
996
|
-
return entry;
|
|
997
|
-
}
|
|
998
|
-
function mapRawScheme(raw) {
|
|
999
|
-
if (raw === "Eip191" || raw === "eip191") return "Eip191";
|
|
1000
|
-
if (raw === "Ed25519" || raw === "ed25519") return "Ed25519";
|
|
1001
|
-
return raw;
|
|
1002
|
-
}
|
|
1003
|
-
var AccountMappingModule = class {
|
|
1004
|
-
constructor(substrate) {
|
|
1005
|
-
this.substrate = substrate;
|
|
1006
|
-
}
|
|
1007
|
-
// ─── Address resolution ─────────────────────────────────────────────────────
|
|
1008
|
-
/**
|
|
1009
|
-
* Returns the explicitly mapped (or fallback) Substrate AccountId32 hex for
|
|
1010
|
-
* an EVM address. `mapped` is set only when `map_account` was called.
|
|
1011
|
-
* `fallback` is always the EeSuffix rule: `H160 ++ [0x00; 12]`.
|
|
1012
|
-
*/
|
|
1013
|
-
async getAccountAddresses(accountId) {
|
|
1014
|
-
try {
|
|
1015
|
-
const raw = await this.substrate.request(
|
|
1016
|
-
"accountMapping_getAccountAddresses",
|
|
1017
|
-
[accountId]
|
|
1018
|
-
);
|
|
1019
|
-
return { mapped: raw.mapped ?? null, fallback: raw.fallback ?? null };
|
|
1020
|
-
} catch {
|
|
1021
|
-
return { mapped: null, fallback: null };
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
/**
|
|
1025
|
-
* Returns the explicitly mapped Substrate AccountId32 hex for a given EVM
|
|
1026
|
-
* address, or null if no explicit mapping exists.
|
|
1027
|
-
*/
|
|
1028
|
-
async getMappedAccount(evmAddress) {
|
|
1029
|
-
try {
|
|
1030
|
-
return await this.substrate.request("accountMapping_getMappedAccount", [
|
|
1031
|
-
normalizeEvmAddress(evmAddress)
|
|
1032
|
-
]);
|
|
1033
|
-
} catch {
|
|
1034
|
-
return null;
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
// ─── Alias queries ──────────────────────────────────────────────────────────
|
|
1038
|
-
/**
|
|
1039
|
-
* Resolves "@alias" to basic info (owner, optional EVM address, link count).
|
|
1040
|
-
* Accepts the alias with or without the leading "@".
|
|
1041
|
-
*/
|
|
1042
|
-
async resolveAlias(alias) {
|
|
1043
|
-
try {
|
|
1044
|
-
const raw = await this.substrate.request(
|
|
1045
|
-
"accountMapping_resolveAlias",
|
|
1046
|
-
[alias]
|
|
1047
|
-
);
|
|
1048
|
-
if (!raw) return null;
|
|
1049
|
-
return {
|
|
1050
|
-
owner: raw.substrate_account,
|
|
1051
|
-
evmAddress: raw.evm_address ? normalizeEvmAddress(raw.evm_address) : null,
|
|
1052
|
-
chainLinksCount: raw.chain_links_count
|
|
1053
|
-
};
|
|
1054
|
-
} catch {
|
|
1055
|
-
return null;
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
/**
|
|
1059
|
-
* Returns the alias registered for the given Substrate AccountId32 hex, or null.
|
|
1060
|
-
*/
|
|
1061
|
-
async getAliasOf(accountId) {
|
|
1062
|
-
try {
|
|
1063
|
-
return await this.substrate.request("accountMapping_getAliasOf", [
|
|
1064
|
-
accountId
|
|
1065
|
-
]);
|
|
1066
|
-
} catch {
|
|
1067
|
-
return null;
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
// ─── Full identity ──────────────────────────────────────────────────────────
|
|
1071
|
-
/**
|
|
1072
|
-
* Resolves "@alias" to its full identity: owner, EVM address, all public
|
|
1073
|
-
* chain links, and profile metadata.
|
|
1734
|
+
* Resolves "@alias" to its full identity: owner, EVM address, all public
|
|
1735
|
+
* chain links, and profile metadata.
|
|
1074
1736
|
*/
|
|
1075
1737
|
async resolveFullIdentity(alias) {
|
|
1076
1738
|
try {
|
|
@@ -1239,18 +1901,18 @@ var AccountMappingModule = class {
|
|
|
1239
1901
|
* Extrinsic: accountMapping.mapAccount()
|
|
1240
1902
|
*/
|
|
1241
1903
|
async mapAccount(signer) {
|
|
1242
|
-
const entry =
|
|
1243
|
-
const tx =
|
|
1244
|
-
return
|
|
1904
|
+
const entry = resolveTx(this.substrate.unsafe, "accountMapping", "mapAccount");
|
|
1905
|
+
const tx = callUnsafeTx(entry);
|
|
1906
|
+
return toTxResult(await tx.signAndSubmit(signer));
|
|
1245
1907
|
}
|
|
1246
1908
|
/**
|
|
1247
1909
|
* Removes the EVM → Substrate mapping for the caller.
|
|
1248
1910
|
* Extrinsic: accountMapping.unmapAccount()
|
|
1249
1911
|
*/
|
|
1250
1912
|
async unmapAccount(signer) {
|
|
1251
|
-
const entry =
|
|
1252
|
-
const tx =
|
|
1253
|
-
return
|
|
1913
|
+
const entry = resolveTx(this.substrate.unsafe, "accountMapping", "unmapAccount");
|
|
1914
|
+
const tx = callUnsafeTx(entry);
|
|
1915
|
+
return toTxResult(await tx.signAndSubmit(signer));
|
|
1254
1916
|
}
|
|
1255
1917
|
/**
|
|
1256
1918
|
* Registers a unique @alias for the caller.
|
|
@@ -1258,27 +1920,27 @@ var AccountMappingModule = class {
|
|
|
1258
1920
|
* Extrinsic: accountMapping.registerAlias(alias)
|
|
1259
1921
|
*/
|
|
1260
1922
|
async registerAlias(alias, signer) {
|
|
1261
|
-
const entry =
|
|
1262
|
-
const tx =
|
|
1263
|
-
return
|
|
1923
|
+
const entry = resolveTx(this.substrate.unsafe, "accountMapping", "registerAlias");
|
|
1924
|
+
const tx = callUnsafeTx(entry, import_polkadot_api3.Binary.fromText(alias));
|
|
1925
|
+
return toTxResult(await tx.signAndSubmit(signer));
|
|
1264
1926
|
}
|
|
1265
1927
|
/**
|
|
1266
1928
|
* Releases the caller's alias and recovers the deposit.
|
|
1267
1929
|
* Extrinsic: accountMapping.releaseAlias()
|
|
1268
1930
|
*/
|
|
1269
1931
|
async releaseAlias(signer) {
|
|
1270
|
-
const entry =
|
|
1271
|
-
const tx =
|
|
1272
|
-
return
|
|
1932
|
+
const entry = resolveTx(this.substrate.unsafe, "accountMapping", "releaseAlias");
|
|
1933
|
+
const tx = callUnsafeTx(entry);
|
|
1934
|
+
return toTxResult(await tx.signAndSubmit(signer));
|
|
1273
1935
|
}
|
|
1274
1936
|
/**
|
|
1275
1937
|
* Transfers the caller's alias to another account.
|
|
1276
1938
|
* Extrinsic: accountMapping.transferAlias(newOwner)
|
|
1277
1939
|
*/
|
|
1278
1940
|
async transferAlias(newOwnerHex, signer) {
|
|
1279
|
-
const entry =
|
|
1280
|
-
const tx =
|
|
1281
|
-
return
|
|
1941
|
+
const entry = resolveTx(this.substrate.unsafe, "accountMapping", "transferAlias");
|
|
1942
|
+
const tx = callUnsafeTx(entry, newOwnerHex);
|
|
1943
|
+
return toTxResult(await tx.signAndSubmit(signer));
|
|
1282
1944
|
}
|
|
1283
1945
|
/**
|
|
1284
1946
|
* Adds a verified public link to an external-chain wallet.
|
|
@@ -1291,65 +1953,65 @@ var AccountMappingModule = class {
|
|
|
1291
1953
|
* Extrinsic: accountMapping.addChainLink(chainId, address, signature)
|
|
1292
1954
|
*/
|
|
1293
1955
|
async addChainLink(params, signer) {
|
|
1294
|
-
const entry =
|
|
1295
|
-
const tx =
|
|
1956
|
+
const entry = resolveTx(this.substrate.unsafe, "accountMapping", "addChainLink");
|
|
1957
|
+
const tx = callUnsafeTx(
|
|
1296
1958
|
entry,
|
|
1297
1959
|
params.chainId,
|
|
1298
1960
|
import_polkadot_api3.Binary.fromBytes(params.address),
|
|
1299
1961
|
import_polkadot_api3.Binary.fromBytes(params.signature)
|
|
1300
1962
|
);
|
|
1301
|
-
return
|
|
1963
|
+
return toTxResult(await tx.signAndSubmit(signer));
|
|
1302
1964
|
}
|
|
1303
1965
|
/**
|
|
1304
1966
|
* Removes the external-chain link for the given chain ID.
|
|
1305
1967
|
* Extrinsic: accountMapping.removeChainLink(chainId)
|
|
1306
1968
|
*/
|
|
1307
1969
|
async removeChainLink(chainId, signer) {
|
|
1308
|
-
const entry =
|
|
1309
|
-
const tx =
|
|
1310
|
-
return
|
|
1970
|
+
const entry = resolveTx(this.substrate.unsafe, "accountMapping", "removeChainLink");
|
|
1971
|
+
const tx = callUnsafeTx(entry, chainId);
|
|
1972
|
+
return toTxResult(await tx.signAndSubmit(signer));
|
|
1311
1973
|
}
|
|
1312
1974
|
/**
|
|
1313
1975
|
* Updates the caller's public profile metadata.
|
|
1314
1976
|
* Extrinsic: accountMapping.setAccountMetadata(displayName, bio, avatar)
|
|
1315
1977
|
*/
|
|
1316
1978
|
async setAccountMetadata(params, signer) {
|
|
1317
|
-
const entry =
|
|
1979
|
+
const entry = resolveTx(this.substrate.unsafe, "accountMapping", "setAccountMetadata");
|
|
1318
1980
|
const encode2 = (v) => v != null ? import_polkadot_api3.Binary.fromText(v) : void 0;
|
|
1319
|
-
const tx =
|
|
1981
|
+
const tx = callUnsafeTx(
|
|
1320
1982
|
entry,
|
|
1321
1983
|
encode2(params.displayName),
|
|
1322
1984
|
encode2(params.bio),
|
|
1323
1985
|
encode2(params.avatar)
|
|
1324
1986
|
);
|
|
1325
|
-
return
|
|
1987
|
+
return toTxResult(await tx.signAndSubmit(signer));
|
|
1326
1988
|
}
|
|
1327
1989
|
/**
|
|
1328
1990
|
* Lists the caller's alias for sale on the alias marketplace.
|
|
1329
1991
|
* Extrinsic: accountMapping.putAliasOnSale(price, isPrivate)
|
|
1330
1992
|
*/
|
|
1331
1993
|
async putAliasOnSale(params, signer) {
|
|
1332
|
-
const entry =
|
|
1333
|
-
const tx =
|
|
1334
|
-
return
|
|
1994
|
+
const entry = resolveTx(this.substrate.unsafe, "accountMapping", "putAliasOnSale");
|
|
1995
|
+
const tx = callUnsafeTx(entry, params.price.toString(), params.isPrivate);
|
|
1996
|
+
return toTxResult(await tx.signAndSubmit(signer));
|
|
1335
1997
|
}
|
|
1336
1998
|
/**
|
|
1337
1999
|
* Cancels an active alias sale listing.
|
|
1338
2000
|
* Extrinsic: accountMapping.cancelSale()
|
|
1339
2001
|
*/
|
|
1340
2002
|
async cancelSale(signer) {
|
|
1341
|
-
const entry =
|
|
1342
|
-
const tx =
|
|
1343
|
-
return
|
|
2003
|
+
const entry = resolveTx(this.substrate.unsafe, "accountMapping", "cancelSale");
|
|
2004
|
+
const tx = callUnsafeTx(entry);
|
|
2005
|
+
return toTxResult(await tx.signAndSubmit(signer));
|
|
1344
2006
|
}
|
|
1345
2007
|
/**
|
|
1346
2008
|
* Purchases an alias listed for sale.
|
|
1347
2009
|
* Extrinsic: accountMapping.buyAlias(alias)
|
|
1348
2010
|
*/
|
|
1349
2011
|
async buyAlias(alias, signer) {
|
|
1350
|
-
const entry =
|
|
1351
|
-
const tx =
|
|
1352
|
-
return
|
|
2012
|
+
const entry = resolveTx(this.substrate.unsafe, "accountMapping", "buyAlias");
|
|
2013
|
+
const tx = callUnsafeTx(entry, import_polkadot_api3.Binary.fromText(alias));
|
|
2014
|
+
return toTxResult(await tx.signAndSubmit(signer));
|
|
1353
2015
|
}
|
|
1354
2016
|
/**
|
|
1355
2017
|
* Dispatches an arbitrary call on behalf of a linked external-chain wallet.
|
|
@@ -1363,8 +2025,8 @@ var AccountMappingModule = class {
|
|
|
1363
2025
|
* Extrinsic: accountMapping.dispatchAsLinkedAccount(owner, chainId, address, signature, call)
|
|
1364
2026
|
*/
|
|
1365
2027
|
async dispatchAsLinkedAccount(params, signer) {
|
|
1366
|
-
const entry =
|
|
1367
|
-
const tx =
|
|
2028
|
+
const entry = resolveTx(this.substrate.unsafe, "accountMapping", "dispatchAsLinkedAccount");
|
|
2029
|
+
const tx = callUnsafeTx(
|
|
1368
2030
|
entry,
|
|
1369
2031
|
params.owner,
|
|
1370
2032
|
params.chainId,
|
|
@@ -1372,18 +2034,118 @@ var AccountMappingModule = class {
|
|
|
1372
2034
|
import_polkadot_api3.Binary.fromBytes(params.signature),
|
|
1373
2035
|
import_polkadot_api3.Binary.fromBytes(params.callData)
|
|
1374
2036
|
);
|
|
1375
|
-
return
|
|
2037
|
+
return toTxResult(await tx.signAndSubmit(signer));
|
|
1376
2038
|
}
|
|
1377
2039
|
};
|
|
1378
2040
|
|
|
1379
|
-
// src/
|
|
2041
|
+
// src/rpc-v2/helpers.ts
|
|
2042
|
+
function mapAssetBalance(balance) {
|
|
2043
|
+
return {
|
|
2044
|
+
assetId: balance.asset_id,
|
|
2045
|
+
balance: balance.balance.toString()
|
|
2046
|
+
};
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
// src/rpc-v2/PrivacyModule.ts
|
|
2050
|
+
var PrivacyModule = class {
|
|
2051
|
+
constructor(substrate) {
|
|
2052
|
+
this.substrate = substrate;
|
|
2053
|
+
}
|
|
2054
|
+
/** Returns the current Merkle tree root. */
|
|
2055
|
+
async getMerkleRoot() {
|
|
2056
|
+
return this.substrate.request("privacy_getMerkleRoot", []);
|
|
2057
|
+
}
|
|
2058
|
+
/** Returns the Merkle proof for the given leaf index or commitment hex. */
|
|
2059
|
+
async getMerkleProof(leafIndex) {
|
|
2060
|
+
const raw = await this.substrate.request("privacy_getMerkleProof", [
|
|
2061
|
+
leafIndex
|
|
2062
|
+
]);
|
|
2063
|
+
return {
|
|
2064
|
+
path: raw.path,
|
|
2065
|
+
leafIndex: raw.leaf_index,
|
|
2066
|
+
treeDepth: raw.tree_depth
|
|
2067
|
+
};
|
|
2068
|
+
}
|
|
2069
|
+
/**
|
|
2070
|
+
* Returns the Merkle inclusion proof for a given commitment hex,
|
|
2071
|
+
* bundled with the current Merkle root.
|
|
2072
|
+
*/
|
|
2073
|
+
async getMerkleProofByCommitment(commitmentHex) {
|
|
2074
|
+
const [proof, root] = await Promise.all([
|
|
2075
|
+
this.getMerkleProof(commitmentHex),
|
|
2076
|
+
this.getMerkleRoot()
|
|
2077
|
+
]);
|
|
2078
|
+
return { ...proof, root };
|
|
2079
|
+
}
|
|
2080
|
+
/** Returns the spend status of a nullifier. */
|
|
2081
|
+
async getNullifierStatus(nullifier) {
|
|
2082
|
+
const raw = await this.substrate.request(
|
|
2083
|
+
"privacy_getNullifierStatus",
|
|
2084
|
+
[nullifier]
|
|
2085
|
+
);
|
|
2086
|
+
return {
|
|
2087
|
+
nullifier: raw.nullifier,
|
|
2088
|
+
isSpent: raw.is_spent
|
|
2089
|
+
};
|
|
2090
|
+
}
|
|
2091
|
+
/** Returns aggregated statistics for the shielded pool from `rpc-v2`. */
|
|
2092
|
+
async getPoolStats() {
|
|
2093
|
+
const raw = await this.substrate.request("privacy_getPoolStats", []);
|
|
2094
|
+
return {
|
|
2095
|
+
merkleRoot: raw.merkle_root,
|
|
2096
|
+
commitmentCount: raw.commitment_count,
|
|
2097
|
+
totalBalance: raw.total_balance.toString(),
|
|
2098
|
+
assetBalances: raw.asset_balances.map(mapAssetBalance),
|
|
2099
|
+
treeDepth: raw.tree_depth
|
|
2100
|
+
};
|
|
2101
|
+
}
|
|
2102
|
+
};
|
|
2103
|
+
|
|
2104
|
+
// src/zk-verifier/ZkVerifierModule.ts
|
|
2105
|
+
function mapVkHash(raw) {
|
|
2106
|
+
return { version: raw.version, vkHash: raw.vk_hash };
|
|
2107
|
+
}
|
|
2108
|
+
function mapCircuitVersionInfo(raw) {
|
|
2109
|
+
return {
|
|
2110
|
+
circuitId: raw.circuit_id,
|
|
2111
|
+
activeVersion: raw.active_version,
|
|
2112
|
+
proofSystem: "Groth16",
|
|
2113
|
+
supportedVersions: raw.supported_versions,
|
|
2114
|
+
vkHashes: raw.vk_hashes.map(mapVkHash),
|
|
2115
|
+
historicalVersions: []
|
|
2116
|
+
};
|
|
2117
|
+
}
|
|
2118
|
+
var ZkVerifierModule = class {
|
|
2119
|
+
constructor(substrate) {
|
|
2120
|
+
this.substrate = substrate;
|
|
2121
|
+
}
|
|
2122
|
+
/** Returns basic version info for all registered circuits. */
|
|
2123
|
+
async getAllCircuitVersions() {
|
|
2124
|
+
const raw = await this.substrate.request(
|
|
2125
|
+
"zkVerifier_getAllCircuitVersions",
|
|
2126
|
+
[]
|
|
2127
|
+
);
|
|
2128
|
+
return raw.map(mapCircuitVersionInfo);
|
|
2129
|
+
}
|
|
2130
|
+
/** Returns version info for a specific circuit, or null if not found. */
|
|
2131
|
+
async getCircuitVersionInfo(circuitId) {
|
|
2132
|
+
const raw = await this.substrate.request(
|
|
2133
|
+
"zkVerifier_getCircuitVersionInfo",
|
|
2134
|
+
[circuitId]
|
|
2135
|
+
);
|
|
2136
|
+
return raw ? mapCircuitVersionInfo(raw) : null;
|
|
2137
|
+
}
|
|
2138
|
+
};
|
|
2139
|
+
|
|
2140
|
+
// src/precompiles/helpers.ts
|
|
2141
|
+
var STATIC_TYPES = /* @__PURE__ */ new Set(["uint", "bytes32", "address", "bool"]);
|
|
1380
2142
|
function concat(arrays) {
|
|
1381
|
-
const total = arrays.reduce((
|
|
2143
|
+
const total = arrays.reduce((sum, array) => sum + array.length, 0);
|
|
1382
2144
|
const out = new Uint8Array(total);
|
|
1383
|
-
let
|
|
1384
|
-
for (const
|
|
1385
|
-
out.set(
|
|
1386
|
-
|
|
2145
|
+
let offset = 0;
|
|
2146
|
+
for (const array of arrays) {
|
|
2147
|
+
out.set(array, offset);
|
|
2148
|
+
offset += array.length;
|
|
1387
2149
|
}
|
|
1388
2150
|
return out;
|
|
1389
2151
|
}
|
|
@@ -1394,7 +2156,6 @@ function padTo32Multiple(data) {
|
|
|
1394
2156
|
padded.set(data);
|
|
1395
2157
|
return padded;
|
|
1396
2158
|
}
|
|
1397
|
-
var STATIC_TYPES = /* @__PURE__ */ new Set(["uint", "bytes32", "address", "bool"]);
|
|
1398
2159
|
function encodeStaticParam(param) {
|
|
1399
2160
|
const buf = new Uint8Array(32);
|
|
1400
2161
|
switch (param.type) {
|
|
@@ -1475,6 +2236,8 @@ function encodeDynamicParam(param) {
|
|
|
1475
2236
|
);
|
|
1476
2237
|
}
|
|
1477
2238
|
}
|
|
2239
|
+
|
|
2240
|
+
// src/precompiles/abi.ts
|
|
1478
2241
|
function encode(selector, ...params) {
|
|
1479
2242
|
const n = params.length;
|
|
1480
2243
|
const headSize = n * 32;
|
|
@@ -1999,23 +2762,28 @@ var AccountMappingPrecompile = class {
|
|
|
1999
2762
|
return signer({ to: this.addr, data });
|
|
2000
2763
|
}
|
|
2001
2764
|
/**
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2765
|
+
* Updates the signer's public profile metadata.
|
|
2766
|
+
* Pass `null` for any field to leave it unchanged.
|
|
2767
|
+
}
|
|
2768
|
+
displayName: string | null,
|
|
2769
|
+
bio: string | null,
|
|
2770
|
+
avatar: string | null,
|
|
2771
|
+
signer: EvmSigner
|
|
2772
|
+
): Promise<string> {
|
|
2773
|
+
const enc = (v: string | null): Uint8Array =>
|
|
2774
|
+
v != null ? new TextEncoder().encode(v) : new Uint8Array(0);
|
|
2775
|
+
const data = encodeHex(
|
|
2776
|
+
AM_SEL.SET_ACCOUNT_METADATA,
|
|
2777
|
+
{ type: 'bytes', value: enc(displayName) },
|
|
2778
|
+
{ type: 'bytes', value: enc(bio) },
|
|
2779
|
+
{ type: 'bytes', value: enc(avatar) }
|
|
2780
|
+
);
|
|
2781
|
+
return signer({ to: this.addr, data });
|
|
2782
|
+
}
|
|
2783
|
+
|
|
2784
|
+
// ─── Calldata builders (for custom signing / batching) ─────────────────────
|
|
2785
|
+
|
|
2786
|
+
/** Returns the raw ABI-encoded calldata for `registerAlias`. */
|
|
2019
2787
|
buildRegisterAliasCalldata(alias) {
|
|
2020
2788
|
return encodeHex(AM_SEL.REGISTER_ALIAS, { type: "string", value: alias });
|
|
2021
2789
|
}
|
|
@@ -2137,30 +2905,44 @@ var CryptoPrecompiles = class {
|
|
|
2137
2905
|
}
|
|
2138
2906
|
};
|
|
2139
2907
|
|
|
2140
|
-
// src/client.ts
|
|
2908
|
+
// src/client/OrbinumClient.ts
|
|
2141
2909
|
var OrbinumClient = class _OrbinumClient {
|
|
2142
2910
|
/** Raw access to the Substrate WebSocket connection and RPC. */
|
|
2143
2911
|
substrate;
|
|
2144
2912
|
/** Raw access to the EVM HTTP JSON-RPC endpoint (if configured). */
|
|
2145
2913
|
evm;
|
|
2914
|
+
/**
|
|
2915
|
+
* High-level EVM block and transaction explorer (if `evmRpc` is configured).
|
|
2916
|
+
* Provides enriched queries for blocks, transactions, addresses, and token transfers.
|
|
2917
|
+
*/
|
|
2918
|
+
evmExplorer;
|
|
2919
|
+
/**
|
|
2920
|
+
* HTTP client for the Orbinum indexer REST API (if `indexerUrl` is configured).
|
|
2921
|
+
* Provides paginated access to indexed blocks, extrinsics, shielded events, and nullifiers.
|
|
2922
|
+
*/
|
|
2923
|
+
indexer;
|
|
2146
2924
|
/** Shielded-pool operations: shield, unshield, privateTransfer, and merkle queries. */
|
|
2147
2925
|
shieldedPool;
|
|
2148
|
-
/** General chain queries: node info, identity resolution. */
|
|
2149
|
-
chain;
|
|
2150
2926
|
/** Account mapping: aliases, chain links, metadata, marketplace, and identity extrinsics. */
|
|
2151
2927
|
accountMapping;
|
|
2928
|
+
/** Typed access to Orbinum `privacy_*` RPC endpoints. */
|
|
2929
|
+
privacy;
|
|
2930
|
+
/** Typed access to zkVerifier_* RPC endpoints. */
|
|
2931
|
+
zkVerifier;
|
|
2152
2932
|
/**
|
|
2153
2933
|
* EVM precompiles: shielded pool + account mapping callable from an EVM wallet.
|
|
2154
2934
|
* Only available when `evmRpc` is configured. Methods throw if `evm` is null.
|
|
2155
2935
|
*/
|
|
2156
2936
|
precompiles;
|
|
2157
|
-
constructor(substrate, evm) {
|
|
2937
|
+
constructor(substrate, evm, indexer) {
|
|
2158
2938
|
this.substrate = substrate;
|
|
2159
2939
|
this.evm = evm;
|
|
2160
|
-
|
|
2161
|
-
this.
|
|
2162
|
-
this.
|
|
2940
|
+
this.evmExplorer = evm ? new EvmExplorer(evm) : null;
|
|
2941
|
+
this.indexer = indexer;
|
|
2942
|
+
this.shieldedPool = new ShieldedPoolModule(substrate);
|
|
2163
2943
|
this.accountMapping = new AccountMappingModule(substrate);
|
|
2944
|
+
this.privacy = new PrivacyModule(substrate);
|
|
2945
|
+
this.zkVerifier = new ZkVerifierModule(substrate);
|
|
2164
2946
|
this.precompiles = evm ? {
|
|
2165
2947
|
shieldedPool: new ShieldedPoolPrecompile(evm),
|
|
2166
2948
|
accountMapping: new AccountMappingPrecompile(evm),
|
|
@@ -2177,13 +2959,8 @@ var OrbinumClient = class _OrbinumClient {
|
|
|
2177
2959
|
config.connectTimeoutMs ?? 15e3
|
|
2178
2960
|
);
|
|
2179
2961
|
const evm = config.evmRpc ? new EvmClient(config.evmRpc) : null;
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
/**
|
|
2183
|
-
* Convenience getter for the Merkle module (shortcut for `shieldedPool.merkle`).
|
|
2184
|
-
*/
|
|
2185
|
-
get merkle() {
|
|
2186
|
-
return this.shieldedPool.merkle;
|
|
2962
|
+
const indexer = config.indexerUrl ? new IndexerClient({ baseUrl: config.indexerUrl }) : null;
|
|
2963
|
+
return new _OrbinumClient(substrate, evm, indexer);
|
|
2187
2964
|
}
|
|
2188
2965
|
/** Closes the WebSocket connection to the Substrate node. */
|
|
2189
2966
|
destroy() {
|
|
@@ -2191,6 +2968,215 @@ var OrbinumClient = class _OrbinumClient {
|
|
|
2191
2968
|
}
|
|
2192
2969
|
};
|
|
2193
2970
|
|
|
2971
|
+
// src/client/OrbinumClientProvider.ts
|
|
2972
|
+
var DEFAULT_CONNECT_TIMEOUT_MS = 8e3;
|
|
2973
|
+
var DEFAULT_HEARTBEAT_INTERVAL_MS = 5e3;
|
|
2974
|
+
var DEFAULT_HEARTBEAT_TIMEOUT_MS = 4e3;
|
|
2975
|
+
var DEFAULT_RECONNECT_BASE_MS = 3e3;
|
|
2976
|
+
var DEFAULT_RECONNECT_MAX_MS = 3e4;
|
|
2977
|
+
var OrbinumClientProvider = class {
|
|
2978
|
+
config;
|
|
2979
|
+
connectTimeoutMs;
|
|
2980
|
+
heartbeatIntervalMs;
|
|
2981
|
+
heartbeatTimeoutMs;
|
|
2982
|
+
reconnectBaseMs;
|
|
2983
|
+
reconnectMaxMs;
|
|
2984
|
+
// ─── State ──────────────────────────────────────────────────────────────
|
|
2985
|
+
_status = "idle";
|
|
2986
|
+
_orbinumClient = null;
|
|
2987
|
+
_connectingPromise = null;
|
|
2988
|
+
// ─── Timers ─────────────────────────────────────────────────────────────
|
|
2989
|
+
_heartbeatTimer = null;
|
|
2990
|
+
_reconnectTimer = null;
|
|
2991
|
+
_reconnectAttempt = 0;
|
|
2992
|
+
// ─── Events ─────────────────────────────────────────────────────────────
|
|
2993
|
+
_listeners = /* @__PURE__ */ new Set();
|
|
2994
|
+
constructor(config) {
|
|
2995
|
+
this.config = config;
|
|
2996
|
+
this.connectTimeoutMs = config.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
|
|
2997
|
+
this.heartbeatIntervalMs = config.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS;
|
|
2998
|
+
this.heartbeatTimeoutMs = config.heartbeatTimeoutMs ?? DEFAULT_HEARTBEAT_TIMEOUT_MS;
|
|
2999
|
+
this.reconnectBaseMs = config.reconnectBaseMs ?? DEFAULT_RECONNECT_BASE_MS;
|
|
3000
|
+
this.reconnectMaxMs = config.reconnectMaxMs ?? DEFAULT_RECONNECT_MAX_MS;
|
|
3001
|
+
}
|
|
3002
|
+
// ─── Status ─────────────────────────────────────────────────────────────
|
|
3003
|
+
get status() {
|
|
3004
|
+
return this._status;
|
|
3005
|
+
}
|
|
3006
|
+
setStatus(status, error) {
|
|
3007
|
+
this._status = status;
|
|
3008
|
+
const event = { status, ...error ? { error } : {} };
|
|
3009
|
+
this._listeners.forEach((fn) => {
|
|
3010
|
+
try {
|
|
3011
|
+
fn(event);
|
|
3012
|
+
} catch {
|
|
3013
|
+
}
|
|
3014
|
+
});
|
|
3015
|
+
}
|
|
3016
|
+
onStatusChange(listener) {
|
|
3017
|
+
this._listeners.add(listener);
|
|
3018
|
+
return () => {
|
|
3019
|
+
this._listeners.delete(listener);
|
|
3020
|
+
};
|
|
3021
|
+
}
|
|
3022
|
+
// ─── Lifecycle ──────────────────────────────────────────────────────────
|
|
3023
|
+
connect() {
|
|
3024
|
+
if (this._status !== "idle") return;
|
|
3025
|
+
this.startConnectAttempt();
|
|
3026
|
+
}
|
|
3027
|
+
reset() {
|
|
3028
|
+
this.cancelReconnect();
|
|
3029
|
+
this.teardownClient();
|
|
3030
|
+
this._reconnectAttempt = 0;
|
|
3031
|
+
this.setStatus("idle");
|
|
3032
|
+
}
|
|
3033
|
+
// ─── Internal connection flow ───────────────────────────────────────────
|
|
3034
|
+
startConnectAttempt() {
|
|
3035
|
+
this.setStatus("connecting");
|
|
3036
|
+
this._connectingPromise = this.attemptConnect();
|
|
3037
|
+
this._connectingPromise.catch(() => {
|
|
3038
|
+
if (this._status !== "idle") this.scheduleReconnect();
|
|
3039
|
+
});
|
|
3040
|
+
}
|
|
3041
|
+
async attemptConnect() {
|
|
3042
|
+
let timeoutId = null;
|
|
3043
|
+
let orphanClient = null;
|
|
3044
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
3045
|
+
timeoutId = setTimeout(
|
|
3046
|
+
() => reject(
|
|
3047
|
+
new Error(
|
|
3048
|
+
`Node unavailable \u2014 could not connect to ${this.config.substrateWs} within ${this.connectTimeoutMs / 1e3}s`
|
|
3049
|
+
)
|
|
3050
|
+
),
|
|
3051
|
+
this.connectTimeoutMs
|
|
3052
|
+
);
|
|
3053
|
+
});
|
|
3054
|
+
try {
|
|
3055
|
+
const connectConfig = {
|
|
3056
|
+
substrateWs: this.config.substrateWs
|
|
3057
|
+
};
|
|
3058
|
+
if (this.config.evmRpc) connectConfig.evmRpc = this.config.evmRpc;
|
|
3059
|
+
if (this.config.indexerUrl) connectConfig.indexerUrl = this.config.indexerUrl;
|
|
3060
|
+
const clientPromise = OrbinumClient.connect(connectConfig);
|
|
3061
|
+
const client = await Promise.race([clientPromise, timeoutPromise]);
|
|
3062
|
+
orphanClient = client;
|
|
3063
|
+
clearTimeout(timeoutId);
|
|
3064
|
+
orphanClient = null;
|
|
3065
|
+
this._orbinumClient = client;
|
|
3066
|
+
this._connectingPromise = null;
|
|
3067
|
+
this._reconnectAttempt = 0;
|
|
3068
|
+
this.setStatus("connected");
|
|
3069
|
+
this.startHeartbeat();
|
|
3070
|
+
return client;
|
|
3071
|
+
} catch (err) {
|
|
3072
|
+
clearTimeout(timeoutId);
|
|
3073
|
+
if (orphanClient) {
|
|
3074
|
+
try {
|
|
3075
|
+
orphanClient.destroy();
|
|
3076
|
+
} catch {
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
this._connectingPromise = null;
|
|
3080
|
+
this.setStatus(
|
|
3081
|
+
"disconnected",
|
|
3082
|
+
err instanceof Error ? err.message : "Connection failed"
|
|
3083
|
+
);
|
|
3084
|
+
throw err;
|
|
3085
|
+
}
|
|
3086
|
+
}
|
|
3087
|
+
// ─── Heartbeat ──────────────────────────────────────────────────────────
|
|
3088
|
+
startHeartbeat() {
|
|
3089
|
+
this.stopHeartbeat();
|
|
3090
|
+
this._heartbeatTimer = setInterval(async () => {
|
|
3091
|
+
if (this._status !== "connected" || !this._orbinumClient) return;
|
|
3092
|
+
const alive = await this.probe();
|
|
3093
|
+
if (!alive && this._status === "connected") {
|
|
3094
|
+
this.setStatus("disconnected", "Node is unreachable");
|
|
3095
|
+
this.teardownClient();
|
|
3096
|
+
this.scheduleReconnect();
|
|
3097
|
+
}
|
|
3098
|
+
}, this.heartbeatIntervalMs);
|
|
3099
|
+
}
|
|
3100
|
+
stopHeartbeat() {
|
|
3101
|
+
if (this._heartbeatTimer) {
|
|
3102
|
+
clearInterval(this._heartbeatTimer);
|
|
3103
|
+
this._heartbeatTimer = null;
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
3106
|
+
async probe() {
|
|
3107
|
+
if (!this._orbinumClient) return false;
|
|
3108
|
+
try {
|
|
3109
|
+
await Promise.race([
|
|
3110
|
+
this._orbinumClient.substrate.request("system_health", []),
|
|
3111
|
+
new Promise(
|
|
3112
|
+
(_, reject) => setTimeout(() => reject(new Error("timeout")), this.heartbeatTimeoutMs)
|
|
3113
|
+
)
|
|
3114
|
+
]);
|
|
3115
|
+
return true;
|
|
3116
|
+
} catch {
|
|
3117
|
+
return false;
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3120
|
+
// ─── Reconnection ───────────────────────────────────────────────────────
|
|
3121
|
+
scheduleReconnect() {
|
|
3122
|
+
if (this._reconnectTimer) clearTimeout(this._reconnectTimer);
|
|
3123
|
+
const delay = Math.min(
|
|
3124
|
+
this.reconnectBaseMs * 2 ** this._reconnectAttempt,
|
|
3125
|
+
this.reconnectMaxMs
|
|
3126
|
+
);
|
|
3127
|
+
this._reconnectAttempt++;
|
|
3128
|
+
this.setStatus("reconnecting");
|
|
3129
|
+
this._reconnectTimer = setTimeout(() => {
|
|
3130
|
+
this._reconnectTimer = null;
|
|
3131
|
+
if (this._status !== "idle") this.startConnectAttempt();
|
|
3132
|
+
}, delay);
|
|
3133
|
+
}
|
|
3134
|
+
cancelReconnect() {
|
|
3135
|
+
if (this._reconnectTimer) {
|
|
3136
|
+
clearTimeout(this._reconnectTimer);
|
|
3137
|
+
this._reconnectTimer = null;
|
|
3138
|
+
}
|
|
3139
|
+
}
|
|
3140
|
+
// ─── Client teardown ────────────────────────────────────────────────────
|
|
3141
|
+
teardownClient() {
|
|
3142
|
+
this.stopHeartbeat();
|
|
3143
|
+
try {
|
|
3144
|
+
this._orbinumClient?.destroy();
|
|
3145
|
+
} catch {
|
|
3146
|
+
}
|
|
3147
|
+
this._orbinumClient = null;
|
|
3148
|
+
this._connectingPromise = null;
|
|
3149
|
+
}
|
|
3150
|
+
// ─── Client access ──────────────────────────────────────────────────────
|
|
3151
|
+
async getOrbinumClient() {
|
|
3152
|
+
if (this._orbinumClient) return this._orbinumClient;
|
|
3153
|
+
if (this._connectingPromise) return this._connectingPromise;
|
|
3154
|
+
throw new Error(`OrbinumClientProvider: cannot get client in status '${this._status}'`);
|
|
3155
|
+
}
|
|
3156
|
+
async tryGetOrbinumClient() {
|
|
3157
|
+
try {
|
|
3158
|
+
return await this.getOrbinumClient();
|
|
3159
|
+
} catch {
|
|
3160
|
+
return null;
|
|
3161
|
+
}
|
|
3162
|
+
}
|
|
3163
|
+
// ─── Convenience RPC helpers ────────────────────────────────────────────
|
|
3164
|
+
async rpcSend(method, params = []) {
|
|
3165
|
+
const client = await this.getOrbinumClient();
|
|
3166
|
+
return client.substrate.request(method, params);
|
|
3167
|
+
}
|
|
3168
|
+
async evmRpc(method, params = []) {
|
|
3169
|
+
const client = await this.getOrbinumClient();
|
|
3170
|
+
if (!client.evm) throw new Error("EVM RPC not configured");
|
|
3171
|
+
return client.evm.request(method, params);
|
|
3172
|
+
}
|
|
3173
|
+
async evmRpcBatch(calls) {
|
|
3174
|
+
const client = await this.getOrbinumClient();
|
|
3175
|
+
if (!client.evm) throw new Error("EVM RPC not configured");
|
|
3176
|
+
return client.evm.batchRequest(calls);
|
|
3177
|
+
}
|
|
3178
|
+
};
|
|
3179
|
+
|
|
2194
3180
|
// src/shielded-pool/NoteDecryptor.ts
|
|
2195
3181
|
var import_poseidon_lite2 = require("poseidon-lite");
|
|
2196
3182
|
function tryDecryptNote(commitment, viewingKey, spendingKey) {
|
|
@@ -2233,7 +3219,11 @@ function tryDecryptNote(commitment, viewingKey, spendingKey) {
|
|
|
2233
3219
|
var import_hkdf = require("@noble/hashes/hkdf.js");
|
|
2234
3220
|
var import_sha22 = require("@noble/hashes/sha2.js");
|
|
2235
3221
|
var import_baby_jubjub = require("@zk-kit/baby-jubjub");
|
|
3222
|
+
|
|
3223
|
+
// src/shielded-pool/constants.ts
|
|
2236
3224
|
var BN254_R = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
3225
|
+
|
|
3226
|
+
// src/shielded-pool/PrivacyKeys.ts
|
|
2237
3227
|
var IVK_DOMAIN = new TextEncoder().encode("orbinum-ivk-v1");
|
|
2238
3228
|
function deriveSpendingKeyMessage(chainId, address) {
|
|
2239
3229
|
return `orbinum-spending-key-v1
|
|
@@ -2264,13 +3254,12 @@ function deriveOwnerPk(spendingKey) {
|
|
|
2264
3254
|
}
|
|
2265
3255
|
|
|
2266
3256
|
// src/shielded-pool/PrivacyKeyManager.ts
|
|
2267
|
-
var
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
};
|
|
2273
|
-
var PrivacyKeyManager = {
|
|
3257
|
+
var PrivacyKeyManager = class {
|
|
3258
|
+
_state = {
|
|
3259
|
+
spendingKey: null,
|
|
3260
|
+
viewingKey: null,
|
|
3261
|
+
ownerPk: null
|
|
3262
|
+
};
|
|
2274
3263
|
/**
|
|
2275
3264
|
* Load a spending key into the in-memory session.
|
|
2276
3265
|
* Derives viewingKey and ownerPk immediately.
|
|
@@ -2279,52 +3268,52 @@ var PrivacyKeyManager = {
|
|
|
2279
3268
|
async load(spendingKey) {
|
|
2280
3269
|
const viewingKey = deriveViewingKey(spendingKey);
|
|
2281
3270
|
const ownerPk = deriveOwnerPk(spendingKey);
|
|
2282
|
-
_state = { spendingKey, viewingKey, ownerPk };
|
|
2283
|
-
}
|
|
3271
|
+
this._state = { spendingKey, viewingKey, ownerPk };
|
|
3272
|
+
}
|
|
2284
3273
|
/** Clear all key material from memory. Call on vault lock / sign-out. */
|
|
2285
3274
|
clear() {
|
|
2286
|
-
_state = { spendingKey: null, viewingKey: null, ownerPk: null };
|
|
2287
|
-
}
|
|
3275
|
+
this._state = { spendingKey: null, viewingKey: null, ownerPk: null };
|
|
3276
|
+
}
|
|
2288
3277
|
/** Returns true if a spending key has been loaded. */
|
|
2289
3278
|
isLoaded() {
|
|
2290
|
-
return _state.spendingKey !== null;
|
|
2291
|
-
}
|
|
3279
|
+
return this._state.spendingKey !== null;
|
|
3280
|
+
}
|
|
2292
3281
|
/** Returns the spending key. Throws if not loaded. */
|
|
2293
3282
|
getSpendingKey() {
|
|
2294
|
-
if (_state.spendingKey === null) {
|
|
3283
|
+
if (this._state.spendingKey === null) {
|
|
2295
3284
|
throw new Error("PrivacyKeyManager: no key loaded. Call load() first.");
|
|
2296
3285
|
}
|
|
2297
|
-
return _state.spendingKey;
|
|
2298
|
-
}
|
|
3286
|
+
return this._state.spendingKey;
|
|
3287
|
+
}
|
|
2299
3288
|
/** Returns the 32-byte viewing key. Throws if not loaded. */
|
|
2300
3289
|
getViewingKey() {
|
|
2301
|
-
if (_state.viewingKey === null) {
|
|
3290
|
+
if (this._state.viewingKey === null) {
|
|
2302
3291
|
throw new Error("PrivacyKeyManager: no key loaded. Call load() first.");
|
|
2303
3292
|
}
|
|
2304
|
-
return _state.viewingKey;
|
|
2305
|
-
}
|
|
3293
|
+
return this._state.viewingKey;
|
|
3294
|
+
}
|
|
2306
3295
|
/** Returns the BabyJubJub owner public key (x-coordinate). Throws if not loaded. */
|
|
2307
3296
|
getOwnerPk() {
|
|
2308
|
-
if (_state.ownerPk === null) {
|
|
3297
|
+
if (this._state.ownerPk === null) {
|
|
2309
3298
|
throw new Error("PrivacyKeyManager: no key loaded. Call load() first.");
|
|
2310
3299
|
}
|
|
2311
|
-
return _state.ownerPk;
|
|
2312
|
-
}
|
|
3300
|
+
return this._state.ownerPk;
|
|
3301
|
+
}
|
|
2313
3302
|
/** Returns the spending key as a 32-byte little-endian Uint8Array. Throws if not loaded. */
|
|
2314
3303
|
getSpendingKeyBytes() {
|
|
2315
3304
|
return bigintTo32Le(this.getSpendingKey());
|
|
2316
|
-
}
|
|
3305
|
+
}
|
|
2317
3306
|
/** Exports the spending key as a 0x-prefixed 64-char hex string. Throws if not loaded. */
|
|
2318
3307
|
exportHex() {
|
|
2319
3308
|
return "0x" + this.getSpendingKey().toString(16).padStart(64, "0");
|
|
2320
|
-
}
|
|
3309
|
+
}
|
|
2321
3310
|
/**
|
|
2322
3311
|
* Load a spending key from a 0x-prefixed or bare hex string.
|
|
2323
3312
|
* Validates the key is in the valid range [1, BN254_R).
|
|
2324
3313
|
*/
|
|
2325
3314
|
async importFromHex(hex) {
|
|
2326
3315
|
const key = BigInt(hex.startsWith("0x") ? hex : "0x" + hex);
|
|
2327
|
-
if (key === 0n || key >=
|
|
3316
|
+
if (key === 0n || key >= BN254_R) {
|
|
2328
3317
|
throw new Error("PrivacyKeyManager: invalid spending key \u2014 out of BN254 range.");
|
|
2329
3318
|
}
|
|
2330
3319
|
await this.load(key);
|
|
@@ -2342,18 +3331,6 @@ function vaultReviver(_key, value) {
|
|
|
2342
3331
|
}
|
|
2343
3332
|
return value;
|
|
2344
3333
|
}
|
|
2345
|
-
function toBase64(buf) {
|
|
2346
|
-
const bytes = buf instanceof Uint8Array ? buf : new Uint8Array(buf);
|
|
2347
|
-
let str = "";
|
|
2348
|
-
for (const b of bytes) str += String.fromCharCode(b);
|
|
2349
|
-
return btoa(str);
|
|
2350
|
-
}
|
|
2351
|
-
function fromBase64(b64) {
|
|
2352
|
-
const bin = atob(b64);
|
|
2353
|
-
const out = new Uint8Array(bin.length);
|
|
2354
|
-
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
2355
|
-
return out;
|
|
2356
|
-
}
|
|
2357
3334
|
var VAULT_KEY_INFO = new TextEncoder().encode("orbinum-vault-key-v1");
|
|
2358
3335
|
var IV_BYTES = 12;
|
|
2359
3336
|
async function deriveVaultKey(spendingKeyBytes) {
|
|
@@ -2392,71 +3369,70 @@ async function decryptJson(key, iv, ciphertext) {
|
|
|
2392
3369
|
return JSON.parse(new TextDecoder().decode(plainBuf), vaultReviver);
|
|
2393
3370
|
}
|
|
2394
3371
|
|
|
2395
|
-
// src/
|
|
2396
|
-
var
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
3372
|
+
// src/account-mapping/types/index.ts
|
|
3373
|
+
var SignatureScheme = {
|
|
3374
|
+
Eip191: "Eip191",
|
|
3375
|
+
Ed25519: "Ed25519"
|
|
3376
|
+
};
|
|
3377
|
+
var SLIP0044_NAMESPACE = 2147483648;
|
|
3378
|
+
|
|
3379
|
+
// src/precompiles/decode.ts
|
|
3380
|
+
function decodePrecompileCalldata(address, input) {
|
|
3381
|
+
const info = KNOWN_PRECOMPILES[address.toLowerCase()];
|
|
3382
|
+
if (!info || !input || input.length < 10) return null;
|
|
3383
|
+
const selector = input.slice(2, 10).toLowerCase();
|
|
3384
|
+
const fnSig = info.functions[selector];
|
|
3385
|
+
if (!fnSig) return null;
|
|
3386
|
+
if (fnSig.startsWith("registerAlias")) {
|
|
3387
|
+
try {
|
|
3388
|
+
const data = hexToBytes(input.slice(10));
|
|
3389
|
+
const alias = decodeString(data, 0);
|
|
3390
|
+
return { fnSig, args: { alias } };
|
|
3391
|
+
} catch {
|
|
3392
|
+
return { fnSig, args: {} };
|
|
3393
|
+
}
|
|
2402
3394
|
}
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
3395
|
+
if (fnSig.startsWith("shield(")) {
|
|
3396
|
+
try {
|
|
3397
|
+
const data = hexToBytes(input.slice(10));
|
|
3398
|
+
const assetId = decodeUint(data, 0);
|
|
3399
|
+
const amount = decodeUint(data, 32);
|
|
3400
|
+
const commitment = toHex(data.slice(64, 96));
|
|
3401
|
+
return { fnSig, args: { assetId, amount, commitment } };
|
|
3402
|
+
} catch {
|
|
3403
|
+
return { fnSig, args: {} };
|
|
3404
|
+
}
|
|
2411
3405
|
}
|
|
2412
|
-
if (
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
const intPart = abs / divider;
|
|
2425
|
-
const fracPart = abs % divider;
|
|
2426
|
-
const fracStr = fracPart.toString().padStart(decimals, "0");
|
|
2427
|
-
return (negative ? "-" : "") + intPart.toString() + "." + fracStr;
|
|
2428
|
-
}
|
|
2429
|
-
function formatBalance(raw, options = {}) {
|
|
2430
|
-
const opts = typeof options === "number" ? { decimals: options } : options;
|
|
2431
|
-
const { decimals = 18, symbol = "ORB", showSymbol = true, precision = 6 } = opts;
|
|
2432
|
-
const zero = showSymbol ? `0 ${symbol}` : "0";
|
|
2433
|
-
if (raw === null || raw === void 0) return zero;
|
|
2434
|
-
const rawStr = String(raw).trim().replace(/,/g, "");
|
|
2435
|
-
if (!rawStr || rawStr === "0" || rawStr === "0x0") return zero;
|
|
2436
|
-
if (rawStr.includes(".") && !rawStr.startsWith("0x")) {
|
|
2437
|
-
const formatted = normalizeDecimalForDisplay(rawStr, precision);
|
|
2438
|
-
if (!formatted || formatted === "0" || formatted === "-0") return zero;
|
|
2439
|
-
return showSymbol ? `${formatted} ${symbol}` : formatted;
|
|
3406
|
+
if (fnSig.startsWith("unshield(")) {
|
|
3407
|
+
try {
|
|
3408
|
+
const data = hexToBytes(input.slice(10));
|
|
3409
|
+
const root = toHex(data.slice(32, 64));
|
|
3410
|
+
const nullifier = toHex(data.slice(64, 96));
|
|
3411
|
+
const assetId = decodeUint(data, 96);
|
|
3412
|
+
const amount = decodeUint(data, 128);
|
|
3413
|
+
const recipient = toHex(data.slice(160, 192));
|
|
3414
|
+
return { fnSig, args: { root, nullifier, assetId, amount, recipient } };
|
|
3415
|
+
} catch {
|
|
3416
|
+
return { fnSig, args: {} };
|
|
3417
|
+
}
|
|
2440
3418
|
}
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
3419
|
+
if (fnSig.startsWith("privateTransfer(")) {
|
|
3420
|
+
try {
|
|
3421
|
+
const data = hexToBytes(input.slice(10));
|
|
3422
|
+
const root = toHex(data.slice(32, 64));
|
|
3423
|
+
const nullOffset = Number(decodeUint(data, 64));
|
|
3424
|
+
const commOffset = Number(decodeUint(data, 96));
|
|
3425
|
+
const nullifiers = Number(decodeUint(data, nullOffset));
|
|
3426
|
+
const commitments = Number(decodeUint(data, commOffset));
|
|
3427
|
+
return { fnSig, args: { root, nullifiers, commitments } };
|
|
3428
|
+
} catch {
|
|
3429
|
+
return { fnSig, args: {} };
|
|
3430
|
+
}
|
|
2450
3431
|
}
|
|
2451
|
-
}
|
|
2452
|
-
function formatORB(raw, precision = 6) {
|
|
2453
|
-
return formatBalance(raw, { decimals: 18, symbol: "ORB", showSymbol: true, precision });
|
|
3432
|
+
return { fnSig, args: {} };
|
|
2454
3433
|
}
|
|
2455
3434
|
|
|
2456
|
-
// src/types.ts
|
|
2457
|
-
var SLIP0044_NAMESPACE = 2147483648;
|
|
2458
|
-
|
|
2459
|
-
// src/types/pallet-extrinsics/zk-verifier.ts
|
|
3435
|
+
// src/zk-verifier/types/pallet-extrinsics.ts
|
|
2460
3436
|
var CircuitId = {
|
|
2461
3437
|
Transfer: 1,
|
|
2462
3438
|
Unshield: 2,
|
|
@@ -2464,35 +3440,783 @@ var CircuitId = {
|
|
|
2464
3440
|
PrivateLink: 4
|
|
2465
3441
|
};
|
|
2466
3442
|
|
|
3443
|
+
// src/utils/string.ts
|
|
3444
|
+
function truncateMiddle(str, start, end) {
|
|
3445
|
+
if (!str) return "";
|
|
3446
|
+
if (str.length <= start + end + 1) return str;
|
|
3447
|
+
return `${str.slice(0, start)}\u2026${str.slice(-end)}`;
|
|
3448
|
+
}
|
|
3449
|
+
function shortHash(h, start = 8, end = 6) {
|
|
3450
|
+
return truncateMiddle(h, start, end);
|
|
3451
|
+
}
|
|
3452
|
+
|
|
3453
|
+
// src/extrinsic/index.ts
|
|
3454
|
+
function mapExtrinsicArgs(section, method, args) {
|
|
3455
|
+
if (!args || Object.keys(args).length === 0) return args;
|
|
3456
|
+
const s = section.toLowerCase();
|
|
3457
|
+
const m = method.toLowerCase();
|
|
3458
|
+
const get = (idx, name) => {
|
|
3459
|
+
if (name in args) return args[name];
|
|
3460
|
+
const argKey = `arg${idx}`;
|
|
3461
|
+
if (argKey in args) return args[argKey];
|
|
3462
|
+
if (idx in args) return args[idx];
|
|
3463
|
+
const strIdx = idx.toString();
|
|
3464
|
+
if (strIdx in args) return args[strIdx];
|
|
3465
|
+
return void 0;
|
|
3466
|
+
};
|
|
3467
|
+
if (s === "system") {
|
|
3468
|
+
const m_norm = m.replace(/_/g, "");
|
|
3469
|
+
if (m_norm === "remark" || m_norm === "remarkwithevent") {
|
|
3470
|
+
return { remark: get(0, "remark") };
|
|
3471
|
+
}
|
|
3472
|
+
if (m_norm === "setheappages") {
|
|
3473
|
+
return { pages: get(0, "pages") };
|
|
3474
|
+
}
|
|
3475
|
+
if (m_norm === "setcode" || m_norm === "setcodewithoutchecks") {
|
|
3476
|
+
return { code: get(0, "code") };
|
|
3477
|
+
}
|
|
3478
|
+
if (m_norm === "setstorage") {
|
|
3479
|
+
return { items: get(0, "items") };
|
|
3480
|
+
}
|
|
3481
|
+
if (m_norm === "killstorage") {
|
|
3482
|
+
return { keys: get(0, "keys") };
|
|
3483
|
+
}
|
|
3484
|
+
if (m_norm === "killprefix") {
|
|
3485
|
+
return {
|
|
3486
|
+
prefix: get(0, "prefix"),
|
|
3487
|
+
subkeys: get(1, "subkeys")
|
|
3488
|
+
};
|
|
3489
|
+
}
|
|
3490
|
+
if (m_norm === "authorizeupgrade" || m_norm === "authorizeupgradewithoutchecks") {
|
|
3491
|
+
return { code_hash: get(0, "code_hash") };
|
|
3492
|
+
}
|
|
3493
|
+
if (m_norm === "applyauthorizedupgrade") {
|
|
3494
|
+
return { code: get(0, "code") };
|
|
3495
|
+
}
|
|
3496
|
+
}
|
|
3497
|
+
if (s === "timestamp") {
|
|
3498
|
+
if (m === "set") {
|
|
3499
|
+
return { now: get(0, "now") };
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3502
|
+
if (s === "balances") {
|
|
3503
|
+
const m_norm = m.replace(/_/g, "");
|
|
3504
|
+
if (m_norm.startsWith("transfer")) {
|
|
3505
|
+
return {
|
|
3506
|
+
recipient: get(0, "dest") || get(0, "destination") || get(0, "recipient"),
|
|
3507
|
+
amount: get(1, "value") || get(1, "amount")
|
|
3508
|
+
};
|
|
3509
|
+
}
|
|
3510
|
+
if (m_norm === "forcetransfer") {
|
|
3511
|
+
return {
|
|
3512
|
+
source: get(0, "source"),
|
|
3513
|
+
dest: get(1, "dest"),
|
|
3514
|
+
value: get(2, "value")
|
|
3515
|
+
};
|
|
3516
|
+
}
|
|
3517
|
+
if (m_norm === "forceunreserve") {
|
|
3518
|
+
return {
|
|
3519
|
+
who: get(0, "who"),
|
|
3520
|
+
amount: get(1, "amount")
|
|
3521
|
+
};
|
|
3522
|
+
}
|
|
3523
|
+
if (m_norm === "upgradeaccounts") {
|
|
3524
|
+
return { who: get(0, "who") };
|
|
3525
|
+
}
|
|
3526
|
+
if (m_norm === "forcesetbalance") {
|
|
3527
|
+
return {
|
|
3528
|
+
who: get(0, "who"),
|
|
3529
|
+
new_free: get(1, "new_free")
|
|
3530
|
+
};
|
|
3531
|
+
}
|
|
3532
|
+
if (m_norm === "forceadjusttotalissuance") {
|
|
3533
|
+
return {
|
|
3534
|
+
direction: get(0, "direction"),
|
|
3535
|
+
delta: get(1, "delta")
|
|
3536
|
+
};
|
|
3537
|
+
}
|
|
3538
|
+
if (m_norm === "burn") {
|
|
3539
|
+
return {
|
|
3540
|
+
value: get(0, "value"),
|
|
3541
|
+
keep_alive: get(1, "keep_alive")
|
|
3542
|
+
};
|
|
3543
|
+
}
|
|
3544
|
+
}
|
|
3545
|
+
if (s === "sudo") {
|
|
3546
|
+
const m_norm = m.replace(/_/g, "");
|
|
3547
|
+
if (m_norm === "sudo") {
|
|
3548
|
+
return { call: get(0, "call") };
|
|
3549
|
+
}
|
|
3550
|
+
if (m_norm === "sudouncheckedweight") {
|
|
3551
|
+
return {
|
|
3552
|
+
call: get(0, "call"),
|
|
3553
|
+
weight: get(1, "weight")
|
|
3554
|
+
};
|
|
3555
|
+
}
|
|
3556
|
+
if (m_norm === "setkey") {
|
|
3557
|
+
return { new: get(0, "new") };
|
|
3558
|
+
}
|
|
3559
|
+
if (m_norm === "sudoas") {
|
|
3560
|
+
return {
|
|
3561
|
+
who: get(0, "who"),
|
|
3562
|
+
call: get(1, "call")
|
|
3563
|
+
};
|
|
3564
|
+
}
|
|
3565
|
+
}
|
|
3566
|
+
if (s === "grandpa") {
|
|
3567
|
+
const m_norm = m.replace(/_/g, "");
|
|
3568
|
+
if (m_norm === "reportequivocation" || m_norm === "reportequivocationunsigned") {
|
|
3569
|
+
return {
|
|
3570
|
+
equivocation_proof: get(0, "equivocation_proof"),
|
|
3571
|
+
key_owner_proof: get(1, "key_owner_proof")
|
|
3572
|
+
};
|
|
3573
|
+
}
|
|
3574
|
+
if (m_norm === "notestalled") {
|
|
3575
|
+
return {
|
|
3576
|
+
delay: get(0, "delay"),
|
|
3577
|
+
best_finalized_block_number: get(1, "best_finalized_block_number")
|
|
3578
|
+
};
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
if (s === "shieldedpool") {
|
|
3582
|
+
const m_norm = m.replace(/_/g, "");
|
|
3583
|
+
if (m_norm === "shield") {
|
|
3584
|
+
return {
|
|
3585
|
+
asset_id: get(0, "asset_id"),
|
|
3586
|
+
amount: get(1, "amount"),
|
|
3587
|
+
commitment: get(2, "commitment"),
|
|
3588
|
+
encrypted_memo: get(3, "encrypted_memo")
|
|
3589
|
+
};
|
|
3590
|
+
}
|
|
3591
|
+
if (m_norm === "shieldbatch") {
|
|
3592
|
+
const ops = get(0, "operations") || get(0, "arg0");
|
|
3593
|
+
if (Array.isArray(ops)) {
|
|
3594
|
+
return {
|
|
3595
|
+
operations: ops.map((op) => {
|
|
3596
|
+
if (Array.isArray(op)) {
|
|
3597
|
+
return {
|
|
3598
|
+
asset_id: op[0],
|
|
3599
|
+
amount: op[1],
|
|
3600
|
+
commitment: op[2],
|
|
3601
|
+
encrypted_memo: op[3]
|
|
3602
|
+
};
|
|
3603
|
+
}
|
|
3604
|
+
return op;
|
|
3605
|
+
})
|
|
3606
|
+
};
|
|
3607
|
+
}
|
|
3608
|
+
return { operations: ops };
|
|
3609
|
+
}
|
|
3610
|
+
if (m_norm === "privatetransfer" || m_norm === "transfer") {
|
|
3611
|
+
return {
|
|
3612
|
+
proof: get(0, "proof"),
|
|
3613
|
+
merkle_root: get(1, "merkle_root"),
|
|
3614
|
+
nullifiers: get(2, "nullifiers"),
|
|
3615
|
+
commitments: get(3, "commitments"),
|
|
3616
|
+
encrypted_memos: get(4, "encrypted_memos")
|
|
3617
|
+
};
|
|
3618
|
+
}
|
|
3619
|
+
if (m_norm === "unshield") {
|
|
3620
|
+
return {
|
|
3621
|
+
proof: get(0, "proof"),
|
|
3622
|
+
merkle_root: get(1, "merkle_root"),
|
|
3623
|
+
nullifier: get(2, "nullifier"),
|
|
3624
|
+
asset_id: get(3, "asset_id"),
|
|
3625
|
+
amount: get(4, "amount"),
|
|
3626
|
+
recipient: get(5, "recipient")
|
|
3627
|
+
};
|
|
3628
|
+
}
|
|
3629
|
+
if (m_norm === "setauditpolicy") {
|
|
3630
|
+
return {
|
|
3631
|
+
auditors: get(0, "auditors"),
|
|
3632
|
+
conditions: get(1, "conditions"),
|
|
3633
|
+
max_frequency: get(2, "max_frequency"),
|
|
3634
|
+
valid_until: get(3, "valid_until")
|
|
3635
|
+
};
|
|
3636
|
+
}
|
|
3637
|
+
if (m_norm === "requestdisclosure") {
|
|
3638
|
+
return {
|
|
3639
|
+
target: get(0, "target"),
|
|
3640
|
+
reason: get(1, "reason")
|
|
3641
|
+
};
|
|
3642
|
+
}
|
|
3643
|
+
if (m_norm === "disclose") {
|
|
3644
|
+
return {
|
|
3645
|
+
commitment: get(0, "commitment"),
|
|
3646
|
+
proof_bytes: get(1, "proof_bytes"),
|
|
3647
|
+
public_signals: get(2, "public_signals"),
|
|
3648
|
+
auditor: get(3, "auditor")
|
|
3649
|
+
};
|
|
3650
|
+
}
|
|
3651
|
+
if (m_norm === "rejectdisclosure") {
|
|
3652
|
+
return {
|
|
3653
|
+
auditor: get(0, "auditor"),
|
|
3654
|
+
reason: get(1, "reason")
|
|
3655
|
+
};
|
|
3656
|
+
}
|
|
3657
|
+
if (m_norm === "registerasset") {
|
|
3658
|
+
return {
|
|
3659
|
+
name: get(0, "name"),
|
|
3660
|
+
symbol: get(1, "symbol"),
|
|
3661
|
+
decimals: get(2, "decimals"),
|
|
3662
|
+
contract_address: get(3, "contract_address")
|
|
3663
|
+
};
|
|
3664
|
+
}
|
|
3665
|
+
if (m_norm === "verifyasset") {
|
|
3666
|
+
return { asset_id: get(0, "asset_id") };
|
|
3667
|
+
}
|
|
3668
|
+
if (m_norm === "unverifyasset") {
|
|
3669
|
+
return { asset_id: get(0, "asset_id") };
|
|
3670
|
+
}
|
|
3671
|
+
if (m_norm === "batchsubmitdisclosureproofs") {
|
|
3672
|
+
return { submissions: get(0, "submissions") };
|
|
3673
|
+
}
|
|
3674
|
+
if (m_norm === "pruneexpiredrequest") {
|
|
3675
|
+
return {
|
|
3676
|
+
target: get(0, "target"),
|
|
3677
|
+
auditor: get(1, "auditor")
|
|
3678
|
+
};
|
|
3679
|
+
}
|
|
3680
|
+
if (m_norm === "revokedisclosurerecord") {
|
|
3681
|
+
return { commitment: get(0, "commitment") };
|
|
3682
|
+
}
|
|
3683
|
+
}
|
|
3684
|
+
if (s === "ethereum" && m === "transact") {
|
|
3685
|
+
return { transaction: get(0, "transaction") };
|
|
3686
|
+
}
|
|
3687
|
+
if (s === "evm") {
|
|
3688
|
+
if (m === "withdraw") {
|
|
3689
|
+
return {
|
|
3690
|
+
address: get(0, "address"),
|
|
3691
|
+
value: get(1, "value")
|
|
3692
|
+
};
|
|
3693
|
+
}
|
|
3694
|
+
if (m === "call") {
|
|
3695
|
+
return {
|
|
3696
|
+
source: get(0, "source"),
|
|
3697
|
+
target: get(1, "target"),
|
|
3698
|
+
input: get(2, "input"),
|
|
3699
|
+
value: get(3, "value"),
|
|
3700
|
+
gas_limit: get(4, "gas_limit"),
|
|
3701
|
+
max_fee_per_gas: get(5, "max_fee_per_gas"),
|
|
3702
|
+
max_priority_fee_per_gas: get(6, "max_priority_fee_per_gas"),
|
|
3703
|
+
nonce: get(7, "nonce"),
|
|
3704
|
+
access_list: get(8, "access_list"),
|
|
3705
|
+
authorization_list: get(9, "authorization_list")
|
|
3706
|
+
};
|
|
3707
|
+
}
|
|
3708
|
+
if (m === "create") {
|
|
3709
|
+
return {
|
|
3710
|
+
source: get(0, "source"),
|
|
3711
|
+
init: get(1, "init"),
|
|
3712
|
+
value: get(2, "value"),
|
|
3713
|
+
gas_limit: get(3, "gas_limit"),
|
|
3714
|
+
max_fee_per_gas: get(4, "max_fee_per_gas"),
|
|
3715
|
+
max_priority_fee_per_gas: get(5, "max_priority_fee_per_gas"),
|
|
3716
|
+
nonce: get(6, "nonce"),
|
|
3717
|
+
access_list: get(7, "access_list"),
|
|
3718
|
+
authorization_list: get(8, "authorization_list")
|
|
3719
|
+
};
|
|
3720
|
+
}
|
|
3721
|
+
if (m === "create2") {
|
|
3722
|
+
return {
|
|
3723
|
+
source: get(0, "source"),
|
|
3724
|
+
init: get(1, "init"),
|
|
3725
|
+
salt: get(2, "salt"),
|
|
3726
|
+
value: get(3, "value"),
|
|
3727
|
+
gas_limit: get(4, "gas_limit"),
|
|
3728
|
+
max_fee_per_gas: get(5, "max_fee_per_gas"),
|
|
3729
|
+
max_priority_fee_per_gas: get(6, "max_priority_fee_per_gas"),
|
|
3730
|
+
nonce: get(7, "nonce"),
|
|
3731
|
+
access_list: get(8, "access_list"),
|
|
3732
|
+
authorization_list: get(9, "authorization_list")
|
|
3733
|
+
};
|
|
3734
|
+
}
|
|
3735
|
+
}
|
|
3736
|
+
if (s === "accountmapping") {
|
|
3737
|
+
const m_norm = m.replace(/_/g, "");
|
|
3738
|
+
if (m_norm === "registeralias") {
|
|
3739
|
+
return { alias: get(0, "alias") };
|
|
3740
|
+
}
|
|
3741
|
+
if (m_norm === "transferalias") {
|
|
3742
|
+
return { new_owner: get(0, "new_owner") };
|
|
3743
|
+
}
|
|
3744
|
+
if (m_norm === "putaliasonsale") {
|
|
3745
|
+
return {
|
|
3746
|
+
price: get(0, "price"),
|
|
3747
|
+
allowed_buyers: get(1, "allowed_buyers")
|
|
3748
|
+
};
|
|
3749
|
+
}
|
|
3750
|
+
if (m_norm === "buyalias") {
|
|
3751
|
+
return { alias: get(0, "alias") };
|
|
3752
|
+
}
|
|
3753
|
+
if (m_norm === "addchainlink") {
|
|
3754
|
+
return {
|
|
3755
|
+
chain_id: get(0, "chain_id"),
|
|
3756
|
+
address: get(1, "address"),
|
|
3757
|
+
signature: get(2, "signature")
|
|
3758
|
+
};
|
|
3759
|
+
}
|
|
3760
|
+
if (m_norm === "removechainlink") {
|
|
3761
|
+
return { chain_id: get(0, "chain_id") };
|
|
3762
|
+
}
|
|
3763
|
+
if (m_norm === "setaccountmetadata") {
|
|
3764
|
+
return {
|
|
3765
|
+
display_name: get(0, "display_name"),
|
|
3766
|
+
bio: get(1, "bio"),
|
|
3767
|
+
avatar: get(2, "avatar")
|
|
3768
|
+
};
|
|
3769
|
+
}
|
|
3770
|
+
if (m_norm === "addsupportedchain") {
|
|
3771
|
+
return {
|
|
3772
|
+
chain_id: get(0, "chain_id"),
|
|
3773
|
+
scheme: get(1, "scheme")
|
|
3774
|
+
};
|
|
3775
|
+
}
|
|
3776
|
+
if (m_norm === "removesupportedchain") {
|
|
3777
|
+
return { chain_id: get(0, "chain_id") };
|
|
3778
|
+
}
|
|
3779
|
+
if (m_norm === "dispatchaslinkedaccount") {
|
|
3780
|
+
return {
|
|
3781
|
+
owner: get(0, "owner"),
|
|
3782
|
+
chain_id: get(1, "chain_id"),
|
|
3783
|
+
address: get(2, "address"),
|
|
3784
|
+
signature: get(3, "signature"),
|
|
3785
|
+
call: get(4, "call")
|
|
3786
|
+
};
|
|
3787
|
+
}
|
|
3788
|
+
if (m_norm === "registerprivatelink") {
|
|
3789
|
+
return {
|
|
3790
|
+
chain_id: get(0, "chain_id"),
|
|
3791
|
+
commitment: get(1, "commitment")
|
|
3792
|
+
};
|
|
3793
|
+
}
|
|
3794
|
+
if (m_norm === "removeprivatelink") {
|
|
3795
|
+
return { commitment: get(0, "commitment") };
|
|
3796
|
+
}
|
|
3797
|
+
if (m_norm === "revealprivatelink") {
|
|
3798
|
+
return {
|
|
3799
|
+
commitment: get(0, "commitment"),
|
|
3800
|
+
address: get(1, "address"),
|
|
3801
|
+
blinding: get(2, "blinding"),
|
|
3802
|
+
signature: get(3, "signature")
|
|
3803
|
+
};
|
|
3804
|
+
}
|
|
3805
|
+
if (m_norm === "dispatchasprivatelink") {
|
|
3806
|
+
return {
|
|
3807
|
+
owner: get(0, "owner"),
|
|
3808
|
+
commitment: get(1, "commitment"),
|
|
3809
|
+
zk_proof: get(2, "zk_proof"),
|
|
3810
|
+
call: get(3, "call")
|
|
3811
|
+
};
|
|
3812
|
+
}
|
|
3813
|
+
}
|
|
3814
|
+
if (s === "zkverifier") {
|
|
3815
|
+
const m_norm = m.replace(/_/g, "");
|
|
3816
|
+
if (m_norm === "batchregisterverificationkeys") {
|
|
3817
|
+
const entries = get(0, "entries");
|
|
3818
|
+
if (Array.isArray(entries)) {
|
|
3819
|
+
return {
|
|
3820
|
+
entries: entries.map((e) => ({
|
|
3821
|
+
circuit_id: e["circuit_id"],
|
|
3822
|
+
version: e["version"],
|
|
3823
|
+
verification_key: e["verification_key"],
|
|
3824
|
+
set_active: e["set_active"]
|
|
3825
|
+
}))
|
|
3826
|
+
};
|
|
3827
|
+
}
|
|
3828
|
+
return { entries };
|
|
3829
|
+
}
|
|
3830
|
+
if (m_norm === "registerverificationkey") {
|
|
3831
|
+
return {
|
|
3832
|
+
circuit_id: get(0, "circuit_id"),
|
|
3833
|
+
version: get(1, "version"),
|
|
3834
|
+
verification_key: get(2, "verification_key")
|
|
3835
|
+
};
|
|
3836
|
+
}
|
|
3837
|
+
if (m_norm === "setactiveversion") {
|
|
3838
|
+
return {
|
|
3839
|
+
circuit_id: get(0, "circuit_id"),
|
|
3840
|
+
version: get(1, "version")
|
|
3841
|
+
};
|
|
3842
|
+
}
|
|
3843
|
+
if (m_norm === "removeverificationkey") {
|
|
3844
|
+
return {
|
|
3845
|
+
circuit_id: get(0, "circuit_id"),
|
|
3846
|
+
version: get(1, "version")
|
|
3847
|
+
};
|
|
3848
|
+
}
|
|
3849
|
+
if (m_norm === "verifyproof") {
|
|
3850
|
+
return {
|
|
3851
|
+
circuit_id: get(0, "circuit_id"),
|
|
3852
|
+
proof: get(1, "proof"),
|
|
3853
|
+
public_inputs: get(2, "public_inputs")
|
|
3854
|
+
};
|
|
3855
|
+
}
|
|
3856
|
+
}
|
|
3857
|
+
return args;
|
|
3858
|
+
}
|
|
3859
|
+
function mapZkEventData(method, data) {
|
|
3860
|
+
const m = method.toLowerCase();
|
|
3861
|
+
const get = (idx, name) => {
|
|
3862
|
+
if (name in data) return data[name];
|
|
3863
|
+
const argKey = `arg${idx}`;
|
|
3864
|
+
if (argKey in data) return data[argKey];
|
|
3865
|
+
if (idx in data) return data[idx];
|
|
3866
|
+
const strIdx = idx.toString();
|
|
3867
|
+
if (strIdx in data) return data[strIdx];
|
|
3868
|
+
return void 0;
|
|
3869
|
+
};
|
|
3870
|
+
const formatAmount = (val) => {
|
|
3871
|
+
if (val === void 0 || val === null) return null;
|
|
3872
|
+
return formatBalance(String(val));
|
|
3873
|
+
};
|
|
3874
|
+
if (m === "shielded" || m === "deposit") {
|
|
3875
|
+
return {
|
|
3876
|
+
sender: get(0, "depositor") || get(0, "sender"),
|
|
3877
|
+
amount: formatAmount(get(1, "amount")),
|
|
3878
|
+
commitment: get(2, "commitment"),
|
|
3879
|
+
memo: get(3, "encrypted_memo") || get(3, "memo"),
|
|
3880
|
+
index: get(4, "leaf_index") || get(4, "index")
|
|
3881
|
+
};
|
|
3882
|
+
}
|
|
3883
|
+
if (m === "privatetransfer") {
|
|
3884
|
+
return {
|
|
3885
|
+
nullifiers: get(0, "nullifiers"),
|
|
3886
|
+
commitments: get(1, "commitments"),
|
|
3887
|
+
memos: get(2, "encrypted_memos") || get(2, "memos"),
|
|
3888
|
+
indices: get(3, "leaf_indices") || get(3, "indices")
|
|
3889
|
+
};
|
|
3890
|
+
}
|
|
3891
|
+
if (m === "unshielded" || m === "withdraw") {
|
|
3892
|
+
return {
|
|
3893
|
+
nullifier: get(0, "nullifier"),
|
|
3894
|
+
amount: formatAmount(get(1, "amount")),
|
|
3895
|
+
recipient: get(2, "recipient")
|
|
3896
|
+
};
|
|
3897
|
+
}
|
|
3898
|
+
if (m === "merklerootupdated" || m === "merkleroot") {
|
|
3899
|
+
return {
|
|
3900
|
+
old_root: get(0, "old_root"),
|
|
3901
|
+
new_root: get(1, "new_root"),
|
|
3902
|
+
size: get(2, "tree_size") || get(2, "size")
|
|
3903
|
+
};
|
|
3904
|
+
}
|
|
3905
|
+
const m_norm = m.replace(/_/g, "");
|
|
3906
|
+
if (m_norm === "auditpolicyset") {
|
|
3907
|
+
return {
|
|
3908
|
+
account: get(0, "account"),
|
|
3909
|
+
version: get(1, "version")
|
|
3910
|
+
};
|
|
3911
|
+
}
|
|
3912
|
+
if (m_norm === "disclosed") {
|
|
3913
|
+
return {
|
|
3914
|
+
who: get(0, "who"),
|
|
3915
|
+
commitment: get(1, "commitment"),
|
|
3916
|
+
auditor: get(2, "auditor")
|
|
3917
|
+
};
|
|
3918
|
+
}
|
|
3919
|
+
if (m_norm === "disclosurerequested") {
|
|
3920
|
+
return {
|
|
3921
|
+
target: get(0, "target"),
|
|
3922
|
+
auditor: get(1, "auditor"),
|
|
3923
|
+
reason: get(2, "reason")
|
|
3924
|
+
};
|
|
3925
|
+
}
|
|
3926
|
+
if (m_norm === "disclosurerejected") {
|
|
3927
|
+
return {
|
|
3928
|
+
target: get(0, "target"),
|
|
3929
|
+
auditor: get(1, "auditor"),
|
|
3930
|
+
reason: get(2, "reason")
|
|
3931
|
+
};
|
|
3932
|
+
}
|
|
3933
|
+
if (m_norm === "disclosurerequestexpired") {
|
|
3934
|
+
return {
|
|
3935
|
+
target: get(0, "target"),
|
|
3936
|
+
auditor: get(1, "auditor")
|
|
3937
|
+
};
|
|
3938
|
+
}
|
|
3939
|
+
if (m_norm === "disclosurerecordrevoked") {
|
|
3940
|
+
return {
|
|
3941
|
+
who: get(0, "who"),
|
|
3942
|
+
commitment: get(1, "commitment")
|
|
3943
|
+
};
|
|
3944
|
+
}
|
|
3945
|
+
if (m_norm === "assetregistered") {
|
|
3946
|
+
return { asset_id: get(0, "asset_id") };
|
|
3947
|
+
}
|
|
3948
|
+
if (m_norm === "assetverified") {
|
|
3949
|
+
return { asset_id: get(0, "asset_id") };
|
|
3950
|
+
}
|
|
3951
|
+
if (m_norm === "assetunverified") {
|
|
3952
|
+
return { asset_id: get(0, "asset_id") };
|
|
3953
|
+
}
|
|
3954
|
+
if (m_norm === "accountmapped" || m_norm === "accountunmapped") {
|
|
3955
|
+
return {
|
|
3956
|
+
account: get(0, "account"),
|
|
3957
|
+
address: get(1, "address")
|
|
3958
|
+
};
|
|
3959
|
+
}
|
|
3960
|
+
if (m_norm === "aliasregistered") {
|
|
3961
|
+
return {
|
|
3962
|
+
account: get(0, "account"),
|
|
3963
|
+
alias: get(1, "alias"),
|
|
3964
|
+
evm_address: get(2, "evm_address")
|
|
3965
|
+
};
|
|
3966
|
+
}
|
|
3967
|
+
if (m_norm === "aliasreleased") {
|
|
3968
|
+
return {
|
|
3969
|
+
account: get(0, "account"),
|
|
3970
|
+
alias: get(1, "alias")
|
|
3971
|
+
};
|
|
3972
|
+
}
|
|
3973
|
+
if (m_norm === "aliastransferred") {
|
|
3974
|
+
return {
|
|
3975
|
+
from: get(0, "from"),
|
|
3976
|
+
to: get(1, "to"),
|
|
3977
|
+
alias: get(2, "alias")
|
|
3978
|
+
};
|
|
3979
|
+
}
|
|
3980
|
+
if (m_norm === "aliaslistedforsale") {
|
|
3981
|
+
return {
|
|
3982
|
+
seller: get(0, "seller"),
|
|
3983
|
+
alias: get(1, "alias"),
|
|
3984
|
+
price: get(2, "price"),
|
|
3985
|
+
private: get(3, "private")
|
|
3986
|
+
};
|
|
3987
|
+
}
|
|
3988
|
+
if (m_norm === "aliassalecancelled") {
|
|
3989
|
+
return {
|
|
3990
|
+
seller: get(0, "seller"),
|
|
3991
|
+
alias: get(1, "alias")
|
|
3992
|
+
};
|
|
3993
|
+
}
|
|
3994
|
+
if (m_norm === "aliassold") {
|
|
3995
|
+
return {
|
|
3996
|
+
seller: get(0, "seller"),
|
|
3997
|
+
buyer: get(1, "buyer"),
|
|
3998
|
+
alias: get(2, "alias"),
|
|
3999
|
+
price: get(3, "price")
|
|
4000
|
+
};
|
|
4001
|
+
}
|
|
4002
|
+
if (m_norm === "chainlinkadded") {
|
|
4003
|
+
return {
|
|
4004
|
+
account: get(0, "account"),
|
|
4005
|
+
chain_id: get(1, "chain_id"),
|
|
4006
|
+
address: get(2, "address")
|
|
4007
|
+
};
|
|
4008
|
+
}
|
|
4009
|
+
if (m_norm === "chainlinkremoved") {
|
|
4010
|
+
return {
|
|
4011
|
+
account: get(0, "account"),
|
|
4012
|
+
chain_id: get(1, "chain_id")
|
|
4013
|
+
};
|
|
4014
|
+
}
|
|
4015
|
+
if (m_norm === "metadataupdated") {
|
|
4016
|
+
return { account: get(0, "account") };
|
|
4017
|
+
}
|
|
4018
|
+
if (m_norm === "supportedchainadded") {
|
|
4019
|
+
return {
|
|
4020
|
+
chain_id: get(0, "chain_id"),
|
|
4021
|
+
scheme: get(1, "scheme")
|
|
4022
|
+
};
|
|
4023
|
+
}
|
|
4024
|
+
if (m_norm === "supportedchainremoved") {
|
|
4025
|
+
return { chain_id: get(0, "chain_id") };
|
|
4026
|
+
}
|
|
4027
|
+
if (m_norm === "proxycallexecuted") {
|
|
4028
|
+
return {
|
|
4029
|
+
owner: get(0, "owner"),
|
|
4030
|
+
chain_id: get(1, "chain_id"),
|
|
4031
|
+
address: get(2, "address")
|
|
4032
|
+
};
|
|
4033
|
+
}
|
|
4034
|
+
if (m_norm === "privatechainlinkadded" || m_norm === "privatechainlinkremoved") {
|
|
4035
|
+
return {
|
|
4036
|
+
account: get(0, "account"),
|
|
4037
|
+
chain_id: get(1, "chain_id"),
|
|
4038
|
+
commitment: get(2, "commitment")
|
|
4039
|
+
};
|
|
4040
|
+
}
|
|
4041
|
+
if (m_norm === "privatechainlinkrevealed") {
|
|
4042
|
+
return {
|
|
4043
|
+
account: get(0, "account"),
|
|
4044
|
+
chain_id: get(1, "chain_id"),
|
|
4045
|
+
address: get(2, "address")
|
|
4046
|
+
};
|
|
4047
|
+
}
|
|
4048
|
+
if (m_norm === "privatelinkdispatchexecuted") {
|
|
4049
|
+
return {
|
|
4050
|
+
owner: get(0, "owner"),
|
|
4051
|
+
commitment: get(1, "commitment")
|
|
4052
|
+
};
|
|
4053
|
+
}
|
|
4054
|
+
if (m_norm === "verificationkeyregistered" || m_norm === "activeversionset" || m_norm === "verificationkeyremoved" || m_norm === "proofverified" || m_norm === "proofverificationfailed") {
|
|
4055
|
+
return {
|
|
4056
|
+
circuit_id: get(0, "circuit_id"),
|
|
4057
|
+
version: get(1, "version")
|
|
4058
|
+
};
|
|
4059
|
+
}
|
|
4060
|
+
if (m_norm === "log") {
|
|
4061
|
+
return { log: get(0, "log") };
|
|
4062
|
+
}
|
|
4063
|
+
if (m_norm === "created" || m_norm === "createdfailed" || m_norm === "executed" || m_norm === "executedfailed") {
|
|
4064
|
+
return { address: get(0, "address") };
|
|
4065
|
+
}
|
|
4066
|
+
if (m_norm === "executed") {
|
|
4067
|
+
return {
|
|
4068
|
+
from: get(0, "from"),
|
|
4069
|
+
to: get(1, "to"),
|
|
4070
|
+
transaction_hash: get(2, "transaction_hash"),
|
|
4071
|
+
exit_reason: get(3, "exit_reason")
|
|
4072
|
+
};
|
|
4073
|
+
}
|
|
4074
|
+
if (m_norm === "extrinsicsuccess") {
|
|
4075
|
+
return { dispatch_info: get(0, "dispatch_info") };
|
|
4076
|
+
}
|
|
4077
|
+
if (m_norm === "extrinsicfailed") {
|
|
4078
|
+
return {
|
|
4079
|
+
dispatch_error: get(0, "dispatch_error"),
|
|
4080
|
+
dispatch_info: get(1, "dispatch_info")
|
|
4081
|
+
};
|
|
4082
|
+
}
|
|
4083
|
+
if (m_norm === "newaccount" || m_norm === "killedaccount") {
|
|
4084
|
+
return { account: get(0, "account") };
|
|
4085
|
+
}
|
|
4086
|
+
if (m_norm === "remarked") {
|
|
4087
|
+
return {
|
|
4088
|
+
sender: get(0, "sender"),
|
|
4089
|
+
hash: get(1, "hash")
|
|
4090
|
+
};
|
|
4091
|
+
}
|
|
4092
|
+
if (m_norm === "upgradeauthorized") {
|
|
4093
|
+
return {
|
|
4094
|
+
code_hash: get(0, "code_hash"),
|
|
4095
|
+
check_version: get(1, "check_version")
|
|
4096
|
+
};
|
|
4097
|
+
}
|
|
4098
|
+
if (m_norm === "rejectedinvalidauthorizedupgrade") {
|
|
4099
|
+
return {
|
|
4100
|
+
code_hash: get(0, "code_hash"),
|
|
4101
|
+
error: get(1, "error")
|
|
4102
|
+
};
|
|
4103
|
+
}
|
|
4104
|
+
if (m_norm === "endowed") {
|
|
4105
|
+
return {
|
|
4106
|
+
account: get(0, "account"),
|
|
4107
|
+
free_balance: get(1, "free_balance")
|
|
4108
|
+
};
|
|
4109
|
+
}
|
|
4110
|
+
if (m_norm === "dustlost") {
|
|
4111
|
+
return {
|
|
4112
|
+
account: get(0, "account"),
|
|
4113
|
+
amount: get(1, "amount")
|
|
4114
|
+
};
|
|
4115
|
+
}
|
|
4116
|
+
if (m_norm === "transfer") {
|
|
4117
|
+
return {
|
|
4118
|
+
from: get(0, "from"),
|
|
4119
|
+
to: get(1, "to"),
|
|
4120
|
+
amount: get(2, "amount")
|
|
4121
|
+
};
|
|
4122
|
+
}
|
|
4123
|
+
if (m_norm === "balanceset") {
|
|
4124
|
+
return {
|
|
4125
|
+
who: get(0, "who"),
|
|
4126
|
+
free: get(1, "free")
|
|
4127
|
+
};
|
|
4128
|
+
}
|
|
4129
|
+
if (m_norm === "reserved" || m_norm === "unreserved" || m_norm === "deposit" || m_norm === "slashed" || m_norm === "minted" || m_norm === "burned" || m_norm === "suspended" || m_norm === "restored" || m_norm === "locked" || m_norm === "unlocked" || m_norm === "frozen" || m_norm === "thawed") {
|
|
4130
|
+
return {
|
|
4131
|
+
who: get(0, "who"),
|
|
4132
|
+
amount: get(1, "amount")
|
|
4133
|
+
};
|
|
4134
|
+
}
|
|
4135
|
+
if (m_norm === "reserverepatriated") {
|
|
4136
|
+
return {
|
|
4137
|
+
from: get(0, "from"),
|
|
4138
|
+
to: get(1, "to"),
|
|
4139
|
+
amount: get(2, "amount"),
|
|
4140
|
+
destination_status: get(3, "destination_status")
|
|
4141
|
+
};
|
|
4142
|
+
}
|
|
4143
|
+
if (m_norm === "upgraded") {
|
|
4144
|
+
return { who: get(0, "who") };
|
|
4145
|
+
}
|
|
4146
|
+
if (m_norm === "issued" || m_norm === "rescinded") {
|
|
4147
|
+
return { amount: get(0, "amount") };
|
|
4148
|
+
}
|
|
4149
|
+
if (m_norm === "totalissuanceforced") {
|
|
4150
|
+
return {
|
|
4151
|
+
old: get(0, "old"),
|
|
4152
|
+
new: get(1, "new")
|
|
4153
|
+
};
|
|
4154
|
+
}
|
|
4155
|
+
if (m_norm === "sudid" || m_norm === "sudoasdone") {
|
|
4156
|
+
return { sudo_result: get(0, "sudo_result") };
|
|
4157
|
+
}
|
|
4158
|
+
if (m_norm === "keychanged") {
|
|
4159
|
+
return {
|
|
4160
|
+
old: get(0, "old"),
|
|
4161
|
+
new: get(1, "new")
|
|
4162
|
+
};
|
|
4163
|
+
}
|
|
4164
|
+
if (m_norm === "newauthorities") {
|
|
4165
|
+
return { authority_set: get(0, "authority_set") };
|
|
4166
|
+
}
|
|
4167
|
+
if (m_norm === "transactionfeepaid") {
|
|
4168
|
+
return {
|
|
4169
|
+
who: get(0, "who"),
|
|
4170
|
+
actual_fee: get(1, "actual_fee"),
|
|
4171
|
+
tip: get(2, "tip")
|
|
4172
|
+
};
|
|
4173
|
+
}
|
|
4174
|
+
return data;
|
|
4175
|
+
}
|
|
4176
|
+
|
|
2467
4177
|
// src/index.ts
|
|
4178
|
+
var import_substrate_bindings3 = require("@polkadot-api/substrate-bindings");
|
|
4179
|
+
var import_base = require("@scure/base");
|
|
2468
4180
|
var import_signer = require("polkadot-api/signer");
|
|
2469
4181
|
var import_pjs_signer = require("polkadot-api/pjs-signer");
|
|
4182
|
+
var import_polkadot_api4 = require("polkadot-api");
|
|
2470
4183
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2471
4184
|
0 && (module.exports = {
|
|
4185
|
+
AccountId,
|
|
2472
4186
|
AccountMappingModule,
|
|
2473
4187
|
AccountMappingPrecompile,
|
|
2474
|
-
|
|
4188
|
+
Blake2256,
|
|
2475
4189
|
CircuitId,
|
|
2476
4190
|
CryptoPrecompiles,
|
|
2477
4191
|
EncryptedMemo,
|
|
2478
4192
|
EvmClient,
|
|
4193
|
+
EvmExplorer,
|
|
4194
|
+
IndexerClient,
|
|
2479
4195
|
KNOWN_PRECOMPILES,
|
|
2480
|
-
|
|
4196
|
+
Keccak256,
|
|
2481
4197
|
NoteBuilder,
|
|
2482
4198
|
OrbinumClient,
|
|
4199
|
+
OrbinumClientProvider,
|
|
2483
4200
|
PRECOMPILE_ADDR,
|
|
2484
4201
|
PrivacyKeyManager,
|
|
4202
|
+
PrivacyModule,
|
|
2485
4203
|
SLIP0044_NAMESPACE,
|
|
2486
4204
|
ShieldedPoolModule,
|
|
2487
4205
|
ShieldedPoolPrecompile,
|
|
4206
|
+
SignatureScheme,
|
|
4207
|
+
Storage,
|
|
2488
4208
|
SubstrateClient,
|
|
4209
|
+
ZkVerifierModule,
|
|
2489
4210
|
accountIdHexToSs58,
|
|
2490
4211
|
addressToAccountIdHex,
|
|
4212
|
+
base58,
|
|
2491
4213
|
bigintTo32Be,
|
|
2492
4214
|
bigintTo32Le,
|
|
2493
4215
|
bigintTo32LeArr,
|
|
2494
4216
|
bytesToBigintLE,
|
|
2495
4217
|
computePathIndices,
|
|
4218
|
+
connectInjectedExtension,
|
|
4219
|
+
decodePrecompileCalldata,
|
|
2496
4220
|
decryptJson,
|
|
2497
4221
|
deriveOwnerPk,
|
|
2498
4222
|
deriveSpendingKeyFromSignature,
|
|
@@ -2503,13 +4227,19 @@ var import_pjs_signer = require("polkadot-api/pjs-signer");
|
|
|
2503
4227
|
ensureHexPrefix,
|
|
2504
4228
|
evmAddressToAccountId,
|
|
2505
4229
|
evmToImplicitSubstrate,
|
|
4230
|
+
evmToMappedAccountHex,
|
|
2506
4231
|
evmToSubstrate,
|
|
2507
4232
|
formatBalance,
|
|
2508
4233
|
formatORB,
|
|
4234
|
+
fromBase64,
|
|
2509
4235
|
fromHex,
|
|
4236
|
+
getInjectedExtensions,
|
|
2510
4237
|
getPolkadotSigner,
|
|
2511
4238
|
getPolkadotSignerFromPjs,
|
|
2512
4239
|
getPrecompileLabel,
|
|
4240
|
+
getSs58AddressInfo,
|
|
4241
|
+
hexToBigint,
|
|
4242
|
+
hexToNumber,
|
|
2513
4243
|
implicitSubstrateToEvm,
|
|
2514
4244
|
isEvmAddress,
|
|
2515
4245
|
isImplicitEvmAccount,
|
|
@@ -2517,11 +4247,19 @@ var import_pjs_signer = require("polkadot-api/pjs-signer");
|
|
|
2517
4247
|
isSubstrateAddress,
|
|
2518
4248
|
isUnifiedAddress,
|
|
2519
4249
|
leHexToBigint,
|
|
4250
|
+
mapExtrinsicArgs,
|
|
4251
|
+
mapZkEventData,
|
|
2520
4252
|
normalizeEvmAddress,
|
|
4253
|
+
shortHash,
|
|
2521
4254
|
substrateSs58ToAccountIdHex,
|
|
2522
4255
|
substrateToEvm,
|
|
4256
|
+
toBase64,
|
|
2523
4257
|
toHex,
|
|
4258
|
+
toTxResult,
|
|
4259
|
+
truncateMiddle,
|
|
2524
4260
|
tryDecryptNote,
|
|
4261
|
+
u128,
|
|
4262
|
+
u64,
|
|
2525
4263
|
vaultReplacer,
|
|
2526
4264
|
vaultReviver
|
|
2527
4265
|
});
|