@portal-hq/web 3.6.2-alpha → 3.7.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/hypernative.d.ts +346 -0
- package/lib/commonjs/index.js +144 -2
- package/lib/commonjs/index.test.js +119 -2
- package/lib/commonjs/integrations/security/hypernative/index.js +101 -0
- package/lib/commonjs/integrations/security/hypernative/index.test.js +151 -0
- package/lib/commonjs/integrations/security/index.js +16 -0
- package/lib/commonjs/integrations/trading/zero-x/index.js +17 -4
- package/lib/commonjs/integrations/trading/zero-x/index.test.js +61 -15
- package/lib/commonjs/mpc/index.js +156 -5
- package/lib/commonjs/mpc/index.test.js +794 -5
- package/lib/commonjs/passkeys/index.js +394 -0
- package/lib/commonjs/passkeys/types.js +2 -0
- package/lib/commonjs/provider/index.js +5 -2
- package/lib/esm/index.js +144 -2
- package/lib/esm/index.test.js +119 -2
- package/lib/esm/integrations/security/hypernative/index.js +98 -0
- package/lib/esm/integrations/security/hypernative/index.test.js +146 -0
- package/lib/esm/integrations/security/index.js +10 -0
- package/lib/esm/integrations/trading/zero-x/index.js +17 -4
- package/lib/esm/integrations/trading/zero-x/index.test.js +62 -16
- package/lib/esm/mpc/index.js +156 -5
- package/lib/esm/mpc/index.test.js +795 -6
- package/lib/esm/passkeys/index.js +390 -0
- package/lib/esm/passkeys/types.js +1 -0
- package/lib/esm/provider/index.js +5 -2
- package/lifi-types.d.ts +1236 -0
- package/package.json +6 -3
- package/src/__mocks/constants.ts +422 -5
- package/src/__mocks/portal/mpc.ts +1 -0
- package/src/index.test.ts +179 -3
- package/src/index.ts +212 -4
- package/src/integrations/security/hypernative/index.test.ts +196 -0
- package/src/integrations/security/hypernative/index.ts +106 -0
- package/src/integrations/security/index.ts +14 -0
- package/src/integrations/trading/zero-x/index.test.ts +98 -19
- package/src/integrations/trading/zero-x/index.ts +29 -9
- package/src/mpc/index.test.ts +944 -7
- package/src/mpc/index.ts +200 -10
- package/src/passkeys/index.ts +536 -0
- package/src/passkeys/types.ts +78 -0
- package/src/provider/index.ts +5 -0
- package/tsconfig.json +7 -1
- package/types.d.ts +45 -12
- package/yieldxyz-types.d.ts +778 -0
- package/zero-x.d.ts +204 -0
package/lib/esm/index.test.js
CHANGED
|
@@ -116,6 +116,123 @@ describe('Portal', () => {
|
|
|
116
116
|
}, mockProgressFn);
|
|
117
117
|
}));
|
|
118
118
|
});
|
|
119
|
+
describe('generateBackupShare', () => {
|
|
120
|
+
it('should request a custom backup and return cipherText and encryptionKey', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
121
|
+
const storageCallback = jest.fn().mockResolvedValue(undefined);
|
|
122
|
+
portal.mpc.backup.mockResolvedValueOnce({
|
|
123
|
+
cipherText: mockCipherText,
|
|
124
|
+
encryptionKey: 'manual-key',
|
|
125
|
+
storageCallback,
|
|
126
|
+
});
|
|
127
|
+
const result = yield portal.generateBackupShare();
|
|
128
|
+
expect(result).toEqual({
|
|
129
|
+
cipherText: mockCipherText,
|
|
130
|
+
encryptionKey: 'manual-key',
|
|
131
|
+
});
|
|
132
|
+
expect(portal.mpc.backup).toHaveBeenCalledWith({
|
|
133
|
+
backupMethod: BackupMethods.custom,
|
|
134
|
+
backupConfigs: {},
|
|
135
|
+
host: 'web.portalhq.io',
|
|
136
|
+
mpcVersion: 'v6',
|
|
137
|
+
featureFlags: {},
|
|
138
|
+
}, expect.any(Function));
|
|
139
|
+
}));
|
|
140
|
+
it('should throw if the iframe response does not contain an encryption key', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
141
|
+
;
|
|
142
|
+
portal.mpc.backup.mockResolvedValueOnce({
|
|
143
|
+
cipherText: mockCipherText,
|
|
144
|
+
storageCallback: jest.fn(),
|
|
145
|
+
});
|
|
146
|
+
yield expect(portal.generateBackupShare()).rejects.toThrow('Custom backup did not return an encryption key');
|
|
147
|
+
}));
|
|
148
|
+
});
|
|
149
|
+
describe('registerPasskeyAndStoreEncryptionKey', () => {
|
|
150
|
+
it('should delegate to the passkey service with computed relying party data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
151
|
+
const passkeyServiceMock = {
|
|
152
|
+
registerPasskeyAndStoreKey: jest.fn().mockResolvedValue(undefined),
|
|
153
|
+
};
|
|
154
|
+
portal.passkeyService = passkeyServiceMock;
|
|
155
|
+
portal.passkeyServiceDefaultDomain = 'backup.web.portalhq.io';
|
|
156
|
+
portal.passkeyServiceApiKey = portal.apiKey;
|
|
157
|
+
yield portal.registerPasskeyAndStoreEncryptionKey(mockCipherText, 'manual-key');
|
|
158
|
+
expect(passkeyServiceMock.registerPasskeyAndStoreKey).toHaveBeenCalledTimes(1);
|
|
159
|
+
expect(passkeyServiceMock.registerPasskeyAndStoreKey).toHaveBeenCalledWith(expect.objectContaining({
|
|
160
|
+
customDomain: undefined,
|
|
161
|
+
encryptionKey: 'manual-key',
|
|
162
|
+
relyingPartyId: 'backup.web.portalhq.io',
|
|
163
|
+
relyingPartyName: 'Portal',
|
|
164
|
+
cipherText: mockCipherText,
|
|
165
|
+
}));
|
|
166
|
+
}));
|
|
167
|
+
it('should throw when usePopup is requested', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
168
|
+
yield expect(portal.registerPasskeyAndStoreEncryptionKey(mockCipherText, 'manual-key', { usePopup: true })).rejects.toThrow('does not support the popup flow');
|
|
169
|
+
}));
|
|
170
|
+
});
|
|
171
|
+
describe('authenticatePasskeyAndRetrieveKey', () => {
|
|
172
|
+
it('should invoke the passkey service for direct authentication', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
173
|
+
const passkeyServiceMock = {
|
|
174
|
+
authenticatePasskeyAndRetrieveKey: jest
|
|
175
|
+
.fn()
|
|
176
|
+
.mockResolvedValue('retrieved-key'),
|
|
177
|
+
};
|
|
178
|
+
portal.passkeyService = passkeyServiceMock;
|
|
179
|
+
portal.passkeyServiceDefaultDomain = 'backup.web.portalhq.io';
|
|
180
|
+
portal.passkeyServiceApiKey = portal.apiKey;
|
|
181
|
+
const key = yield portal.authenticatePasskeyAndRetrieveKey();
|
|
182
|
+
expect(key).toEqual('retrieved-key');
|
|
183
|
+
expect(passkeyServiceMock.authenticatePasskeyAndRetrieveKey).toHaveBeenCalledWith(expect.objectContaining({
|
|
184
|
+
customDomain: undefined,
|
|
185
|
+
relyingPartyId: 'backup.web.portalhq.io',
|
|
186
|
+
relyingPartyName: 'Portal',
|
|
187
|
+
}));
|
|
188
|
+
}));
|
|
189
|
+
it('should throw when usePopup is true', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
190
|
+
yield expect(portal.authenticatePasskeyAndRetrieveKey({ usePopup: true })).rejects.toThrow('does not support the popup flow');
|
|
191
|
+
}));
|
|
192
|
+
});
|
|
193
|
+
describe('backupWithPasskey', () => {
|
|
194
|
+
it('should orchestrate the direct passkey flow when usePopup is false', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
195
|
+
const directShare = {
|
|
196
|
+
cipherText: mockCipherText,
|
|
197
|
+
encryptionKey: 'manual-key',
|
|
198
|
+
};
|
|
199
|
+
const generateSpy = jest
|
|
200
|
+
.spyOn(portal, 'generateBackupShare')
|
|
201
|
+
.mockResolvedValue(directShare);
|
|
202
|
+
const registerSpy = jest
|
|
203
|
+
.spyOn(portal, 'registerPasskeyAndStoreEncryptionKey')
|
|
204
|
+
.mockResolvedValue(undefined);
|
|
205
|
+
const storedClientBackupShareSpy = jest
|
|
206
|
+
.spyOn(portal, 'storedClientBackupShare')
|
|
207
|
+
.mockResolvedValue(undefined);
|
|
208
|
+
yield portal.backupWithPasskey({
|
|
209
|
+
usePopup: false,
|
|
210
|
+
customDomain: 'passkeys.wigwam.app',
|
|
211
|
+
relyingPartyName: 'Wigwam',
|
|
212
|
+
}, undefined);
|
|
213
|
+
expect(generateSpy).toHaveBeenCalledTimes(1);
|
|
214
|
+
expect(registerSpy).toHaveBeenCalledWith(directShare.cipherText, directShare.encryptionKey, expect.objectContaining({
|
|
215
|
+
customDomain: 'passkeys.wigwam.app',
|
|
216
|
+
relyingPartyName: 'Wigwam',
|
|
217
|
+
usePopup: false,
|
|
218
|
+
}));
|
|
219
|
+
expect(storedClientBackupShareSpy).toHaveBeenCalledWith(true, BackupMethods.passkey);
|
|
220
|
+
generateSpy.mockRestore();
|
|
221
|
+
registerSpy.mockRestore();
|
|
222
|
+
storedClientBackupShareSpy.mockRestore();
|
|
223
|
+
}));
|
|
224
|
+
it('should fall back to the legacy popup flow when usePopup is true', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
225
|
+
const progress = jest.fn();
|
|
226
|
+
yield portal.backupWithPasskey({}, progress);
|
|
227
|
+
expect(portal.mpc.backup).toHaveBeenCalledWith({
|
|
228
|
+
backupMethod: BackupMethods.passkey,
|
|
229
|
+
backupConfigs: {},
|
|
230
|
+
host: 'web.portalhq.io',
|
|
231
|
+
mpcVersion: 'v6',
|
|
232
|
+
featureFlags: {},
|
|
233
|
+
}, progress);
|
|
234
|
+
}));
|
|
235
|
+
});
|
|
119
236
|
describe('recoverWallet', () => {
|
|
120
237
|
it('should successfully recover a wallet and call mpc.recover correctly', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
121
238
|
const mockProgressFn = jest.fn();
|
|
@@ -537,14 +654,14 @@ describe('Portal', () => {
|
|
|
537
654
|
it('should correctly call mpc.getQuote', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
538
655
|
yield portal.getQuote('test', mockQuoteArgs, 'eip155:1');
|
|
539
656
|
expect(portal.mpc.getQuote).toHaveBeenCalledTimes(1);
|
|
540
|
-
expect(portal.mpc.getQuote).toHaveBeenCalledWith('
|
|
657
|
+
expect(portal.mpc.getQuote).toHaveBeenCalledWith('eip155:1', mockQuoteArgs, 'test');
|
|
541
658
|
}));
|
|
542
659
|
});
|
|
543
660
|
describe('getSources', () => {
|
|
544
661
|
it('should correctly call mpc.getSources', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
545
662
|
yield portal.getSources('test', 'eip155:1');
|
|
546
663
|
expect(portal.mpc.getSources).toHaveBeenCalledTimes(1);
|
|
547
|
-
expect(portal.mpc.getSources).toHaveBeenCalledWith('
|
|
664
|
+
expect(portal.mpc.getSources).toHaveBeenCalledWith('eip155:1', 'test');
|
|
548
665
|
}));
|
|
549
666
|
});
|
|
550
667
|
describe('storedClientBackupShare', () => {
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
export default class Hypernative {
|
|
11
|
+
constructor({ mpc }) {
|
|
12
|
+
this.mpc = mpc;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Scans an EIP-155 transaction for security risks.
|
|
16
|
+
* @param data - The parameters for the EIP-155 transaction scan request.
|
|
17
|
+
* @returns A `ScanEVMResponse` promise.
|
|
18
|
+
* @throws An error if the operation fails.
|
|
19
|
+
*/
|
|
20
|
+
scanEVMTx(data) {
|
|
21
|
+
var _a;
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
return (_a = this.mpc) === null || _a === void 0 ? void 0 : _a.scanEVMTx(data);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Scans an EIP-712 typed message for security risks.
|
|
28
|
+
* @param data - The parameters for the EIP-712 message scan request.
|
|
29
|
+
* @returns A `ScanEip712Response` promise.
|
|
30
|
+
* @throws An error if the operation fails.
|
|
31
|
+
*/
|
|
32
|
+
scanEip712Tx(data) {
|
|
33
|
+
var _a;
|
|
34
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
return (_a = this.mpc) === null || _a === void 0 ? void 0 : _a.scanEip712Tx(data);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Scans a Solana transaction for security risks.
|
|
40
|
+
* @param data - The parameters for the Solana transaction scan request.
|
|
41
|
+
* @returns A `ScanSolanaResponse` promise.
|
|
42
|
+
* @throws An error if the operation fails.
|
|
43
|
+
*/
|
|
44
|
+
scanSolanaTx(data) {
|
|
45
|
+
var _a;
|
|
46
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
return (_a = this.mpc) === null || _a === void 0 ? void 0 : _a.scanSolanaTx(data);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Scans addresses for security risks and flags.
|
|
52
|
+
* @param data - The parameters for the address scan request.
|
|
53
|
+
* @returns A `ScreenAddressApiResponse` promise.
|
|
54
|
+
* @throws An error if the operation fails.
|
|
55
|
+
*/
|
|
56
|
+
scanAddresses(addresses, options) {
|
|
57
|
+
var _a;
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
return (_a = this.mpc) === null || _a === void 0 ? void 0 : _a.scanAddresses(Object.assign({ addresses }, options));
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Scans NFTs for security risks.
|
|
64
|
+
* @param data - The parameters for the NFT scan request.
|
|
65
|
+
* @returns A `ScanNftResponse` promise.
|
|
66
|
+
* @throws An error if the operation fails.
|
|
67
|
+
*/
|
|
68
|
+
scanNFTs(nfts) {
|
|
69
|
+
var _a;
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
return (_a = this.mpc) === null || _a === void 0 ? void 0 : _a.scanNFTs(nfts);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Scans tokens for security risks.
|
|
76
|
+
* @param data - The parameters for the token scan request.
|
|
77
|
+
* @returns A `ScanTokenResponse` promise.
|
|
78
|
+
* @throws An error if the operation fails.
|
|
79
|
+
*/
|
|
80
|
+
scanTokens(tokens) {
|
|
81
|
+
var _a;
|
|
82
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
83
|
+
return (_a = this.mpc) === null || _a === void 0 ? void 0 : _a.scanTokens(tokens);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Scans a URL for malicious content.
|
|
88
|
+
* @param data - The parameters for the URL scan request.
|
|
89
|
+
* @returns A `ScanUrlResponse` promise.
|
|
90
|
+
* @throws An error if the operation fails.
|
|
91
|
+
*/
|
|
92
|
+
scanURL(url) {
|
|
93
|
+
var _a;
|
|
94
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
95
|
+
return (_a = this.mpc) === null || _a === void 0 ? void 0 : _a.scanUrl(url);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
5
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
6
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
7
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
8
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
9
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
10
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
14
|
+
var t = {};
|
|
15
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
16
|
+
t[p] = s[p];
|
|
17
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
18
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
19
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
20
|
+
t[p[i]] = s[p[i]];
|
|
21
|
+
}
|
|
22
|
+
return t;
|
|
23
|
+
};
|
|
24
|
+
import Hypernative from '.';
|
|
25
|
+
import Mpc from '../../../mpc';
|
|
26
|
+
import portalMock from '../../../__mocks/portal/portal';
|
|
27
|
+
import { mockHost, mockScanAddressesRequest, mockScanAddressesResponse, mockScanEVMTxRequest, mockScanEVMTxResponse, mockScanEip712TxRequest, mockScanEip712TxResponse, mockScanSolanaTxRequest, mockScanSolanaTxResponse, mockScanNftRequest, mockScanNftResponse, mockScanTokenRequest, mockScanTokenResponse, mockScanUrlRequest, mockScanUrlResponse, } from '../../../__mocks/constants';
|
|
28
|
+
describe('Hypernative', () => {
|
|
29
|
+
let hypernative;
|
|
30
|
+
let mpc;
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
jest.clearAllMocks();
|
|
33
|
+
portalMock.host = mockHost;
|
|
34
|
+
mpc = new Mpc({
|
|
35
|
+
portal: portalMock,
|
|
36
|
+
});
|
|
37
|
+
hypernative = new Hypernative({ mpc });
|
|
38
|
+
});
|
|
39
|
+
describe('scanEVMTx', () => {
|
|
40
|
+
it('should call mpc.scanEVMTx with the correct arguments', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
|
+
const spy = jest
|
|
42
|
+
.spyOn(mpc, 'scanEVMTx')
|
|
43
|
+
.mockResolvedValue(mockScanEVMTxResponse);
|
|
44
|
+
const result = yield hypernative.scanEVMTx(mockScanEVMTxRequest);
|
|
45
|
+
expect(spy).toHaveBeenCalledWith(mockScanEVMTxRequest);
|
|
46
|
+
expect(result).toEqual(mockScanEVMTxResponse);
|
|
47
|
+
}));
|
|
48
|
+
it('should propagate errors from mpc.scanEVMTx', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
|
+
const error = new Error('Test error');
|
|
50
|
+
jest.spyOn(mpc, 'scanEVMTx').mockRejectedValue(error);
|
|
51
|
+
yield expect(hypernative.scanEVMTx(mockScanEVMTxRequest)).rejects.toThrow('Test error');
|
|
52
|
+
}));
|
|
53
|
+
});
|
|
54
|
+
describe('scanEip712Tx', () => {
|
|
55
|
+
it('should call mpc.scanEip712Tx with the correct arguments', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
56
|
+
const spy = jest
|
|
57
|
+
.spyOn(mpc, 'scanEip712Tx')
|
|
58
|
+
.mockResolvedValue(mockScanEip712TxResponse);
|
|
59
|
+
const result = yield hypernative.scanEip712Tx(mockScanEip712TxRequest);
|
|
60
|
+
expect(spy).toHaveBeenCalledWith(mockScanEip712TxRequest);
|
|
61
|
+
expect(result).toEqual(mockScanEip712TxResponse);
|
|
62
|
+
}));
|
|
63
|
+
it('should propagate errors from mpc.scanEip712Tx', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
|
+
const error = new Error('Test error');
|
|
65
|
+
jest.spyOn(mpc, 'scanEip712Tx').mockRejectedValue(error);
|
|
66
|
+
yield expect(hypernative.scanEip712Tx(mockScanEip712TxRequest)).rejects.toThrow('Test error');
|
|
67
|
+
}));
|
|
68
|
+
});
|
|
69
|
+
describe('scanSolanaTx', () => {
|
|
70
|
+
it('should call mpc.scanSolanaTx with the correct arguments', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
|
+
const spy = jest
|
|
72
|
+
.spyOn(mpc, 'scanSolanaTx')
|
|
73
|
+
.mockResolvedValue(mockScanSolanaTxResponse);
|
|
74
|
+
const result = yield hypernative.scanSolanaTx(mockScanSolanaTxRequest);
|
|
75
|
+
expect(spy).toHaveBeenCalledWith(mockScanSolanaTxRequest);
|
|
76
|
+
expect(result).toEqual(mockScanSolanaTxResponse);
|
|
77
|
+
}));
|
|
78
|
+
it('should propagate errors from mpc.scanSolanaTx', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
79
|
+
const error = new Error('Test error');
|
|
80
|
+
jest.spyOn(mpc, 'scanSolanaTx').mockRejectedValue(error);
|
|
81
|
+
yield expect(hypernative.scanSolanaTx(mockScanSolanaTxRequest)).rejects.toThrow('Test error');
|
|
82
|
+
}));
|
|
83
|
+
});
|
|
84
|
+
describe('scanAddresses', () => {
|
|
85
|
+
it('should call mpc.scanAddresses with the correct arguments', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
86
|
+
const spy = jest
|
|
87
|
+
.spyOn(mpc, 'scanAddresses')
|
|
88
|
+
.mockResolvedValue(mockScanAddressesResponse);
|
|
89
|
+
const { addresses } = mockScanAddressesRequest, options = __rest(mockScanAddressesRequest, ["addresses"]);
|
|
90
|
+
const result = yield hypernative.scanAddresses(addresses, options);
|
|
91
|
+
expect(spy).toHaveBeenCalledWith(mockScanAddressesRequest);
|
|
92
|
+
expect(result).toEqual(mockScanAddressesResponse);
|
|
93
|
+
}));
|
|
94
|
+
it('should propagate errors from mpc.scanAddresses', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
+
const error = new Error('Test error');
|
|
96
|
+
jest.spyOn(mpc, 'scanAddresses').mockRejectedValue(error);
|
|
97
|
+
const { addresses } = mockScanAddressesRequest, options = __rest(mockScanAddressesRequest, ["addresses"]);
|
|
98
|
+
yield expect(hypernative.scanAddresses(addresses, options)).rejects.toThrow('Test error');
|
|
99
|
+
}));
|
|
100
|
+
});
|
|
101
|
+
describe('scanNFTs', () => {
|
|
102
|
+
it('should call mpc.scanNFTs with the correct arguments', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
103
|
+
const spy = jest
|
|
104
|
+
.spyOn(mpc, 'scanNFTs')
|
|
105
|
+
.mockResolvedValue(mockScanNftResponse);
|
|
106
|
+
const result = yield hypernative.scanNFTs(mockScanNftRequest);
|
|
107
|
+
expect(spy).toHaveBeenCalledWith(mockScanNftRequest);
|
|
108
|
+
expect(result).toEqual(mockScanNftResponse);
|
|
109
|
+
}));
|
|
110
|
+
it('should propagate errors from mpc.scanNFTs', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
111
|
+
const error = new Error('Test error');
|
|
112
|
+
jest.spyOn(mpc, 'scanNFTs').mockRejectedValue(error);
|
|
113
|
+
yield expect(hypernative.scanNFTs(mockScanNftRequest)).rejects.toThrow('Test error');
|
|
114
|
+
}));
|
|
115
|
+
});
|
|
116
|
+
describe('scanTokens', () => {
|
|
117
|
+
it('should call mpc.scanTokens with the correct arguments', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
118
|
+
const spy = jest
|
|
119
|
+
.spyOn(mpc, 'scanTokens')
|
|
120
|
+
.mockResolvedValue(mockScanTokenResponse);
|
|
121
|
+
const result = yield hypernative.scanTokens(mockScanTokenRequest);
|
|
122
|
+
expect(spy).toHaveBeenCalledWith(mockScanTokenRequest);
|
|
123
|
+
expect(result).toEqual(mockScanTokenResponse);
|
|
124
|
+
}));
|
|
125
|
+
it('should propagate errors from mpc.scanTokens', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
126
|
+
const error = new Error('Test error');
|
|
127
|
+
jest.spyOn(mpc, 'scanTokens').mockRejectedValue(error);
|
|
128
|
+
yield expect(hypernative.scanTokens(mockScanTokenRequest)).rejects.toThrow('Test error');
|
|
129
|
+
}));
|
|
130
|
+
});
|
|
131
|
+
describe('scanURL', () => {
|
|
132
|
+
it('should call mpc.scanUrl with the correct arguments', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
133
|
+
const spy = jest
|
|
134
|
+
.spyOn(mpc, 'scanUrl')
|
|
135
|
+
.mockResolvedValue(mockScanUrlResponse);
|
|
136
|
+
const result = yield hypernative.scanURL(mockScanUrlRequest);
|
|
137
|
+
expect(spy).toHaveBeenCalledWith(mockScanUrlRequest);
|
|
138
|
+
expect(result).toEqual(mockScanUrlResponse);
|
|
139
|
+
}));
|
|
140
|
+
it('should propagate errors from mpc.scanUrl', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
141
|
+
const error = new Error('Test error');
|
|
142
|
+
jest.spyOn(mpc, 'scanUrl').mockRejectedValue(error);
|
|
143
|
+
yield expect(hypernative.scanURL(mockScanUrlRequest)).rejects.toThrow('Test error');
|
|
144
|
+
}));
|
|
145
|
+
});
|
|
146
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Hypernative from './hypernative';
|
|
2
|
+
/**
|
|
3
|
+
* This class is a container for the Hypernative class.
|
|
4
|
+
* In the future, Security domain logic should be here.
|
|
5
|
+
*/
|
|
6
|
+
export default class Security {
|
|
7
|
+
constructor({ mpc }) {
|
|
8
|
+
this.hypernative = new Hypernative({ mpc });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -19,10 +19,10 @@ export default class ZeroX {
|
|
|
19
19
|
* @param chainId - The chain ID for the quote.
|
|
20
20
|
* @returns The quote response.
|
|
21
21
|
*/
|
|
22
|
-
getQuote(
|
|
22
|
+
getQuote(args, options) {
|
|
23
23
|
var _a;
|
|
24
24
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
-
return (_a = this.mpc) === null || _a === void 0 ? void 0 : _a.
|
|
25
|
+
return (_a = this.mpc) === null || _a === void 0 ? void 0 : _a.getSwapsQuoteV2(args, options);
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
@@ -32,10 +32,23 @@ export default class ZeroX {
|
|
|
32
32
|
* @param chainId - The chain ID for the sources.
|
|
33
33
|
* @returns The sources response.
|
|
34
34
|
*/
|
|
35
|
-
getSources(
|
|
35
|
+
getSources(chainId, options) {
|
|
36
36
|
var _a;
|
|
37
37
|
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
-
return (_a = this.mpc) === null || _a === void 0 ? void 0 : _a.
|
|
38
|
+
return (_a = this.mpc) === null || _a === void 0 ? void 0 : _a.getSwapsSourcesV2({ chainId }, options);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get the price of a token from the Swaps API.
|
|
43
|
+
*
|
|
44
|
+
* @param args - The arguments for the price.
|
|
45
|
+
* @param options - The options for the price.
|
|
46
|
+
* @returns The price response.
|
|
47
|
+
*/
|
|
48
|
+
getPrice(args, options) {
|
|
49
|
+
var _a;
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
return (_a = this.mpc) === null || _a === void 0 ? void 0 : _a.getSwapsPrice(args, options);
|
|
39
52
|
});
|
|
40
53
|
}
|
|
41
54
|
}
|
|
@@ -13,7 +13,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
13
13
|
import ZeroX from '.';
|
|
14
14
|
import Mpc from '../../../mpc';
|
|
15
15
|
import portalMock from '../../../__mocks/portal/portal';
|
|
16
|
-
import { mockHost,
|
|
16
|
+
import { mockHost, mockSourcesRes, mockZeroExQuoteV2Request, mockZeroExQuoteV2Response, mockZeroExOptions, mockZeroExPriceRequest, mockZeroExPriceResponse, } from '../../../__mocks/constants';
|
|
17
17
|
describe('ZeroX', () => {
|
|
18
18
|
let zeroX;
|
|
19
19
|
let mpc;
|
|
@@ -26,35 +26,81 @@ describe('ZeroX', () => {
|
|
|
26
26
|
zeroX = new ZeroX({ mpc });
|
|
27
27
|
});
|
|
28
28
|
describe('getQuote', () => {
|
|
29
|
-
it('should correctly call mpc.
|
|
29
|
+
it('should correctly call mpc.getSwapsQuoteV2 with args and options', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
30
|
const spy = jest
|
|
31
|
-
.spyOn(mpc, '
|
|
32
|
-
.mockResolvedValue(
|
|
33
|
-
const result = yield zeroX.getQuote(
|
|
31
|
+
.spyOn(mpc, 'getSwapsQuoteV2')
|
|
32
|
+
.mockResolvedValue(mockZeroExQuoteV2Response);
|
|
33
|
+
const result = yield zeroX.getQuote(mockZeroExQuoteV2Request, mockZeroExOptions);
|
|
34
34
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
35
|
-
expect(spy).toHaveBeenCalledWith(
|
|
36
|
-
expect(result).toEqual(
|
|
35
|
+
expect(spy).toHaveBeenCalledWith(mockZeroExQuoteV2Request, mockZeroExOptions);
|
|
36
|
+
expect(result).toEqual(mockZeroExQuoteV2Response);
|
|
37
37
|
}));
|
|
38
|
-
it('should
|
|
38
|
+
it('should correctly call mpc.getSwapsQuoteV2 without options', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
+
const spy = jest
|
|
40
|
+
.spyOn(mpc, 'getSwapsQuoteV2')
|
|
41
|
+
.mockResolvedValue(mockZeroExQuoteV2Response);
|
|
42
|
+
const result = yield zeroX.getQuote(mockZeroExQuoteV2Request);
|
|
43
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
44
|
+
expect(spy).toHaveBeenCalledWith(mockZeroExQuoteV2Request, undefined);
|
|
45
|
+
expect(result).toEqual(mockZeroExQuoteV2Response);
|
|
46
|
+
}));
|
|
47
|
+
it('should propagate errors from mpc.getSwapsQuoteV2', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
48
|
const error = new Error('Test error');
|
|
40
|
-
jest.spyOn(mpc, '
|
|
41
|
-
yield expect(zeroX.getQuote(
|
|
49
|
+
jest.spyOn(mpc, 'getSwapsQuoteV2').mockRejectedValue(error);
|
|
50
|
+
yield expect(zeroX.getQuote(mockZeroExQuoteV2Request)).rejects.toThrow('Test error');
|
|
42
51
|
}));
|
|
43
52
|
});
|
|
44
53
|
describe('getSources', () => {
|
|
45
|
-
it('should correctly call mpc.getSources', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
54
|
+
it('should correctly call mpc.getSources with chainId and apiKey', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
46
55
|
const spy = jest
|
|
47
|
-
.spyOn(mpc, '
|
|
56
|
+
.spyOn(mpc, 'getSwapsSourcesV2')
|
|
48
57
|
.mockResolvedValue(mockSourcesRes);
|
|
49
|
-
const result = yield zeroX.getSources('
|
|
58
|
+
const result = yield zeroX.getSources('eip155:1', {
|
|
59
|
+
zeroXApiKey: 'test-api-key',
|
|
60
|
+
});
|
|
61
|
+
console.log(`Result:`, result);
|
|
50
62
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
51
|
-
expect(spy).toHaveBeenCalledWith(
|
|
63
|
+
expect(spy).toHaveBeenCalledWith({ chainId: 'eip155:1' }, { zeroXApiKey: 'test-api-key' });
|
|
64
|
+
expect(result).toEqual(mockSourcesRes);
|
|
65
|
+
}));
|
|
66
|
+
it('should correctly call mpc.getSources without apiKey', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
67
|
+
const spy = jest
|
|
68
|
+
.spyOn(mpc, 'getSwapsSourcesV2')
|
|
69
|
+
.mockResolvedValue(mockSourcesRes);
|
|
70
|
+
const result = yield zeroX.getSources('eip155:1');
|
|
71
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
72
|
+
expect(spy).toHaveBeenCalledWith({ chainId: 'eip155:1' }, undefined);
|
|
52
73
|
expect(result).toEqual(mockSourcesRes);
|
|
53
74
|
}));
|
|
54
75
|
it('should propagate errors from mpc.getSources', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
55
76
|
const error = new Error('Test error');
|
|
56
|
-
jest.spyOn(mpc, '
|
|
57
|
-
yield expect(zeroX.getSources('
|
|
77
|
+
jest.spyOn(mpc, 'getSwapsSourcesV2').mockRejectedValue(error);
|
|
78
|
+
yield expect(zeroX.getSources('eip155:1')).rejects.toThrow('Test error');
|
|
79
|
+
}));
|
|
80
|
+
});
|
|
81
|
+
describe('getPrice', () => {
|
|
82
|
+
it('should correctly call mpc.getSwapsPrice with args and options', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
83
|
+
const spy = jest
|
|
84
|
+
.spyOn(mpc, 'getSwapsPrice')
|
|
85
|
+
.mockResolvedValue(mockZeroExPriceResponse);
|
|
86
|
+
const result = yield zeroX.getPrice(mockZeroExPriceRequest, mockZeroExOptions);
|
|
87
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
88
|
+
expect(spy).toHaveBeenCalledWith(mockZeroExPriceRequest, mockZeroExOptions);
|
|
89
|
+
expect(result).toEqual(mockZeroExPriceResponse);
|
|
90
|
+
}));
|
|
91
|
+
it('should correctly call mpc.getSwapsPrice without options', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
|
+
const spy = jest
|
|
93
|
+
.spyOn(mpc, 'getSwapsPrice')
|
|
94
|
+
.mockResolvedValue(mockZeroExPriceResponse);
|
|
95
|
+
const result = yield zeroX.getPrice(mockZeroExPriceRequest);
|
|
96
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
97
|
+
expect(spy).toHaveBeenCalledWith(mockZeroExPriceRequest, undefined);
|
|
98
|
+
expect(result).toEqual(mockZeroExPriceResponse);
|
|
99
|
+
}));
|
|
100
|
+
it('should propagate errors from mpc.getSwapsPrice', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
101
|
+
const error = new Error('Test error');
|
|
102
|
+
jest.spyOn(mpc, 'getSwapsPrice').mockRejectedValue(error);
|
|
103
|
+
yield expect(zeroX.getPrice(mockZeroExPriceRequest)).rejects.toThrow('Test error');
|
|
58
104
|
}));
|
|
59
105
|
});
|
|
60
106
|
});
|