@portal-hq/web 3.17.0 → 3.18.0
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/lib/commonjs/index.js +62 -20
- package/lib/commonjs/index.test.js +51 -10
- package/lib/commonjs/integrations/ramps/index.js +2 -0
- package/lib/commonjs/integrations/ramps/meld/index.js +121 -0
- package/lib/commonjs/integrations/ramps/meld/index.test.js +162 -0
- package/lib/commonjs/integrations/ramps/noah/index.js +2 -2
- package/lib/commonjs/integrations/ramps/noah/index.test.js +11 -2
- package/lib/commonjs/mpc/index.js +199 -3
- package/lib/commonjs/mpc/index.test.js +634 -0
- package/lib/commonjs/provider/index.js +44 -2
- package/lib/commonjs/provider/index.test.js +186 -0
- package/lib/commonjs/rpc.test.js +162 -0
- package/lib/commonjs/shared/rpc/auth.js +29 -0
- package/lib/commonjs/shared/rpc/defaults.js +40 -0
- package/lib/commonjs/shared/types/index.js +1 -0
- package/lib/commonjs/shared/types/meld.js +2 -0
- package/lib/esm/index.js +59 -19
- package/lib/esm/index.test.js +51 -10
- package/lib/esm/integrations/ramps/index.js +2 -0
- package/lib/esm/integrations/ramps/meld/index.js +118 -0
- package/lib/esm/integrations/ramps/meld/index.test.js +157 -0
- package/lib/esm/integrations/ramps/noah/index.js +2 -2
- package/lib/esm/integrations/ramps/noah/index.test.js +11 -2
- package/lib/esm/mpc/index.js +199 -3
- package/lib/esm/mpc/index.test.js +635 -1
- package/lib/esm/provider/index.js +44 -2
- package/lib/esm/provider/index.test.js +186 -0
- package/lib/esm/rpc.test.js +157 -0
- package/lib/esm/shared/rpc/auth.js +25 -0
- package/lib/esm/shared/rpc/defaults.js +36 -0
- package/lib/esm/shared/types/index.js +1 -0
- package/lib/esm/shared/types/meld.js +1 -0
- package/noah-types.d.ts +17 -1
- package/package.json +1 -1
- package/src/__mocks/constants.ts +68 -0
- package/src/__mocks/portal/portal.ts +0 -1
- package/src/index.test.ts +90 -0
- package/src/index.ts +159 -7
- package/src/integrations/ramps/index.ts +3 -0
- package/src/integrations/ramps/meld/index.test.ts +189 -0
- package/src/integrations/ramps/meld/index.ts +149 -0
- package/src/integrations/ramps/noah/index.test.ts +11 -2
- package/src/integrations/ramps/noah/index.ts +5 -2
- package/src/mpc/index.test.ts +804 -7
- package/src/mpc/index.ts +247 -3
- package/src/provider/index.test.ts +233 -0
- package/src/provider/index.ts +64 -1
- package/src/rpc.test.ts +190 -0
- package/src/shared/rpc/auth.ts +27 -0
- package/src/shared/rpc/defaults.ts +41 -0
- package/src/shared/types/common.ts +24 -0
- package/src/shared/types/index.ts +1 -0
- package/src/shared/types/meld.ts +302 -0
- package/src/shared/types/noah.ts +191 -29
- package/types.d.ts +65 -3
package/lib/esm/mpc/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import { PortalMpcError } from './errors';
|
|
|
11
11
|
import { sdkLogger } from '../logger';
|
|
12
12
|
import { BackupMethods, } from '../index';
|
|
13
13
|
import { generateTraceId } from '../shared/trace';
|
|
14
|
-
const WEB_SDK_VERSION = '3.
|
|
14
|
+
const WEB_SDK_VERSION = '3.18.0';
|
|
15
15
|
class Mpc {
|
|
16
16
|
get ready() {
|
|
17
17
|
return this._ready;
|
|
@@ -217,7 +217,10 @@ class Mpc {
|
|
|
217
217
|
});
|
|
218
218
|
}
|
|
219
219
|
rawSign(curve, param, options) {
|
|
220
|
+
var _a;
|
|
220
221
|
return __awaiter(this, void 0, void 0, function* () {
|
|
222
|
+
const traceId = (_a = options === null || options === void 0 ? void 0 : options.traceId) !== null && _a !== void 0 ? _a : generateTraceId();
|
|
223
|
+
sdkLogger.debug(`[Portal MPC] rawSign started | traceId=${traceId}`);
|
|
221
224
|
return this.handleRequestToIframeAndPost({
|
|
222
225
|
methodMessage: 'portal:mpc:rawSign',
|
|
223
226
|
errorMessage: 'portal:mpc:rawSignError',
|
|
@@ -226,7 +229,7 @@ class Mpc {
|
|
|
226
229
|
param }, ((options === null || options === void 0 ? void 0 : options.signatureApprovalMemo) !== undefined && {
|
|
227
230
|
signatureApprovalMemo: options.signatureApprovalMemo,
|
|
228
231
|
})),
|
|
229
|
-
traceId
|
|
232
|
+
traceId,
|
|
230
233
|
});
|
|
231
234
|
});
|
|
232
235
|
}
|
|
@@ -705,16 +708,176 @@ class Mpc {
|
|
|
705
708
|
});
|
|
706
709
|
});
|
|
707
710
|
}
|
|
708
|
-
getPaymentMethods() {
|
|
711
|
+
getPaymentMethods(data) {
|
|
709
712
|
return __awaiter(this, void 0, void 0, function* () {
|
|
710
713
|
return this.handleRequestToIframeAndPost({
|
|
711
714
|
methodMessage: 'portal:noah:getPaymentMethods',
|
|
712
715
|
errorMessage: 'portal:noah:getPaymentMethodsError',
|
|
713
716
|
resultMessage: 'portal:noah:getPaymentMethodsResult',
|
|
717
|
+
data,
|
|
718
|
+
});
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
meldCreateCustomer(data) {
|
|
722
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
723
|
+
return this.handleRequestToIframeAndPost({
|
|
724
|
+
methodMessage: 'portal:meld:createCustomer',
|
|
725
|
+
errorMessage: 'portal:meld:createCustomerError',
|
|
726
|
+
resultMessage: 'portal:meld:createCustomerResult',
|
|
727
|
+
data,
|
|
728
|
+
});
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
meldSearchCustomer() {
|
|
732
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
733
|
+
return this.handleRequestToIframeAndPost({
|
|
734
|
+
methodMessage: 'portal:meld:searchCustomer',
|
|
735
|
+
errorMessage: 'portal:meld:searchCustomerError',
|
|
736
|
+
resultMessage: 'portal:meld:searchCustomerResult',
|
|
714
737
|
data: {},
|
|
715
738
|
});
|
|
716
739
|
});
|
|
717
740
|
}
|
|
741
|
+
meldGetRetailQuote(data) {
|
|
742
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
743
|
+
return this.handleRequestToIframeAndPost({
|
|
744
|
+
methodMessage: 'portal:meld:getRetailQuote',
|
|
745
|
+
errorMessage: 'portal:meld:getRetailQuoteError',
|
|
746
|
+
resultMessage: 'portal:meld:getRetailQuoteResult',
|
|
747
|
+
data,
|
|
748
|
+
});
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
meldCreateRetailWidget(data) {
|
|
752
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
753
|
+
return this.handleRequestToIframeAndPost({
|
|
754
|
+
methodMessage: 'portal:meld:createRetailWidget',
|
|
755
|
+
errorMessage: 'portal:meld:createRetailWidgetError',
|
|
756
|
+
resultMessage: 'portal:meld:createRetailWidgetResult',
|
|
757
|
+
data,
|
|
758
|
+
});
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
meldSearchRetailTransactions(data) {
|
|
762
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
763
|
+
return this.handleRequestToIframeAndPost({
|
|
764
|
+
methodMessage: 'portal:meld:searchRetailTransactions',
|
|
765
|
+
errorMessage: 'portal:meld:searchRetailTransactionsError',
|
|
766
|
+
resultMessage: 'portal:meld:searchRetailTransactionsResult',
|
|
767
|
+
data,
|
|
768
|
+
});
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
meldGetRetailTransactionBySession(sessionId) {
|
|
772
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
773
|
+
return this.handleRequestToIframeAndPost({
|
|
774
|
+
methodMessage: 'portal:meld:getRetailTransactionBySession',
|
|
775
|
+
errorMessage: 'portal:meld:getRetailTransactionBySessionError',
|
|
776
|
+
resultMessage: 'portal:meld:getRetailTransactionBySessionResult',
|
|
777
|
+
data: sessionId,
|
|
778
|
+
});
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
meldGetRetailTransaction(id) {
|
|
782
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
783
|
+
return this.handleRequestToIframeAndPost({
|
|
784
|
+
methodMessage: 'portal:meld:getRetailTransaction',
|
|
785
|
+
errorMessage: 'portal:meld:getRetailTransactionError',
|
|
786
|
+
resultMessage: 'portal:meld:getRetailTransactionResult',
|
|
787
|
+
data: id,
|
|
788
|
+
});
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
meldGetServiceProviders(data) {
|
|
792
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
793
|
+
return this.handleRequestToIframeAndPost({
|
|
794
|
+
methodMessage: 'portal:meld:getServiceProviders',
|
|
795
|
+
errorMessage: 'portal:meld:getServiceProvidersError',
|
|
796
|
+
resultMessage: 'portal:meld:getServiceProvidersResult',
|
|
797
|
+
data: data !== null && data !== void 0 ? data : {},
|
|
798
|
+
});
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
meldGetCountries(data) {
|
|
802
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
803
|
+
return this.handleRequestToIframeAndPost({
|
|
804
|
+
methodMessage: 'portal:meld:getCountries',
|
|
805
|
+
errorMessage: 'portal:meld:getCountriesError',
|
|
806
|
+
resultMessage: 'portal:meld:getCountriesResult',
|
|
807
|
+
data: data !== null && data !== void 0 ? data : {},
|
|
808
|
+
});
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
meldGetFiatCurrencies(data) {
|
|
812
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
813
|
+
return this.handleRequestToIframeAndPost({
|
|
814
|
+
methodMessage: 'portal:meld:getFiatCurrencies',
|
|
815
|
+
errorMessage: 'portal:meld:getFiatCurrenciesError',
|
|
816
|
+
resultMessage: 'portal:meld:getFiatCurrenciesResult',
|
|
817
|
+
data: data !== null && data !== void 0 ? data : {},
|
|
818
|
+
});
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
meldGetCryptoCurrencies(data) {
|
|
822
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
823
|
+
return this.handleRequestToIframeAndPost({
|
|
824
|
+
methodMessage: 'portal:meld:getCryptoCurrencies',
|
|
825
|
+
errorMessage: 'portal:meld:getCryptoCurrenciesError',
|
|
826
|
+
resultMessage: 'portal:meld:getCryptoCurrenciesResult',
|
|
827
|
+
data: data !== null && data !== void 0 ? data : {},
|
|
828
|
+
});
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
meldGetPaymentMethods(data) {
|
|
832
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
833
|
+
return this.handleRequestToIframeAndPost({
|
|
834
|
+
methodMessage: 'portal:meld:getPaymentMethods',
|
|
835
|
+
errorMessage: 'portal:meld:getPaymentMethodsError',
|
|
836
|
+
resultMessage: 'portal:meld:getPaymentMethodsResult',
|
|
837
|
+
data: data !== null && data !== void 0 ? data : {},
|
|
838
|
+
});
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
meldGetDefaults(data) {
|
|
842
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
843
|
+
return this.handleRequestToIframeAndPost({
|
|
844
|
+
methodMessage: 'portal:meld:getDefaults',
|
|
845
|
+
errorMessage: 'portal:meld:getDefaultsError',
|
|
846
|
+
resultMessage: 'portal:meld:getDefaultsResult',
|
|
847
|
+
data: data !== null && data !== void 0 ? data : {},
|
|
848
|
+
});
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
meldGetBuyLimits(data) {
|
|
852
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
853
|
+
return this.handleRequestToIframeAndPost({
|
|
854
|
+
methodMessage: 'portal:meld:getBuyLimits',
|
|
855
|
+
errorMessage: 'portal:meld:getBuyLimitsError',
|
|
856
|
+
resultMessage: 'portal:meld:getBuyLimitsResult',
|
|
857
|
+
data: data !== null && data !== void 0 ? data : {},
|
|
858
|
+
});
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
meldGetSellLimits(data) {
|
|
862
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
863
|
+
return this.handleRequestToIframeAndPost({
|
|
864
|
+
methodMessage: 'portal:meld:getSellLimits',
|
|
865
|
+
errorMessage: 'portal:meld:getSellLimitsError',
|
|
866
|
+
resultMessage: 'portal:meld:getSellLimitsResult',
|
|
867
|
+
data: data !== null && data !== void 0 ? data : {},
|
|
868
|
+
});
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
meldGetKycLimits(data) {
|
|
872
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
873
|
+
return this.handleRequestToIframeAndPost({
|
|
874
|
+
methodMessage: 'portal:meld:getKycLimits',
|
|
875
|
+
errorMessage: 'portal:meld:getKycLimitsError',
|
|
876
|
+
resultMessage: 'portal:meld:getKycLimitsResult',
|
|
877
|
+
data: data !== null && data !== void 0 ? data : {},
|
|
878
|
+
});
|
|
879
|
+
});
|
|
880
|
+
}
|
|
718
881
|
getSwapsQuoteV2(data, options) {
|
|
719
882
|
return __awaiter(this, void 0, void 0, function* () {
|
|
720
883
|
return this.handleRequestToIframeAndPost({
|
|
@@ -959,6 +1122,12 @@ class Mpc {
|
|
|
959
1122
|
handleRequestToIframeAndPost({ methodMessage, errorMessage, resultMessage, data, progressMessage, progressCallback, mapReturnValue, traceId: providedTraceId, }) {
|
|
960
1123
|
return __awaiter(this, void 0, void 0, function* () {
|
|
961
1124
|
// Single traceId per operation: use provided or generate. Propagates to iframe and all internal REST/MPC calls.
|
|
1125
|
+
if (!providedTraceId &&
|
|
1126
|
+
(methodMessage.startsWith('portal:wasm:') ||
|
|
1127
|
+
methodMessage.startsWith('portal:mpc:') ||
|
|
1128
|
+
methodMessage.startsWith('portal:accountAbstraction:'))) {
|
|
1129
|
+
sdkLogger.debug(`[Portal] No traceId propagated to handleRequestToIframeAndPost for method=${methodMessage}; generating a new one.`);
|
|
1130
|
+
}
|
|
962
1131
|
const traceId = providedTraceId !== null && providedTraceId !== void 0 ? providedTraceId : generateTraceId();
|
|
963
1132
|
sdkLogger.debug('[Portal] request traceId:', traceId, 'method:', methodMessage);
|
|
964
1133
|
return new Promise((resolve, reject) => {
|
|
@@ -1175,6 +1344,33 @@ class Mpc {
|
|
|
1175
1344
|
// Update the address
|
|
1176
1345
|
const address = yield this.getAddress();
|
|
1177
1346
|
this.portal.address = address;
|
|
1347
|
+
// Detect if wallet shares were cleared from storage (e.g., Safari ITP).
|
|
1348
|
+
// Must be awaited before triggerReady so the event fires before app callbacks run.
|
|
1349
|
+
try {
|
|
1350
|
+
const [client, shares] = yield Promise.all([
|
|
1351
|
+
this.getClient(),
|
|
1352
|
+
this.checkSharesOnDevice(),
|
|
1353
|
+
]);
|
|
1354
|
+
const completedWallets = client.wallets.filter((w) => w.signingSharePairs.some((sp) => sp.status === 'completed'));
|
|
1355
|
+
const requiredCurves = completedWallets.map((w) => w.curve);
|
|
1356
|
+
const walletOnDevice = requiredCurves.length > 0 &&
|
|
1357
|
+
requiredCurves.every((curve) => !!shares[curve]);
|
|
1358
|
+
// No completed wallets means the user is in initial setup — no prior
|
|
1359
|
+
// device state to have been lost.
|
|
1360
|
+
const isInitialSetup = completedWallets.length === 0;
|
|
1361
|
+
const shouldEmitWalletNotOnDevice = !isInitialSetup && !walletOnDevice && !client.ejectedAt;
|
|
1362
|
+
if (shouldEmitWalletNotOnDevice) {
|
|
1363
|
+
const isBackedUp = client.wallets.some((w) => w.backupSharePairs.some((bp) => bp.status === 'completed'));
|
|
1364
|
+
this.portal.triggerWalletNotOnDevice({
|
|
1365
|
+
clientId: client.id,
|
|
1366
|
+
isBackedUp,
|
|
1367
|
+
reason: 'storage_cleared',
|
|
1368
|
+
});
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
catch (detectionError) {
|
|
1372
|
+
sdkLogger.warn('[Portal] walletNotOnDevice detection failed (initialization continues):', detectionError);
|
|
1373
|
+
}
|
|
1178
1374
|
// Trigger the ready callback
|
|
1179
1375
|
this.portal.triggerReady();
|
|
1180
1376
|
}
|