ton-provider-system 0.1.13 → 0.2.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.cjs +645 -218
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +241 -19
- package/dist/index.d.ts +241 -19
- package/dist/index.js +636 -219
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -554,183 +554,461 @@ function createRegistryFromData(data, logger) {
|
|
|
554
554
|
return new ProviderRegistry(mergedConfig, logger);
|
|
555
555
|
}
|
|
556
556
|
|
|
557
|
-
// src/
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
normalized = normalized.slice(0, -1);
|
|
557
|
+
// src/providers/base.ts
|
|
558
|
+
var BaseProvider = class {
|
|
559
|
+
constructor(provider) {
|
|
560
|
+
this.provider = provider;
|
|
562
561
|
}
|
|
563
|
-
|
|
564
|
-
|
|
562
|
+
/**
|
|
563
|
+
* Get the provider instance
|
|
564
|
+
*/
|
|
565
|
+
getProvider() {
|
|
566
|
+
return this.provider;
|
|
565
567
|
}
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
568
|
+
/**
|
|
569
|
+
* Build a JSON-RPC request body.
|
|
570
|
+
* Most providers use standard JSON-RPC 2.0, but some may need modifications.
|
|
571
|
+
*/
|
|
572
|
+
buildRequest(method, params = {}) {
|
|
573
|
+
return {
|
|
574
|
+
id: "1",
|
|
575
|
+
jsonrpc: "2.0",
|
|
576
|
+
method,
|
|
577
|
+
params
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Parse response from provider.
|
|
582
|
+
* Handles provider-specific response formats.
|
|
583
|
+
*/
|
|
584
|
+
parseResponse(data) {
|
|
585
|
+
if (data && typeof data === "object") {
|
|
586
|
+
const dataObj = data;
|
|
587
|
+
if ("ok" in dataObj) {
|
|
588
|
+
if (!dataObj.ok) {
|
|
589
|
+
const error = dataObj.error;
|
|
590
|
+
throw new Error(error || "API returned ok=false");
|
|
591
|
+
}
|
|
592
|
+
const result = dataObj.result;
|
|
593
|
+
return result || dataObj;
|
|
571
594
|
}
|
|
572
|
-
if (
|
|
573
|
-
return
|
|
595
|
+
if ("result" in dataObj) {
|
|
596
|
+
return dataObj.result;
|
|
574
597
|
}
|
|
575
|
-
|
|
598
|
+
if ("last" in dataObj || "@type" in dataObj) {
|
|
599
|
+
return dataObj;
|
|
600
|
+
}
|
|
601
|
+
if ("error" in dataObj) {
|
|
602
|
+
const errorObj = dataObj.error;
|
|
603
|
+
const errorMsg = typeof errorObj === "string" ? errorObj : errorObj?.message || errorObj?.code || String(errorObj);
|
|
604
|
+
throw new Error(`API error: ${errorMsg}`);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return data;
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Parse masterchain info from response.
|
|
611
|
+
* Validates the response structure and extracts seqno.
|
|
612
|
+
*/
|
|
613
|
+
parseMasterchainInfo(data) {
|
|
614
|
+
const info = this.parseResponse(data);
|
|
615
|
+
if (!info || typeof info !== "object") {
|
|
616
|
+
throw new Error("Invalid response structure");
|
|
617
|
+
}
|
|
618
|
+
const infoObj = info;
|
|
619
|
+
const seqno = infoObj.last?.seqno;
|
|
620
|
+
if (seqno === void 0 || seqno === null || seqno <= 0 || !Number.isInteger(seqno)) {
|
|
621
|
+
throw new Error(`Invalid seqno: ${seqno} (must be positive integer)`);
|
|
622
|
+
}
|
|
623
|
+
return info;
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Validate provider configuration.
|
|
627
|
+
* Checks if required API keys are present, etc.
|
|
628
|
+
*/
|
|
629
|
+
validateConfig() {
|
|
630
|
+
return { valid: true };
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Get the normalized endpoint for this provider.
|
|
634
|
+
*/
|
|
635
|
+
getNormalizedEndpoint() {
|
|
636
|
+
return this.normalizeEndpoint(this.provider.endpointV2);
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Check if this provider requires an API key.
|
|
640
|
+
*/
|
|
641
|
+
requiresApiKey() {
|
|
642
|
+
return false;
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Check if API key is present (if required).
|
|
646
|
+
*/
|
|
647
|
+
hasApiKey() {
|
|
648
|
+
return !!this.provider.apiKey;
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
// src/providers/chainstack.ts
|
|
653
|
+
var ChainstackProvider = class extends BaseProvider {
|
|
654
|
+
constructor(provider) {
|
|
655
|
+
super(provider);
|
|
656
|
+
}
|
|
657
|
+
normalizeEndpoint(endpoint) {
|
|
658
|
+
let normalized = endpoint.trim();
|
|
659
|
+
if (normalized.endsWith("/")) {
|
|
660
|
+
normalized = normalized.slice(0, -1);
|
|
661
|
+
}
|
|
662
|
+
if (normalized.toLowerCase().endsWith("/jsonrpc")) {
|
|
663
|
+
return normalized;
|
|
664
|
+
}
|
|
665
|
+
if (normalized.endsWith("/api/v2")) {
|
|
576
666
|
return normalized + "/jsonRPC";
|
|
577
667
|
}
|
|
668
|
+
if (normalized.endsWith("/api/v3")) {
|
|
669
|
+
return normalized.replace("/api/v3", "/api/v2/jsonRPC");
|
|
670
|
+
}
|
|
671
|
+
return normalized;
|
|
578
672
|
}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
673
|
+
buildHeaders() {
|
|
674
|
+
return {
|
|
675
|
+
"Content-Type": "application/json"
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
validateConfig() {
|
|
679
|
+
if (this.provider.endpointV2.includes("{key}")) {
|
|
680
|
+
return {
|
|
681
|
+
valid: false,
|
|
682
|
+
error: "Chainstack API key not resolved in endpoint URL"
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
return { valid: true };
|
|
686
|
+
}
|
|
687
|
+
};
|
|
688
|
+
|
|
689
|
+
// src/providers/tatum.ts
|
|
690
|
+
var TatumProvider = class extends BaseProvider {
|
|
691
|
+
constructor(provider) {
|
|
692
|
+
super(provider);
|
|
693
|
+
}
|
|
694
|
+
normalizeEndpoint(endpoint) {
|
|
695
|
+
let normalized = endpoint.trim();
|
|
696
|
+
if (normalized.endsWith("/")) {
|
|
697
|
+
normalized = normalized.slice(0, -1);
|
|
698
|
+
}
|
|
699
|
+
if (normalized.toLowerCase().endsWith("/jsonrpc")) {
|
|
700
|
+
return normalized;
|
|
701
|
+
}
|
|
702
|
+
if (normalized.includes("gateway.tatum.io")) {
|
|
703
|
+
try {
|
|
704
|
+
const url = new URL(normalized);
|
|
705
|
+
if (!url.pathname || url.pathname === "/") {
|
|
706
|
+
return normalized + "/jsonRPC";
|
|
587
707
|
}
|
|
588
|
-
|
|
708
|
+
if (!url.pathname.toLowerCase().endsWith("/jsonrpc")) {
|
|
709
|
+
return normalized + "/jsonRPC";
|
|
710
|
+
}
|
|
711
|
+
} catch {
|
|
712
|
+
return normalized + "/jsonRPC";
|
|
589
713
|
}
|
|
590
|
-
|
|
714
|
+
}
|
|
715
|
+
return normalized;
|
|
716
|
+
}
|
|
717
|
+
buildHeaders() {
|
|
718
|
+
const headers = {
|
|
719
|
+
"Content-Type": "application/json"
|
|
720
|
+
};
|
|
721
|
+
if (this.provider.apiKey) {
|
|
722
|
+
headers["x-api-key"] = this.provider.apiKey;
|
|
723
|
+
}
|
|
724
|
+
return headers;
|
|
725
|
+
}
|
|
726
|
+
requiresApiKey() {
|
|
727
|
+
return true;
|
|
728
|
+
}
|
|
729
|
+
validateConfig() {
|
|
730
|
+
if (!this.provider.apiKey) {
|
|
731
|
+
return {
|
|
732
|
+
valid: false,
|
|
733
|
+
error: "Tatum provider requires API key (set TATUM_API_KEY_TESTNET or TATUM_API_KEY_MAINNET)"
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
return { valid: true };
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
|
|
740
|
+
// src/providers/onfinality.ts
|
|
741
|
+
var OnFinalityProvider = class extends BaseProvider {
|
|
742
|
+
constructor(provider) {
|
|
743
|
+
super(provider);
|
|
744
|
+
}
|
|
745
|
+
normalizeEndpoint(endpoint) {
|
|
746
|
+
let normalized = endpoint.trim();
|
|
747
|
+
if (normalized.endsWith("/")) {
|
|
748
|
+
normalized = normalized.slice(0, -1);
|
|
749
|
+
}
|
|
750
|
+
if (normalized.includes("onfinality.io")) {
|
|
751
|
+
try {
|
|
752
|
+
const url = new URL(normalized);
|
|
753
|
+
const baseUrl = normalized.split("?")[0];
|
|
754
|
+
if (!url.pathname || url.pathname === "/") {
|
|
755
|
+
if (this.provider.apiKey) {
|
|
756
|
+
return baseUrl.replace(/\/?$/, "/rpc");
|
|
757
|
+
}
|
|
758
|
+
return baseUrl.replace(/\/?$/, "/public");
|
|
759
|
+
}
|
|
760
|
+
if (url.pathname === "/rpc" || url.pathname === "/public") {
|
|
761
|
+
return baseUrl;
|
|
762
|
+
}
|
|
591
763
|
return baseUrl;
|
|
764
|
+
} catch {
|
|
765
|
+
if (normalized.includes("{key}")) {
|
|
766
|
+
return normalized.split("?")[0].replace(/\/?$/, "/public");
|
|
767
|
+
}
|
|
768
|
+
if (!normalized.includes("/rpc") && !normalized.includes("/public")) {
|
|
769
|
+
return normalized.split("?")[0] + "/public";
|
|
770
|
+
}
|
|
771
|
+
return normalized.split("?")[0];
|
|
592
772
|
}
|
|
593
|
-
return baseUrl;
|
|
594
|
-
} catch {
|
|
595
|
-
if (normalized.includes("{key}")) {
|
|
596
|
-
return normalized.split("?")[0].replace(/\/?$/, "/public");
|
|
597
|
-
}
|
|
598
|
-
if (!normalized.includes("/rpc") && !normalized.includes("/public")) {
|
|
599
|
-
return normalized.split("?")[0] + "/public";
|
|
600
|
-
}
|
|
601
|
-
return normalized.split("?")[0];
|
|
602
773
|
}
|
|
774
|
+
return normalized;
|
|
603
775
|
}
|
|
604
|
-
|
|
605
|
-
|
|
776
|
+
buildHeaders() {
|
|
777
|
+
const headers = {
|
|
778
|
+
"Content-Type": "application/json"
|
|
779
|
+
};
|
|
780
|
+
if (this.provider.apiKey) {
|
|
781
|
+
headers["apikey"] = this.provider.apiKey;
|
|
782
|
+
}
|
|
783
|
+
return headers;
|
|
606
784
|
}
|
|
607
|
-
|
|
608
|
-
|
|
785
|
+
parseResponse(data) {
|
|
786
|
+
if (typeof data === "string") {
|
|
787
|
+
if (data.includes("Backend error") || data.includes("backend error")) {
|
|
788
|
+
throw new Error(`OnFinality backend error: ${data}`);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
return super.parseResponse(data);
|
|
609
792
|
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
793
|
+
};
|
|
794
|
+
|
|
795
|
+
// src/providers/quicknode.ts
|
|
796
|
+
var QuickNodeProvider = class extends BaseProvider {
|
|
797
|
+
constructor(provider) {
|
|
798
|
+
super(provider);
|
|
799
|
+
}
|
|
800
|
+
normalizeEndpoint(endpoint) {
|
|
801
|
+
let normalized = endpoint.trim();
|
|
802
|
+
if (normalized.endsWith("/")) {
|
|
803
|
+
normalized = normalized.slice(0, -1);
|
|
804
|
+
}
|
|
805
|
+
if (normalized.toLowerCase().endsWith("/jsonrpc")) {
|
|
806
|
+
return normalized;
|
|
807
|
+
}
|
|
808
|
+
if (normalized.includes("quiknode.pro")) {
|
|
809
|
+
try {
|
|
810
|
+
const url = new URL(normalized);
|
|
811
|
+
if (!url.pathname || url.pathname === "/") {
|
|
812
|
+
return normalized + "/jsonRPC";
|
|
813
|
+
}
|
|
814
|
+
if (!url.pathname.toLowerCase().endsWith("/jsonrpc")) {
|
|
815
|
+
return normalized + "/jsonRPC";
|
|
816
|
+
}
|
|
817
|
+
} catch {
|
|
614
818
|
return normalized + "/jsonRPC";
|
|
615
819
|
}
|
|
616
|
-
|
|
820
|
+
}
|
|
821
|
+
return normalized;
|
|
822
|
+
}
|
|
823
|
+
buildHeaders() {
|
|
824
|
+
return {
|
|
825
|
+
"Content-Type": "application/json"
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
validateConfig() {
|
|
829
|
+
if (this.provider.endpointV2.includes("{key}")) {
|
|
830
|
+
return {
|
|
831
|
+
valid: false,
|
|
832
|
+
error: "QuickNode API key not resolved in endpoint URL"
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
return { valid: true };
|
|
836
|
+
}
|
|
837
|
+
};
|
|
838
|
+
|
|
839
|
+
// src/providers/getblock.ts
|
|
840
|
+
var GetBlockProvider = class extends BaseProvider {
|
|
841
|
+
constructor(provider) {
|
|
842
|
+
super(provider);
|
|
843
|
+
}
|
|
844
|
+
normalizeEndpoint(endpoint) {
|
|
845
|
+
let normalized = endpoint.trim();
|
|
846
|
+
if (normalized.endsWith("/")) {
|
|
847
|
+
normalized = normalized.slice(0, -1);
|
|
848
|
+
}
|
|
849
|
+
if (normalized.toLowerCase().endsWith("/jsonrpc")) {
|
|
850
|
+
return normalized;
|
|
851
|
+
}
|
|
852
|
+
if (normalized.includes("getblock.io")) {
|
|
853
|
+
try {
|
|
854
|
+
const url = new URL(normalized);
|
|
855
|
+
if (!url.pathname || url.pathname === "/") {
|
|
856
|
+
return normalized + "/jsonRPC";
|
|
857
|
+
}
|
|
858
|
+
if (!url.pathname.toLowerCase().endsWith("/jsonrpc")) {
|
|
859
|
+
return normalized + "/jsonRPC";
|
|
860
|
+
}
|
|
861
|
+
} catch {
|
|
617
862
|
return normalized + "/jsonRPC";
|
|
618
863
|
}
|
|
619
|
-
} catch {
|
|
620
|
-
return normalized + "/jsonRPC";
|
|
621
864
|
}
|
|
865
|
+
return normalized;
|
|
622
866
|
}
|
|
623
|
-
|
|
624
|
-
const
|
|
625
|
-
|
|
626
|
-
|
|
867
|
+
buildHeaders() {
|
|
868
|
+
const headers = {
|
|
869
|
+
"Content-Type": "application/json"
|
|
870
|
+
};
|
|
871
|
+
if (this.provider.apiKey) {
|
|
872
|
+
headers["x-api-key"] = this.provider.apiKey;
|
|
627
873
|
}
|
|
628
|
-
|
|
629
|
-
}
|
|
630
|
-
return normalized;
|
|
631
|
-
}
|
|
632
|
-
function toV2Base(endpoint) {
|
|
633
|
-
let normalized = endpoint.trim();
|
|
634
|
-
if (normalized.endsWith("/")) {
|
|
635
|
-
normalized = normalized.slice(0, -1);
|
|
874
|
+
return headers;
|
|
636
875
|
}
|
|
637
|
-
|
|
638
|
-
|
|
876
|
+
requiresApiKey() {
|
|
877
|
+
return true;
|
|
639
878
|
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
879
|
+
validateConfig() {
|
|
880
|
+
if (!this.provider.apiKey) {
|
|
881
|
+
return {
|
|
882
|
+
valid: false,
|
|
883
|
+
error: "GetBlock provider requires API key"
|
|
884
|
+
};
|
|
645
885
|
}
|
|
886
|
+
return { valid: true };
|
|
646
887
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
function getBaseUrl(endpoint) {
|
|
654
|
-
try {
|
|
655
|
-
const url = new URL(endpoint);
|
|
656
|
-
return `${url.protocol}//${url.host}`;
|
|
657
|
-
} catch {
|
|
658
|
-
return endpoint;
|
|
888
|
+
};
|
|
889
|
+
|
|
890
|
+
// src/providers/toncenter.ts
|
|
891
|
+
var TonCenterProvider = class extends BaseProvider {
|
|
892
|
+
constructor(provider) {
|
|
893
|
+
super(provider);
|
|
659
894
|
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
895
|
+
normalizeEndpoint(endpoint) {
|
|
896
|
+
let normalized = endpoint.trim();
|
|
897
|
+
if (normalized.endsWith("/")) {
|
|
898
|
+
normalized = normalized.slice(0, -1);
|
|
899
|
+
}
|
|
900
|
+
if (normalized.toLowerCase().endsWith("/jsonrpc")) {
|
|
901
|
+
return normalized;
|
|
902
|
+
}
|
|
903
|
+
if (normalized.endsWith("/api/v2")) {
|
|
904
|
+
return normalized + "/jsonRPC";
|
|
905
|
+
}
|
|
906
|
+
if (normalized.endsWith("/api/v3")) {
|
|
907
|
+
return normalized.replace("/api/v3", "/api/v2/jsonRPC");
|
|
908
|
+
}
|
|
909
|
+
return normalized;
|
|
667
910
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
return parsed.hostname.includes("quiknode.pro");
|
|
673
|
-
} catch {
|
|
674
|
-
return false;
|
|
911
|
+
buildHeaders() {
|
|
912
|
+
return {
|
|
913
|
+
"Content-Type": "application/json"
|
|
914
|
+
};
|
|
675
915
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
try {
|
|
679
|
-
const parsed = new URL(url.trim());
|
|
680
|
-
return parsed.hostname.includes("toncenter.com");
|
|
681
|
-
} catch {
|
|
916
|
+
// TON Center API key is optional (1 RPS without key, 10 RPS with key)
|
|
917
|
+
requiresApiKey() {
|
|
682
918
|
return false;
|
|
683
919
|
}
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
return false;
|
|
920
|
+
};
|
|
921
|
+
|
|
922
|
+
// src/providers/orbs.ts
|
|
923
|
+
var OrbsProvider = class extends BaseProvider {
|
|
924
|
+
constructor(provider) {
|
|
925
|
+
super(provider);
|
|
691
926
|
}
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
const base = toV2Base(baseEndpoint);
|
|
707
|
-
return `${base}/getAddressInformation?address=${encodeURIComponent(address)}`;
|
|
708
|
-
}
|
|
709
|
-
function detectNetworkFromEndpoint(endpoint) {
|
|
710
|
-
const lower = endpoint.toLowerCase();
|
|
711
|
-
if (lower.includes("testnet") || lower.includes("test") || lower.includes("sandbox")) {
|
|
712
|
-
return "testnet";
|
|
927
|
+
normalizeEndpoint(endpoint) {
|
|
928
|
+
let normalized = endpoint.trim();
|
|
929
|
+
if (normalized.endsWith("/")) {
|
|
930
|
+
normalized = normalized.slice(0, -1);
|
|
931
|
+
}
|
|
932
|
+
if (normalized.endsWith("/api/v2")) {
|
|
933
|
+
return normalized;
|
|
934
|
+
}
|
|
935
|
+
return normalized;
|
|
936
|
+
}
|
|
937
|
+
buildHeaders() {
|
|
938
|
+
return {
|
|
939
|
+
"Content-Type": "application/json"
|
|
940
|
+
};
|
|
713
941
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
942
|
+
/**
|
|
943
|
+
* Get dynamic endpoint from Orbs TON Access.
|
|
944
|
+
* This should be called before making requests.
|
|
945
|
+
*/
|
|
946
|
+
async getDynamicEndpoint() {
|
|
947
|
+
if (!this.provider.isDynamic) {
|
|
948
|
+
return this.normalizeEndpoint(this.provider.endpointV2);
|
|
949
|
+
}
|
|
950
|
+
try {
|
|
951
|
+
const { getHttpEndpoint } = await import('@orbs-network/ton-access');
|
|
952
|
+
const endpoint = await getHttpEndpoint({ network: this.provider.network });
|
|
953
|
+
return this.normalizeEndpoint(endpoint);
|
|
954
|
+
} catch (error) {
|
|
955
|
+
return this.normalizeEndpoint(this.provider.endpointV2);
|
|
956
|
+
}
|
|
717
957
|
}
|
|
718
|
-
|
|
719
|
-
}
|
|
720
|
-
function isValidHttpUrl(str) {
|
|
721
|
-
try {
|
|
722
|
-
const url = new URL(str);
|
|
723
|
-
return url.protocol === "http:" || url.protocol === "https:";
|
|
724
|
-
} catch {
|
|
958
|
+
requiresApiKey() {
|
|
725
959
|
return false;
|
|
726
960
|
}
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
961
|
+
};
|
|
962
|
+
|
|
963
|
+
// src/providers/index.ts
|
|
964
|
+
var GenericProvider = class extends BaseProvider {
|
|
965
|
+
normalizeEndpoint(endpoint) {
|
|
966
|
+
let normalized = endpoint.trim();
|
|
967
|
+
if (normalized.endsWith("/")) {
|
|
968
|
+
normalized = normalized.slice(0, -1);
|
|
969
|
+
}
|
|
970
|
+
if (normalized.toLowerCase().endsWith("/jsonrpc")) {
|
|
971
|
+
return normalized;
|
|
972
|
+
}
|
|
973
|
+
try {
|
|
974
|
+
const url = new URL(normalized);
|
|
975
|
+
if (!url.pathname || url.pathname === "/") {
|
|
976
|
+
return normalized + "/jsonRPC";
|
|
977
|
+
}
|
|
978
|
+
} catch {
|
|
979
|
+
}
|
|
980
|
+
return normalized;
|
|
981
|
+
}
|
|
982
|
+
buildHeaders() {
|
|
983
|
+
const headers = {
|
|
984
|
+
"Content-Type": "application/json"
|
|
985
|
+
};
|
|
986
|
+
if (this.provider.apiKey) {
|
|
987
|
+
headers["x-api-key"] = this.provider.apiKey;
|
|
988
|
+
}
|
|
989
|
+
return headers;
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
function createProvider(provider) {
|
|
993
|
+
switch (provider.type) {
|
|
994
|
+
case "chainstack":
|
|
995
|
+
return new ChainstackProvider(provider);
|
|
996
|
+
case "tatum":
|
|
997
|
+
return new TatumProvider(provider);
|
|
998
|
+
case "onfinality":
|
|
999
|
+
return new OnFinalityProvider(provider);
|
|
1000
|
+
case "quicknode":
|
|
1001
|
+
return new QuickNodeProvider(provider);
|
|
1002
|
+
case "getblock":
|
|
1003
|
+
return new GetBlockProvider(provider);
|
|
1004
|
+
case "toncenter":
|
|
1005
|
+
return new TonCenterProvider(provider);
|
|
1006
|
+
case "orbs":
|
|
1007
|
+
return new OrbsProvider(provider);
|
|
1008
|
+
case "custom":
|
|
1009
|
+
return new GenericProvider(provider);
|
|
1010
|
+
default:
|
|
1011
|
+
return new GenericProvider(provider);
|
|
734
1012
|
}
|
|
735
1013
|
}
|
|
736
1014
|
|
|
@@ -790,21 +1068,25 @@ var HealthChecker = class {
|
|
|
790
1068
|
if (!endpoint) {
|
|
791
1069
|
throw new Error("No valid endpoint available");
|
|
792
1070
|
}
|
|
793
|
-
|
|
794
|
-
|
|
1071
|
+
const providerImpl = createProvider(provider);
|
|
1072
|
+
const validation = providerImpl.validateConfig();
|
|
1073
|
+
if (!validation.valid) {
|
|
1074
|
+
throw new Error(validation.error || "Provider configuration invalid");
|
|
795
1075
|
}
|
|
796
|
-
|
|
1076
|
+
const normalizedEndpoint = providerImpl.normalizeEndpoint(endpoint);
|
|
797
1077
|
if (provider.type === "onfinality") {
|
|
798
1078
|
this.logger.debug(`OnFinality endpoint: ${endpoint} -> ${normalizedEndpoint}, API key: ${provider.apiKey ? "set" : "not set"}`);
|
|
799
1079
|
}
|
|
800
1080
|
let info;
|
|
801
1081
|
try {
|
|
802
|
-
info = await this.callGetMasterchainInfo(normalizedEndpoint, provider);
|
|
1082
|
+
info = await this.callGetMasterchainInfo(normalizedEndpoint, provider, providerImpl);
|
|
803
1083
|
} catch (error) {
|
|
804
1084
|
if (provider.type === "onfinality" && normalizedEndpoint.includes("/rpc") && provider.apiKey && error.message?.includes("backend error")) {
|
|
805
1085
|
this.logger.debug(`OnFinality /rpc failed, retrying with /public endpoint`);
|
|
806
1086
|
const publicEndpoint = normalizedEndpoint.replace("/rpc", "/public");
|
|
807
|
-
|
|
1087
|
+
const publicProvider = { ...provider, apiKey: void 0 };
|
|
1088
|
+
const publicProviderImpl = createProvider(publicProvider);
|
|
1089
|
+
info = await this.callGetMasterchainInfo(publicEndpoint, publicProvider, publicProviderImpl);
|
|
808
1090
|
} else {
|
|
809
1091
|
throw error;
|
|
810
1092
|
}
|
|
@@ -950,14 +1232,17 @@ var HealthChecker = class {
|
|
|
950
1232
|
}
|
|
951
1233
|
/**
|
|
952
1234
|
* Mark a provider as degraded (e.g., on 429 error)
|
|
1235
|
+
*
|
|
1236
|
+
* Providers marked as degraded have failed health checks (e.g., rate limit errors)
|
|
1237
|
+
* and should not be selected. The system will failover to the next available provider.
|
|
953
1238
|
*/
|
|
954
1239
|
markDegraded(providerId, network, error) {
|
|
955
1240
|
const key = this.getResultKey(providerId, network);
|
|
956
1241
|
const existing = this.results.get(key);
|
|
957
1242
|
const result = existing ? {
|
|
958
1243
|
...existing,
|
|
959
|
-
success:
|
|
960
|
-
// Degraded providers
|
|
1244
|
+
success: false,
|
|
1245
|
+
// Degraded providers with errors should not be selected
|
|
961
1246
|
status: "degraded",
|
|
962
1247
|
error: error || "Marked as degraded",
|
|
963
1248
|
lastTested: /* @__PURE__ */ new Date(),
|
|
@@ -965,8 +1250,8 @@ var HealthChecker = class {
|
|
|
965
1250
|
} : {
|
|
966
1251
|
id: providerId,
|
|
967
1252
|
network,
|
|
968
|
-
success:
|
|
969
|
-
// Degraded providers
|
|
1253
|
+
success: false,
|
|
1254
|
+
// Degraded providers with errors should not be selected
|
|
970
1255
|
status: "degraded",
|
|
971
1256
|
latencyMs: null,
|
|
972
1257
|
seqno: null,
|
|
@@ -1029,44 +1314,19 @@ var HealthChecker = class {
|
|
|
1029
1314
|
}
|
|
1030
1315
|
return provider.endpointV2 || provider.endpointV3 || null;
|
|
1031
1316
|
}
|
|
1032
|
-
/**
|
|
1033
|
-
* Normalize endpoint for provider-specific requirements
|
|
1034
|
-
*
|
|
1035
|
-
* Note: normalizeV2Endpoint now handles all provider-specific cases correctly,
|
|
1036
|
-
* including Tatum (/jsonRPC), OnFinality (/public or /rpc), QuickNode, and GetBlock.
|
|
1037
|
-
*/
|
|
1038
|
-
normalizeEndpointForProvider(provider, endpoint) {
|
|
1039
|
-
if (provider.type === "tatum" && endpoint.includes("api.tatum.io/v3/blockchain/node")) {
|
|
1040
|
-
const network = provider.network === "testnet" ? "testnet" : "mainnet";
|
|
1041
|
-
endpoint = `https://ton-${network}.gateway.tatum.io`;
|
|
1042
|
-
}
|
|
1043
|
-
return normalizeV2Endpoint(endpoint);
|
|
1044
|
-
}
|
|
1045
1317
|
/**
|
|
1046
1318
|
* Call getMasterchainInfo API with provider-specific handling
|
|
1047
1319
|
*/
|
|
1048
|
-
async callGetMasterchainInfo(endpoint, provider) {
|
|
1320
|
+
async callGetMasterchainInfo(endpoint, provider, providerImpl) {
|
|
1049
1321
|
const controller = new AbortController();
|
|
1050
1322
|
const timeoutId = setTimeout(() => controller.abort(), this.config.timeoutMs);
|
|
1051
|
-
const headers =
|
|
1052
|
-
|
|
1053
|
-
};
|
|
1054
|
-
if (provider.type === "tatum" && provider.apiKey) {
|
|
1055
|
-
headers["x-api-key"] = provider.apiKey;
|
|
1056
|
-
}
|
|
1057
|
-
if (provider.type === "onfinality" && provider.apiKey) {
|
|
1058
|
-
headers["apikey"] = provider.apiKey;
|
|
1059
|
-
}
|
|
1323
|
+
const headers = providerImpl.buildHeaders();
|
|
1324
|
+
const requestBody = providerImpl.buildRequest("getMasterchainInfo", {});
|
|
1060
1325
|
try {
|
|
1061
1326
|
const response = await fetch(endpoint, {
|
|
1062
1327
|
method: "POST",
|
|
1063
1328
|
headers,
|
|
1064
|
-
body: JSON.stringify(
|
|
1065
|
-
id: "1",
|
|
1066
|
-
jsonrpc: "2.0",
|
|
1067
|
-
method: "getMasterchainInfo",
|
|
1068
|
-
params: {}
|
|
1069
|
-
}),
|
|
1329
|
+
body: JSON.stringify(requestBody),
|
|
1070
1330
|
signal: controller.signal
|
|
1071
1331
|
});
|
|
1072
1332
|
clearTimeout(timeoutId);
|
|
@@ -1092,40 +1352,7 @@ var HealthChecker = class {
|
|
|
1092
1352
|
}
|
|
1093
1353
|
}
|
|
1094
1354
|
data = await response.json();
|
|
1095
|
-
|
|
1096
|
-
if (data && typeof data === "object") {
|
|
1097
|
-
const dataObj = data;
|
|
1098
|
-
if ("ok" in dataObj) {
|
|
1099
|
-
if (!dataObj.ok) {
|
|
1100
|
-
const error = dataObj.error;
|
|
1101
|
-
throw new Error(error || "API returned ok=false");
|
|
1102
|
-
}
|
|
1103
|
-
const result = dataObj.result;
|
|
1104
|
-
info = result || dataObj;
|
|
1105
|
-
} else if ("result" in dataObj) {
|
|
1106
|
-
info = dataObj.result;
|
|
1107
|
-
} else if ("last" in dataObj || "@type" in dataObj) {
|
|
1108
|
-
info = dataObj;
|
|
1109
|
-
} else if ("error" in dataObj) {
|
|
1110
|
-
const errorObj = dataObj.error;
|
|
1111
|
-
const errorMsg = typeof errorObj === "string" ? errorObj : errorObj?.message || errorObj?.code || String(errorObj);
|
|
1112
|
-
throw new Error(`API error: ${errorMsg}`);
|
|
1113
|
-
} else {
|
|
1114
|
-
throw new Error(`Unknown response format from ${provider.type}`);
|
|
1115
|
-
}
|
|
1116
|
-
} else {
|
|
1117
|
-
throw new Error(`Invalid response type: ${typeof data}`);
|
|
1118
|
-
}
|
|
1119
|
-
if (!info || typeof info !== "object") {
|
|
1120
|
-
this.logger.debug(`Invalid response structure from ${provider.type}: ${JSON.stringify(data)}`);
|
|
1121
|
-
throw new Error("Invalid response structure");
|
|
1122
|
-
}
|
|
1123
|
-
const infoObj = info;
|
|
1124
|
-
const seqno = infoObj.last?.seqno;
|
|
1125
|
-
if (seqno === void 0 || seqno === null || seqno <= 0 || !Number.isInteger(seqno)) {
|
|
1126
|
-
this.logger.debug(`Invalid seqno from ${provider.type}:`, { seqno, info });
|
|
1127
|
-
throw new Error(`Invalid seqno: ${seqno} (must be positive integer)`);
|
|
1128
|
-
}
|
|
1355
|
+
const info = providerImpl.parseMasterchainInfo(data);
|
|
1129
1356
|
return info;
|
|
1130
1357
|
} catch (error) {
|
|
1131
1358
|
clearTimeout(timeoutId);
|
|
@@ -1985,6 +2212,193 @@ function createSelector(registry, healthChecker, config, logger, adapter = "node
|
|
|
1985
2212
|
return new ProviderSelector(registry, healthChecker, config, logger, adapter);
|
|
1986
2213
|
}
|
|
1987
2214
|
|
|
2215
|
+
// src/utils/endpoint.ts
|
|
2216
|
+
function normalizeV2Endpoint(endpoint, provider) {
|
|
2217
|
+
if (provider) {
|
|
2218
|
+
const providerImpl = createProvider(provider);
|
|
2219
|
+
return providerImpl.normalizeEndpoint(endpoint);
|
|
2220
|
+
}
|
|
2221
|
+
return normalizeV2EndpointFallback(endpoint);
|
|
2222
|
+
}
|
|
2223
|
+
function normalizeV2EndpointFallback(endpoint) {
|
|
2224
|
+
let normalized = endpoint.trim();
|
|
2225
|
+
if (normalized.endsWith("/")) {
|
|
2226
|
+
normalized = normalized.slice(0, -1);
|
|
2227
|
+
}
|
|
2228
|
+
if (normalized.toLowerCase().endsWith("/jsonrpc")) {
|
|
2229
|
+
return normalized;
|
|
2230
|
+
}
|
|
2231
|
+
if (normalized.includes("gateway.tatum.io")) {
|
|
2232
|
+
try {
|
|
2233
|
+
const url = new URL(normalized);
|
|
2234
|
+
if (!url.pathname || url.pathname === "/") {
|
|
2235
|
+
return normalized + "/jsonRPC";
|
|
2236
|
+
}
|
|
2237
|
+
if (!url.pathname.toLowerCase().endsWith("/jsonrpc")) {
|
|
2238
|
+
return normalized + "/jsonRPC";
|
|
2239
|
+
}
|
|
2240
|
+
} catch {
|
|
2241
|
+
return normalized + "/jsonRPC";
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
if (normalized.includes("onfinality.io")) {
|
|
2245
|
+
try {
|
|
2246
|
+
const url = new URL(normalized);
|
|
2247
|
+
const baseUrl = normalized.split("?")[0];
|
|
2248
|
+
if (!url.pathname || url.pathname === "/") {
|
|
2249
|
+
const apikey = url.searchParams.get("apikey");
|
|
2250
|
+
if (apikey && apikey !== "{key}" && apikey.length > 0) {
|
|
2251
|
+
return baseUrl.replace(/\/?$/, "/rpc");
|
|
2252
|
+
}
|
|
2253
|
+
return baseUrl.replace(/\/?$/, "/public");
|
|
2254
|
+
}
|
|
2255
|
+
if (url.pathname === "/rpc" || url.pathname === "/public") {
|
|
2256
|
+
return baseUrl;
|
|
2257
|
+
}
|
|
2258
|
+
return baseUrl;
|
|
2259
|
+
} catch {
|
|
2260
|
+
if (normalized.includes("{key}")) {
|
|
2261
|
+
return normalized.split("?")[0].replace(/\/?$/, "/public");
|
|
2262
|
+
}
|
|
2263
|
+
if (!normalized.includes("/rpc") && !normalized.includes("/public")) {
|
|
2264
|
+
return normalized.split("?")[0] + "/public";
|
|
2265
|
+
}
|
|
2266
|
+
return normalized.split("?")[0];
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
if (normalized.endsWith("/api/v2")) {
|
|
2270
|
+
return normalized + "/jsonRPC";
|
|
2271
|
+
}
|
|
2272
|
+
if (normalized.endsWith("/api/v3")) {
|
|
2273
|
+
return normalized.replace("/api/v3", "/api/v2/jsonRPC");
|
|
2274
|
+
}
|
|
2275
|
+
if (normalized.includes("quiknode.pro") || normalized.includes("getblock.io")) {
|
|
2276
|
+
try {
|
|
2277
|
+
const url = new URL(normalized);
|
|
2278
|
+
if (!url.pathname || url.pathname === "/") {
|
|
2279
|
+
return normalized + "/jsonRPC";
|
|
2280
|
+
}
|
|
2281
|
+
if (!url.pathname.toLowerCase().endsWith("/jsonrpc")) {
|
|
2282
|
+
return normalized + "/jsonRPC";
|
|
2283
|
+
}
|
|
2284
|
+
} catch {
|
|
2285
|
+
return normalized + "/jsonRPC";
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
try {
|
|
2289
|
+
const url = new URL(normalized);
|
|
2290
|
+
if (!url.pathname || url.pathname === "/") {
|
|
2291
|
+
return normalized + "/jsonRPC";
|
|
2292
|
+
}
|
|
2293
|
+
} catch {
|
|
2294
|
+
}
|
|
2295
|
+
return normalized;
|
|
2296
|
+
}
|
|
2297
|
+
function toV2Base(endpoint) {
|
|
2298
|
+
let normalized = endpoint.trim();
|
|
2299
|
+
if (normalized.endsWith("/")) {
|
|
2300
|
+
normalized = normalized.slice(0, -1);
|
|
2301
|
+
}
|
|
2302
|
+
if (normalized.toLowerCase().endsWith("/jsonrpc")) {
|
|
2303
|
+
normalized = normalized.slice(0, -8);
|
|
2304
|
+
}
|
|
2305
|
+
normalized = normalized.replace(/\/api\/v3\b/, "/api/v2");
|
|
2306
|
+
if (!normalized.endsWith("/api/v2")) {
|
|
2307
|
+
if (normalized.includes("/api/v2")) {
|
|
2308
|
+
const idx = normalized.indexOf("/api/v2");
|
|
2309
|
+
normalized = normalized.slice(0, idx + 7);
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
return normalized;
|
|
2313
|
+
}
|
|
2314
|
+
function toV3Base(endpoint) {
|
|
2315
|
+
const normalized = toV2Base(endpoint);
|
|
2316
|
+
return normalized.replace("/api/v2", "/api/v3");
|
|
2317
|
+
}
|
|
2318
|
+
function getBaseUrl(endpoint) {
|
|
2319
|
+
try {
|
|
2320
|
+
const url = new URL(endpoint);
|
|
2321
|
+
return `${url.protocol}//${url.host}`;
|
|
2322
|
+
} catch {
|
|
2323
|
+
return endpoint;
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
function isChainstackUrl(url) {
|
|
2327
|
+
try {
|
|
2328
|
+
const parsed = new URL(url.trim());
|
|
2329
|
+
return parsed.hostname.includes("chainstack.com");
|
|
2330
|
+
} catch {
|
|
2331
|
+
return false;
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
function isQuickNodeUrl(url) {
|
|
2335
|
+
try {
|
|
2336
|
+
const parsed = new URL(url.trim());
|
|
2337
|
+
return parsed.hostname.includes("quiknode.pro");
|
|
2338
|
+
} catch {
|
|
2339
|
+
return false;
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
function isTonCenterUrl(url) {
|
|
2343
|
+
try {
|
|
2344
|
+
const parsed = new URL(url.trim());
|
|
2345
|
+
return parsed.hostname.includes("toncenter.com");
|
|
2346
|
+
} catch {
|
|
2347
|
+
return false;
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
function isOrbsUrl(url) {
|
|
2351
|
+
try {
|
|
2352
|
+
const parsed = new URL(url.trim());
|
|
2353
|
+
return parsed.hostname.includes("orbs.network") || parsed.hostname.includes("ton-access");
|
|
2354
|
+
} catch {
|
|
2355
|
+
return false;
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
function buildRestUrl(baseEndpoint, method) {
|
|
2359
|
+
const base = toV2Base(baseEndpoint);
|
|
2360
|
+
return `${base}/${method}`;
|
|
2361
|
+
}
|
|
2362
|
+
function buildGetAddressStateUrl(baseEndpoint, address) {
|
|
2363
|
+
const base = toV2Base(baseEndpoint);
|
|
2364
|
+
return `${base}/getAddressState?address=${encodeURIComponent(address)}`;
|
|
2365
|
+
}
|
|
2366
|
+
function buildGetAddressBalanceUrl(baseEndpoint, address) {
|
|
2367
|
+
const base = toV2Base(baseEndpoint);
|
|
2368
|
+
return `${base}/getAddressBalance?address=${encodeURIComponent(address)}`;
|
|
2369
|
+
}
|
|
2370
|
+
function buildGetAddressInfoUrl(baseEndpoint, address) {
|
|
2371
|
+
const base = toV2Base(baseEndpoint);
|
|
2372
|
+
return `${base}/getAddressInformation?address=${encodeURIComponent(address)}`;
|
|
2373
|
+
}
|
|
2374
|
+
function detectNetworkFromEndpoint(endpoint) {
|
|
2375
|
+
const lower = endpoint.toLowerCase();
|
|
2376
|
+
if (lower.includes("testnet") || lower.includes("test") || lower.includes("sandbox")) {
|
|
2377
|
+
return "testnet";
|
|
2378
|
+
}
|
|
2379
|
+
if (lower.includes("mainnet") || lower.includes("main") || // TonCenter mainnet doesn't have 'mainnet' in URL
|
|
2380
|
+
lower.includes("toncenter.com") && !lower.includes("testnet")) {
|
|
2381
|
+
return "mainnet";
|
|
2382
|
+
}
|
|
2383
|
+
return null;
|
|
2384
|
+
}
|
|
2385
|
+
function isValidHttpUrl(str) {
|
|
2386
|
+
try {
|
|
2387
|
+
const url = new URL(str);
|
|
2388
|
+
return url.protocol === "http:" || url.protocol === "https:";
|
|
2389
|
+
} catch {
|
|
2390
|
+
return false;
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
function isValidWsUrl(str) {
|
|
2394
|
+
try {
|
|
2395
|
+
const url = new URL(str);
|
|
2396
|
+
return url.protocol === "ws:" || url.protocol === "wss:";
|
|
2397
|
+
} catch {
|
|
2398
|
+
return false;
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
|
|
1988
2402
|
// src/core/manager.ts
|
|
1989
2403
|
var consoleLogger5 = {
|
|
1990
2404
|
debug: (msg, data) => console.debug(`[ProviderManager] ${msg}`, data || ""),
|
|
@@ -2183,17 +2597,20 @@ var _ProviderManager = class _ProviderManager {
|
|
|
2183
2597
|
this.options.logger.warn("No providers available, using fallback");
|
|
2184
2598
|
return this.getFallbackEndpoint();
|
|
2185
2599
|
}
|
|
2186
|
-
|
|
2600
|
+
const activeProviderId = this.selector.getActiveProviderId(this.network);
|
|
2601
|
+
if (!activeProviderId) {
|
|
2602
|
+
this.selector.getBestProvider(this.network);
|
|
2603
|
+
}
|
|
2187
2604
|
if (provider.isDynamic && provider.type === "orbs") {
|
|
2188
2605
|
try {
|
|
2189
2606
|
const { getHttpEndpoint } = await import('@orbs-network/ton-access');
|
|
2190
2607
|
const endpoint = await getHttpEndpoint({ network: this.network });
|
|
2191
|
-
return normalizeV2Endpoint(endpoint);
|
|
2608
|
+
return normalizeV2Endpoint(endpoint, provider);
|
|
2192
2609
|
} catch (error) {
|
|
2193
2610
|
this.options.logger.warn(`Failed to get Orbs endpoint: ${error.message}`);
|
|
2194
2611
|
}
|
|
2195
2612
|
}
|
|
2196
|
-
return normalizeV2Endpoint(provider.endpointV2);
|
|
2613
|
+
return normalizeV2Endpoint(provider.endpointV2, provider);
|
|
2197
2614
|
}
|
|
2198
2615
|
/**
|
|
2199
2616
|
* Get endpoint with rate limiting
|
|
@@ -2216,11 +2633,11 @@ var _ProviderManager = class _ProviderManager {
|
|
|
2216
2633
|
this.options.logger.warn(`Rate limit timeout for ${provider.id}`);
|
|
2217
2634
|
const next = this.selector.getNextProvider(this.network, [provider.id]);
|
|
2218
2635
|
if (next) {
|
|
2219
|
-
return normalizeV2Endpoint(next.endpointV2);
|
|
2636
|
+
return normalizeV2Endpoint(next.endpointV2, next);
|
|
2220
2637
|
}
|
|
2221
2638
|
return this.getFallbackEndpoint();
|
|
2222
2639
|
}
|
|
2223
|
-
return normalizeV2Endpoint(provider.endpointV2);
|
|
2640
|
+
return normalizeV2Endpoint(provider.endpointV2, provider);
|
|
2224
2641
|
}
|
|
2225
2642
|
/**
|
|
2226
2643
|
* Get current active provider
|
|
@@ -3079,6 +3496,6 @@ async function createBrowserAdapterForNetwork(network, configPath, logger) {
|
|
|
3079
3496
|
return new BrowserAdapter(manager, logger);
|
|
3080
3497
|
}
|
|
3081
3498
|
|
|
3082
|
-
export { ApiVersionSchema, BrowserAdapter, CHAINSTACK_RATE_LIMIT, ConfigError, DEFAULT_CONTRACT_TIMEOUT_MS, DEFAULT_HEALTH_CHECK_TIMEOUT_MS, DEFAULT_PROVIDERS, DEFAULT_PROVIDER_TIMEOUT_MS, DEFAULT_RATE_LIMIT, HealthChecker, NetworkSchema, NodeAdapter, ORBS_RATE_LIMIT, ProviderConfigSchema, ProviderError, ProviderManager, ProviderRegistry, ProviderSelector, ProviderTypeSchema, QUICKNODE_RATE_LIMIT, RateLimitError, RateLimiterManager, RpcConfigSchema, TimeoutError, TokenBucketRateLimiter, buildGetAddressBalanceUrl, buildGetAddressInfoUrl, buildGetAddressStateUrl, buildRestUrl, createBrowserAdapter, createBrowserAdapterForNetwork, createDefaultConfig, createDefaultRegistry, createEmptyConfig, createHealthChecker, createNodeAdapter, createProviderManager, createRateLimiter, createRateLimiterManager, createRegistry, createRegistryFromData, createRegistryFromFile, createSelector, createTimeoutController, detectNetworkFromEndpoint, fetchWithTimeout, getBaseUrl, getDefaultProvidersForNetwork, getEnvVar, getProviderManager, getProvidersForNetwork, getRateLimitForType, getTonClient, getTonClientForNetwork, getTonClientWithRateLimit, isApiVersion, isChainstackUrl, isNetwork, isOrbsUrl, isProviderType, isQuickNodeUrl, isRateLimitError, isTimeoutError, isTonCenterUrl, isValidHttpUrl, isValidWsUrl, loadBuiltinConfig, loadConfig, loadConfigFromData, loadConfigFromUrl, mergeConfigs, mergeWithDefaults, normalizeV2Endpoint, parseProviderConfig, parseRpcConfig, resetNodeAdapter, resolveAllProviders, resolveEndpoints, resolveKeyPlaceholder, resolveProvider, sleep, toV2Base, toV3Base, withRetry, withTimeout, withTimeoutAndRetry, withTimeoutFn };
|
|
3499
|
+
export { ApiVersionSchema, BaseProvider, BrowserAdapter, CHAINSTACK_RATE_LIMIT, ChainstackProvider, ConfigError, DEFAULT_CONTRACT_TIMEOUT_MS, DEFAULT_HEALTH_CHECK_TIMEOUT_MS, DEFAULT_PROVIDERS, DEFAULT_PROVIDER_TIMEOUT_MS, DEFAULT_RATE_LIMIT, GenericProvider, GetBlockProvider, HealthChecker, NetworkSchema, NodeAdapter, ORBS_RATE_LIMIT, OnFinalityProvider, OrbsProvider, ProviderConfigSchema, ProviderError, ProviderManager, ProviderRegistry, ProviderSelector, ProviderTypeSchema, QUICKNODE_RATE_LIMIT, QuickNodeProvider, RateLimitError, RateLimiterManager, RpcConfigSchema, TatumProvider, TimeoutError, TokenBucketRateLimiter, TonCenterProvider, buildGetAddressBalanceUrl, buildGetAddressInfoUrl, buildGetAddressStateUrl, buildRestUrl, createBrowserAdapter, createBrowserAdapterForNetwork, createDefaultConfig, createDefaultRegistry, createEmptyConfig, createHealthChecker, createNodeAdapter, createProvider, createProviderManager, createRateLimiter, createRateLimiterManager, createRegistry, createRegistryFromData, createRegistryFromFile, createSelector, createTimeoutController, detectNetworkFromEndpoint, fetchWithTimeout, getBaseUrl, getDefaultProvidersForNetwork, getEnvVar, getProviderManager, getProvidersForNetwork, getRateLimitForType, getTonClient, getTonClientForNetwork, getTonClientWithRateLimit, isApiVersion, isChainstackUrl, isNetwork, isOrbsUrl, isProviderType, isQuickNodeUrl, isRateLimitError, isTimeoutError, isTonCenterUrl, isValidHttpUrl, isValidWsUrl, loadBuiltinConfig, loadConfig, loadConfigFromData, loadConfigFromUrl, mergeConfigs, mergeWithDefaults, normalizeV2Endpoint, parseProviderConfig, parseRpcConfig, resetNodeAdapter, resolveAllProviders, resolveEndpoints, resolveKeyPlaceholder, resolveProvider, sleep, toV2Base, toV3Base, withRetry, withTimeout, withTimeoutAndRetry, withTimeoutFn };
|
|
3083
3500
|
//# sourceMappingURL=index.js.map
|
|
3084
3501
|
//# sourceMappingURL=index.js.map
|