postchain-client 2.1.3 → 2.1.4
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 +8 -0
- package/built/cjs/index.js +55 -24
- package/built/cjs/index.js.map +1 -1
- package/built/esm/index.js +55 -24
- package/built/esm/index.js.map +1 -1
- package/built/src/ICCF/IccfProofTxMaterialBuilder.js +4 -0
- package/built/src/ICCF/IccfProofTxMaterialBuilder.js.map +1 -1
- package/built/src/blockchainClient/errors.d.ts +3 -0
- package/built/src/blockchainClient/errors.js +7 -1
- package/built/src/blockchainClient/errors.js.map +1 -1
- package/built/src/blockchainClient/types.d.ts +4 -0
- package/built/src/blockchainClient/utils.d.ts +3 -1
- package/built/src/blockchainClient/utils.js +44 -23
- package/built/src/blockchainClient/utils.js.map +1 -1
- package/built/test/unit/ICCF/iccfProofMaterialBuilder.test.js +19 -0
- package/built/test/unit/ICCF/iccfProofMaterialBuilder.test.js.map +1 -1
- package/built/test/unit/blockchainClient/util.test.js +53 -0
- package/built/test/unit/blockchainClient/util.test.js.map +1 -1
- package/built/umd/index.js +55 -24
- package/built/umd/index.js.map +1 -1
- package/changelog.md +4 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,6 +43,8 @@ Create a Chromia client instance and configures it according to your needs.
|
|
|
43
43
|
- `settings` (Object): A set of network settings to customize the behavior of the Chromia client.
|
|
44
44
|
- `nodeUrlPool` (Optional): An array of URLs representing the nodes the client will send requests to. Use this if you know the specific nodes that will handle the client requests. These nodes can either be local nodes or belong to the same cluster as the targeted blockchain.
|
|
45
45
|
- `directoryNodeUrlPool` (Optional): An array of URLs representing nodes in the system cluster, where the directory chain is located. The client will automatically discover every node running the targeted application by querying the directory chain. This can be useful when the client needs to automatically adapt to updates to the nodes within the cluster where the blockchain is located."
|
|
46
|
+
- `blockedNodeUrlSubstrings` (Optional): Opt-in node URL filtering. If configured, URLs containing any listed substring are excluded (case-insensitive). By default this is disabled, so existing behavior is unchanged.
|
|
47
|
+
- `nodeUrlFilter` (Optional): Opt-in custom predicate `(url: string) => boolean` used to accept/reject node URLs. If both `blockedNodeUrlSubstrings` and `nodeUrlFilter` are set, a URL is used only when it passes both filters.
|
|
46
48
|
- `blockchainRid` (Optional): Resource Identifier (Rid) of the targeted blockchain. This is a unique identifier for the specific blockchain.
|
|
47
49
|
- `blockchainIid` (Optional): Instance Identifier (Iid) of the targeted blockchain. The directory chain always has Iid 0.
|
|
48
50
|
- `statusPollInterval` (Optional): Interval (in milliseconds) at which the client will poll the status after posting a transaction.
|
|
@@ -54,6 +56,12 @@ Create a Chromia client instance and configures it according to your needs.
|
|
|
54
56
|
- `unreachableDuration` (Optional): Duration (in milliseconds) that an endpoint should remain unreachable before reattempting. Defaults to 30000 ms.
|
|
55
57
|
- `useStickyNode`(Optional): A boolean that will make sure that on succefull requests to a node, the client will continue using this node unless it starts failing.
|
|
56
58
|
|
|
59
|
+
### Optional node URL filtering (opt-in)
|
|
60
|
+
|
|
61
|
+
Node URL filtering is disabled by default for backward compatibility. Existing users do not need to change anything.
|
|
62
|
+
|
|
63
|
+
If you opt in by configuring `blockedNodeUrlSubstrings` and/or `nodeUrlFilter`, filtering is applied consistently to direct node pools, directory node pools, and directory-discovered blockchain API URLs before failover candidates are used.
|
|
64
|
+
|
|
57
65
|
### Returns
|
|
58
66
|
|
|
59
67
|
A promise that resolves to the configured Chromia client instance.
|
package/built/cjs/index.js
CHANGED
|
@@ -1120,7 +1120,7 @@ var utils$1 = {};
|
|
|
1120
1120
|
var errors = {};
|
|
1121
1121
|
|
|
1122
1122
|
Object.defineProperty(errors, "__esModule", { value: true });
|
|
1123
|
-
errors.GetBridFromChainException = errors.SerializedTransactionFormatException = errors.InvalidTxRidException = errors.UnexpectedStatusError = errors.TxRejectedError = errors.GetTransactionRidException = errors.InvalidTransactionFormatException = errors.DirectoryNodeUrlPoolException = errors.BlockchainUrlUndefinedException = errors.MissingNodeUrlError = errors.MissingBlockchainIdentifierError = errors.MissingPubKeyError = void 0;
|
|
1123
|
+
errors.GetBridFromChainException = errors.SerializedTransactionFormatException = errors.InvalidTxRidException = errors.UnexpectedStatusError = errors.TxRejectedError = errors.GetTransactionRidException = errors.InvalidTransactionFormatException = errors.FilteredNodeUrlPoolEmptyError = errors.DirectoryNodeUrlPoolException = errors.BlockchainUrlUndefinedException = errors.MissingNodeUrlError = errors.MissingBlockchainIdentifierError = errors.MissingPubKeyError = void 0;
|
|
1124
1124
|
const customError_1 = customError;
|
|
1125
1125
|
const formatter_1$1 = formatter;
|
|
1126
1126
|
class MissingPubKeyError extends customError_1.CustomError {
|
|
@@ -1154,6 +1154,12 @@ class DirectoryNodeUrlPoolException extends customError_1.CustomError {
|
|
|
1154
1154
|
}
|
|
1155
1155
|
}
|
|
1156
1156
|
errors.DirectoryNodeUrlPoolException = DirectoryNodeUrlPoolException;
|
|
1157
|
+
class FilteredNodeUrlPoolEmptyError extends customError_1.CustomError {
|
|
1158
|
+
constructor(poolName) {
|
|
1159
|
+
super(`All node URLs were filtered out for pool "${poolName}". Update node URL filters or pool configuration.`, 400);
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
errors.FilteredNodeUrlPoolEmptyError = FilteredNodeUrlPoolEmptyError;
|
|
1157
1163
|
class InvalidTransactionFormatException extends customError_1.CustomError {
|
|
1158
1164
|
constructor() {
|
|
1159
1165
|
super(`The transaction is not in the right format`, 400);
|
|
@@ -2481,23 +2487,9 @@ function requireUtils$1 () {
|
|
|
2481
2487
|
responseTimeout: settings.responseTimeout,
|
|
2482
2488
|
});
|
|
2483
2489
|
}))();
|
|
2484
|
-
return {
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
blockchainRid: blockchainRidToUse,
|
|
2488
|
-
merkleHashVersion: (_e = settings.merkleHashVersion) !== null && _e !== void 0 ? _e : constants_1.MERKLE_HASH_VERSIONS.UNSET,
|
|
2489
|
-
dappStatusPolling: setStatusPolling(settings.dappStatusPolling),
|
|
2490
|
-
clusterAnchoringStatusPolling: setStatusPolling(settings.clusterAnchoringStatusPolling),
|
|
2491
|
-
systemAnchoringStatusPolling: setStatusPolling(settings.systemAnchoringStatusPolling),
|
|
2492
|
-
retryTransactionPolling: setRetryTransactionPolling(settings.retryTransactionPolling),
|
|
2493
|
-
failoverStrategy: ((_f = settings.failOverConfig) === null || _f === void 0 ? void 0 : _f.strategy) || exports.defaultFailoverConfig.strategy,
|
|
2494
|
-
attemptsPerEndpoint: ((_g = settings.failOverConfig) === null || _g === void 0 ? void 0 : _g.attemptsPerEndpoint) || exports.defaultFailoverConfig.attemptsPerEndpoint,
|
|
2495
|
-
attemptInterval: ((_h = settings.failOverConfig) === null || _h === void 0 ? void 0 : _h.attemptInterval) || exports.defaultFailoverConfig.attemptInterval,
|
|
2496
|
-
unreachableDuration: ((_j = settings.failOverConfig) === null || _j === void 0 ? void 0 : _j.unreachableDuration) || exports.defaultFailoverConfig.unreachableDuration,
|
|
2497
|
-
directoryChainRid: settings.directoryChainRid || directoryChainRid,
|
|
2498
|
-
connectTimeout: settings.connectTimeout,
|
|
2499
|
-
responseTimeout: settings.responseTimeout,
|
|
2500
|
-
};
|
|
2490
|
+
return Object.assign(Object.assign(Object.assign({ endpointPool, nodeManager: nodeManager }, (settings.blockedNodeUrlSubstrings !== undefined
|
|
2491
|
+
? { blockedNodeUrlSubstrings: settings.blockedNodeUrlSubstrings }
|
|
2492
|
+
: {})), (settings.nodeUrlFilter !== undefined ? { nodeUrlFilter: settings.nodeUrlFilter } : {})), { blockchainRid: blockchainRidToUse, merkleHashVersion: (_e = settings.merkleHashVersion) !== null && _e !== void 0 ? _e : constants_1.MERKLE_HASH_VERSIONS.UNSET, dappStatusPolling: setStatusPolling(settings.dappStatusPolling), clusterAnchoringStatusPolling: setStatusPolling(settings.clusterAnchoringStatusPolling), systemAnchoringStatusPolling: setStatusPolling(settings.systemAnchoringStatusPolling), retryTransactionPolling: setRetryTransactionPolling(settings.retryTransactionPolling), failoverStrategy: ((_f = settings.failOverConfig) === null || _f === void 0 ? void 0 : _f.strategy) || exports.defaultFailoverConfig.strategy, attemptsPerEndpoint: ((_g = settings.failOverConfig) === null || _g === void 0 ? void 0 : _g.attemptsPerEndpoint) || exports.defaultFailoverConfig.attemptsPerEndpoint, attemptInterval: ((_h = settings.failOverConfig) === null || _h === void 0 ? void 0 : _h.attemptInterval) || exports.defaultFailoverConfig.attemptInterval, unreachableDuration: ((_j = settings.failOverConfig) === null || _j === void 0 ? void 0 : _j.unreachableDuration) || exports.defaultFailoverConfig.unreachableDuration, directoryChainRid: settings.directoryChainRid || directoryChainRid, connectTimeout: settings.connectTimeout, responseTimeout: settings.responseTimeout });
|
|
2501
2493
|
});
|
|
2502
2494
|
}
|
|
2503
2495
|
function getMerkleHashVersionFromDapp(config) {
|
|
@@ -2523,7 +2515,7 @@ function requireUtils$1 () {
|
|
|
2523
2515
|
return true;
|
|
2524
2516
|
}
|
|
2525
2517
|
function nodeDiscovery(_a) {
|
|
2526
|
-
return __awaiter(this, arguments, void 0, function* ({ nodeManager, directoryEndpointPool, failOverConfig, blockchainRid, blockchainIid, connectTimeout, responseTimeout, }) {
|
|
2518
|
+
return __awaiter(this, arguments, void 0, function* ({ nodeManager, directoryEndpointPool, blockedNodeUrlSubstrings, nodeUrlFilter, failOverConfig, blockchainRid, blockchainIid, connectTimeout, responseTimeout, }) {
|
|
2527
2519
|
if (directoryEndpointPool.length === 0) {
|
|
2528
2520
|
throw new errors_2.DirectoryNodeUrlPoolException();
|
|
2529
2521
|
}
|
|
@@ -2559,7 +2551,11 @@ function requireUtils$1 () {
|
|
|
2559
2551
|
nodeUrlPool: (0, exports.getUrlsFromEndpoints)(directoryEndpointPool),
|
|
2560
2552
|
blockchainRid: directoryBRID,
|
|
2561
2553
|
});
|
|
2562
|
-
|
|
2554
|
+
const discoveredNodes = yield getBlockchainApiUrls(D1Client, (0, formatter_1.ensureBuffer)(blockchainRidToUse));
|
|
2555
|
+
return applyNodeUrlFilters(discoveredNodes, {
|
|
2556
|
+
blockedNodeUrlSubstrings,
|
|
2557
|
+
nodeUrlFilter,
|
|
2558
|
+
}, "discoveredNodeUrlPool");
|
|
2563
2559
|
});
|
|
2564
2560
|
}
|
|
2565
2561
|
function getBlockchainApiUrls(directoryClient, blockchainRid) {
|
|
@@ -2702,14 +2698,21 @@ function requireUtils$1 () {
|
|
|
2702
2698
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2703
2699
|
var _a;
|
|
2704
2700
|
if (settings.directoryNodeUrlPool) {
|
|
2701
|
+
const directoryNodeUrlsOrNull = applyNodeUrlFilters(ensureArray(settings.directoryNodeUrlPool), settings, "directoryNodeUrlPool");
|
|
2702
|
+
if (directoryNodeUrlsOrNull === null) {
|
|
2703
|
+
throw new errors_2.DirectoryNodeUrlPoolException();
|
|
2704
|
+
}
|
|
2705
|
+
const directoryNodeUrls = directoryNodeUrlsOrNull;
|
|
2705
2706
|
// If directoryNodeUrlPool is provided, use nodeDiscovery
|
|
2706
2707
|
const nodeManager = (0, nodeManager_1.createNodeManager)({
|
|
2707
|
-
nodeUrls:
|
|
2708
|
+
nodeUrls: directoryNodeUrls,
|
|
2708
2709
|
unavailableDuration: (_a = settings.failOverConfig) === null || _a === void 0 ? void 0 : _a.unreachableDuration,
|
|
2709
2710
|
});
|
|
2710
2711
|
const discoveredNodes = yield nodeDiscovery({
|
|
2711
2712
|
nodeManager,
|
|
2712
|
-
directoryEndpointPool: (0, exports.createEndpointObjects)(
|
|
2713
|
+
directoryEndpointPool: (0, exports.createEndpointObjects)(directoryNodeUrls),
|
|
2714
|
+
blockedNodeUrlSubstrings: settings.blockedNodeUrlSubstrings,
|
|
2715
|
+
nodeUrlFilter: settings.nodeUrlFilter,
|
|
2713
2716
|
failOverConfig: settings.failOverConfig,
|
|
2714
2717
|
blockchainRid: settings.blockchainRid,
|
|
2715
2718
|
blockchainIid: settings.blockchainIid,
|
|
@@ -2720,11 +2723,11 @@ function requireUtils$1 () {
|
|
|
2720
2723
|
}
|
|
2721
2724
|
else if (typeof settings.nodeUrlPool === "string") {
|
|
2722
2725
|
// If nodeUrlPool is a string, convert it to an array
|
|
2723
|
-
return [settings.nodeUrlPool];
|
|
2726
|
+
return applyNodeUrlFilters([settings.nodeUrlPool], settings, "nodeUrlPool");
|
|
2724
2727
|
}
|
|
2725
2728
|
else if (Array.isArray(settings.nodeUrlPool)) {
|
|
2726
2729
|
// If nodeUrlPool is already an array, use it as-is
|
|
2727
|
-
return settings.nodeUrlPool;
|
|
2730
|
+
return applyNodeUrlFilters(settings.nodeUrlPool, settings, "nodeUrlPool");
|
|
2728
2731
|
}
|
|
2729
2732
|
else {
|
|
2730
2733
|
// Default to an empty array if no valid configuration is provided
|
|
@@ -2732,6 +2735,30 @@ function requireUtils$1 () {
|
|
|
2732
2735
|
}
|
|
2733
2736
|
});
|
|
2734
2737
|
}
|
|
2738
|
+
function applyNodeUrlFilters(nodeUrls, settings, poolName) {
|
|
2739
|
+
var _a;
|
|
2740
|
+
if (nodeUrls === null) {
|
|
2741
|
+
return null;
|
|
2742
|
+
}
|
|
2743
|
+
const hasBlockedSubstringsFilter = Array.isArray(settings.blockedNodeUrlSubstrings) &&
|
|
2744
|
+
settings.blockedNodeUrlSubstrings.length > 0;
|
|
2745
|
+
const hasNodeUrlFilter = typeof settings.nodeUrlFilter === "function";
|
|
2746
|
+
if (!hasBlockedSubstringsFilter && !hasNodeUrlFilter) {
|
|
2747
|
+
return nodeUrls;
|
|
2748
|
+
}
|
|
2749
|
+
const blockedSubstrings = ((_a = settings.blockedNodeUrlSubstrings) !== null && _a !== void 0 ? _a : [])
|
|
2750
|
+
.map(substring => substring.toLowerCase())
|
|
2751
|
+
.filter(substring => substring.length > 0);
|
|
2752
|
+
const filteredNodeUrls = nodeUrls.filter(url => {
|
|
2753
|
+
const isBlockedBySubstring = blockedSubstrings.some(substring => url.toLowerCase().includes(substring));
|
|
2754
|
+
const passesCustomFilter = settings.nodeUrlFilter ? settings.nodeUrlFilter(url) : true;
|
|
2755
|
+
return !isBlockedBySubstring && passesCustomFilter;
|
|
2756
|
+
});
|
|
2757
|
+
if (filteredNodeUrls.length === 0) {
|
|
2758
|
+
throw new errors_2.FilteredNodeUrlPoolEmptyError(poolName);
|
|
2759
|
+
}
|
|
2760
|
+
return filteredNodeUrls;
|
|
2761
|
+
}
|
|
2735
2762
|
function getSystemClient(directoryNodeUrlPool, directoryChainRid) {
|
|
2736
2763
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2737
2764
|
return yield (0, blockchainClient_1.createClient)({
|
|
@@ -3250,6 +3277,8 @@ function requireIccfProofTxMaterialBuilder () {
|
|
|
3250
3277
|
blockchainRid: (0, formatter_1.ensureString)(sourceBlockchainRid),
|
|
3251
3278
|
merkleHashVersion: merkleHashVersion,
|
|
3252
3279
|
useStickyNode: true,
|
|
3280
|
+
blockedNodeUrlSubstrings: directoryClient.config.blockedNodeUrlSubstrings,
|
|
3281
|
+
nodeUrlFilter: directoryClient.config.nodeUrlFilter,
|
|
3253
3282
|
});
|
|
3254
3283
|
}
|
|
3255
3284
|
else {
|
|
@@ -3258,6 +3287,8 @@ function requireIccfProofTxMaterialBuilder () {
|
|
|
3258
3287
|
blockchainRid: (0, formatter_1.ensureString)(sourceBlockchainRid),
|
|
3259
3288
|
merkleHashVersion: merkleHashVersion,
|
|
3260
3289
|
useStickyNode: true,
|
|
3290
|
+
blockedNodeUrlSubstrings: directoryClient.config.blockedNodeUrlSubstrings,
|
|
3291
|
+
nodeUrlFilter: directoryClient.config.nodeUrlFilter,
|
|
3261
3292
|
});
|
|
3262
3293
|
}
|
|
3263
3294
|
const txProof = yield clientConfiguredToSource.getConfirmationProof(txToProveRid);
|