@portal-hq/web 3.17.0-alpha.0 → 3.18.0-alpha.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 +2 -2
- 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
|
@@ -3764,6 +3764,513 @@ describe('Mpc', () => {
|
|
|
3764
3764
|
});
|
|
3765
3765
|
});
|
|
3766
3766
|
});
|
|
3767
|
+
describe('meldCreateCustomer', () => {
|
|
3768
|
+
const args = constants_1.mockMeldCreateCustomerRequest;
|
|
3769
|
+
const res = constants_1.mockMeldCreateCustomerResponse;
|
|
3770
|
+
it('should successfully return the created customer', (done) => {
|
|
3771
|
+
var _a;
|
|
3772
|
+
jest
|
|
3773
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
3774
|
+
.mockImplementation((message, origin) => {
|
|
3775
|
+
const { type, data } = message;
|
|
3776
|
+
expect(type).toEqual('portal:meld:createCustomer');
|
|
3777
|
+
expect(data).toMatchObject(args);
|
|
3778
|
+
expect(typeof message.traceId).toBe('string');
|
|
3779
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
3780
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
3781
|
+
origin: mockHostOrigin,
|
|
3782
|
+
data: {
|
|
3783
|
+
type: 'portal:meld:createCustomerResult',
|
|
3784
|
+
data: res,
|
|
3785
|
+
},
|
|
3786
|
+
}));
|
|
3787
|
+
});
|
|
3788
|
+
mpc
|
|
3789
|
+
.meldCreateCustomer(args)
|
|
3790
|
+
.then((data) => {
|
|
3791
|
+
expect(data).toEqual(res);
|
|
3792
|
+
done();
|
|
3793
|
+
})
|
|
3794
|
+
.catch((_) => {
|
|
3795
|
+
expect(0).toEqual(1);
|
|
3796
|
+
done();
|
|
3797
|
+
});
|
|
3798
|
+
});
|
|
3799
|
+
it('should error out if the iframe sends an error message', (done) => {
|
|
3800
|
+
var _a;
|
|
3801
|
+
jest
|
|
3802
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
3803
|
+
.mockImplementationOnce((message, origin) => {
|
|
3804
|
+
const { type } = message;
|
|
3805
|
+
expect(type).toEqual('portal:meld:createCustomer');
|
|
3806
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
3807
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
3808
|
+
origin: mockHostOrigin,
|
|
3809
|
+
data: {
|
|
3810
|
+
type: 'portal:meld:createCustomerError',
|
|
3811
|
+
data: { code: 1, message: 'test' },
|
|
3812
|
+
},
|
|
3813
|
+
}));
|
|
3814
|
+
});
|
|
3815
|
+
mpc
|
|
3816
|
+
.meldCreateCustomer(args)
|
|
3817
|
+
.then(() => {
|
|
3818
|
+
expect(0).toEqual(1);
|
|
3819
|
+
done();
|
|
3820
|
+
})
|
|
3821
|
+
.catch((e) => {
|
|
3822
|
+
expect(e).toBeInstanceOf(errors_1.PortalMpcError);
|
|
3823
|
+
expect(e.message).toEqual('test');
|
|
3824
|
+
expect(e.code).toEqual(1);
|
|
3825
|
+
done();
|
|
3826
|
+
});
|
|
3827
|
+
});
|
|
3828
|
+
});
|
|
3829
|
+
describe('meldSearchCustomer', () => {
|
|
3830
|
+
const res = constants_1.mockMeldSearchCustomerResponse;
|
|
3831
|
+
it('should successfully return the customer data', (done) => {
|
|
3832
|
+
var _a;
|
|
3833
|
+
jest
|
|
3834
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
3835
|
+
.mockImplementation((message, origin) => {
|
|
3836
|
+
const { type } = message;
|
|
3837
|
+
expect(type).toEqual('portal:meld:searchCustomer');
|
|
3838
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
3839
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
3840
|
+
origin: mockHostOrigin,
|
|
3841
|
+
data: {
|
|
3842
|
+
type: 'portal:meld:searchCustomerResult',
|
|
3843
|
+
data: res,
|
|
3844
|
+
},
|
|
3845
|
+
}));
|
|
3846
|
+
});
|
|
3847
|
+
mpc
|
|
3848
|
+
.meldSearchCustomer()
|
|
3849
|
+
.then((data) => {
|
|
3850
|
+
expect(data).toEqual(res);
|
|
3851
|
+
done();
|
|
3852
|
+
})
|
|
3853
|
+
.catch((_) => {
|
|
3854
|
+
expect(0).toEqual(1);
|
|
3855
|
+
done();
|
|
3856
|
+
});
|
|
3857
|
+
});
|
|
3858
|
+
it('should error out if the iframe sends an error message', (done) => {
|
|
3859
|
+
var _a;
|
|
3860
|
+
jest
|
|
3861
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
3862
|
+
.mockImplementationOnce((_message, _origin) => {
|
|
3863
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
3864
|
+
origin: mockHostOrigin,
|
|
3865
|
+
data: {
|
|
3866
|
+
type: 'portal:meld:searchCustomerError',
|
|
3867
|
+
data: { code: 2, message: 'not found' },
|
|
3868
|
+
},
|
|
3869
|
+
}));
|
|
3870
|
+
});
|
|
3871
|
+
mpc
|
|
3872
|
+
.meldSearchCustomer()
|
|
3873
|
+
.then(() => {
|
|
3874
|
+
expect(0).toEqual(1);
|
|
3875
|
+
done();
|
|
3876
|
+
})
|
|
3877
|
+
.catch((e) => {
|
|
3878
|
+
expect(e).toBeInstanceOf(errors_1.PortalMpcError);
|
|
3879
|
+
expect(e.code).toEqual(2);
|
|
3880
|
+
done();
|
|
3881
|
+
});
|
|
3882
|
+
});
|
|
3883
|
+
});
|
|
3884
|
+
describe('meldGetRetailQuote', () => {
|
|
3885
|
+
const args = constants_1.mockMeldGetRetailQuoteRequest;
|
|
3886
|
+
const res = constants_1.mockMeldGetRetailQuoteResponse;
|
|
3887
|
+
it('should successfully return the retail quote', (done) => {
|
|
3888
|
+
var _a;
|
|
3889
|
+
jest
|
|
3890
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
3891
|
+
.mockImplementation((message, origin) => {
|
|
3892
|
+
const { type, data } = message;
|
|
3893
|
+
expect(type).toEqual('portal:meld:getRetailQuote');
|
|
3894
|
+
expect(data).toMatchObject(args);
|
|
3895
|
+
expect(typeof message.traceId).toBe('string');
|
|
3896
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
3897
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
3898
|
+
origin: mockHostOrigin,
|
|
3899
|
+
data: {
|
|
3900
|
+
type: 'portal:meld:getRetailQuoteResult',
|
|
3901
|
+
data: res,
|
|
3902
|
+
},
|
|
3903
|
+
}));
|
|
3904
|
+
});
|
|
3905
|
+
mpc
|
|
3906
|
+
.meldGetRetailQuote(args)
|
|
3907
|
+
.then((data) => {
|
|
3908
|
+
expect(data).toEqual(res);
|
|
3909
|
+
done();
|
|
3910
|
+
})
|
|
3911
|
+
.catch((_) => {
|
|
3912
|
+
expect(0).toEqual(1);
|
|
3913
|
+
done();
|
|
3914
|
+
});
|
|
3915
|
+
});
|
|
3916
|
+
it('should error out if the iframe sends an error message', (done) => {
|
|
3917
|
+
var _a;
|
|
3918
|
+
jest
|
|
3919
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
3920
|
+
.mockImplementationOnce((_message, _origin) => {
|
|
3921
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
3922
|
+
origin: mockHostOrigin,
|
|
3923
|
+
data: {
|
|
3924
|
+
type: 'portal:meld:getRetailQuoteError',
|
|
3925
|
+
data: { code: 1, message: 'test' },
|
|
3926
|
+
},
|
|
3927
|
+
}));
|
|
3928
|
+
});
|
|
3929
|
+
mpc
|
|
3930
|
+
.meldGetRetailQuote(args)
|
|
3931
|
+
.then(() => {
|
|
3932
|
+
expect(0).toEqual(1);
|
|
3933
|
+
done();
|
|
3934
|
+
})
|
|
3935
|
+
.catch((e) => {
|
|
3936
|
+
expect(e).toBeInstanceOf(errors_1.PortalMpcError);
|
|
3937
|
+
expect(e.message).toEqual('test');
|
|
3938
|
+
expect(e.code).toEqual(1);
|
|
3939
|
+
done();
|
|
3940
|
+
});
|
|
3941
|
+
});
|
|
3942
|
+
});
|
|
3943
|
+
describe('meldCreateRetailWidget', () => {
|
|
3944
|
+
const args = constants_1.mockMeldCreateRetailWidgetRequest;
|
|
3945
|
+
const res = constants_1.mockMeldCreateRetailWidgetResponse;
|
|
3946
|
+
it('should successfully return the retail widget', (done) => {
|
|
3947
|
+
var _a;
|
|
3948
|
+
jest
|
|
3949
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
3950
|
+
.mockImplementation((message, origin) => {
|
|
3951
|
+
expect(message.type).toEqual('portal:meld:createRetailWidget');
|
|
3952
|
+
expect(message.data).toMatchObject(args);
|
|
3953
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
3954
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
3955
|
+
origin: mockHostOrigin,
|
|
3956
|
+
data: { type: 'portal:meld:createRetailWidgetResult', data: res },
|
|
3957
|
+
}));
|
|
3958
|
+
});
|
|
3959
|
+
mpc
|
|
3960
|
+
.meldCreateRetailWidget(args)
|
|
3961
|
+
.then((data) => {
|
|
3962
|
+
expect(data).toEqual(res);
|
|
3963
|
+
done();
|
|
3964
|
+
})
|
|
3965
|
+
.catch((_) => {
|
|
3966
|
+
expect(0).toEqual(1);
|
|
3967
|
+
done();
|
|
3968
|
+
});
|
|
3969
|
+
});
|
|
3970
|
+
});
|
|
3971
|
+
describe('meldSearchRetailTransactions', () => {
|
|
3972
|
+
const res = constants_1.mockMeldSearchRetailTransactionsResponse;
|
|
3973
|
+
it('should successfully return transactions without params', (done) => {
|
|
3974
|
+
var _a;
|
|
3975
|
+
jest
|
|
3976
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
3977
|
+
.mockImplementation((message, origin) => {
|
|
3978
|
+
expect(message.type).toEqual('portal:meld:searchRetailTransactions');
|
|
3979
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
3980
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
3981
|
+
origin: mockHostOrigin,
|
|
3982
|
+
data: { type: 'portal:meld:searchRetailTransactionsResult', data: res },
|
|
3983
|
+
}));
|
|
3984
|
+
});
|
|
3985
|
+
mpc
|
|
3986
|
+
.meldSearchRetailTransactions()
|
|
3987
|
+
.then((data) => {
|
|
3988
|
+
expect(data).toEqual(res);
|
|
3989
|
+
done();
|
|
3990
|
+
})
|
|
3991
|
+
.catch((_) => {
|
|
3992
|
+
expect(0).toEqual(1);
|
|
3993
|
+
done();
|
|
3994
|
+
});
|
|
3995
|
+
});
|
|
3996
|
+
});
|
|
3997
|
+
describe('meldGetRetailTransactionBySession', () => {
|
|
3998
|
+
const res = constants_1.mockMeldGetRetailTransactionResponse;
|
|
3999
|
+
it('should successfully return a transaction by session ID', (done) => {
|
|
4000
|
+
var _a;
|
|
4001
|
+
jest
|
|
4002
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
4003
|
+
.mockImplementation((message, origin) => {
|
|
4004
|
+
expect(message.type).toEqual('portal:meld:getRetailTransactionBySession');
|
|
4005
|
+
expect(message.data).toEqual('ses-123');
|
|
4006
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
4007
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4008
|
+
origin: mockHostOrigin,
|
|
4009
|
+
data: { type: 'portal:meld:getRetailTransactionBySessionResult', data: res },
|
|
4010
|
+
}));
|
|
4011
|
+
});
|
|
4012
|
+
mpc
|
|
4013
|
+
.meldGetRetailTransactionBySession('ses-123')
|
|
4014
|
+
.then((data) => {
|
|
4015
|
+
expect(data).toEqual(res);
|
|
4016
|
+
done();
|
|
4017
|
+
})
|
|
4018
|
+
.catch((_) => {
|
|
4019
|
+
expect(0).toEqual(1);
|
|
4020
|
+
done();
|
|
4021
|
+
});
|
|
4022
|
+
});
|
|
4023
|
+
});
|
|
4024
|
+
describe('meldGetRetailTransaction', () => {
|
|
4025
|
+
const res = constants_1.mockMeldGetRetailTransactionResponse;
|
|
4026
|
+
it('should successfully return a transaction by ID', (done) => {
|
|
4027
|
+
var _a;
|
|
4028
|
+
jest
|
|
4029
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
4030
|
+
.mockImplementation((message, origin) => {
|
|
4031
|
+
expect(message.type).toEqual('portal:meld:getRetailTransaction');
|
|
4032
|
+
expect(message.data).toEqual('tx-123');
|
|
4033
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
4034
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4035
|
+
origin: mockHostOrigin,
|
|
4036
|
+
data: { type: 'portal:meld:getRetailTransactionResult', data: res },
|
|
4037
|
+
}));
|
|
4038
|
+
});
|
|
4039
|
+
mpc
|
|
4040
|
+
.meldGetRetailTransaction('tx-123')
|
|
4041
|
+
.then((data) => {
|
|
4042
|
+
expect(data).toEqual(res);
|
|
4043
|
+
done();
|
|
4044
|
+
})
|
|
4045
|
+
.catch((_) => {
|
|
4046
|
+
expect(0).toEqual(1);
|
|
4047
|
+
done();
|
|
4048
|
+
});
|
|
4049
|
+
});
|
|
4050
|
+
});
|
|
4051
|
+
describe('meldGetServiceProviders', () => {
|
|
4052
|
+
const res = constants_1.mockMeldDiscoveryResponse;
|
|
4053
|
+
it('should successfully return service providers without params', (done) => {
|
|
4054
|
+
var _a;
|
|
4055
|
+
jest
|
|
4056
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
4057
|
+
.mockImplementation((message, origin) => {
|
|
4058
|
+
expect(message.type).toEqual('portal:meld:getServiceProviders');
|
|
4059
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
4060
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4061
|
+
origin: mockHostOrigin,
|
|
4062
|
+
data: { type: 'portal:meld:getServiceProvidersResult', data: res },
|
|
4063
|
+
}));
|
|
4064
|
+
});
|
|
4065
|
+
mpc
|
|
4066
|
+
.meldGetServiceProviders()
|
|
4067
|
+
.then((data) => {
|
|
4068
|
+
expect(data).toEqual(res);
|
|
4069
|
+
done();
|
|
4070
|
+
})
|
|
4071
|
+
.catch((_) => {
|
|
4072
|
+
expect(0).toEqual(1);
|
|
4073
|
+
done();
|
|
4074
|
+
});
|
|
4075
|
+
});
|
|
4076
|
+
it('should pass params to the iframe when provided', (done) => {
|
|
4077
|
+
var _a;
|
|
4078
|
+
const params = constants_1.mockMeldDiscoveryParams;
|
|
4079
|
+
jest
|
|
4080
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
4081
|
+
.mockImplementation((message, origin) => {
|
|
4082
|
+
expect(message.type).toEqual('portal:meld:getServiceProviders');
|
|
4083
|
+
expect(message.data).toMatchObject(params);
|
|
4084
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
4085
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4086
|
+
origin: mockHostOrigin,
|
|
4087
|
+
data: { type: 'portal:meld:getServiceProvidersResult', data: res },
|
|
4088
|
+
}));
|
|
4089
|
+
});
|
|
4090
|
+
mpc
|
|
4091
|
+
.meldGetServiceProviders(params)
|
|
4092
|
+
.then(() => done())
|
|
4093
|
+
.catch((_) => {
|
|
4094
|
+
expect(0).toEqual(1);
|
|
4095
|
+
done();
|
|
4096
|
+
});
|
|
4097
|
+
});
|
|
4098
|
+
});
|
|
4099
|
+
describe('meldGetCountries', () => {
|
|
4100
|
+
it('should successfully return countries', (done) => {
|
|
4101
|
+
var _a;
|
|
4102
|
+
const res = constants_1.mockMeldDiscoveryResponse;
|
|
4103
|
+
jest
|
|
4104
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
4105
|
+
.mockImplementation((message, origin) => {
|
|
4106
|
+
expect(message.type).toEqual('portal:meld:getCountries');
|
|
4107
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
4108
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4109
|
+
origin: mockHostOrigin,
|
|
4110
|
+
data: { type: 'portal:meld:getCountriesResult', data: res },
|
|
4111
|
+
}));
|
|
4112
|
+
});
|
|
4113
|
+
mpc
|
|
4114
|
+
.meldGetCountries()
|
|
4115
|
+
.then((data) => {
|
|
4116
|
+
expect(data).toEqual(res);
|
|
4117
|
+
done();
|
|
4118
|
+
})
|
|
4119
|
+
.catch((_) => {
|
|
4120
|
+
expect(0).toEqual(1);
|
|
4121
|
+
done();
|
|
4122
|
+
});
|
|
4123
|
+
});
|
|
4124
|
+
it('should error out if the iframe sends an error message', (done) => {
|
|
4125
|
+
var _a;
|
|
4126
|
+
jest
|
|
4127
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
4128
|
+
.mockImplementationOnce((_message, _origin) => {
|
|
4129
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4130
|
+
origin: mockHostOrigin,
|
|
4131
|
+
data: { type: 'portal:meld:getCountriesError', data: { code: 1, message: 'test' } },
|
|
4132
|
+
}));
|
|
4133
|
+
});
|
|
4134
|
+
mpc
|
|
4135
|
+
.meldGetCountries()
|
|
4136
|
+
.then(() => {
|
|
4137
|
+
expect(0).toEqual(1);
|
|
4138
|
+
done();
|
|
4139
|
+
})
|
|
4140
|
+
.catch((e) => {
|
|
4141
|
+
expect(e).toBeInstanceOf(errors_1.PortalMpcError);
|
|
4142
|
+
done();
|
|
4143
|
+
});
|
|
4144
|
+
});
|
|
4145
|
+
});
|
|
4146
|
+
describe('meldGetFiatCurrencies', () => {
|
|
4147
|
+
it('should successfully return fiat currencies', (done) => {
|
|
4148
|
+
var _a;
|
|
4149
|
+
const res = constants_1.mockMeldDiscoveryResponse;
|
|
4150
|
+
jest
|
|
4151
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
4152
|
+
.mockImplementation((message, origin) => {
|
|
4153
|
+
expect(message.type).toEqual('portal:meld:getFiatCurrencies');
|
|
4154
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
4155
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4156
|
+
origin: mockHostOrigin,
|
|
4157
|
+
data: { type: 'portal:meld:getFiatCurrenciesResult', data: res },
|
|
4158
|
+
}));
|
|
4159
|
+
});
|
|
4160
|
+
mpc
|
|
4161
|
+
.meldGetFiatCurrencies()
|
|
4162
|
+
.then((data) => {
|
|
4163
|
+
expect(data).toEqual(res);
|
|
4164
|
+
done();
|
|
4165
|
+
})
|
|
4166
|
+
.catch((_) => {
|
|
4167
|
+
expect(0).toEqual(1);
|
|
4168
|
+
done();
|
|
4169
|
+
});
|
|
4170
|
+
});
|
|
4171
|
+
});
|
|
4172
|
+
describe('meldGetCryptoCurrencies', () => {
|
|
4173
|
+
it('should successfully return crypto currencies', (done) => {
|
|
4174
|
+
var _a;
|
|
4175
|
+
const res = constants_1.mockMeldDiscoveryResponse;
|
|
4176
|
+
jest
|
|
4177
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
4178
|
+
.mockImplementation((message, origin) => {
|
|
4179
|
+
expect(message.type).toEqual('portal:meld:getCryptoCurrencies');
|
|
4180
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
4181
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4182
|
+
origin: mockHostOrigin,
|
|
4183
|
+
data: { type: 'portal:meld:getCryptoCurrenciesResult', data: res },
|
|
4184
|
+
}));
|
|
4185
|
+
});
|
|
4186
|
+
mpc.meldGetCryptoCurrencies().then((data) => { expect(data).toEqual(res); done(); }).catch((_) => { expect(0).toEqual(1); done(); });
|
|
4187
|
+
});
|
|
4188
|
+
});
|
|
4189
|
+
describe('meldGetPaymentMethods', () => {
|
|
4190
|
+
it('should successfully return payment methods', (done) => {
|
|
4191
|
+
var _a;
|
|
4192
|
+
const res = constants_1.mockMeldDiscoveryResponse;
|
|
4193
|
+
jest
|
|
4194
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
4195
|
+
.mockImplementation((message, origin) => {
|
|
4196
|
+
expect(message.type).toEqual('portal:meld:getPaymentMethods');
|
|
4197
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
4198
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4199
|
+
origin: mockHostOrigin,
|
|
4200
|
+
data: { type: 'portal:meld:getPaymentMethodsResult', data: res },
|
|
4201
|
+
}));
|
|
4202
|
+
});
|
|
4203
|
+
mpc.meldGetPaymentMethods().then((data) => { expect(data).toEqual(res); done(); }).catch((_) => { expect(0).toEqual(1); done(); });
|
|
4204
|
+
});
|
|
4205
|
+
});
|
|
4206
|
+
describe('meldGetDefaults', () => {
|
|
4207
|
+
it('should successfully return defaults', (done) => {
|
|
4208
|
+
var _a;
|
|
4209
|
+
const res = constants_1.mockMeldDiscoveryResponse;
|
|
4210
|
+
jest
|
|
4211
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
4212
|
+
.mockImplementation((message, origin) => {
|
|
4213
|
+
expect(message.type).toEqual('portal:meld:getDefaults');
|
|
4214
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
4215
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4216
|
+
origin: mockHostOrigin,
|
|
4217
|
+
data: { type: 'portal:meld:getDefaultsResult', data: res },
|
|
4218
|
+
}));
|
|
4219
|
+
});
|
|
4220
|
+
mpc.meldGetDefaults().then((data) => { expect(data).toEqual(res); done(); }).catch((_) => { expect(0).toEqual(1); done(); });
|
|
4221
|
+
});
|
|
4222
|
+
});
|
|
4223
|
+
describe('meldGetBuyLimits', () => {
|
|
4224
|
+
it('should successfully return buy limits', (done) => {
|
|
4225
|
+
var _a;
|
|
4226
|
+
const res = constants_1.mockMeldDiscoveryResponse;
|
|
4227
|
+
jest
|
|
4228
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
4229
|
+
.mockImplementation((message, origin) => {
|
|
4230
|
+
expect(message.type).toEqual('portal:meld:getBuyLimits');
|
|
4231
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
4232
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4233
|
+
origin: mockHostOrigin,
|
|
4234
|
+
data: { type: 'portal:meld:getBuyLimitsResult', data: res },
|
|
4235
|
+
}));
|
|
4236
|
+
});
|
|
4237
|
+
mpc.meldGetBuyLimits().then((data) => { expect(data).toEqual(res); done(); }).catch((_) => { expect(0).toEqual(1); done(); });
|
|
4238
|
+
});
|
|
4239
|
+
});
|
|
4240
|
+
describe('meldGetSellLimits', () => {
|
|
4241
|
+
it('should successfully return sell limits', (done) => {
|
|
4242
|
+
var _a;
|
|
4243
|
+
const res = constants_1.mockMeldDiscoveryResponse;
|
|
4244
|
+
jest
|
|
4245
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
4246
|
+
.mockImplementation((message, origin) => {
|
|
4247
|
+
expect(message.type).toEqual('portal:meld:getSellLimits');
|
|
4248
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
4249
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4250
|
+
origin: mockHostOrigin,
|
|
4251
|
+
data: { type: 'portal:meld:getSellLimitsResult', data: res },
|
|
4252
|
+
}));
|
|
4253
|
+
});
|
|
4254
|
+
mpc.meldGetSellLimits().then((data) => { expect(data).toEqual(res); done(); }).catch((_) => { expect(0).toEqual(1); done(); });
|
|
4255
|
+
});
|
|
4256
|
+
});
|
|
4257
|
+
describe('meldGetKycLimits', () => {
|
|
4258
|
+
it('should successfully return KYC limits', (done) => {
|
|
4259
|
+
var _a;
|
|
4260
|
+
const res = constants_1.mockMeldDiscoveryResponse;
|
|
4261
|
+
jest
|
|
4262
|
+
.spyOn((_a = mpc.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow, 'postMessage')
|
|
4263
|
+
.mockImplementation((message, origin) => {
|
|
4264
|
+
expect(message.type).toEqual('portal:meld:getKycLimits');
|
|
4265
|
+
expect(origin).toEqual(mockHostOrigin);
|
|
4266
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4267
|
+
origin: mockHostOrigin,
|
|
4268
|
+
data: { type: 'portal:meld:getKycLimitsResult', data: res },
|
|
4269
|
+
}));
|
|
4270
|
+
});
|
|
4271
|
+
mpc.meldGetKycLimits().then((data) => { expect(data).toEqual(res); done(); }).catch((_) => { expect(0).toEqual(1); done(); });
|
|
4272
|
+
});
|
|
4273
|
+
});
|
|
3767
4274
|
describe('accountAbstractionBuildBatchedUserOp', () => {
|
|
3768
4275
|
const args = constants_1.mockBuildBatchedUserOpRequest;
|
|
3769
4276
|
const res = constants_1.mockBuildBatchedUserOpResponse;
|
|
@@ -3898,4 +4405,131 @@ describe('Mpc', () => {
|
|
|
3898
4405
|
});
|
|
3899
4406
|
});
|
|
3900
4407
|
});
|
|
4408
|
+
describe('walletNotOnDevice detection', () => {
|
|
4409
|
+
const makeClient = (overrides = {}) => (Object.assign({ id: 'client-test', address: constants_1.mockAddress, ejectedAt: null, custodian: { id: 'c', name: 'c' }, environment: { id: 'e', name: 'e', backupWithPortalEnabled: false, isMultiBackupEnabled: false }, isAccountAbstracted: false, metadata: { namespaces: {} }, wallets: [] }, overrides));
|
|
4410
|
+
const makeWallet = (curve, signingStatus, backupStatus) => ({
|
|
4411
|
+
id: `wallet-${curve}`,
|
|
4412
|
+
createdAt: '2024-01-01T00:00:00.000Z',
|
|
4413
|
+
curve,
|
|
4414
|
+
publicKey: 'pk',
|
|
4415
|
+
signingSharePairs: [{ id: 'sp1', createdAt: '2024-01-01T00:00:00.000Z', status: signingStatus }],
|
|
4416
|
+
backupSharePairs: [
|
|
4417
|
+
{
|
|
4418
|
+
id: 'bp1',
|
|
4419
|
+
createdAt: '2024-01-01T00:00:00.000Z',
|
|
4420
|
+
backupMethod: index_1.BackupMethods.password,
|
|
4421
|
+
status: backupStatus,
|
|
4422
|
+
},
|
|
4423
|
+
],
|
|
4424
|
+
});
|
|
4425
|
+
const dispatchReady = () => {
|
|
4426
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
4427
|
+
origin: `https://${constants_1.mockHost}`,
|
|
4428
|
+
data: { type: 'portal:ready', data: true },
|
|
4429
|
+
}));
|
|
4430
|
+
};
|
|
4431
|
+
const flushPromises = () => new Promise((resolve) => setTimeout(resolve, 0));
|
|
4432
|
+
beforeEach(() => {
|
|
4433
|
+
jest.spyOn(mpc, 'getAddress').mockResolvedValue(constants_1.mockAddress);
|
|
4434
|
+
mpc.waitForReadyMessage();
|
|
4435
|
+
});
|
|
4436
|
+
it('does not emit when client has no wallets (new user / initial setup)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4437
|
+
jest.spyOn(mpc, 'getClient').mockResolvedValue(makeClient({ wallets: [] }));
|
|
4438
|
+
jest.spyOn(mpc, 'checkSharesOnDevice').mockResolvedValue({ SECP256K1: false, ED25519: false });
|
|
4439
|
+
dispatchReady();
|
|
4440
|
+
yield flushPromises();
|
|
4441
|
+
expect(portal_1.default.triggerWalletNotOnDevice).not.toHaveBeenCalled();
|
|
4442
|
+
expect(portal_1.default.triggerReady).toHaveBeenCalled();
|
|
4443
|
+
}));
|
|
4444
|
+
it('does not emit when wallets exist but all signing share pairs are incomplete (setup in progress)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4445
|
+
jest.spyOn(mpc, 'getClient').mockResolvedValue(makeClient({
|
|
4446
|
+
wallets: [
|
|
4447
|
+
makeWallet(index_1.PortalCurve.SECP256K1, 'incomplete', 'incomplete'),
|
|
4448
|
+
makeWallet(index_1.PortalCurve.ED25519, 'incomplete', 'incomplete'),
|
|
4449
|
+
],
|
|
4450
|
+
}));
|
|
4451
|
+
jest.spyOn(mpc, 'checkSharesOnDevice').mockResolvedValue({ SECP256K1: false, ED25519: false });
|
|
4452
|
+
dispatchReady();
|
|
4453
|
+
yield flushPromises();
|
|
4454
|
+
expect(portal_1.default.triggerWalletNotOnDevice).not.toHaveBeenCalled();
|
|
4455
|
+
expect(portal_1.default.triggerReady).toHaveBeenCalled();
|
|
4456
|
+
}));
|
|
4457
|
+
it('does not emit when wallet is present on device', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4458
|
+
jest.spyOn(mpc, 'getClient').mockResolvedValue(makeClient({
|
|
4459
|
+
wallets: [
|
|
4460
|
+
makeWallet(index_1.PortalCurve.SECP256K1, 'completed', 'completed'),
|
|
4461
|
+
makeWallet(index_1.PortalCurve.ED25519, 'completed', 'completed'),
|
|
4462
|
+
],
|
|
4463
|
+
}));
|
|
4464
|
+
jest.spyOn(mpc, 'checkSharesOnDevice').mockResolvedValue({ SECP256K1: true, ED25519: true });
|
|
4465
|
+
dispatchReady();
|
|
4466
|
+
yield flushPromises();
|
|
4467
|
+
expect(portal_1.default.triggerWalletNotOnDevice).not.toHaveBeenCalled();
|
|
4468
|
+
}));
|
|
4469
|
+
it('emits walletNotOnDevice with isBackedUp=false when wallet is not on device and not backed up', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4470
|
+
jest.spyOn(mpc, 'getClient').mockResolvedValue(makeClient({
|
|
4471
|
+
wallets: [
|
|
4472
|
+
makeWallet(index_1.PortalCurve.SECP256K1, 'completed', 'incomplete'),
|
|
4473
|
+
makeWallet(index_1.PortalCurve.ED25519, 'completed', 'incomplete'),
|
|
4474
|
+
],
|
|
4475
|
+
}));
|
|
4476
|
+
jest.spyOn(mpc, 'checkSharesOnDevice').mockResolvedValue({ SECP256K1: false, ED25519: false });
|
|
4477
|
+
dispatchReady();
|
|
4478
|
+
yield flushPromises();
|
|
4479
|
+
expect(portal_1.default.triggerWalletNotOnDevice).toHaveBeenCalledWith({
|
|
4480
|
+
clientId: 'client-test',
|
|
4481
|
+
isBackedUp: false,
|
|
4482
|
+
reason: 'storage_cleared',
|
|
4483
|
+
});
|
|
4484
|
+
}));
|
|
4485
|
+
it('emits walletNotOnDevice with isBackedUp=true when at least one backup is complete', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4486
|
+
jest.spyOn(mpc, 'getClient').mockResolvedValue(makeClient({
|
|
4487
|
+
wallets: [makeWallet(index_1.PortalCurve.SECP256K1, 'completed', 'completed')],
|
|
4488
|
+
}));
|
|
4489
|
+
jest.spyOn(mpc, 'checkSharesOnDevice').mockResolvedValue({ SECP256K1: false, ED25519: false });
|
|
4490
|
+
dispatchReady();
|
|
4491
|
+
yield flushPromises();
|
|
4492
|
+
expect(portal_1.default.triggerWalletNotOnDevice).toHaveBeenCalledWith({
|
|
4493
|
+
clientId: 'client-test',
|
|
4494
|
+
isBackedUp: true,
|
|
4495
|
+
reason: 'storage_cleared',
|
|
4496
|
+
});
|
|
4497
|
+
}));
|
|
4498
|
+
it('does not emit for EVM-only client when SECP256K1 share is present (ED25519 absence is irrelevant)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4499
|
+
jest.spyOn(mpc, 'getClient').mockResolvedValue(makeClient({
|
|
4500
|
+
wallets: [makeWallet(index_1.PortalCurve.SECP256K1, 'completed', 'incomplete')],
|
|
4501
|
+
}));
|
|
4502
|
+
jest.spyOn(mpc, 'checkSharesOnDevice').mockResolvedValue({ SECP256K1: true, ED25519: false });
|
|
4503
|
+
dispatchReady();
|
|
4504
|
+
yield flushPromises();
|
|
4505
|
+
expect(portal_1.default.triggerWalletNotOnDevice).not.toHaveBeenCalled();
|
|
4506
|
+
}));
|
|
4507
|
+
it('emits for EVM-only client when SECP256K1 share is missing', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4508
|
+
jest.spyOn(mpc, 'getClient').mockResolvedValue(makeClient({
|
|
4509
|
+
wallets: [makeWallet(index_1.PortalCurve.SECP256K1, 'completed', 'incomplete')],
|
|
4510
|
+
}));
|
|
4511
|
+
jest.spyOn(mpc, 'checkSharesOnDevice').mockResolvedValue({ SECP256K1: false, ED25519: false });
|
|
4512
|
+
dispatchReady();
|
|
4513
|
+
yield flushPromises();
|
|
4514
|
+
expect(portal_1.default.triggerWalletNotOnDevice).toHaveBeenCalled();
|
|
4515
|
+
}));
|
|
4516
|
+
it('does not emit when wallet is ejected (recovery is impossible)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4517
|
+
jest.spyOn(mpc, 'getClient').mockResolvedValue(makeClient({
|
|
4518
|
+
ejectedAt: '2024-06-01T00:00:00.000Z',
|
|
4519
|
+
wallets: [makeWallet(index_1.PortalCurve.SECP256K1, 'completed', 'incomplete')],
|
|
4520
|
+
}));
|
|
4521
|
+
jest.spyOn(mpc, 'checkSharesOnDevice').mockResolvedValue({ SECP256K1: false, ED25519: false });
|
|
4522
|
+
dispatchReady();
|
|
4523
|
+
yield flushPromises();
|
|
4524
|
+
expect(portal_1.default.triggerWalletNotOnDevice).not.toHaveBeenCalled();
|
|
4525
|
+
}));
|
|
4526
|
+
it('still calls triggerReady when detection throws (detection must not block initialization)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4527
|
+
jest.spyOn(mpc, 'getClient').mockRejectedValue(new Error('network error'));
|
|
4528
|
+
jest.spyOn(mpc, 'checkSharesOnDevice').mockRejectedValue(new Error('network error'));
|
|
4529
|
+
dispatchReady();
|
|
4530
|
+
yield flushPromises();
|
|
4531
|
+
expect(portal_1.default.triggerWalletNotOnDevice).not.toHaveBeenCalled();
|
|
4532
|
+
expect(portal_1.default.triggerReady).toHaveBeenCalled();
|
|
4533
|
+
}));
|
|
4534
|
+
});
|
|
3901
4535
|
});
|