pmxtjs 2.34.1 → 2.34.3
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/esm/pmxt/client.d.ts +22 -0
- package/dist/esm/pmxt/client.js +386 -88
- package/dist/esm/pmxt/server-manager.js +16 -2
- package/dist/pmxt/client.d.ts +22 -0
- package/dist/pmxt/client.js +386 -88
- package/dist/pmxt/server-manager.js +16 -2
- package/generated/package.json +1 -1
- package/package.json +2 -2
- package/pmxt/client.ts +363 -88
- package/pmxt/server-manager.ts +15 -2
package/pmxt/client.ts
CHANGED
|
@@ -453,6 +453,54 @@ export abstract class Exchange {
|
|
|
453
453
|
return headers;
|
|
454
454
|
}
|
|
455
455
|
|
|
456
|
+
/**
|
|
457
|
+
* Resolve the current sidecar base URL.
|
|
458
|
+
*
|
|
459
|
+
* For hosted mode the configured basePath is returned as-is.
|
|
460
|
+
* For local mode the port is re-read from the lock file on every
|
|
461
|
+
* call so we pick up sidecar restarts that land on a different port.
|
|
462
|
+
*/
|
|
463
|
+
private resolveBaseUrl(): string {
|
|
464
|
+
if (this.isHosted) return this.config.basePath;
|
|
465
|
+
const port = this.serverManager.getRunningPort();
|
|
466
|
+
return `http://localhost:${port}`;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Execute a fetch with retry on connection failures.
|
|
471
|
+
*
|
|
472
|
+
* Only retries on connection-level errors (ECONNREFUSED, ECONNRESET) —
|
|
473
|
+
* never on HTTP responses (4xx, 5xx). On first connection failure,
|
|
474
|
+
* attempts to restart the sidecar.
|
|
475
|
+
*/
|
|
476
|
+
private async fetchWithRetry(
|
|
477
|
+
input: RequestInfo | URL,
|
|
478
|
+
init?: RequestInit,
|
|
479
|
+
): Promise<Response> {
|
|
480
|
+
const delays = [200, 500, 1000];
|
|
481
|
+
let lastError: unknown;
|
|
482
|
+
|
|
483
|
+
for (let attempt = 0; attempt <= delays.length; attempt++) {
|
|
484
|
+
try {
|
|
485
|
+
return await fetch(input, init);
|
|
486
|
+
} catch (error) {
|
|
487
|
+
lastError = error;
|
|
488
|
+
if (attempt >= delays.length) break;
|
|
489
|
+
|
|
490
|
+
// Connection failed — try to restart the sidecar on first failure
|
|
491
|
+
if (attempt === 0 && !this.isHosted) {
|
|
492
|
+
try {
|
|
493
|
+
await this.serverManager.ensureServerRunning();
|
|
494
|
+
} catch {
|
|
495
|
+
// Restart failed — continue retrying anyway
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
await new Promise(resolve => setTimeout(resolve, delays[attempt]));
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
throw lastError;
|
|
502
|
+
}
|
|
503
|
+
|
|
456
504
|
// Low-Level API Access
|
|
457
505
|
|
|
458
506
|
/**
|
|
@@ -473,14 +521,14 @@ export abstract class Exchange {
|
|
|
473
521
|
async callApi(operationId: string, params?: Record<string, any>): Promise<any> {
|
|
474
522
|
await this.initPromise;
|
|
475
523
|
try {
|
|
476
|
-
const url = `${this.
|
|
524
|
+
const url = `${this.resolveBaseUrl()}/api/${this.exchangeName}/callApi`;
|
|
477
525
|
|
|
478
526
|
const requestBody: any = {
|
|
479
527
|
args: [operationId, params],
|
|
480
528
|
credentials: this.getCredentials()
|
|
481
529
|
};
|
|
482
530
|
|
|
483
|
-
const response = await
|
|
531
|
+
const response = await this.fetchWithRetry(url, {
|
|
484
532
|
method: 'POST',
|
|
485
533
|
headers: {
|
|
486
534
|
'Content-Type': 'application/json',
|
|
@@ -529,13 +577,14 @@ export abstract class Exchange {
|
|
|
529
577
|
query: Record<string, unknown>,
|
|
530
578
|
args: unknown[],
|
|
531
579
|
): Promise<any> {
|
|
532
|
-
const
|
|
580
|
+
const resolvedBase = this.resolveBaseUrl();
|
|
581
|
+
const baseUrl = `${resolvedBase}/api/${this.exchangeName}/${methodName}`;
|
|
533
582
|
const hasCredentials = this.getCredentials() !== undefined;
|
|
534
583
|
|
|
535
584
|
if (!hasCredentials && !this._getReadsUnsupported && !queryHasNestedObject(query)) {
|
|
536
585
|
const qs = buildSidecarQueryString(query);
|
|
537
586
|
const getUrl = qs ? `${baseUrl}?${qs}` : baseUrl;
|
|
538
|
-
const response = await
|
|
587
|
+
const response = await this.fetchWithRetry(getUrl, {
|
|
539
588
|
method: 'GET',
|
|
540
589
|
headers: this.getAuthHeaders(),
|
|
541
590
|
});
|
|
@@ -559,7 +608,7 @@ export abstract class Exchange {
|
|
|
559
608
|
}
|
|
560
609
|
|
|
561
610
|
// POST fallback — identical to the original per-method template.
|
|
562
|
-
const response = await
|
|
611
|
+
const response = await this.fetchWithRetry(baseUrl, {
|
|
563
612
|
method: 'POST',
|
|
564
613
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
565
614
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
@@ -581,14 +630,17 @@ export abstract class Exchange {
|
|
|
581
630
|
try {
|
|
582
631
|
const args: any[] = [];
|
|
583
632
|
args.push(reload);
|
|
584
|
-
const response = await
|
|
633
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/loadMarkets`, {
|
|
585
634
|
method: 'POST',
|
|
586
635
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
587
636
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
588
637
|
});
|
|
589
638
|
if (!response.ok) {
|
|
590
|
-
const
|
|
591
|
-
|
|
639
|
+
const body = await response.json().catch(() => ({}));
|
|
640
|
+
if (body.error && typeof body.error === "object") {
|
|
641
|
+
throw fromServerError(body.error);
|
|
642
|
+
}
|
|
643
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
592
644
|
}
|
|
593
645
|
const json = await response.json();
|
|
594
646
|
const data = this.handleResponse(json);
|
|
@@ -598,7 +650,8 @@ export abstract class Exchange {
|
|
|
598
650
|
}
|
|
599
651
|
return result;
|
|
600
652
|
} catch (error) {
|
|
601
|
-
|
|
653
|
+
if (error instanceof PmxtError) throw error;
|
|
654
|
+
throw new PmxtError(`Failed to loadMarkets: ${error}`);
|
|
602
655
|
}
|
|
603
656
|
}
|
|
604
657
|
|
|
@@ -607,20 +660,24 @@ export abstract class Exchange {
|
|
|
607
660
|
try {
|
|
608
661
|
const args: any[] = [];
|
|
609
662
|
if (params !== undefined) args.push(params);
|
|
610
|
-
const response = await
|
|
663
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchMarkets`, {
|
|
611
664
|
method: 'POST',
|
|
612
665
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
613
666
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
614
667
|
});
|
|
615
668
|
if (!response.ok) {
|
|
616
|
-
const
|
|
617
|
-
|
|
669
|
+
const body = await response.json().catch(() => ({}));
|
|
670
|
+
if (body.error && typeof body.error === "object") {
|
|
671
|
+
throw fromServerError(body.error);
|
|
672
|
+
}
|
|
673
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
618
674
|
}
|
|
619
675
|
const json = await response.json();
|
|
620
676
|
const data = this.handleResponse(json);
|
|
621
677
|
return data.map(convertMarket);
|
|
622
678
|
} catch (error) {
|
|
623
|
-
|
|
679
|
+
if (error instanceof PmxtError) throw error;
|
|
680
|
+
throw new PmxtError(`Failed to fetchMarkets: ${error}`);
|
|
624
681
|
}
|
|
625
682
|
}
|
|
626
683
|
|
|
@@ -629,14 +686,17 @@ export abstract class Exchange {
|
|
|
629
686
|
try {
|
|
630
687
|
const args: any[] = [];
|
|
631
688
|
if (params !== undefined) args.push(params);
|
|
632
|
-
const response = await
|
|
689
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchMarketsPaginated`, {
|
|
633
690
|
method: 'POST',
|
|
634
691
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
635
692
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
636
693
|
});
|
|
637
694
|
if (!response.ok) {
|
|
638
|
-
const
|
|
639
|
-
|
|
695
|
+
const body = await response.json().catch(() => ({}));
|
|
696
|
+
if (body.error && typeof body.error === "object") {
|
|
697
|
+
throw fromServerError(body.error);
|
|
698
|
+
}
|
|
699
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
640
700
|
}
|
|
641
701
|
const json = await response.json();
|
|
642
702
|
const data = this.handleResponse(json);
|
|
@@ -646,7 +706,8 @@ export abstract class Exchange {
|
|
|
646
706
|
nextCursor: data.nextCursor,
|
|
647
707
|
};
|
|
648
708
|
} catch (error) {
|
|
649
|
-
|
|
709
|
+
if (error instanceof PmxtError) throw error;
|
|
710
|
+
throw new PmxtError(`Failed to fetchMarketsPaginated: ${error}`);
|
|
650
711
|
}
|
|
651
712
|
}
|
|
652
713
|
|
|
@@ -655,20 +716,24 @@ export abstract class Exchange {
|
|
|
655
716
|
try {
|
|
656
717
|
const args: any[] = [];
|
|
657
718
|
if (params !== undefined) args.push(params);
|
|
658
|
-
const response = await
|
|
719
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchEvents`, {
|
|
659
720
|
method: 'POST',
|
|
660
721
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
661
722
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
662
723
|
});
|
|
663
724
|
if (!response.ok) {
|
|
664
|
-
const
|
|
665
|
-
|
|
725
|
+
const body = await response.json().catch(() => ({}));
|
|
726
|
+
if (body.error && typeof body.error === "object") {
|
|
727
|
+
throw fromServerError(body.error);
|
|
728
|
+
}
|
|
729
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
666
730
|
}
|
|
667
731
|
const json = await response.json();
|
|
668
732
|
const data = this.handleResponse(json);
|
|
669
733
|
return data.map(convertEvent);
|
|
670
734
|
} catch (error) {
|
|
671
|
-
|
|
735
|
+
if (error instanceof PmxtError) throw error;
|
|
736
|
+
throw new PmxtError(`Failed to fetchEvents: ${error}`);
|
|
672
737
|
}
|
|
673
738
|
}
|
|
674
739
|
|
|
@@ -677,20 +742,24 @@ export abstract class Exchange {
|
|
|
677
742
|
try {
|
|
678
743
|
const args: any[] = [];
|
|
679
744
|
if (params !== undefined) args.push(params);
|
|
680
|
-
const response = await
|
|
745
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchMarket`, {
|
|
681
746
|
method: 'POST',
|
|
682
747
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
683
748
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
684
749
|
});
|
|
685
750
|
if (!response.ok) {
|
|
686
|
-
const
|
|
687
|
-
|
|
751
|
+
const body = await response.json().catch(() => ({}));
|
|
752
|
+
if (body.error && typeof body.error === "object") {
|
|
753
|
+
throw fromServerError(body.error);
|
|
754
|
+
}
|
|
755
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
688
756
|
}
|
|
689
757
|
const json = await response.json();
|
|
690
758
|
const data = this.handleResponse(json);
|
|
691
759
|
return convertMarket(data);
|
|
692
760
|
} catch (error) {
|
|
693
|
-
|
|
761
|
+
if (error instanceof PmxtError) throw error;
|
|
762
|
+
throw new PmxtError(`Failed to fetchMarket: ${error}`);
|
|
694
763
|
}
|
|
695
764
|
}
|
|
696
765
|
|
|
@@ -699,20 +768,24 @@ export abstract class Exchange {
|
|
|
699
768
|
try {
|
|
700
769
|
const args: any[] = [];
|
|
701
770
|
if (params !== undefined) args.push(params);
|
|
702
|
-
const response = await
|
|
771
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchEvent`, {
|
|
703
772
|
method: 'POST',
|
|
704
773
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
705
774
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
706
775
|
});
|
|
707
776
|
if (!response.ok) {
|
|
708
|
-
const
|
|
709
|
-
|
|
777
|
+
const body = await response.json().catch(() => ({}));
|
|
778
|
+
if (body.error && typeof body.error === "object") {
|
|
779
|
+
throw fromServerError(body.error);
|
|
780
|
+
}
|
|
781
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
710
782
|
}
|
|
711
783
|
const json = await response.json();
|
|
712
784
|
const data = this.handleResponse(json);
|
|
713
785
|
return convertEvent(data);
|
|
714
786
|
} catch (error) {
|
|
715
|
-
|
|
787
|
+
if (error instanceof PmxtError) throw error;
|
|
788
|
+
throw new PmxtError(`Failed to fetchEvent: ${error}`);
|
|
716
789
|
}
|
|
717
790
|
}
|
|
718
791
|
|
|
@@ -721,20 +794,24 @@ export abstract class Exchange {
|
|
|
721
794
|
try {
|
|
722
795
|
const args: any[] = [];
|
|
723
796
|
args.push(id);
|
|
724
|
-
const response = await
|
|
797
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchOrderBook`, {
|
|
725
798
|
method: 'POST',
|
|
726
799
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
727
800
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
728
801
|
});
|
|
729
802
|
if (!response.ok) {
|
|
730
|
-
const
|
|
731
|
-
|
|
803
|
+
const body = await response.json().catch(() => ({}));
|
|
804
|
+
if (body.error && typeof body.error === "object") {
|
|
805
|
+
throw fromServerError(body.error);
|
|
806
|
+
}
|
|
807
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
732
808
|
}
|
|
733
809
|
const json = await response.json();
|
|
734
810
|
const data = this.handleResponse(json);
|
|
735
811
|
return convertOrderBook(data);
|
|
736
812
|
} catch (error) {
|
|
737
|
-
|
|
813
|
+
if (error instanceof PmxtError) throw error;
|
|
814
|
+
throw new PmxtError(`Failed to fetchOrderBook: ${error}`);
|
|
738
815
|
}
|
|
739
816
|
}
|
|
740
817
|
|
|
@@ -743,20 +820,24 @@ export abstract class Exchange {
|
|
|
743
820
|
try {
|
|
744
821
|
const args: any[] = [];
|
|
745
822
|
args.push(built);
|
|
746
|
-
const response = await
|
|
823
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/submitOrder`, {
|
|
747
824
|
method: 'POST',
|
|
748
825
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
749
826
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
750
827
|
});
|
|
751
828
|
if (!response.ok) {
|
|
752
|
-
const
|
|
753
|
-
|
|
829
|
+
const body = await response.json().catch(() => ({}));
|
|
830
|
+
if (body.error && typeof body.error === "object") {
|
|
831
|
+
throw fromServerError(body.error);
|
|
832
|
+
}
|
|
833
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
754
834
|
}
|
|
755
835
|
const json = await response.json();
|
|
756
836
|
const data = this.handleResponse(json);
|
|
757
837
|
return convertOrder(data);
|
|
758
838
|
} catch (error) {
|
|
759
|
-
|
|
839
|
+
if (error instanceof PmxtError) throw error;
|
|
840
|
+
throw new PmxtError(`Failed to submitOrder: ${error}`);
|
|
760
841
|
}
|
|
761
842
|
}
|
|
762
843
|
|
|
@@ -765,20 +846,24 @@ export abstract class Exchange {
|
|
|
765
846
|
try {
|
|
766
847
|
const args: any[] = [];
|
|
767
848
|
args.push(orderId);
|
|
768
|
-
const response = await
|
|
849
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/cancelOrder`, {
|
|
769
850
|
method: 'POST',
|
|
770
851
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
771
852
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
772
853
|
});
|
|
773
854
|
if (!response.ok) {
|
|
774
|
-
const
|
|
775
|
-
|
|
855
|
+
const body = await response.json().catch(() => ({}));
|
|
856
|
+
if (body.error && typeof body.error === "object") {
|
|
857
|
+
throw fromServerError(body.error);
|
|
858
|
+
}
|
|
859
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
776
860
|
}
|
|
777
861
|
const json = await response.json();
|
|
778
862
|
const data = this.handleResponse(json);
|
|
779
863
|
return convertOrder(data);
|
|
780
864
|
} catch (error) {
|
|
781
|
-
|
|
865
|
+
if (error instanceof PmxtError) throw error;
|
|
866
|
+
throw new PmxtError(`Failed to cancelOrder: ${error}`);
|
|
782
867
|
}
|
|
783
868
|
}
|
|
784
869
|
|
|
@@ -787,20 +872,24 @@ export abstract class Exchange {
|
|
|
787
872
|
try {
|
|
788
873
|
const args: any[] = [];
|
|
789
874
|
args.push(orderId);
|
|
790
|
-
const response = await
|
|
875
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchOrder`, {
|
|
791
876
|
method: 'POST',
|
|
792
877
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
793
878
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
794
879
|
});
|
|
795
880
|
if (!response.ok) {
|
|
796
|
-
const
|
|
797
|
-
|
|
881
|
+
const body = await response.json().catch(() => ({}));
|
|
882
|
+
if (body.error && typeof body.error === "object") {
|
|
883
|
+
throw fromServerError(body.error);
|
|
884
|
+
}
|
|
885
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
798
886
|
}
|
|
799
887
|
const json = await response.json();
|
|
800
888
|
const data = this.handleResponse(json);
|
|
801
889
|
return convertOrder(data);
|
|
802
890
|
} catch (error) {
|
|
803
|
-
|
|
891
|
+
if (error instanceof PmxtError) throw error;
|
|
892
|
+
throw new PmxtError(`Failed to fetchOrder: ${error}`);
|
|
804
893
|
}
|
|
805
894
|
}
|
|
806
895
|
|
|
@@ -809,20 +898,24 @@ export abstract class Exchange {
|
|
|
809
898
|
try {
|
|
810
899
|
const args: any[] = [];
|
|
811
900
|
if (marketId !== undefined) args.push(marketId);
|
|
812
|
-
const response = await
|
|
901
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchOpenOrders`, {
|
|
813
902
|
method: 'POST',
|
|
814
903
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
815
904
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
816
905
|
});
|
|
817
906
|
if (!response.ok) {
|
|
818
|
-
const
|
|
819
|
-
|
|
907
|
+
const body = await response.json().catch(() => ({}));
|
|
908
|
+
if (body.error && typeof body.error === "object") {
|
|
909
|
+
throw fromServerError(body.error);
|
|
910
|
+
}
|
|
911
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
820
912
|
}
|
|
821
913
|
const json = await response.json();
|
|
822
914
|
const data = this.handleResponse(json);
|
|
823
915
|
return data.map(convertOrder);
|
|
824
916
|
} catch (error) {
|
|
825
|
-
|
|
917
|
+
if (error instanceof PmxtError) throw error;
|
|
918
|
+
throw new PmxtError(`Failed to fetchOpenOrders: ${error}`);
|
|
826
919
|
}
|
|
827
920
|
}
|
|
828
921
|
|
|
@@ -831,20 +924,24 @@ export abstract class Exchange {
|
|
|
831
924
|
try {
|
|
832
925
|
const args: any[] = [];
|
|
833
926
|
if (params !== undefined) args.push(params);
|
|
834
|
-
const response = await
|
|
927
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchMyTrades`, {
|
|
835
928
|
method: 'POST',
|
|
836
929
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
837
930
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
838
931
|
});
|
|
839
932
|
if (!response.ok) {
|
|
840
|
-
const
|
|
841
|
-
|
|
933
|
+
const body = await response.json().catch(() => ({}));
|
|
934
|
+
if (body.error && typeof body.error === "object") {
|
|
935
|
+
throw fromServerError(body.error);
|
|
936
|
+
}
|
|
937
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
842
938
|
}
|
|
843
939
|
const json = await response.json();
|
|
844
940
|
const data = this.handleResponse(json);
|
|
845
941
|
return data.map(convertUserTrade);
|
|
846
942
|
} catch (error) {
|
|
847
|
-
|
|
943
|
+
if (error instanceof PmxtError) throw error;
|
|
944
|
+
throw new PmxtError(`Failed to fetchMyTrades: ${error}`);
|
|
848
945
|
}
|
|
849
946
|
}
|
|
850
947
|
|
|
@@ -853,20 +950,24 @@ export abstract class Exchange {
|
|
|
853
950
|
try {
|
|
854
951
|
const args: any[] = [];
|
|
855
952
|
if (params !== undefined) args.push(params);
|
|
856
|
-
const response = await
|
|
953
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchClosedOrders`, {
|
|
857
954
|
method: 'POST',
|
|
858
955
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
859
956
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
860
957
|
});
|
|
861
958
|
if (!response.ok) {
|
|
862
|
-
const
|
|
863
|
-
|
|
959
|
+
const body = await response.json().catch(() => ({}));
|
|
960
|
+
if (body.error && typeof body.error === "object") {
|
|
961
|
+
throw fromServerError(body.error);
|
|
962
|
+
}
|
|
963
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
864
964
|
}
|
|
865
965
|
const json = await response.json();
|
|
866
966
|
const data = this.handleResponse(json);
|
|
867
967
|
return data.map(convertOrder);
|
|
868
968
|
} catch (error) {
|
|
869
|
-
|
|
969
|
+
if (error instanceof PmxtError) throw error;
|
|
970
|
+
throw new PmxtError(`Failed to fetchClosedOrders: ${error}`);
|
|
870
971
|
}
|
|
871
972
|
}
|
|
872
973
|
|
|
@@ -875,20 +976,24 @@ export abstract class Exchange {
|
|
|
875
976
|
try {
|
|
876
977
|
const args: any[] = [];
|
|
877
978
|
if (params !== undefined) args.push(params);
|
|
878
|
-
const response = await
|
|
979
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchAllOrders`, {
|
|
879
980
|
method: 'POST',
|
|
880
981
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
881
982
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
882
983
|
});
|
|
883
984
|
if (!response.ok) {
|
|
884
|
-
const
|
|
885
|
-
|
|
985
|
+
const body = await response.json().catch(() => ({}));
|
|
986
|
+
if (body.error && typeof body.error === "object") {
|
|
987
|
+
throw fromServerError(body.error);
|
|
988
|
+
}
|
|
989
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
886
990
|
}
|
|
887
991
|
const json = await response.json();
|
|
888
992
|
const data = this.handleResponse(json);
|
|
889
993
|
return data.map(convertOrder);
|
|
890
994
|
} catch (error) {
|
|
891
|
-
|
|
995
|
+
if (error instanceof PmxtError) throw error;
|
|
996
|
+
throw new PmxtError(`Failed to fetchAllOrders: ${error}`);
|
|
892
997
|
}
|
|
893
998
|
}
|
|
894
999
|
|
|
@@ -897,20 +1002,24 @@ export abstract class Exchange {
|
|
|
897
1002
|
try {
|
|
898
1003
|
const args: any[] = [];
|
|
899
1004
|
if (address !== undefined) args.push(address);
|
|
900
|
-
const response = await
|
|
1005
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchPositions`, {
|
|
901
1006
|
method: 'POST',
|
|
902
1007
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
903
1008
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
904
1009
|
});
|
|
905
1010
|
if (!response.ok) {
|
|
906
|
-
const
|
|
907
|
-
|
|
1011
|
+
const body = await response.json().catch(() => ({}));
|
|
1012
|
+
if (body.error && typeof body.error === "object") {
|
|
1013
|
+
throw fromServerError(body.error);
|
|
1014
|
+
}
|
|
1015
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
908
1016
|
}
|
|
909
1017
|
const json = await response.json();
|
|
910
1018
|
const data = this.handleResponse(json);
|
|
911
1019
|
return data.map(convertPosition);
|
|
912
1020
|
} catch (error) {
|
|
913
|
-
|
|
1021
|
+
if (error instanceof PmxtError) throw error;
|
|
1022
|
+
throw new PmxtError(`Failed to fetchPositions: ${error}`);
|
|
914
1023
|
}
|
|
915
1024
|
}
|
|
916
1025
|
|
|
@@ -919,20 +1028,24 @@ export abstract class Exchange {
|
|
|
919
1028
|
try {
|
|
920
1029
|
const args: any[] = [];
|
|
921
1030
|
if (address !== undefined) args.push(address);
|
|
922
|
-
const response = await
|
|
1031
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchBalance`, {
|
|
923
1032
|
method: 'POST',
|
|
924
1033
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
925
1034
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
926
1035
|
});
|
|
927
1036
|
if (!response.ok) {
|
|
928
|
-
const
|
|
929
|
-
|
|
1037
|
+
const body = await response.json().catch(() => ({}));
|
|
1038
|
+
if (body.error && typeof body.error === "object") {
|
|
1039
|
+
throw fromServerError(body.error);
|
|
1040
|
+
}
|
|
1041
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
930
1042
|
}
|
|
931
1043
|
const json = await response.json();
|
|
932
1044
|
const data = this.handleResponse(json);
|
|
933
1045
|
return data.map(convertBalance);
|
|
934
1046
|
} catch (error) {
|
|
935
|
-
|
|
1047
|
+
if (error instanceof PmxtError) throw error;
|
|
1048
|
+
throw new PmxtError(`Failed to fetchBalance: ${error}`);
|
|
936
1049
|
}
|
|
937
1050
|
}
|
|
938
1051
|
|
|
@@ -941,19 +1054,23 @@ export abstract class Exchange {
|
|
|
941
1054
|
try {
|
|
942
1055
|
const args: any[] = [];
|
|
943
1056
|
args.push(id);
|
|
944
|
-
const response = await
|
|
1057
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/unwatchOrderBook`, {
|
|
945
1058
|
method: 'POST',
|
|
946
1059
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
947
1060
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
948
1061
|
});
|
|
949
1062
|
if (!response.ok) {
|
|
950
|
-
const
|
|
951
|
-
|
|
1063
|
+
const body = await response.json().catch(() => ({}));
|
|
1064
|
+
if (body.error && typeof body.error === "object") {
|
|
1065
|
+
throw fromServerError(body.error);
|
|
1066
|
+
}
|
|
1067
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
952
1068
|
}
|
|
953
1069
|
const json = await response.json();
|
|
954
1070
|
this.handleResponse(json);
|
|
955
1071
|
} catch (error) {
|
|
956
|
-
|
|
1072
|
+
if (error instanceof PmxtError) throw error;
|
|
1073
|
+
throw new PmxtError(`Failed to unwatchOrderBook: ${error}`);
|
|
957
1074
|
}
|
|
958
1075
|
}
|
|
959
1076
|
|
|
@@ -962,19 +1079,23 @@ export abstract class Exchange {
|
|
|
962
1079
|
try {
|
|
963
1080
|
const args: any[] = [];
|
|
964
1081
|
args.push(address);
|
|
965
|
-
const response = await
|
|
1082
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/unwatchAddress`, {
|
|
966
1083
|
method: 'POST',
|
|
967
1084
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
968
1085
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
969
1086
|
});
|
|
970
1087
|
if (!response.ok) {
|
|
971
|
-
const
|
|
972
|
-
|
|
1088
|
+
const body = await response.json().catch(() => ({}));
|
|
1089
|
+
if (body.error && typeof body.error === "object") {
|
|
1090
|
+
throw fromServerError(body.error);
|
|
1091
|
+
}
|
|
1092
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
973
1093
|
}
|
|
974
1094
|
const json = await response.json();
|
|
975
1095
|
this.handleResponse(json);
|
|
976
1096
|
} catch (error) {
|
|
977
|
-
|
|
1097
|
+
if (error instanceof PmxtError) throw error;
|
|
1098
|
+
throw new PmxtError(`Failed to unwatchAddress: ${error}`);
|
|
978
1099
|
}
|
|
979
1100
|
}
|
|
980
1101
|
|
|
@@ -982,19 +1103,173 @@ export abstract class Exchange {
|
|
|
982
1103
|
await this.initPromise;
|
|
983
1104
|
try {
|
|
984
1105
|
const args: any[] = [];
|
|
985
|
-
const response = await
|
|
1106
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/close`, {
|
|
986
1107
|
method: 'POST',
|
|
987
1108
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
988
1109
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
989
1110
|
});
|
|
990
1111
|
if (!response.ok) {
|
|
991
|
-
const
|
|
992
|
-
|
|
1112
|
+
const body = await response.json().catch(() => ({}));
|
|
1113
|
+
if (body.error && typeof body.error === "object") {
|
|
1114
|
+
throw fromServerError(body.error);
|
|
1115
|
+
}
|
|
1116
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
993
1117
|
}
|
|
994
1118
|
const json = await response.json();
|
|
995
1119
|
this.handleResponse(json);
|
|
996
1120
|
} catch (error) {
|
|
997
|
-
|
|
1121
|
+
if (error instanceof PmxtError) throw error;
|
|
1122
|
+
throw new PmxtError(`Failed to close: ${error}`);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
async fetchMarketMatches(params: any): Promise<any[]> {
|
|
1127
|
+
await this.initPromise;
|
|
1128
|
+
try {
|
|
1129
|
+
const args: any[] = [];
|
|
1130
|
+
args.push(params);
|
|
1131
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchMarketMatches`, {
|
|
1132
|
+
method: 'POST',
|
|
1133
|
+
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
1134
|
+
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
1135
|
+
});
|
|
1136
|
+
if (!response.ok) {
|
|
1137
|
+
const body = await response.json().catch(() => ({}));
|
|
1138
|
+
if (body.error && typeof body.error === "object") {
|
|
1139
|
+
throw fromServerError(body.error);
|
|
1140
|
+
}
|
|
1141
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
1142
|
+
}
|
|
1143
|
+
const json = await response.json();
|
|
1144
|
+
return this.handleResponse(json);
|
|
1145
|
+
} catch (error) {
|
|
1146
|
+
if (error instanceof PmxtError) throw error;
|
|
1147
|
+
throw new PmxtError(`Failed to fetchMarketMatches: ${error}`);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
async fetchMatches(params: any): Promise<any[]> {
|
|
1152
|
+
await this.initPromise;
|
|
1153
|
+
try {
|
|
1154
|
+
const args: any[] = [];
|
|
1155
|
+
args.push(params);
|
|
1156
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchMatches`, {
|
|
1157
|
+
method: 'POST',
|
|
1158
|
+
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
1159
|
+
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
1160
|
+
});
|
|
1161
|
+
if (!response.ok) {
|
|
1162
|
+
const body = await response.json().catch(() => ({}));
|
|
1163
|
+
if (body.error && typeof body.error === "object") {
|
|
1164
|
+
throw fromServerError(body.error);
|
|
1165
|
+
}
|
|
1166
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
1167
|
+
}
|
|
1168
|
+
const json = await response.json();
|
|
1169
|
+
return this.handleResponse(json);
|
|
1170
|
+
} catch (error) {
|
|
1171
|
+
if (error instanceof PmxtError) throw error;
|
|
1172
|
+
throw new PmxtError(`Failed to fetchMatches: ${error}`);
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
async fetchEventMatches(params: any): Promise<any[]> {
|
|
1177
|
+
await this.initPromise;
|
|
1178
|
+
try {
|
|
1179
|
+
const args: any[] = [];
|
|
1180
|
+
args.push(params);
|
|
1181
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchEventMatches`, {
|
|
1182
|
+
method: 'POST',
|
|
1183
|
+
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
1184
|
+
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
1185
|
+
});
|
|
1186
|
+
if (!response.ok) {
|
|
1187
|
+
const body = await response.json().catch(() => ({}));
|
|
1188
|
+
if (body.error && typeof body.error === "object") {
|
|
1189
|
+
throw fromServerError(body.error);
|
|
1190
|
+
}
|
|
1191
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
1192
|
+
}
|
|
1193
|
+
const json = await response.json();
|
|
1194
|
+
return this.handleResponse(json);
|
|
1195
|
+
} catch (error) {
|
|
1196
|
+
if (error instanceof PmxtError) throw error;
|
|
1197
|
+
throw new PmxtError(`Failed to fetchEventMatches: ${error}`);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
async compareMarketPrices(params: any): Promise<any[]> {
|
|
1202
|
+
await this.initPromise;
|
|
1203
|
+
try {
|
|
1204
|
+
const args: any[] = [];
|
|
1205
|
+
args.push(params);
|
|
1206
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/compareMarketPrices`, {
|
|
1207
|
+
method: 'POST',
|
|
1208
|
+
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
1209
|
+
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
1210
|
+
});
|
|
1211
|
+
if (!response.ok) {
|
|
1212
|
+
const body = await response.json().catch(() => ({}));
|
|
1213
|
+
if (body.error && typeof body.error === "object") {
|
|
1214
|
+
throw fromServerError(body.error);
|
|
1215
|
+
}
|
|
1216
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
1217
|
+
}
|
|
1218
|
+
const json = await response.json();
|
|
1219
|
+
return this.handleResponse(json);
|
|
1220
|
+
} catch (error) {
|
|
1221
|
+
if (error instanceof PmxtError) throw error;
|
|
1222
|
+
throw new PmxtError(`Failed to compareMarketPrices: ${error}`);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
async fetchHedges(params: any): Promise<any[]> {
|
|
1227
|
+
await this.initPromise;
|
|
1228
|
+
try {
|
|
1229
|
+
const args: any[] = [];
|
|
1230
|
+
args.push(params);
|
|
1231
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchHedges`, {
|
|
1232
|
+
method: 'POST',
|
|
1233
|
+
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
1234
|
+
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
1235
|
+
});
|
|
1236
|
+
if (!response.ok) {
|
|
1237
|
+
const body = await response.json().catch(() => ({}));
|
|
1238
|
+
if (body.error && typeof body.error === "object") {
|
|
1239
|
+
throw fromServerError(body.error);
|
|
1240
|
+
}
|
|
1241
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
1242
|
+
}
|
|
1243
|
+
const json = await response.json();
|
|
1244
|
+
return this.handleResponse(json);
|
|
1245
|
+
} catch (error) {
|
|
1246
|
+
if (error instanceof PmxtError) throw error;
|
|
1247
|
+
throw new PmxtError(`Failed to fetchHedges: ${error}`);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
async fetchArbitrage(params?: any): Promise<any[]> {
|
|
1252
|
+
await this.initPromise;
|
|
1253
|
+
try {
|
|
1254
|
+
const args: any[] = [];
|
|
1255
|
+
if (params !== undefined) args.push(params);
|
|
1256
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/fetchArbitrage`, {
|
|
1257
|
+
method: 'POST',
|
|
1258
|
+
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
1259
|
+
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
1260
|
+
});
|
|
1261
|
+
if (!response.ok) {
|
|
1262
|
+
const body = await response.json().catch(() => ({}));
|
|
1263
|
+
if (body.error && typeof body.error === "object") {
|
|
1264
|
+
throw fromServerError(body.error);
|
|
1265
|
+
}
|
|
1266
|
+
throw new PmxtError(body.error?.message || response.statusText);
|
|
1267
|
+
}
|
|
1268
|
+
const json = await response.json();
|
|
1269
|
+
return this.handleResponse(json);
|
|
1270
|
+
} catch (error) {
|
|
1271
|
+
if (error instanceof PmxtError) throw error;
|
|
1272
|
+
throw new PmxtError(`Failed to fetchArbitrage: ${error}`);
|
|
998
1273
|
}
|
|
999
1274
|
}
|
|
1000
1275
|
|
|
@@ -1109,7 +1384,7 @@ export abstract class Exchange {
|
|
|
1109
1384
|
args.push(limit);
|
|
1110
1385
|
}
|
|
1111
1386
|
|
|
1112
|
-
const response = await
|
|
1387
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/watchOrderBook`, {
|
|
1113
1388
|
method: 'POST',
|
|
1114
1389
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
1115
1390
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
@@ -1173,7 +1448,7 @@ export abstract class Exchange {
|
|
|
1173
1448
|
args.push(limit);
|
|
1174
1449
|
}
|
|
1175
1450
|
|
|
1176
|
-
const response = await
|
|
1451
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/watchTrades`, {
|
|
1177
1452
|
method: 'POST',
|
|
1178
1453
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
1179
1454
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
@@ -1225,7 +1500,7 @@ export abstract class Exchange {
|
|
|
1225
1500
|
if (types !== undefined) {
|
|
1226
1501
|
args.push(types);
|
|
1227
1502
|
}
|
|
1228
|
-
const response = await
|
|
1503
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/watchAddress`, {
|
|
1229
1504
|
method: 'POST',
|
|
1230
1505
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
1231
1506
|
body: JSON.stringify({ args, credentials: this.getCredentials() }),
|
|
@@ -1320,7 +1595,7 @@ export abstract class Exchange {
|
|
|
1320
1595
|
paramsDict.fee = params.fee;
|
|
1321
1596
|
}
|
|
1322
1597
|
|
|
1323
|
-
const response = await
|
|
1598
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/buildOrder`, {
|
|
1324
1599
|
method: 'POST',
|
|
1325
1600
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
1326
1601
|
body: JSON.stringify({ args: [paramsDict], credentials: this.getCredentials() }),
|
|
@@ -1396,7 +1671,7 @@ export abstract class Exchange {
|
|
|
1396
1671
|
paramsDict.fee = params.fee;
|
|
1397
1672
|
}
|
|
1398
1673
|
|
|
1399
|
-
const response = await
|
|
1674
|
+
const response = await this.fetchWithRetry(`${this.resolveBaseUrl()}/api/${this.exchangeName}/createOrder`, {
|
|
1400
1675
|
method: 'POST',
|
|
1401
1676
|
headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
|
|
1402
1677
|
body: JSON.stringify({ args: [paramsDict], credentials: this.getCredentials() }),
|
|
@@ -1455,9 +1730,9 @@ export abstract class Exchange {
|
|
|
1455
1730
|
body.credentials = credentials;
|
|
1456
1731
|
}
|
|
1457
1732
|
|
|
1458
|
-
const url = `${this.
|
|
1733
|
+
const url = `${this.resolveBaseUrl()}/api/${this.exchangeName}/getExecutionPriceDetailed`;
|
|
1459
1734
|
|
|
1460
|
-
const response = await
|
|
1735
|
+
const response = await this.fetchWithRetry(url, {
|
|
1461
1736
|
method: 'POST',
|
|
1462
1737
|
headers: {
|
|
1463
1738
|
'Content-Type': 'application/json',
|