@orbinum/sdk 0.8.0 → 0.8.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/dist/index.d.mts +19 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.js +62 -17
- package/dist/index.mjs +62 -17
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -844,18 +844,35 @@ declare class IndexerClient {
|
|
|
844
844
|
* For the current Orbinum testnet/mainnet scale this is the recommended approach.
|
|
845
845
|
*/
|
|
846
846
|
getAllSpentNullifiers(): Promise<Set<string>>;
|
|
847
|
+
/** Server-enforced max items per by-nullifiers / by-commitments request. */
|
|
848
|
+
private static readonly TRANSFER_LOOKUP_CHUNK;
|
|
849
|
+
/**
|
|
850
|
+
* Chunked fetch for the transfer timestamp lookups. The reader silently
|
|
851
|
+
* truncates each request to 50 items, so larger inputs MUST be split or
|
|
852
|
+
* results are silently lost. Responses are merged per extrinsic
|
|
853
|
+
* (`blockNumber:extrinsicIndex`), concatenating the matched arrays, and
|
|
854
|
+
* sorted by block descending.
|
|
855
|
+
*
|
|
856
|
+
* Privacy note: these lookups send the wallet's own note identifiers to
|
|
857
|
+
* the indexer — a bounded, documented linkage tradeoff for timestamp
|
|
858
|
+
* recovery. They are NEVER used for spent-STATUS checks (PIR-A: status
|
|
859
|
+
* comes from the anonymous full-set `/shielded/nullifiers/all` download).
|
|
860
|
+
*/
|
|
861
|
+
private fetchTransfersChunked;
|
|
847
862
|
/**
|
|
848
863
|
* Returns temporal metadata for private transfers that spent any of the given nullifiers.
|
|
849
864
|
* Only blockNumber, extrinsicIndex, timestampMs, and hash are returned — no cross-link
|
|
850
865
|
* between inputs and outputs to prevent graph reconstruction.
|
|
851
|
-
*
|
|
866
|
+
* Inputs of any size are transparently chunked into requests of 50 (the server cap)
|
|
867
|
+
* and merged per extrinsic.
|
|
852
868
|
*/
|
|
853
869
|
getTransfersByNullifiers(nullifiers: string[]): Promise<PrivateTransferTimestamp[]>;
|
|
854
870
|
/**
|
|
855
871
|
* Returns temporal metadata for private transfers that produced any of the given commitments.
|
|
856
872
|
* Only blockNumber, extrinsicIndex, timestampMs, and hash are returned — no cross-link
|
|
857
873
|
* between outputs and inputs to prevent graph reconstruction.
|
|
858
|
-
*
|
|
874
|
+
* Inputs of any size are transparently chunked into requests of 50 (the server cap)
|
|
875
|
+
* and merged per extrinsic.
|
|
859
876
|
*/
|
|
860
877
|
getTransfersByCommitments(commitments: string[]): Promise<PrivateTransferTimestamp[]>;
|
|
861
878
|
/** Returns a paginated list of unshield events. */
|
package/dist/index.d.ts
CHANGED
|
@@ -844,18 +844,35 @@ declare class IndexerClient {
|
|
|
844
844
|
* For the current Orbinum testnet/mainnet scale this is the recommended approach.
|
|
845
845
|
*/
|
|
846
846
|
getAllSpentNullifiers(): Promise<Set<string>>;
|
|
847
|
+
/** Server-enforced max items per by-nullifiers / by-commitments request. */
|
|
848
|
+
private static readonly TRANSFER_LOOKUP_CHUNK;
|
|
849
|
+
/**
|
|
850
|
+
* Chunked fetch for the transfer timestamp lookups. The reader silently
|
|
851
|
+
* truncates each request to 50 items, so larger inputs MUST be split or
|
|
852
|
+
* results are silently lost. Responses are merged per extrinsic
|
|
853
|
+
* (`blockNumber:extrinsicIndex`), concatenating the matched arrays, and
|
|
854
|
+
* sorted by block descending.
|
|
855
|
+
*
|
|
856
|
+
* Privacy note: these lookups send the wallet's own note identifiers to
|
|
857
|
+
* the indexer — a bounded, documented linkage tradeoff for timestamp
|
|
858
|
+
* recovery. They are NEVER used for spent-STATUS checks (PIR-A: status
|
|
859
|
+
* comes from the anonymous full-set `/shielded/nullifiers/all` download).
|
|
860
|
+
*/
|
|
861
|
+
private fetchTransfersChunked;
|
|
847
862
|
/**
|
|
848
863
|
* Returns temporal metadata for private transfers that spent any of the given nullifiers.
|
|
849
864
|
* Only blockNumber, extrinsicIndex, timestampMs, and hash are returned — no cross-link
|
|
850
865
|
* between inputs and outputs to prevent graph reconstruction.
|
|
851
|
-
*
|
|
866
|
+
* Inputs of any size are transparently chunked into requests of 50 (the server cap)
|
|
867
|
+
* and merged per extrinsic.
|
|
852
868
|
*/
|
|
853
869
|
getTransfersByNullifiers(nullifiers: string[]): Promise<PrivateTransferTimestamp[]>;
|
|
854
870
|
/**
|
|
855
871
|
* Returns temporal metadata for private transfers that produced any of the given commitments.
|
|
856
872
|
* Only blockNumber, extrinsicIndex, timestampMs, and hash are returned — no cross-link
|
|
857
873
|
* between outputs and inputs to prevent graph reconstruction.
|
|
858
|
-
*
|
|
874
|
+
* Inputs of any size are transparently chunked into requests of 50 (the server cap)
|
|
875
|
+
* and merged per extrinsic.
|
|
859
876
|
*/
|
|
860
877
|
getTransfersByCommitments(commitments: string[]): Promise<PrivateTransferTimestamp[]>;
|
|
861
878
|
/** Returns a paginated list of unshield events. */
|
package/dist/index.js
CHANGED
|
@@ -1147,7 +1147,7 @@ var EvmExplorer = class _EvmExplorer {
|
|
|
1147
1147
|
};
|
|
1148
1148
|
|
|
1149
1149
|
// src/indexer/IndexerClient.ts
|
|
1150
|
-
var IndexerClient = class {
|
|
1150
|
+
var IndexerClient = class _IndexerClient {
|
|
1151
1151
|
baseUrl;
|
|
1152
1152
|
timeoutMs;
|
|
1153
1153
|
constructor(config) {
|
|
@@ -1247,37 +1247,82 @@ var IndexerClient = class {
|
|
|
1247
1247
|
return new Set(res.data.map((h) => h.toLowerCase()));
|
|
1248
1248
|
}
|
|
1249
1249
|
// ─── Private transfers ─────────────────────────────────────────────────────
|
|
1250
|
+
/** Server-enforced max items per by-nullifiers / by-commitments request. */
|
|
1251
|
+
static TRANSFER_LOOKUP_CHUNK = 50;
|
|
1252
|
+
/**
|
|
1253
|
+
* Chunked fetch for the transfer timestamp lookups. The reader silently
|
|
1254
|
+
* truncates each request to 50 items, so larger inputs MUST be split or
|
|
1255
|
+
* results are silently lost. Responses are merged per extrinsic
|
|
1256
|
+
* (`blockNumber:extrinsicIndex`), concatenating the matched arrays, and
|
|
1257
|
+
* sorted by block descending.
|
|
1258
|
+
*
|
|
1259
|
+
* Privacy note: these lookups send the wallet's own note identifiers to
|
|
1260
|
+
* the indexer — a bounded, documented linkage tradeoff for timestamp
|
|
1261
|
+
* recovery. They are NEVER used for spent-STATUS checks (PIR-A: status
|
|
1262
|
+
* comes from the anonymous full-set `/shielded/nullifiers/all` download).
|
|
1263
|
+
*/
|
|
1264
|
+
async fetchTransfersChunked(path, param, items, matchedField) {
|
|
1265
|
+
if (items.length === 0) return [];
|
|
1266
|
+
const normalized = items.map((i) => i.toLowerCase());
|
|
1267
|
+
const chunks = [];
|
|
1268
|
+
for (let i = 0; i < normalized.length; i += _IndexerClient.TRANSFER_LOOKUP_CHUNK) {
|
|
1269
|
+
chunks.push(normalized.slice(i, i + _IndexerClient.TRANSFER_LOOKUP_CHUNK));
|
|
1270
|
+
}
|
|
1271
|
+
const responses = await Promise.all(
|
|
1272
|
+
chunks.map((chunk) => {
|
|
1273
|
+
const qs = this.buildQuery({ [param]: chunk.join(",") });
|
|
1274
|
+
return this.get(
|
|
1275
|
+
`${path}${qs}`
|
|
1276
|
+
);
|
|
1277
|
+
})
|
|
1278
|
+
);
|
|
1279
|
+
const byExtrinsic = /* @__PURE__ */ new Map();
|
|
1280
|
+
for (const res of responses) {
|
|
1281
|
+
for (const transfer of res.data) {
|
|
1282
|
+
const key = `${transfer.blockNumber}:${transfer.extrinsicIndex ?? "null"}`;
|
|
1283
|
+
const existing = byExtrinsic.get(key);
|
|
1284
|
+
if (!existing) {
|
|
1285
|
+
byExtrinsic.set(key, transfer);
|
|
1286
|
+
continue;
|
|
1287
|
+
}
|
|
1288
|
+
const merged = /* @__PURE__ */ new Set([
|
|
1289
|
+
...existing[matchedField] ?? [],
|
|
1290
|
+
...transfer[matchedField] ?? []
|
|
1291
|
+
]);
|
|
1292
|
+
existing[matchedField] = [...merged];
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
return [...byExtrinsic.values()].sort((a, b) => b.blockNumber - a.blockNumber);
|
|
1296
|
+
}
|
|
1250
1297
|
/**
|
|
1251
1298
|
* Returns temporal metadata for private transfers that spent any of the given nullifiers.
|
|
1252
1299
|
* Only blockNumber, extrinsicIndex, timestampMs, and hash are returned — no cross-link
|
|
1253
1300
|
* between inputs and outputs to prevent graph reconstruction.
|
|
1254
|
-
*
|
|
1301
|
+
* Inputs of any size are transparently chunked into requests of 50 (the server cap)
|
|
1302
|
+
* and merged per extrinsic.
|
|
1255
1303
|
*/
|
|
1256
1304
|
async getTransfersByNullifiers(nullifiers) {
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
nullifiers
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
`/shielded/transfers/by-nullifiers${qs}`
|
|
1305
|
+
return this.fetchTransfersChunked(
|
|
1306
|
+
"/shielded/transfers/by-nullifiers",
|
|
1307
|
+
"nullifiers",
|
|
1308
|
+
nullifiers,
|
|
1309
|
+
"matchedNullifiers"
|
|
1263
1310
|
);
|
|
1264
|
-
return res.data;
|
|
1265
1311
|
}
|
|
1266
1312
|
/**
|
|
1267
1313
|
* Returns temporal metadata for private transfers that produced any of the given commitments.
|
|
1268
1314
|
* Only blockNumber, extrinsicIndex, timestampMs, and hash are returned — no cross-link
|
|
1269
1315
|
* between outputs and inputs to prevent graph reconstruction.
|
|
1270
|
-
*
|
|
1316
|
+
* Inputs of any size are transparently chunked into requests of 50 (the server cap)
|
|
1317
|
+
* and merged per extrinsic.
|
|
1271
1318
|
*/
|
|
1272
1319
|
async getTransfersByCommitments(commitments) {
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
commitments
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
`/shielded/transfers/by-commitments${qs}`
|
|
1320
|
+
return this.fetchTransfersChunked(
|
|
1321
|
+
"/shielded/transfers/by-commitments",
|
|
1322
|
+
"commitments",
|
|
1323
|
+
commitments,
|
|
1324
|
+
"matchedCommitments"
|
|
1279
1325
|
);
|
|
1280
|
-
return res.data;
|
|
1281
1326
|
}
|
|
1282
1327
|
// ─── Unshields ─────────────────────────────────────────────────────────────
|
|
1283
1328
|
/** Returns a paginated list of unshield events. */
|
package/dist/index.mjs
CHANGED
|
@@ -1020,7 +1020,7 @@ var EvmExplorer = class _EvmExplorer {
|
|
|
1020
1020
|
};
|
|
1021
1021
|
|
|
1022
1022
|
// src/indexer/IndexerClient.ts
|
|
1023
|
-
var IndexerClient = class {
|
|
1023
|
+
var IndexerClient = class _IndexerClient {
|
|
1024
1024
|
baseUrl;
|
|
1025
1025
|
timeoutMs;
|
|
1026
1026
|
constructor(config) {
|
|
@@ -1120,37 +1120,82 @@ var IndexerClient = class {
|
|
|
1120
1120
|
return new Set(res.data.map((h) => h.toLowerCase()));
|
|
1121
1121
|
}
|
|
1122
1122
|
// ─── Private transfers ─────────────────────────────────────────────────────
|
|
1123
|
+
/** Server-enforced max items per by-nullifiers / by-commitments request. */
|
|
1124
|
+
static TRANSFER_LOOKUP_CHUNK = 50;
|
|
1125
|
+
/**
|
|
1126
|
+
* Chunked fetch for the transfer timestamp lookups. The reader silently
|
|
1127
|
+
* truncates each request to 50 items, so larger inputs MUST be split or
|
|
1128
|
+
* results are silently lost. Responses are merged per extrinsic
|
|
1129
|
+
* (`blockNumber:extrinsicIndex`), concatenating the matched arrays, and
|
|
1130
|
+
* sorted by block descending.
|
|
1131
|
+
*
|
|
1132
|
+
* Privacy note: these lookups send the wallet's own note identifiers to
|
|
1133
|
+
* the indexer — a bounded, documented linkage tradeoff for timestamp
|
|
1134
|
+
* recovery. They are NEVER used for spent-STATUS checks (PIR-A: status
|
|
1135
|
+
* comes from the anonymous full-set `/shielded/nullifiers/all` download).
|
|
1136
|
+
*/
|
|
1137
|
+
async fetchTransfersChunked(path, param, items, matchedField) {
|
|
1138
|
+
if (items.length === 0) return [];
|
|
1139
|
+
const normalized = items.map((i) => i.toLowerCase());
|
|
1140
|
+
const chunks = [];
|
|
1141
|
+
for (let i = 0; i < normalized.length; i += _IndexerClient.TRANSFER_LOOKUP_CHUNK) {
|
|
1142
|
+
chunks.push(normalized.slice(i, i + _IndexerClient.TRANSFER_LOOKUP_CHUNK));
|
|
1143
|
+
}
|
|
1144
|
+
const responses = await Promise.all(
|
|
1145
|
+
chunks.map((chunk) => {
|
|
1146
|
+
const qs = this.buildQuery({ [param]: chunk.join(",") });
|
|
1147
|
+
return this.get(
|
|
1148
|
+
`${path}${qs}`
|
|
1149
|
+
);
|
|
1150
|
+
})
|
|
1151
|
+
);
|
|
1152
|
+
const byExtrinsic = /* @__PURE__ */ new Map();
|
|
1153
|
+
for (const res of responses) {
|
|
1154
|
+
for (const transfer of res.data) {
|
|
1155
|
+
const key = `${transfer.blockNumber}:${transfer.extrinsicIndex ?? "null"}`;
|
|
1156
|
+
const existing = byExtrinsic.get(key);
|
|
1157
|
+
if (!existing) {
|
|
1158
|
+
byExtrinsic.set(key, transfer);
|
|
1159
|
+
continue;
|
|
1160
|
+
}
|
|
1161
|
+
const merged = /* @__PURE__ */ new Set([
|
|
1162
|
+
...existing[matchedField] ?? [],
|
|
1163
|
+
...transfer[matchedField] ?? []
|
|
1164
|
+
]);
|
|
1165
|
+
existing[matchedField] = [...merged];
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
return [...byExtrinsic.values()].sort((a, b) => b.blockNumber - a.blockNumber);
|
|
1169
|
+
}
|
|
1123
1170
|
/**
|
|
1124
1171
|
* Returns temporal metadata for private transfers that spent any of the given nullifiers.
|
|
1125
1172
|
* Only blockNumber, extrinsicIndex, timestampMs, and hash are returned — no cross-link
|
|
1126
1173
|
* between inputs and outputs to prevent graph reconstruction.
|
|
1127
|
-
*
|
|
1174
|
+
* Inputs of any size are transparently chunked into requests of 50 (the server cap)
|
|
1175
|
+
* and merged per extrinsic.
|
|
1128
1176
|
*/
|
|
1129
1177
|
async getTransfersByNullifiers(nullifiers) {
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
nullifiers
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
`/shielded/transfers/by-nullifiers${qs}`
|
|
1178
|
+
return this.fetchTransfersChunked(
|
|
1179
|
+
"/shielded/transfers/by-nullifiers",
|
|
1180
|
+
"nullifiers",
|
|
1181
|
+
nullifiers,
|
|
1182
|
+
"matchedNullifiers"
|
|
1136
1183
|
);
|
|
1137
|
-
return res.data;
|
|
1138
1184
|
}
|
|
1139
1185
|
/**
|
|
1140
1186
|
* Returns temporal metadata for private transfers that produced any of the given commitments.
|
|
1141
1187
|
* Only blockNumber, extrinsicIndex, timestampMs, and hash are returned — no cross-link
|
|
1142
1188
|
* between outputs and inputs to prevent graph reconstruction.
|
|
1143
|
-
*
|
|
1189
|
+
* Inputs of any size are transparently chunked into requests of 50 (the server cap)
|
|
1190
|
+
* and merged per extrinsic.
|
|
1144
1191
|
*/
|
|
1145
1192
|
async getTransfersByCommitments(commitments) {
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
commitments
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
`/shielded/transfers/by-commitments${qs}`
|
|
1193
|
+
return this.fetchTransfersChunked(
|
|
1194
|
+
"/shielded/transfers/by-commitments",
|
|
1195
|
+
"commitments",
|
|
1196
|
+
commitments,
|
|
1197
|
+
"matchedCommitments"
|
|
1152
1198
|
);
|
|
1153
|
-
return res.data;
|
|
1154
1199
|
}
|
|
1155
1200
|
// ─── Unshields ─────────────────────────────────────────────────────────────
|
|
1156
1201
|
/** Returns a paginated list of unshield events. */
|