@imtbl/sdk 0.0.1-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,2547 @@
1
+ import { ImmutableX, Config, TransfersApi, OrdersApi, UsersApi, Contracts, TradesApi, ExchangesApi, WithdrawalsApi, MintsApi, DepositsApi, EncodingApi, TokensApi, Configuration, generateLegacyStarkPrivateKey, createStarkSigner } from '@imtbl/core-sdk';
2
+ import BN from 'bn.js';
3
+ import * as encUtils from 'enc-utils';
4
+ import { parseUnits } from '@ethersproject/units';
5
+ import { BigNumber } from '@ethersproject/bignumber';
6
+ import { ethers, utils, Contract } from 'ethers';
7
+ import detectEthereumProvider from '@metamask/detect-provider';
8
+ import { UserManager } from 'oidc-client-ts';
9
+ import { Magic } from 'magic-sdk';
10
+ import { OpenIdExtension } from '@magic-ext/oidc';
11
+ import { Web3Provider } from '@ethersproject/providers';
12
+
13
+ var Environment;
14
+ (function (Environment) {
15
+ Environment["PRODUCTION"] = "production";
16
+ Environment["SANDBOX"] = "sandbox";
17
+ })(Environment || (Environment = {}));
18
+ class ImmutableConfiguration {
19
+ environment;
20
+ apiKey;
21
+ constructor(options) {
22
+ this.environment = options.environment;
23
+ this.apiKey = options.apiKey;
24
+ }
25
+ }
26
+
27
+ /* eslint-disable @typescript-eslint/no-unused-vars */
28
+ const StarkExAPIFactory = (config) => {
29
+ const imtblClient = new ImmutableX(config.immutableXConfig);
30
+ const { deposit, registerOffchain, isRegisteredOnchain, prepareWithdrawal, completeWithdrawal, createOrder, cancelOrder, createTrade, transfer, batchNftTransfer, ...StarkEx } = imtblClient;
31
+ return { ...StarkEx };
32
+ };
33
+
34
+ // used to sign message with L1 keys. Used for registration
35
+ function serializeEthSignature(sig) {
36
+ // This is because golang appends a recovery param
37
+ // https://github.com/ethers-io/ethers.js/issues/823
38
+ return encUtils.addHexPrefix(encUtils.padLeft(sig.r.toString(16), 64) +
39
+ encUtils.padLeft(sig.s.toString(16), 64) +
40
+ encUtils.padLeft(sig.recoveryParam?.toString(16) || '', 2));
41
+ }
42
+ function importRecoveryParam(v) {
43
+ return v.trim()
44
+ ? new BN(v, 16).cmp(new BN(27)) !== -1
45
+ ? new BN(v, 16).sub(new BN(27)).toNumber()
46
+ : new BN(v, 16).toNumber()
47
+ : undefined;
48
+ }
49
+ // used chained with serializeEthSignature. serializeEthSignature(deserializeSignature(...))
50
+ function deserializeSignature(sig, size = 64) {
51
+ sig = encUtils.removeHexPrefix(sig);
52
+ return {
53
+ r: new BN(sig.substring(0, size), 'hex'),
54
+ s: new BN(sig.substring(size, size * 2), 'hex'),
55
+ recoveryParam: importRecoveryParam(sig.substring(size * 2, size * 2 + 2)),
56
+ };
57
+ }
58
+ async function signRaw(payload, signer) {
59
+ const signature = deserializeSignature(await signer.signMessage(payload));
60
+ return serializeEthSignature(signature);
61
+ }
62
+ async function signMessage(message, signer) {
63
+ const ethAddress = await signer.getAddress();
64
+ const ethSignature = await signRaw(message, signer);
65
+ return {
66
+ message,
67
+ ethAddress,
68
+ ethSignature,
69
+ };
70
+ }
71
+
72
+ /**
73
+ * Helper method to convert token type to a SignableToken type
74
+ * @param token - the token type to convert to a SignableToken type
75
+ * @returns the converted SignableToken
76
+ */
77
+ function convertToSignableToken(token) {
78
+ switch (token.type) {
79
+ case 'ERC721':
80
+ return {
81
+ type: 'ERC721',
82
+ data: {
83
+ token_id: token.tokenId,
84
+ token_address: token.tokenAddress,
85
+ },
86
+ };
87
+ case 'ERC20':
88
+ return {
89
+ type: 'ERC20',
90
+ data: {
91
+ token_address: token.tokenAddress,
92
+ },
93
+ };
94
+ case 'ETH':
95
+ return {
96
+ type: 'ETH',
97
+ data: {
98
+ decimals: 18,
99
+ },
100
+ };
101
+ }
102
+ }
103
+
104
+ function isChainValid(chainID, config) {
105
+ return chainID === config.ethConfiguration.chainID;
106
+ }
107
+ async function validateChain(signer, config) {
108
+ const chainID = await signer.getChainId();
109
+ if (!isChainValid(chainID, config))
110
+ throw new Error('The wallet used for this operation is not connected to the correct network.');
111
+ }
112
+
113
+ async function transfer$1({ signers: { ethSigner, starkExSigner }, request, config, }) {
114
+ await validateChain(ethSigner, config.immutableXConfig);
115
+ const ethAddress = await ethSigner.getAddress();
116
+ const transfersApi = new TransfersApi(config.immutableXConfig.apiConfiguration);
117
+ const transferAmount = request.type === 'ERC721' ? '1' : request.amount;
118
+ const signableResult = await transfersApi.getSignableTransferV1({
119
+ getSignableTransferRequest: {
120
+ sender: ethAddress,
121
+ token: convertToSignableToken(request),
122
+ amount: transferAmount,
123
+ receiver: request.receiver,
124
+ },
125
+ });
126
+ const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
127
+ const ethSignature = await signRaw(signableMessage, ethSigner);
128
+ const starkSignature = await starkExSigner.signMessage(payloadHash);
129
+ const transferSigningParams = {
130
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
131
+ sender_stark_key: signableResult.data.sender_stark_key,
132
+ sender_vault_id: signableResult.data.sender_vault_id,
133
+ receiver_stark_key: signableResult.data.receiver_stark_key,
134
+ receiver_vault_id: signableResult.data.receiver_vault_id,
135
+ asset_id: signableResult.data.asset_id,
136
+ amount: signableResult.data.amount,
137
+ nonce: signableResult.data.nonce,
138
+ expiration_timestamp: signableResult.data.expiration_timestamp,
139
+ stark_signature: starkSignature,
140
+ };
141
+ const response = await transfersApi.createTransferV1({
142
+ createTransferRequest: transferSigningParams,
143
+ xImxEthAddress: ethAddress,
144
+ xImxEthSignature: ethSignature,
145
+ });
146
+ return {
147
+ sent_signature: response?.data.sent_signature,
148
+ status: response?.data.status?.toString(),
149
+ time: response?.data.time,
150
+ transfer_id: response?.data.transfer_id,
151
+ };
152
+ }
153
+ async function batchTransfer({ signers: { ethSigner, starkExSigner }, request, config, }) {
154
+ await validateChain(ethSigner, config.immutableXConfig);
155
+ const ethAddress = await ethSigner.getAddress();
156
+ const transfersApi = new TransfersApi(config.immutableXConfig.apiConfiguration);
157
+ const signableRequests = request.map((nftTransfer) => {
158
+ return {
159
+ amount: '1',
160
+ token: convertToSignableToken({
161
+ type: 'ERC721',
162
+ tokenId: nftTransfer.tokenId,
163
+ tokenAddress: nftTransfer.tokenAddress,
164
+ }),
165
+ receiver: nftTransfer.receiver,
166
+ };
167
+ });
168
+ const signableResult = await transfersApi.getSignableTransfer({
169
+ getSignableTransferRequestV2: {
170
+ sender_ether_key: ethAddress,
171
+ signable_requests: signableRequests,
172
+ },
173
+ });
174
+ const signableMessage = signableResult.data.signable_message;
175
+ if (signableMessage === undefined) {
176
+ throw new Error('Invalid response from Signable registration offchain');
177
+ }
178
+ const ethSignature = await signRaw(signableMessage, ethSigner);
179
+ const requests = [];
180
+ for (const resp of signableResult.data.signable_responses) {
181
+ const starkSignature = await starkExSigner.signMessage(resp.payload_hash);
182
+ const req = {
183
+ sender_vault_id: resp.sender_vault_id,
184
+ receiver_stark_key: resp.receiver_stark_key,
185
+ receiver_vault_id: resp.receiver_vault_id,
186
+ asset_id: resp.asset_id,
187
+ amount: resp.amount,
188
+ nonce: resp.nonce,
189
+ expiration_timestamp: resp.expiration_timestamp,
190
+ stark_signature: starkSignature,
191
+ };
192
+ requests.push(req);
193
+ }
194
+ // TODO: throw error on missing payload hash?
195
+ const transferSigningParams = {
196
+ sender_stark_key: signableResult.data.sender_stark_key,
197
+ requests,
198
+ };
199
+ const response = await transfersApi.createTransfer({
200
+ createTransferRequestV2: transferSigningParams,
201
+ xImxEthAddress: ethAddress,
202
+ xImxEthSignature: ethSignature,
203
+ });
204
+ return {
205
+ transfer_ids: response?.data.transfer_ids,
206
+ };
207
+ }
208
+
209
+ async function createOrder$1({ signers, request, config, }) {
210
+ await validateChain(signers.ethSigner, config.immutableXConfig);
211
+ const ethAddress = await signers.ethSigner.getAddress();
212
+ const ordersApi = new OrdersApi(config.immutableXConfig.apiConfiguration);
213
+ const amountSell = request.sell.type === 'ERC721' ? '1' : request.sell.amount;
214
+ const amountBuy = request.buy.type === 'ERC721' ? '1' : request.buy.amount;
215
+ const getSignableOrderRequest = {
216
+ user: ethAddress,
217
+ amount_buy: amountBuy,
218
+ token_buy: convertToSignableToken(request.buy),
219
+ amount_sell: amountSell,
220
+ token_sell: convertToSignableToken(request.sell),
221
+ fees: request.fees,
222
+ expiration_timestamp: request.expiration_timestamp,
223
+ };
224
+ const getSignableOrderResponse = await ordersApi.getSignableOrder({
225
+ getSignableOrderRequestV3: getSignableOrderRequest,
226
+ });
227
+ const { signable_message: signableMessage, payload_hash: payloadHash } = getSignableOrderResponse.data;
228
+ const ethSignature = await signRaw(signableMessage, signers.ethSigner);
229
+ const starkSignature = await signers.starkExSigner.signMessage(payloadHash);
230
+ const resp = getSignableOrderResponse.data;
231
+ const orderParams = {
232
+ createOrderRequest: {
233
+ amount_buy: resp.amount_buy,
234
+ amount_sell: resp.amount_sell,
235
+ asset_id_buy: resp.asset_id_buy,
236
+ asset_id_sell: resp.asset_id_sell,
237
+ expiration_timestamp: resp.expiration_timestamp,
238
+ include_fees: true,
239
+ fees: request.fees,
240
+ nonce: resp.nonce,
241
+ stark_key: resp.stark_key,
242
+ stark_signature: starkSignature,
243
+ vault_id_buy: resp.vault_id_buy,
244
+ vault_id_sell: resp.vault_id_sell,
245
+ },
246
+ xImxEthAddress: ethAddress,
247
+ xImxEthSignature: ethSignature,
248
+ };
249
+ const createOrderResponse = await ordersApi.createOrder(orderParams);
250
+ return {
251
+ ...createOrderResponse.data,
252
+ };
253
+ }
254
+ async function cancelOrder$1({ signers, request, config, }) {
255
+ const ordersApi = new OrdersApi(config.immutableXConfig.apiConfiguration);
256
+ const getSignableCancelOrderResponse = await ordersApi.getSignableCancelOrder({
257
+ getSignableCancelOrderRequest: {
258
+ order_id: request.order_id,
259
+ },
260
+ });
261
+ const { signable_message: signableMessage, payload_hash: payloadHash } = getSignableCancelOrderResponse.data;
262
+ const ethSignature = await signRaw(signableMessage, signers.ethSigner);
263
+ const starkSignature = await signers.starkExSigner.signMessage(payloadHash);
264
+ const ethAddress = await signers.ethSigner.getAddress();
265
+ const cancelOrderResponse = await ordersApi.cancelOrder({
266
+ id: request.order_id.toString(),
267
+ cancelOrderRequest: {
268
+ order_id: request.order_id,
269
+ stark_signature: starkSignature,
270
+ },
271
+ xImxEthAddress: ethAddress,
272
+ xImxEthSignature: ethSignature,
273
+ });
274
+ return {
275
+ order_id: cancelOrderResponse.data.order_id,
276
+ status: cancelOrderResponse.data.status,
277
+ };
278
+ }
279
+
280
+ async function registerOffchain(signers, config) {
281
+ await validateChain(signers.ethSigner, config.immutableXConfig);
282
+ const usersApi = new UsersApi(config.immutableXConfig.apiConfiguration);
283
+ const userAddress = await signers.ethSigner.getAddress();
284
+ const starkPublicKey = await signers.starkExSigner.getAddress();
285
+ const signableResult = await usersApi.getSignableRegistrationOffchain({
286
+ getSignableRegistrationRequest: {
287
+ ether_key: userAddress,
288
+ stark_key: starkPublicKey,
289
+ },
290
+ });
291
+ const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
292
+ const ethSignature = await signRaw(signableMessage, signers.ethSigner);
293
+ const starkSignature = await signers.starkExSigner.signMessage(payloadHash);
294
+ const registeredUser = await usersApi.registerUser({
295
+ registerUserRequest: {
296
+ eth_signature: ethSignature,
297
+ ether_key: userAddress,
298
+ stark_signature: starkSignature,
299
+ stark_key: starkPublicKey,
300
+ },
301
+ });
302
+ return registeredUser.data;
303
+ }
304
+ async function isRegisteredOnChain(starkPublicKey, ethSigner, config) {
305
+ await validateChain(ethSigner, config.immutableXConfig);
306
+ const registrationContract = Contracts.Registration.connect(config.immutableXConfig.ethConfiguration.registrationContractAddress, ethSigner);
307
+ try {
308
+ return await registrationContract.isRegistered(starkPublicKey);
309
+ }
310
+ catch (ex) {
311
+ if (ex.reason === 'USER_UNREGISTERED') {
312
+ return false;
313
+ }
314
+ throw ex;
315
+ }
316
+ }
317
+ async function getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi) {
318
+ const response = await usersApi.getSignableRegistration({
319
+ getSignableRegistrationRequest: {
320
+ ether_key: etherKey,
321
+ stark_key: starkPublicKey,
322
+ },
323
+ });
324
+ return {
325
+ operator_signature: response.data.operator_signature,
326
+ payload_hash: response.data.payload_hash,
327
+ };
328
+ }
329
+
330
+ const assertIsDefined = (value) => {
331
+ if (value !== undefined)
332
+ return value;
333
+ throw new Error('undefined field exception');
334
+ };
335
+ async function prepareWithdrawalAction(params) {
336
+ const { signers: { ethSigner, starkExSigner }, type, config, } = params;
337
+ await validateChain(ethSigner, params.config);
338
+ const withdrawalsApi = new WithdrawalsApi(config.apiConfiguration);
339
+ const withdrawalAmount = type === 'ERC721' ? '1' : params.amount;
340
+ const signableWithdrawalResult = await withdrawalsApi.getSignableWithdrawal({
341
+ getSignableWithdrawalRequest: {
342
+ user: await ethSigner.getAddress(),
343
+ token: convertToSignableToken(params),
344
+ amount: withdrawalAmount,
345
+ },
346
+ });
347
+ const { signable_message: signableMessage, payload_hash: payloadHash } = signableWithdrawalResult.data;
348
+ const starkSignature = await starkExSigner.signMessage(payloadHash);
349
+ const { ethAddress, ethSignature } = await signMessage(signableMessage, ethSigner);
350
+ const prepareWithdrawalResponse = await withdrawalsApi.createWithdrawal({
351
+ createWithdrawalRequest: {
352
+ stark_key: assertIsDefined(signableWithdrawalResult.data.stark_key),
353
+ amount: withdrawalAmount,
354
+ asset_id: assertIsDefined(signableWithdrawalResult.data.asset_id),
355
+ vault_id: assertIsDefined(signableWithdrawalResult.data.vault_id),
356
+ nonce: assertIsDefined(signableWithdrawalResult.data.nonce),
357
+ stark_signature: starkSignature,
358
+ },
359
+ xImxEthAddress: ethAddress,
360
+ xImxEthSignature: ethSignature,
361
+ });
362
+ return prepareWithdrawalResponse.data;
363
+ }
364
+
365
+ async function getEncodeAssetInfo(assetType, tokenType, config, tokenData) {
366
+ const encodingApi = new EncodingApi(config.apiConfiguration);
367
+ const result = await encodingApi.encodeAsset({
368
+ assetType,
369
+ encodeAssetRequest: {
370
+ token: {
371
+ type: tokenType,
372
+ ...(tokenData && { data: tokenData }),
373
+ },
374
+ },
375
+ });
376
+ return result.data;
377
+ }
378
+
379
+ async function executeRegisterAndWithdrawERC20({ ethSigner, assetType, starkPublicKey, config, }) {
380
+ const etherKey = await ethSigner.getAddress();
381
+ const starkExConfig = config.immutableXConfig;
382
+ const usersApi = new UsersApi(starkExConfig.apiConfiguration);
383
+ const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
384
+ const contract = Contracts.Registration.connect(config.immutableXConfig.ethConfiguration.registrationContractAddress, ethSigner);
385
+ const populatedTransaction = await contract.populateTransaction.registerAndWithdraw(etherKey, starkPublicKey, signableResult.operator_signature, assetType);
386
+ return ethSigner.sendTransaction(populatedTransaction);
387
+ }
388
+ async function executeWithdrawERC20(ethSigner, assetType, starkPublicKey, config) {
389
+ const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
390
+ const populatedTransaction = await contract.populateTransaction.withdraw(starkPublicKey, assetType);
391
+ return ethSigner.sendTransaction(populatedTransaction);
392
+ }
393
+ async function completeERC20WithdrawalAction({ ethSigner, starkPublicKey, token, config, }) {
394
+ await validateChain(ethSigner, config.immutableXConfig);
395
+ const starkExConfig = config.immutableXConfig;
396
+ const assetType = await getEncodeAssetInfo('asset', 'ERC20', starkExConfig, {
397
+ token_address: token.tokenAddress,
398
+ });
399
+ const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
400
+ if (!isRegistered) {
401
+ return executeRegisterAndWithdrawERC20({
402
+ ethSigner,
403
+ assetType: assetType.asset_type,
404
+ starkPublicKey,
405
+ config,
406
+ });
407
+ }
408
+ else {
409
+ return executeWithdrawERC20(ethSigner, assetType.asset_type, starkPublicKey, starkExConfig);
410
+ }
411
+ }
412
+
413
+ async function executeWithdrawMintableERC721(ethSigner, assetType, starkPublicKey, mintingBlob, config) {
414
+ const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
415
+ const populatedTransaction = await contract.populateTransaction.withdrawAndMint(starkPublicKey, assetType, mintingBlob);
416
+ return ethSigner.sendTransaction(populatedTransaction);
417
+ }
418
+ async function executeRegisterAndWithdrawMintableERC721(ethSigner, assetType, starkPublicKey, mintingBlob, config) {
419
+ const etherKey = await ethSigner.getAddress();
420
+ const usersApi = new UsersApi(config.apiConfiguration);
421
+ const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
422
+ const contract = Contracts.Registration.connect(config.ethConfiguration.registrationContractAddress, ethSigner);
423
+ const populatedTransaction = await contract.populateTransaction.regsiterAndWithdrawAndMint(etherKey, starkPublicKey, signableResult.operator_signature, assetType, mintingBlob);
424
+ return ethSigner.sendTransaction(populatedTransaction);
425
+ }
426
+ function getMintingBlob(token) {
427
+ const id = token.data.id;
428
+ const blueprint = token.data.blueprint || '';
429
+ return encUtils.sanitizeHex(encUtils.utf8ToHex(`{${id}}:{${blueprint}}`));
430
+ }
431
+ async function completeMintableERC721Withdrawal(ethSigner, starkPublicKey, token, config) {
432
+ const starkExConfig = config.immutableXConfig;
433
+ const assetType = await getEncodeAssetInfo('mintable-asset', 'ERC721', starkExConfig, {
434
+ id: token.data.id,
435
+ token_address: token.data.tokenAddress,
436
+ ...(token.data.blueprint && { blueprint: token.data.blueprint }),
437
+ });
438
+ const mintingBlob = getMintingBlob(token);
439
+ const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
440
+ if (!isRegistered) {
441
+ return executeRegisterAndWithdrawMintableERC721(ethSigner, assetType.asset_type, starkPublicKey, mintingBlob, starkExConfig);
442
+ }
443
+ else {
444
+ return executeWithdrawMintableERC721(ethSigner, assetType.asset_type, starkPublicKey, mintingBlob, starkExConfig);
445
+ }
446
+ }
447
+ async function executeRegisterAndWithdrawERC721(ethSigner, assetType, starkPublicKey, tokenId, config) {
448
+ const etherKey = await ethSigner.getAddress();
449
+ const usersApi = new UsersApi(config.apiConfiguration);
450
+ const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
451
+ const contract = Contracts.Registration.connect(config.ethConfiguration.registrationContractAddress, ethSigner);
452
+ const populatedTransaction = await contract.populateTransaction.registerAndWithdrawNft(etherKey, starkPublicKey, signableResult.operator_signature, assetType, tokenId);
453
+ return ethSigner.sendTransaction(populatedTransaction);
454
+ }
455
+ async function executeWithdrawERC721(ethSigner, assetType, starkPublicKey, tokenId, config) {
456
+ const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
457
+ const populatedTransaction = await contract.populateTransaction.withdrawNft(starkPublicKey, assetType, tokenId);
458
+ return ethSigner.sendTransaction(populatedTransaction);
459
+ }
460
+ async function completeERC721Withdrawal(ethSigner, starkPublicKey, token, config) {
461
+ const starkExConfig = config.immutableXConfig;
462
+ const assetType = await getEncodeAssetInfo('asset', 'ERC721', starkExConfig, {
463
+ token_id: token.tokenId,
464
+ token_address: token.tokenAddress,
465
+ });
466
+ const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
467
+ if (!isRegistered) {
468
+ return executeRegisterAndWithdrawERC721(ethSigner, assetType.asset_type, starkPublicKey, token.tokenId, starkExConfig);
469
+ }
470
+ else {
471
+ return executeWithdrawERC721(ethSigner, assetType.asset_type, starkPublicKey, token.tokenId, starkExConfig);
472
+ }
473
+ }
474
+ async function completeERC721WithdrawalAction({ ethSigner, starkPublicKey, token, config, }) {
475
+ await validateChain(ethSigner, config.immutableXConfig);
476
+ const tokenAddress = token.tokenAddress;
477
+ const tokenId = token.tokenId;
478
+ const starkExConfig = config.immutableXConfig;
479
+ const mintsApi = new MintsApi(starkExConfig.apiConfiguration);
480
+ return await mintsApi
481
+ .getMintableTokenDetailsByClientTokenId({
482
+ tokenAddress,
483
+ tokenId,
484
+ })
485
+ .then((mintableToken) => completeMintableERC721Withdrawal(ethSigner, starkPublicKey, {
486
+ type: 'ERC721',
487
+ data: {
488
+ id: tokenId,
489
+ tokenAddress: tokenAddress,
490
+ blueprint: mintableToken.data.blueprint,
491
+ },
492
+ }, config))
493
+ .catch((error) => {
494
+ if (error.response?.status === 404) {
495
+ // token is already minted on L1
496
+ return completeERC721Withdrawal(ethSigner, starkPublicKey, token, config);
497
+ }
498
+ throw error; // unable to recover from any other kind of error
499
+ });
500
+ }
501
+
502
+ async function executeRegisterAndWithdrawEth(ethSigner, assetType, starkPublicKey, config) {
503
+ const etherKey = await ethSigner.getAddress();
504
+ const usersApi = new UsersApi(config.apiConfiguration);
505
+ const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
506
+ const contract = Contracts.Registration.connect(config.ethConfiguration.registrationContractAddress, ethSigner);
507
+ const populatedTransaction = await contract.populateTransaction.registerAndWithdraw(etherKey, starkPublicKey, signableResult.operator_signature, assetType);
508
+ return ethSigner.sendTransaction(populatedTransaction);
509
+ }
510
+ async function executeWithdrawEth(ethSigner, assetType, starkPublicKey, config) {
511
+ const contract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
512
+ const populatedTransaction = await contract.populateTransaction.withdraw(starkPublicKey, assetType);
513
+ return ethSigner.sendTransaction(populatedTransaction);
514
+ }
515
+ async function completeEthWithdrawalAction({ ethSigner, starkPublicKey, config, }) {
516
+ await validateChain(ethSigner, config.immutableXConfig);
517
+ const starkExConfig = config.immutableXConfig;
518
+ const assetType = await getEncodeAssetInfo('asset', 'ETH', starkExConfig);
519
+ const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
520
+ if (!isRegistered) {
521
+ return executeRegisterAndWithdrawEth(ethSigner, assetType.asset_type, starkPublicKey, starkExConfig);
522
+ }
523
+ else {
524
+ return executeWithdrawEth(ethSigner, assetType.asset_type, starkPublicKey, starkExConfig);
525
+ }
526
+ }
527
+
528
+ async function prepareWithdrawal({ signers, withdrawal, config, }) {
529
+ return prepareWithdrawalAction({
530
+ signers,
531
+ config: config.immutableXConfig,
532
+ ...withdrawal,
533
+ });
534
+ }
535
+ async function completeWithdrawal({ signers: { ethSigner }, starkPublicKey, token, config, }) {
536
+ switch (token.type) {
537
+ case 'ETH':
538
+ return completeEthWithdrawalAction({ ethSigner, starkPublicKey, config });
539
+ case 'ERC20':
540
+ return completeERC20WithdrawalAction({
541
+ ethSigner,
542
+ starkPublicKey,
543
+ token,
544
+ config,
545
+ });
546
+ case 'ERC721':
547
+ return completeERC721WithdrawalAction({
548
+ ethSigner,
549
+ starkPublicKey,
550
+ token,
551
+ config,
552
+ });
553
+ }
554
+ }
555
+
556
+ async function createTrade$1({ signers: { ethSigner, starkExSigner }, request, config, }) {
557
+ await validateChain(ethSigner, config.immutableXConfig);
558
+ const ethAddress = await ethSigner.getAddress();
559
+ const tradesApi = new TradesApi(config.immutableXConfig.apiConfiguration);
560
+ const signableResult = await tradesApi.getSignableTrade({
561
+ getSignableTradeRequest: {
562
+ user: ethAddress,
563
+ order_id: request.order_id,
564
+ fees: request.fees,
565
+ },
566
+ });
567
+ const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
568
+ const ethSignature = await signRaw(signableMessage, ethSigner);
569
+ const starkSignature = await starkExSigner.signMessage(payloadHash);
570
+ const createTradeResponse = await tradesApi.createTrade({
571
+ createTradeRequest: {
572
+ amount_buy: signableResult.data.amount_buy,
573
+ amount_sell: signableResult.data.amount_sell,
574
+ asset_id_buy: signableResult.data.asset_id_buy,
575
+ asset_id_sell: signableResult.data.asset_id_sell,
576
+ expiration_timestamp: signableResult.data.expiration_timestamp,
577
+ fee_info: signableResult.data.fee_info,
578
+ fees: request.fees,
579
+ include_fees: true,
580
+ nonce: signableResult.data.nonce,
581
+ order_id: request.order_id,
582
+ stark_key: signableResult.data.stark_key,
583
+ vault_id_buy: signableResult.data.vault_id_buy,
584
+ vault_id_sell: signableResult.data.vault_id_sell,
585
+ stark_signature: starkSignature,
586
+ },
587
+ xImxEthAddress: ethAddress,
588
+ xImxEthSignature: ethSignature,
589
+ });
590
+ return createTradeResponse.data;
591
+ }
592
+
593
+ async function depositEth({ signers: { ethSigner }, deposit, config, }) {
594
+ await validateChain(ethSigner, config.immutableXConfig);
595
+ const user = await ethSigner.getAddress();
596
+ const data = {
597
+ decimals: 18,
598
+ };
599
+ const amount = parseUnits(deposit.amount, 'wei');
600
+ const starkExConfig = config.immutableXConfig;
601
+ const depositsApi = new DepositsApi(starkExConfig.apiConfiguration);
602
+ const encodingApi = new EncodingApi(starkExConfig.apiConfiguration);
603
+ const usersApi = new UsersApi(starkExConfig.apiConfiguration);
604
+ const getSignableDepositRequest = {
605
+ user,
606
+ token: {
607
+ type: deposit.type,
608
+ data,
609
+ },
610
+ amount: amount.toString(),
611
+ };
612
+ const signableDepositResult = await depositsApi.getSignableDeposit({
613
+ getSignableDepositRequest,
614
+ });
615
+ const encodingResult = await encodingApi.encodeAsset({
616
+ assetType: 'asset',
617
+ encodeAssetRequest: {
618
+ token: {
619
+ type: deposit.type,
620
+ },
621
+ },
622
+ });
623
+ const assetType = encodingResult.data.asset_type;
624
+ const starkPublicKey = signableDepositResult.data.stark_key;
625
+ const vaultId = signableDepositResult.data.vault_id;
626
+ const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
627
+ if (!isRegistered) {
628
+ return executeRegisterAndDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, starkExConfig, usersApi);
629
+ }
630
+ else {
631
+ return executeDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, starkExConfig);
632
+ }
633
+ }
634
+ async function executeRegisterAndDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, config, usersApi) {
635
+ const etherKey = await ethSigner.getAddress();
636
+ const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
637
+ const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
638
+ const populatedTransaction = await coreContract.populateTransaction.registerAndDepositEth(etherKey, starkPublicKey, signableResult.operator_signature, assetType, vaultId);
639
+ return ethSigner.sendTransaction({ ...populatedTransaction, value: amount });
640
+ }
641
+ async function executeDepositEth(ethSigner, amount, assetType, starkPublicKey, vaultId, config) {
642
+ const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
643
+ const populatedTransaction = await coreContract.populateTransaction['deposit(uint256,uint256,uint256)'](starkPublicKey, assetType, vaultId);
644
+ return ethSigner.sendTransaction({ ...populatedTransaction, value: amount });
645
+ }
646
+
647
+ async function depositERC20({ signers: { ethSigner }, deposit, config, }) {
648
+ await validateChain(ethSigner, config.immutableXConfig);
649
+ const { apiConfiguration, ethConfiguration } = config.immutableXConfig;
650
+ const user = await ethSigner.getAddress();
651
+ const tokensApi = new TokensApi(apiConfiguration);
652
+ const depositsApi = new DepositsApi(apiConfiguration);
653
+ const encodingApi = new EncodingApi(apiConfiguration);
654
+ const usersApi = new UsersApi(apiConfiguration);
655
+ // Get decimals for this specific ERC20
656
+ const token = await tokensApi.getToken({ address: deposit.tokenAddress });
657
+ const decimals = parseInt(token.data.decimals);
658
+ const data = {
659
+ decimals,
660
+ token_address: deposit.tokenAddress,
661
+ };
662
+ const amount = parseUnits(deposit.amount, 0); // 0 to always use undecimalized value
663
+ // Approve whether an amount of token from an account can be spent by a third-party account
664
+ const tokenContract = Contracts.IERC20.connect(deposit.tokenAddress, ethSigner);
665
+ const approveTransaction = await tokenContract.populateTransaction.approve(ethConfiguration.coreContractAddress, amount);
666
+ await ethSigner.sendTransaction(approveTransaction);
667
+ const getSignableDepositRequest = {
668
+ user,
669
+ token: {
670
+ type: deposit.type,
671
+ data,
672
+ },
673
+ amount: amount.toString(),
674
+ };
675
+ const signableDepositResult = await depositsApi.getSignableDeposit({
676
+ getSignableDepositRequest,
677
+ });
678
+ // Perform encoding on asset details to get an assetType (required for stark contract request)
679
+ const encodingResult = await encodingApi.encodeAsset({
680
+ assetType: 'asset',
681
+ encodeAssetRequest: {
682
+ token: {
683
+ type: deposit.type,
684
+ data: {
685
+ token_address: deposit.tokenAddress,
686
+ },
687
+ },
688
+ },
689
+ });
690
+ const assetType = encodingResult.data.asset_type;
691
+ const starkPublicKey = signableDepositResult.data.stark_key;
692
+ const vaultId = signableDepositResult.data.vault_id;
693
+ const quantizedAmount = BigNumber.from(signableDepositResult.data.amount);
694
+ const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
695
+ if (!isRegistered) {
696
+ return executeRegisterAndDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, ethConfiguration, usersApi);
697
+ }
698
+ else {
699
+ return executeDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, ethConfiguration);
700
+ }
701
+ }
702
+ async function executeDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, config) {
703
+ const coreContract = Contracts.Core.connect(config.coreContractAddress, ethSigner);
704
+ const populatedTransaction = await coreContract.populateTransaction.depositERC20(starkPublicKey, assetType, vaultId, quantizedAmount);
705
+ return ethSigner.sendTransaction(populatedTransaction);
706
+ }
707
+ async function executeRegisterAndDepositERC20(ethSigner, quantizedAmount, assetType, starkPublicKey, vaultId, config, usersApi) {
708
+ const etherKey = await ethSigner.getAddress();
709
+ const coreContract = Contracts.Core.connect(config.coreContractAddress, ethSigner);
710
+ const signableResult = await getSignableRegistrationOnchain(etherKey, starkPublicKey, usersApi);
711
+ const populatedTransaction = await coreContract.populateTransaction.registerAndDepositERC20(etherKey, starkPublicKey, signableResult.operator_signature, assetType, vaultId, quantizedAmount);
712
+ return ethSigner.sendTransaction(populatedTransaction);
713
+ }
714
+
715
+ async function depositERC721({ signers: { ethSigner }, deposit, config, }) {
716
+ await validateChain(ethSigner, config.immutableXConfig);
717
+ const user = await ethSigner.getAddress();
718
+ const { immutableXConfig } = config;
719
+ const depositsApi = new DepositsApi(immutableXConfig.apiConfiguration);
720
+ const encodingApi = new EncodingApi(immutableXConfig.apiConfiguration);
721
+ const usersApi = new UsersApi(immutableXConfig.apiConfiguration);
722
+ const data = {
723
+ token_address: deposit.tokenAddress,
724
+ token_id: deposit.tokenId,
725
+ };
726
+ const amount = '1';
727
+ const getSignableDepositRequest = {
728
+ user,
729
+ token: {
730
+ type: deposit.type,
731
+ data,
732
+ },
733
+ amount: amount.toString(),
734
+ };
735
+ const signableDepositResult = await depositsApi.getSignableDeposit({
736
+ getSignableDepositRequest,
737
+ });
738
+ // Perform encoding on asset details to get an assetType (required for stark contract request)
739
+ const encodingResult = await encodingApi.encodeAsset({
740
+ assetType: 'asset',
741
+ encodeAssetRequest: {
742
+ token: {
743
+ type: deposit.type,
744
+ data: {
745
+ token_address: deposit.tokenAddress,
746
+ token_id: deposit.tokenId,
747
+ },
748
+ },
749
+ },
750
+ });
751
+ const assetType = encodingResult.data.asset_type;
752
+ const starkPublicKey = signableDepositResult.data.stark_key;
753
+ const vaultId = signableDepositResult.data.vault_id;
754
+ const isRegistered = await isRegisteredOnChain(starkPublicKey, ethSigner, config);
755
+ // Approve whether an amount of token from an account can be spent by a third-party account
756
+ const tokenContract = Contracts.IERC721.connect(deposit.tokenAddress, ethSigner);
757
+ const operator = immutableXConfig.ethConfiguration.coreContractAddress;
758
+ const isApprovedForAll = await tokenContract.isApprovedForAll(user, operator);
759
+ if (!isApprovedForAll) {
760
+ await tokenContract.setApprovalForAll(operator, true);
761
+ }
762
+ if (!isRegistered) {
763
+ const signableResult = await getSignableRegistrationOnchain(user, starkPublicKey, usersApi);
764
+ const coreContract = Contracts.Core.connect(immutableXConfig.ethConfiguration.coreContractAddress, ethSigner);
765
+ // Note: proxy registration contract registerAndDepositNft method is not used as it currently fails erc721 transfer ownership check
766
+ await coreContract.registerUser(user, starkPublicKey, signableResult.operator_signature);
767
+ }
768
+ return executeDepositERC721(ethSigner, deposit.tokenId, assetType, starkPublicKey, vaultId, immutableXConfig);
769
+ }
770
+ async function executeDepositERC721(ethSigner, tokenId, assetType, starkPublicKey, vaultId, config) {
771
+ const coreContract = Contracts.Core.connect(config.ethConfiguration.coreContractAddress, ethSigner);
772
+ const populatedTransaction = await coreContract.populateTransaction.depositNft(starkPublicKey, assetType, vaultId, tokenId);
773
+ return ethSigner.sendTransaction(populatedTransaction);
774
+ }
775
+
776
+ async function deposit({ signers, deposit, config }) {
777
+ switch (deposit.type) {
778
+ case 'ETH':
779
+ return depositEth({ signers, deposit, config });
780
+ case 'ERC20':
781
+ return depositERC20({ signers, deposit, config });
782
+ case 'ERC721':
783
+ return depositERC721({ signers, deposit, config });
784
+ }
785
+ }
786
+
787
+ async function exchangeTransfer$1({ signers, request, config, }) {
788
+ await validateChain(signers.ethSigner, config.immutableXConfig);
789
+ const exchangeApi = new ExchangesApi(config.immutableXConfig.apiConfiguration);
790
+ const ethAddress = await signers.ethSigner.getAddress();
791
+ const transferAmount = request.amount;
792
+ const signableResult = await exchangeApi.getExchangeSignableTransfer({
793
+ id: request.transactionID,
794
+ getSignableTransferRequest: {
795
+ sender: ethAddress,
796
+ token: convertToSignableToken(request),
797
+ amount: transferAmount,
798
+ receiver: request.receiver,
799
+ },
800
+ });
801
+ const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
802
+ const ethSignature = await signRaw(signableMessage, signers.ethSigner);
803
+ const starkSignature = await signers.starkExSigner.signMessage(payloadHash);
804
+ const transferSigningParams = {
805
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
806
+ sender_stark_key: signableResult.data.sender_stark_key,
807
+ sender_vault_id: signableResult.data.sender_vault_id,
808
+ receiver_stark_key: signableResult.data.receiver_stark_key,
809
+ receiver_vault_id: signableResult.data.receiver_vault_id,
810
+ asset_id: signableResult.data.asset_id,
811
+ amount: signableResult.data.amount,
812
+ nonce: signableResult.data.nonce,
813
+ expiration_timestamp: signableResult.data.expiration_timestamp,
814
+ stark_signature: starkSignature,
815
+ };
816
+ const response = await exchangeApi.createExchangeTransfer({
817
+ id: request.transactionID,
818
+ createTransferRequest: transferSigningParams,
819
+ xImxEthAddress: ethAddress,
820
+ xImxEthSignature: ethSignature,
821
+ });
822
+ return {
823
+ sent_signature: response?.data.sent_signature,
824
+ status: response?.data.status?.toString(),
825
+ time: response?.data.time,
826
+ transfer_id: response?.data.transfer_id,
827
+ };
828
+ }
829
+
830
+ class GenericIMXProvider {
831
+ config;
832
+ signers;
833
+ constructor(config, ethSigner, starkExSigner) {
834
+ this.config = config;
835
+ this.signers = { ethSigner, starkExSigner };
836
+ }
837
+ async getAddress() {
838
+ return await this.signers.ethSigner.getAddress();
839
+ }
840
+ registerOffchain() {
841
+ return registerOffchain(this.signers, this.config);
842
+ }
843
+ batchNftTransfer(request) {
844
+ return batchTransfer({
845
+ signers: this.signers,
846
+ request,
847
+ config: this.config,
848
+ });
849
+ }
850
+ cancelOrder(request) {
851
+ return cancelOrder$1({
852
+ signers: this.signers,
853
+ request,
854
+ config: this.config,
855
+ });
856
+ }
857
+ completeWithdrawal(starkPublicKey, token) {
858
+ return completeWithdrawal({
859
+ config: this.config,
860
+ signers: this.signers,
861
+ token,
862
+ starkPublicKey,
863
+ });
864
+ }
865
+ createOrder(request) {
866
+ return createOrder$1({
867
+ signers: this.signers,
868
+ request,
869
+ config: this.config,
870
+ });
871
+ }
872
+ createTrade(request) {
873
+ return createTrade$1({
874
+ signers: this.signers,
875
+ request,
876
+ config: this.config,
877
+ });
878
+ }
879
+ deposit(tokenAmount) {
880
+ return deposit({
881
+ signers: this.signers,
882
+ deposit: tokenAmount,
883
+ config: this.config,
884
+ });
885
+ }
886
+ exchangeTransfer(request) {
887
+ return exchangeTransfer$1({
888
+ signers: this.signers,
889
+ request,
890
+ config: this.config,
891
+ });
892
+ }
893
+ async isRegisteredOnchain() {
894
+ const starkPublicKey = await this.signers.starkExSigner.getAddress();
895
+ return isRegisteredOnChain(starkPublicKey, this.signers.ethSigner, this.config);
896
+ }
897
+ prepareWithdrawal(request) {
898
+ return prepareWithdrawal({
899
+ signers: this.signers,
900
+ withdrawal: request,
901
+ config: this.config,
902
+ });
903
+ }
904
+ transfer(request) {
905
+ return transfer$1({
906
+ signers: this.signers,
907
+ request,
908
+ config: this.config,
909
+ });
910
+ }
911
+ }
912
+
913
+ const WALLET_ACTION = {
914
+ SWITCH_CHAIN: 'wallet_switchEthereumChain',
915
+ CONNECT: 'eth_requestAccounts',
916
+ };
917
+ function isRequestableProvider(provider) {
918
+ return !!provider?.request;
919
+ }
920
+ async function connectProvider(provider, chainID) {
921
+ await provider.request({ method: WALLET_ACTION.CONNECT });
922
+ if (chainID) {
923
+ await provider.request({
924
+ method: WALLET_ACTION.SWITCH_CHAIN,
925
+ params: [{ chainId: `0x${chainID.toString(16)}` }],
926
+ });
927
+ }
928
+ }
929
+
930
+ const ERRORS = {
931
+ PROVIDER_NOT_FOUND: 'The Metamask provider was not found',
932
+ };
933
+ async function connect$1({ chainID, }) {
934
+ const provider = (await detectEthereumProvider());
935
+ if (!isRequestableProvider(provider)) {
936
+ throw new Error(ERRORS.PROVIDER_NOT_FOUND);
937
+ }
938
+ await connectProvider(provider, chainID);
939
+ // NOTE: if we want to listen to Metamask events in the future, we can add a
940
+ // listener here.
941
+ return new ethers.providers.Web3Provider(provider);
942
+ }
943
+
944
+ const COMMUNICATION_TYPE = 'message';
945
+ var RequestEventType;
946
+ (function (RequestEventType) {
947
+ RequestEventType["GET_CONNECTION_REQUEST"] = "GET_CONNECTION_REQUEST";
948
+ RequestEventType["CONNECT_WALLET_REQUEST"] = "CONNECT_WALLET_REQUEST";
949
+ RequestEventType["SIGN_MESSAGE_REQUEST"] = "SIGN_MESSAGE_REQUEST";
950
+ RequestEventType["DISCONNECT_WALLET_REQUEST"] = "DISCONNECT_WALLET_REQUEST";
951
+ })(RequestEventType || (RequestEventType = {}));
952
+ var ResponseEventType;
953
+ (function (ResponseEventType) {
954
+ ResponseEventType["CONNECT_WALLET_RESPONSE"] = "CONNECT_WALLET_RESPONSE";
955
+ ResponseEventType["SIGN_MESSAGE_RESPONSE"] = "SIGN_MESSAGE_RESPONSE";
956
+ ResponseEventType["GET_CONNECTION_RESPONSE"] = "GET_CONNECTION_RESPONSE";
957
+ ResponseEventType["DISCONNECT_WALLET_RESPONSE"] = "DISCONNECT_WALLET_RESPONSE";
958
+ })(ResponseEventType || (ResponseEventType = {}));
959
+
960
+ function postRequestMessage(iframe, payload) {
961
+ if (iframe && iframe.contentWindow) {
962
+ iframe.contentWindow.postMessage(payload, new URL(iframe.src).origin);
963
+ }
964
+ }
965
+
966
+ function messageResponseListener(iframe, event, eventType, callback) {
967
+ if (iframe && event.source !== iframe.contentWindow) {
968
+ return;
969
+ }
970
+ const l2WalletMessage = event.data;
971
+ if (l2WalletMessage.type !== eventType) {
972
+ return;
973
+ }
974
+ callback(l2WalletMessage.details);
975
+ }
976
+
977
+ class ImxSigner {
978
+ publicAddress;
979
+ iframe;
980
+ constructor(publicAddress, iframe) {
981
+ this.publicAddress = publicAddress;
982
+ this.iframe = iframe;
983
+ }
984
+ getAddress() {
985
+ return this.publicAddress;
986
+ }
987
+ signMessage(rawMessage) {
988
+ return new Promise((resolve, reject) => {
989
+ const listener = (event) => {
990
+ messageResponseListener(this.iframe, event, ResponseEventType.SIGN_MESSAGE_RESPONSE, (messageDetails) => {
991
+ window.removeEventListener(COMMUNICATION_TYPE, listener);
992
+ if (!messageDetails.success) {
993
+ reject(new Error(messageDetails.error?.message));
994
+ }
995
+ resolve(messageDetails.data.signedMessage);
996
+ });
997
+ };
998
+ window.addEventListener(COMMUNICATION_TYPE, listener);
999
+ postRequestMessage(this.iframe, {
1000
+ type: RequestEventType.SIGN_MESSAGE_REQUEST,
1001
+ details: { starkPublicKey: this.publicAddress, message: rawMessage },
1002
+ });
1003
+ });
1004
+ }
1005
+ getIFrame() {
1006
+ return this.iframe;
1007
+ }
1008
+ }
1009
+
1010
+ const IMX_WALLET_IFRAME_ID = 'imx-wallet-app';
1011
+ const IMX_WALLET_IFRAME_HOSTS = {
1012
+ [Environment.SANDBOX]: 'https://wallets.sandbox.immutable.com',
1013
+ [Environment.PRODUCTION]: 'https://wallets.immutable.com',
1014
+ };
1015
+ const IMX_WALLET_IFRAME_STYLE = 'display: none;';
1016
+ function getIFrame() {
1017
+ return document.querySelector(`iframe#${IMX_WALLET_IFRAME_ID}`);
1018
+ }
1019
+ async function setupIFrame(env) {
1020
+ return new Promise((resolve) => {
1021
+ const iframe = document.createElement('iframe');
1022
+ iframe.setAttribute('id', IMX_WALLET_IFRAME_ID);
1023
+ iframe.setAttribute('src', IMX_WALLET_IFRAME_HOSTS[env]);
1024
+ iframe.setAttribute('style', IMX_WALLET_IFRAME_STYLE);
1025
+ document.body.appendChild(iframe);
1026
+ iframe.onload = () => resolve(iframe);
1027
+ });
1028
+ }
1029
+ async function getOrSetupIFrame(env) {
1030
+ const iframe = getIFrame();
1031
+ if (iframe)
1032
+ return iframe;
1033
+ return await setupIFrame(env);
1034
+ }
1035
+
1036
+ const DEFAULT_CONNECTION_MESSAGE = 'Only sign this request if you’ve initiated an action with Immutable X.';
1037
+ const CONNECTION_FAILED_ERROR = 'The L2 IMX Wallet connection has failed';
1038
+ async function connect(l1Provider, env) {
1039
+ const l1Signer = l1Provider.getSigner();
1040
+ const address = await l1Signer.getAddress();
1041
+ const signature = await l1Signer.signMessage(DEFAULT_CONNECTION_MESSAGE);
1042
+ const iframe = await getOrSetupIFrame(env);
1043
+ return new Promise((resolve, reject) => {
1044
+ const listener = (event) => {
1045
+ messageResponseListener(iframe, event, ResponseEventType.CONNECT_WALLET_RESPONSE, (messageDetails) => {
1046
+ window.removeEventListener(COMMUNICATION_TYPE, listener);
1047
+ if (!messageDetails.success) {
1048
+ reject(new Error(CONNECTION_FAILED_ERROR));
1049
+ }
1050
+ resolve(new ImxSigner(messageDetails.data.starkPublicKey, iframe));
1051
+ });
1052
+ };
1053
+ window.addEventListener(COMMUNICATION_TYPE, listener);
1054
+ postRequestMessage(iframe, {
1055
+ type: RequestEventType.CONNECT_WALLET_REQUEST,
1056
+ details: { ethAddress: address, signature },
1057
+ });
1058
+ });
1059
+ }
1060
+ async function disconnect(imxSigner) {
1061
+ const iframe = imxSigner.getIFrame();
1062
+ return new Promise((resolve, reject) => {
1063
+ const listener = (event) => {
1064
+ messageResponseListener(iframe, event, ResponseEventType.DISCONNECT_WALLET_RESPONSE, (messageDetails) => {
1065
+ window.removeEventListener(COMMUNICATION_TYPE, listener);
1066
+ if (!messageDetails.success && messageDetails.error) {
1067
+ reject(messageDetails.error);
1068
+ }
1069
+ iframe.remove();
1070
+ resolve();
1071
+ });
1072
+ };
1073
+ window.addEventListener(COMMUNICATION_TYPE, listener);
1074
+ postRequestMessage(iframe, {
1075
+ type: RequestEventType.DISCONNECT_WALLET_REQUEST,
1076
+ details: { starkPublicKey: imxSigner.getAddress() },
1077
+ });
1078
+ });
1079
+ }
1080
+
1081
+ var ProviderErrorType;
1082
+ (function (ProviderErrorType) {
1083
+ ProviderErrorType["PROVIDER_CONNECTION_ERROR"] = "PROVIDER_CONNECTION_ERROR";
1084
+ ProviderErrorType["WALLET_CONNECTION_ERROR"] = "WALLET_CONNECTION_ERROR";
1085
+ })(ProviderErrorType || (ProviderErrorType = {}));
1086
+ class ProviderError extends Error {
1087
+ type;
1088
+ constructor(message, type) {
1089
+ super(message);
1090
+ this.type = type;
1091
+ }
1092
+ }
1093
+ const withProviderError = async (fn, customError) => {
1094
+ try {
1095
+ return await fn();
1096
+ }
1097
+ catch (error) {
1098
+ const errorMessage = customError.message || `${error.message}` || 'UnknownError';
1099
+ throw new ProviderError(errorMessage, customError.type);
1100
+ }
1101
+ };
1102
+
1103
+ class MetaMaskIMXProvider extends GenericIMXProvider {
1104
+ static imxSigner;
1105
+ constructor(config, ethSigner, starkExSigner) {
1106
+ super(config, ethSigner, starkExSigner);
1107
+ }
1108
+ static async connect(config) {
1109
+ return await withProviderError(async () => {
1110
+ const metaMaskProvider = await connect$1({
1111
+ chainID: config.immutableXConfig.ethConfiguration.chainID,
1112
+ });
1113
+ this.imxSigner = await connect(metaMaskProvider, config.baseConfig.environment);
1114
+ return new MetaMaskIMXProvider(config, metaMaskProvider.getSigner(), this.imxSigner);
1115
+ }, { type: ProviderErrorType.WALLET_CONNECTION_ERROR });
1116
+ }
1117
+ static async disconnect() {
1118
+ if (!this.imxSigner) {
1119
+ throw new ProviderError('Attempted to disconnect from the MetaMask IMX provider without an established connection', ProviderErrorType.PROVIDER_CONNECTION_ERROR);
1120
+ }
1121
+ return withProviderError(async () => {
1122
+ await disconnect(this.imxSigner);
1123
+ }, { type: ProviderErrorType.PROVIDER_CONNECTION_ERROR });
1124
+ }
1125
+ static async signMessage(message) {
1126
+ if (!this.imxSigner) {
1127
+ throw new ProviderError('Attempted to sign a message with the MetaMask IMX provider without an established connection', ProviderErrorType.PROVIDER_CONNECTION_ERROR);
1128
+ }
1129
+ return withProviderError(async () => {
1130
+ return await this.imxSigner.signMessage(message);
1131
+ }, { type: ProviderErrorType.PROVIDER_CONNECTION_ERROR });
1132
+ }
1133
+ }
1134
+
1135
+ class ProviderConfiguration {
1136
+ immutableXConfig;
1137
+ baseConfig;
1138
+ constructor({ baseConfig, overrides }) {
1139
+ this.baseConfig = baseConfig;
1140
+ if (overrides) {
1141
+ this.immutableXConfig = overrides.immutableXConfig;
1142
+ }
1143
+ else {
1144
+ switch (baseConfig.environment) {
1145
+ case Environment.SANDBOX: {
1146
+ this.immutableXConfig = Config.SANDBOX;
1147
+ break;
1148
+ }
1149
+ case Environment.PRODUCTION: {
1150
+ this.immutableXConfig = Config.PRODUCTION;
1151
+ break;
1152
+ }
1153
+ }
1154
+ }
1155
+ }
1156
+ }
1157
+
1158
+ var PassportErrorType;
1159
+ (function (PassportErrorType) {
1160
+ PassportErrorType["AUTHENTICATION_ERROR"] = "AUTHENTICATION_ERROR";
1161
+ PassportErrorType["INVALID_CONFIGURATION"] = "INVALID_CONFIGURATION";
1162
+ PassportErrorType["WALLET_CONNECTION_ERROR"] = "WALLET_CONNECTION_ERROR";
1163
+ PassportErrorType["NOT_LOGGED_IN_ERROR"] = "NOT_LOGGED_IN_ERROR";
1164
+ PassportErrorType["REFRESH_TOKEN_ERROR"] = "REFRESH_TOKEN_ERROR";
1165
+ PassportErrorType["USER_REGISTRATION_ERROR"] = "USER_REGISTRATION_ERROR";
1166
+ PassportErrorType["LOGOUT_ERROR"] = "LOGOUT_ERROR";
1167
+ PassportErrorType["TRANSFER_ERROR"] = "TRANSFER_ERROR";
1168
+ PassportErrorType["CREATE_ORDER_ERROR"] = "CREATE_ORDER_ERROR";
1169
+ PassportErrorType["CANCEL_ORDER_ERROR"] = "CANCEL_ORDER_ERROR";
1170
+ PassportErrorType["EXCHANGE_TRANSFER_ERROR"] = "EXCHANGE_TRANSFER_ERROR";
1171
+ PassportErrorType["CREATE_TRADE_ERROR"] = "CREATE_TRADE_ERROR";
1172
+ PassportErrorType["OPERATION_NOT_SUPPORTED_ERROR"] = "OPERATION_NOT_SUPPORTED_ERROR";
1173
+ })(PassportErrorType || (PassportErrorType = {}));
1174
+ class PassportError extends Error {
1175
+ type;
1176
+ constructor(message, type) {
1177
+ super(message);
1178
+ this.type = type;
1179
+ }
1180
+ }
1181
+ const withPassportError = async (fn, customErrorType) => {
1182
+ try {
1183
+ return await fn();
1184
+ }
1185
+ catch (error) {
1186
+ const errorMessage = `${customErrorType}: ${error.message}` || 'UnknownError';
1187
+ throw new PassportError(errorMessage, customErrorType);
1188
+ }
1189
+ };
1190
+
1191
+ const POLL_INTERVAL = 1 * 1000; // every 1 second
1192
+ const MAX_RETRIES = 3;
1193
+ const wait = (ms) => new Promise((resolve) => {
1194
+ setTimeout(() => resolve(), ms);
1195
+ });
1196
+ const retryWithDelay = async (fn, options) => {
1197
+ const { retries = MAX_RETRIES, interval = POLL_INTERVAL, finalErr = Error('Retry failed'), } = options || {};
1198
+ try {
1199
+ return await fn();
1200
+ }
1201
+ catch (err) {
1202
+ if (retries <= 0) {
1203
+ return Promise.reject(finalErr);
1204
+ }
1205
+ await wait(interval);
1206
+ return retryWithDelay(fn, { retries: retries - 1, finalErr });
1207
+ }
1208
+ };
1209
+
1210
+ const getAuthConfiguration = ({ oidcConfiguration, authenticationDomain, }) => {
1211
+ const baseConfiguration = {
1212
+ authority: authenticationDomain,
1213
+ redirect_uri: oidcConfiguration.redirectUri,
1214
+ popup_redirect_uri: oidcConfiguration.redirectUri,
1215
+ client_id: oidcConfiguration.clientId,
1216
+ metadata: {
1217
+ authorization_endpoint: `${authenticationDomain}/authorize`,
1218
+ token_endpoint: `${authenticationDomain}/oauth/token`,
1219
+ userinfo_endpoint: `${authenticationDomain}/userinfo`,
1220
+ end_session_endpoint: `${authenticationDomain}/v2/logout` +
1221
+ `?returnTo=${encodeURIComponent(oidcConfiguration.logoutRedirectUri)}` +
1222
+ `&client_id=${oidcConfiguration.clientId}`,
1223
+ },
1224
+ mergeClaims: true,
1225
+ loadUserInfo: true,
1226
+ scope: oidcConfiguration.scope,
1227
+ };
1228
+ if (oidcConfiguration.audience) {
1229
+ baseConfiguration.extraQueryParams = {
1230
+ audience: oidcConfiguration.audience,
1231
+ };
1232
+ }
1233
+ return baseConfiguration;
1234
+ };
1235
+ class AuthManager {
1236
+ userManager;
1237
+ config;
1238
+ constructor(config) {
1239
+ this.config = config;
1240
+ this.userManager = new UserManager(getAuthConfiguration(config));
1241
+ }
1242
+ mapOidcUserToDomainModel = (oidcUser) => {
1243
+ const passport = oidcUser.profile?.passport;
1244
+ return {
1245
+ idToken: oidcUser.id_token,
1246
+ accessToken: oidcUser.access_token,
1247
+ refreshToken: oidcUser.refresh_token,
1248
+ profile: {
1249
+ sub: oidcUser.profile.sub,
1250
+ email: oidcUser.profile.email,
1251
+ nickname: oidcUser.profile.nickname,
1252
+ },
1253
+ etherKey: passport?.ether_key || '',
1254
+ };
1255
+ };
1256
+ async login() {
1257
+ return withPassportError(async () => {
1258
+ const popupWindowFeatures = { width: 400, height: 420 };
1259
+ const oidcUser = await this.userManager.signinPopup({
1260
+ popupWindowFeatures,
1261
+ });
1262
+ return this.mapOidcUserToDomainModel(oidcUser);
1263
+ }, PassportErrorType.AUTHENTICATION_ERROR);
1264
+ }
1265
+ async loginCallback() {
1266
+ return withPassportError(async () => this.userManager.signinPopupCallback(), PassportErrorType.AUTHENTICATION_ERROR);
1267
+ }
1268
+ async logout() {
1269
+ return withPassportError(async () => this.userManager.signoutRedirect(), PassportErrorType.LOGOUT_ERROR);
1270
+ }
1271
+ async getUser() {
1272
+ return withPassportError(async () => {
1273
+ const oidcUser = await this.userManager.getUser();
1274
+ if (!oidcUser) {
1275
+ throw new Error('Failed to retrieve user');
1276
+ }
1277
+ return this.mapOidcUserToDomainModel(oidcUser);
1278
+ }, PassportErrorType.NOT_LOGGED_IN_ERROR);
1279
+ }
1280
+ async requestRefreshTokenAfterRegistration() {
1281
+ return withPassportError(async () => {
1282
+ const updatedUser = await retryWithDelay(async () => {
1283
+ const user = await this.userManager.signinSilent();
1284
+ const passportMetadata = user?.profile?.passport;
1285
+ const metadataExists = !!passportMetadata?.ether_key &&
1286
+ !!passportMetadata?.stark_key &&
1287
+ !!passportMetadata?.user_admin_key;
1288
+ if (metadataExists) {
1289
+ return user;
1290
+ }
1291
+ return Promise.reject('user wallet addresses not exist');
1292
+ });
1293
+ if (!updatedUser) {
1294
+ return null;
1295
+ }
1296
+ return this.mapOidcUserToDomainModel(updatedUser);
1297
+ }, PassportErrorType.REFRESH_TOKEN_ERROR);
1298
+ }
1299
+ }
1300
+
1301
+ class MagicAdapter {
1302
+ magicClient;
1303
+ config;
1304
+ constructor(config) {
1305
+ this.config = config;
1306
+ this.magicClient = new Magic(config.magicPublishableApiKey, {
1307
+ network: config.network,
1308
+ extensions: [new OpenIdExtension()],
1309
+ });
1310
+ }
1311
+ async login(idToken) {
1312
+ return withPassportError(async () => {
1313
+ await this.magicClient.openid.loginWithOIDC({
1314
+ jwt: idToken,
1315
+ providerId: this.config.magicProviderId,
1316
+ });
1317
+ return new ethers.providers.Web3Provider(this.magicClient
1318
+ .rpcProvider);
1319
+ }, PassportErrorType.WALLET_CONNECTION_ERROR);
1320
+ }
1321
+ }
1322
+
1323
+ var ReceiveMessage;
1324
+ (function (ReceiveMessage) {
1325
+ ReceiveMessage["CONFIRMATION_WINDOW_READY"] = "confirmation_window_ready";
1326
+ ReceiveMessage["TRANSACTION_CONFIRMED"] = "transaction_confirmed";
1327
+ ReceiveMessage["TRANSACTION_ERROR"] = "transaction_error";
1328
+ })(ReceiveMessage || (ReceiveMessage = {}));
1329
+ var SendMessage;
1330
+ (function (SendMessage) {
1331
+ SendMessage["TRANSACTION_START"] = "transaction_start";
1332
+ })(SendMessage || (SendMessage = {}));
1333
+ var TransactionTypes;
1334
+ (function (TransactionTypes) {
1335
+ TransactionTypes["CancelOrder"] = "delete:v1/orders";
1336
+ TransactionTypes["CreateOrder"] = "post:v1/orders";
1337
+ TransactionTypes["CreateTrade"] = "post:v1/trades";
1338
+ TransactionTypes["CreateTransfer"] = "post:v1/transfers";
1339
+ TransactionTypes["CreateBatchTransfer"] = "post:v2/transfers";
1340
+ })(TransactionTypes || (TransactionTypes = {}));
1341
+ const PassportEventType = 'imx_passport_confirmation';
1342
+
1343
+ const openPopupCenter = ({ url, title, width, height, }) => {
1344
+ const left = Math.max(0, Math.round(window.screenX + (window.outerWidth - width) / 2));
1345
+ const top = Math.max(0, Math.round(window.screenY + (window.outerHeight - height) / 2));
1346
+ const newWindow = window.open(url, title, `
1347
+ scrollbars=yes,
1348
+ width=${width},
1349
+ height=${height},
1350
+ top=${top},
1351
+ left=${left}
1352
+ `);
1353
+ if (!newWindow) {
1354
+ throw new Error('Failed to open confirmation screen');
1355
+ }
1356
+ newWindow.focus();
1357
+ return newWindow;
1358
+ };
1359
+
1360
+ const ConfirmationWindowTitle = 'Confirm this transaction';
1361
+ const ConfirmationWindowHeight = 380;
1362
+ const ConfirmationWindowWidth = 480;
1363
+ const ConfirmationWindowClosedPollingDuration = 1000;
1364
+ class ConfirmationScreen {
1365
+ config;
1366
+ constructor(config) {
1367
+ this.config = config;
1368
+ }
1369
+ postMessage(destinationWindow, accessToken, message) {
1370
+ destinationWindow.postMessage({
1371
+ eventType: PassportEventType,
1372
+ accessToken,
1373
+ ...message,
1374
+ }, this.config.passportDomain);
1375
+ }
1376
+ startTransaction(accessToken, transaction, popupOptions) {
1377
+ return new Promise((resolve, reject) => {
1378
+ const messageHandler = ({ data, origin }) => {
1379
+ if (origin != this.config.passportDomain ||
1380
+ data.eventType != PassportEventType) {
1381
+ return;
1382
+ }
1383
+ switch (data.messageType) {
1384
+ case ReceiveMessage.CONFIRMATION_WINDOW_READY: {
1385
+ this.postMessage(confirmationWindow, accessToken, {
1386
+ messageType: SendMessage.TRANSACTION_START,
1387
+ messageData: transaction,
1388
+ });
1389
+ break;
1390
+ }
1391
+ case ReceiveMessage.TRANSACTION_CONFIRMED: {
1392
+ resolve({ confirmed: true });
1393
+ break;
1394
+ }
1395
+ case ReceiveMessage.TRANSACTION_ERROR: {
1396
+ reject(new Error('Transaction error'));
1397
+ break;
1398
+ }
1399
+ default:
1400
+ reject(new Error('Unsupported message type'));
1401
+ }
1402
+ };
1403
+ window.addEventListener('message', messageHandler);
1404
+ const confirmationWindow = openPopupCenter({
1405
+ url: `${this.config.passportDomain}/transaction-confirmation`,
1406
+ title: ConfirmationWindowTitle,
1407
+ width: popupOptions?.width || ConfirmationWindowWidth,
1408
+ height: popupOptions?.height || ConfirmationWindowHeight,
1409
+ });
1410
+ // https://stackoverflow.com/questions/9388380/capture-the-close-event-of-popup-window-in-javascript/48240128#48240128
1411
+ const timer = setInterval(function () {
1412
+ if (confirmationWindow.closed) {
1413
+ clearInterval(timer);
1414
+ window.removeEventListener('message', messageHandler);
1415
+ resolve({ confirmed: false });
1416
+ }
1417
+ }, ConfirmationWindowClosedPollingDuration);
1418
+ });
1419
+ }
1420
+ }
1421
+
1422
+ const ERC721$1 = 'ERC721';
1423
+ const transfer = ({ request, transfersApi, starkSigner, user, passportConfig, }) => {
1424
+ return withPassportError(async () => {
1425
+ const transferAmount = request.type === ERC721$1 ? '1' : request.amount;
1426
+ const getSignableTransferRequest = {
1427
+ sender: user.etherKey,
1428
+ token: convertToSignableToken(request),
1429
+ amount: transferAmount,
1430
+ receiver: request.receiver,
1431
+ };
1432
+ const signableResult = await transfersApi.getSignableTransferV1({
1433
+ getSignableTransferRequest,
1434
+ });
1435
+ const confirmationScreen = new ConfirmationScreen(passportConfig);
1436
+ const confirmationResult = await confirmationScreen.startTransaction(user.accessToken, {
1437
+ transactionType: TransactionTypes.CreateTransfer,
1438
+ transactionData: getSignableTransferRequest,
1439
+ });
1440
+ if (!confirmationResult.confirmed) {
1441
+ throw new Error('Transaction rejected by user');
1442
+ }
1443
+ const signableResultData = signableResult.data;
1444
+ const { payload_hash: payloadHash } = signableResultData;
1445
+ const starkSignature = await starkSigner.signMessage(payloadHash);
1446
+ const senderStarkKey = await starkSigner.getAddress();
1447
+ const transferSigningParams = {
1448
+ sender_stark_key: signableResultData.sender_stark_key || senderStarkKey,
1449
+ sender_vault_id: signableResultData.sender_vault_id,
1450
+ receiver_stark_key: signableResultData.receiver_stark_key,
1451
+ receiver_vault_id: signableResultData.receiver_vault_id,
1452
+ asset_id: signableResultData.asset_id,
1453
+ amount: signableResultData.amount,
1454
+ nonce: signableResultData.nonce,
1455
+ expiration_timestamp: signableResultData.expiration_timestamp,
1456
+ stark_signature: starkSignature,
1457
+ };
1458
+ const createTransferRequest = {
1459
+ createTransferRequest: transferSigningParams,
1460
+ };
1461
+ const headers = {
1462
+ Authorization: 'Bearer ' + user.accessToken,
1463
+ };
1464
+ const { data: responseData } = await transfersApi.createTransferV1(createTransferRequest, { headers });
1465
+ return {
1466
+ sent_signature: responseData.sent_signature,
1467
+ status: responseData.status?.toString(),
1468
+ time: responseData.time,
1469
+ transfer_id: responseData.transfer_id,
1470
+ };
1471
+ }, PassportErrorType.TRANSFER_ERROR);
1472
+ };
1473
+ async function batchNftTransfer({ user, starkSigner, request, transfersApi, passportConfig, }) {
1474
+ return withPassportError(async () => {
1475
+ const ethAddress = user.etherKey;
1476
+ const signableRequests = request.map((nftTransfer) => {
1477
+ return {
1478
+ amount: '1',
1479
+ token: convertToSignableToken({
1480
+ type: ERC721$1,
1481
+ tokenId: nftTransfer.tokenId,
1482
+ tokenAddress: nftTransfer.tokenAddress,
1483
+ }),
1484
+ receiver: nftTransfer.receiver,
1485
+ };
1486
+ });
1487
+ const getSignableTransferRequestV2 = {
1488
+ sender_ether_key: ethAddress,
1489
+ signable_requests: signableRequests,
1490
+ };
1491
+ const signableResult = await transfersApi.getSignableTransfer({
1492
+ getSignableTransferRequestV2,
1493
+ });
1494
+ const confirmationScreen = new ConfirmationScreen(passportConfig);
1495
+ const popupWindowSize = { width: 480, height: 784 };
1496
+ const confirmationResult = await confirmationScreen.startTransaction(user.accessToken, {
1497
+ transactionType: TransactionTypes.CreateBatchTransfer,
1498
+ transactionData: getSignableTransferRequestV2,
1499
+ }, popupWindowSize);
1500
+ if (!confirmationResult.confirmed) {
1501
+ throw new Error('Transaction rejected by user');
1502
+ }
1503
+ const requests = await Promise.all(signableResult.data.signable_responses.map(async (resp) => {
1504
+ const starkSignature = await starkSigner.signMessage(resp.payload_hash);
1505
+ return {
1506
+ sender_vault_id: resp.sender_vault_id,
1507
+ receiver_stark_key: resp.receiver_stark_key,
1508
+ receiver_vault_id: resp.receiver_vault_id,
1509
+ asset_id: resp.asset_id,
1510
+ amount: resp.amount,
1511
+ nonce: resp.nonce,
1512
+ expiration_timestamp: resp.expiration_timestamp,
1513
+ stark_signature: starkSignature,
1514
+ };
1515
+ }));
1516
+ const transferSigningParams = {
1517
+ sender_stark_key: signableResult.data.sender_stark_key,
1518
+ requests,
1519
+ };
1520
+ const headers = {
1521
+ Authorization: 'Bearer ' + user.accessToken,
1522
+ };
1523
+ const response = await transfersApi.createTransfer({
1524
+ createTransferRequestV2: transferSigningParams,
1525
+ }, { headers });
1526
+ return {
1527
+ transfer_ids: response?.data.transfer_ids,
1528
+ };
1529
+ }, PassportErrorType.TRANSFER_ERROR);
1530
+ }
1531
+
1532
+ const ERC721 = 'ERC721';
1533
+ async function createOrder({ starkSigner, user, request, ordersApi, passportConfig, }) {
1534
+ return withPassportError(async () => {
1535
+ const ethAddress = user.etherKey;
1536
+ const amountSell = request.sell.type === ERC721 ? '1' : request.sell.amount;
1537
+ const amountBuy = request.buy.type === ERC721 ? '1' : request.buy.amount;
1538
+ const getSignableOrderRequestV3 = {
1539
+ user: ethAddress,
1540
+ amount_buy: amountBuy,
1541
+ token_buy: convertToSignableToken(request.buy),
1542
+ amount_sell: amountSell,
1543
+ token_sell: convertToSignableToken(request.sell),
1544
+ fees: request.fees,
1545
+ expiration_timestamp: request.expiration_timestamp,
1546
+ };
1547
+ const getSignableOrderResponse = await ordersApi.getSignableOrder({
1548
+ getSignableOrderRequestV3,
1549
+ });
1550
+ const confirmationScreen = new ConfirmationScreen(passportConfig);
1551
+ const confirmationResult = await confirmationScreen.startTransaction(user.accessToken, {
1552
+ transactionType: TransactionTypes.CreateOrder,
1553
+ transactionData: getSignableOrderRequestV3,
1554
+ });
1555
+ if (!confirmationResult.confirmed) {
1556
+ throw new Error('Transaction rejected by user');
1557
+ }
1558
+ const { payload_hash: payloadHash } = getSignableOrderResponse.data;
1559
+ const starkSignature = await starkSigner.signMessage(payloadHash);
1560
+ const signableResultData = getSignableOrderResponse.data;
1561
+ const orderParams = {
1562
+ createOrderRequest: {
1563
+ include_fees: true,
1564
+ fees: request.fees,
1565
+ stark_signature: starkSignature,
1566
+ amount_buy: signableResultData.amount_buy,
1567
+ amount_sell: signableResultData.amount_sell,
1568
+ asset_id_buy: signableResultData.asset_id_buy,
1569
+ asset_id_sell: signableResultData.asset_id_sell,
1570
+ expiration_timestamp: signableResultData.expiration_timestamp,
1571
+ nonce: signableResultData.nonce,
1572
+ stark_key: signableResultData.stark_key,
1573
+ vault_id_buy: signableResultData.vault_id_buy,
1574
+ vault_id_sell: signableResultData.vault_id_sell,
1575
+ },
1576
+ };
1577
+ const headers = {
1578
+ Authorization: 'Bearer ' + user.accessToken,
1579
+ };
1580
+ const createOrderResponse = await ordersApi.createOrder(orderParams, {
1581
+ headers,
1582
+ });
1583
+ return {
1584
+ ...createOrderResponse.data,
1585
+ };
1586
+ }, PassportErrorType.CREATE_ORDER_ERROR);
1587
+ }
1588
+ async function cancelOrder({ user, starkSigner, request, ordersApi, passportConfig, }) {
1589
+ return withPassportError(async () => {
1590
+ const getSignableCancelOrderRequest = {
1591
+ order_id: request.order_id,
1592
+ };
1593
+ const getSignableCancelOrderResponse = await ordersApi.getSignableCancelOrder({
1594
+ getSignableCancelOrderRequest,
1595
+ });
1596
+ const confirmationScreen = new ConfirmationScreen(passportConfig);
1597
+ const confirmationResult = await confirmationScreen.startTransaction(user.accessToken, {
1598
+ transactionType: TransactionTypes.CancelOrder,
1599
+ transactionData: getSignableCancelOrderRequest,
1600
+ });
1601
+ if (!confirmationResult.confirmed) {
1602
+ throw new Error('Transaction rejected by user');
1603
+ }
1604
+ const { payload_hash: payloadHash } = getSignableCancelOrderResponse.data;
1605
+ const starkSignature = await starkSigner.signMessage(payloadHash);
1606
+ const headers = {
1607
+ Authorization: 'Bearer ' + user.accessToken,
1608
+ };
1609
+ const cancelOrderResponse = await ordersApi.cancelOrder({
1610
+ id: request.order_id.toString(),
1611
+ cancelOrderRequest: {
1612
+ order_id: request.order_id,
1613
+ stark_signature: starkSignature,
1614
+ },
1615
+ }, { headers });
1616
+ return {
1617
+ order_id: cancelOrderResponse.data.order_id,
1618
+ status: cancelOrderResponse.data.status,
1619
+ };
1620
+ }, PassportErrorType.CANCEL_ORDER_ERROR);
1621
+ }
1622
+
1623
+ async function exchangeTransfer({ user, starkSigner, request, exchangesApi, }) {
1624
+ return withPassportError(async () => {
1625
+ const ethAddress = user.etherKey;
1626
+ const transferAmount = request.amount;
1627
+ const signableResult = await exchangesApi.getExchangeSignableTransfer({
1628
+ id: request.transactionID,
1629
+ getSignableTransferRequest: {
1630
+ sender: ethAddress,
1631
+ token: convertToSignableToken(request),
1632
+ amount: transferAmount,
1633
+ receiver: request.receiver,
1634
+ },
1635
+ });
1636
+ const starkAddress = await starkSigner.getAddress();
1637
+ const { payload_hash: payloadHash } = signableResult.data;
1638
+ const starkSignature = await starkSigner.signMessage(payloadHash);
1639
+ const transferSigningParams = {
1640
+ sender_stark_key: signableResult.data.sender_stark_key || starkAddress,
1641
+ sender_vault_id: signableResult.data.sender_vault_id,
1642
+ receiver_stark_key: signableResult.data.receiver_stark_key,
1643
+ receiver_vault_id: signableResult.data.receiver_vault_id,
1644
+ asset_id: signableResult.data.asset_id,
1645
+ amount: signableResult.data.amount,
1646
+ nonce: signableResult.data.nonce,
1647
+ expiration_timestamp: signableResult.data.expiration_timestamp,
1648
+ stark_signature: starkSignature,
1649
+ };
1650
+ const headers = {
1651
+ Authorization: 'Bearer ' + user.accessToken,
1652
+ };
1653
+ const response = await exchangesApi.createExchangeTransfer({
1654
+ id: request.transactionID,
1655
+ createTransferRequest: transferSigningParams,
1656
+ }, { headers });
1657
+ return {
1658
+ sent_signature: response?.data.sent_signature,
1659
+ status: response?.data.status?.toString(),
1660
+ time: response?.data.time,
1661
+ transfer_id: response?.data.transfer_id,
1662
+ };
1663
+ }, PassportErrorType.EXCHANGE_TRANSFER_ERROR);
1664
+ }
1665
+
1666
+ async function createTrade({ request, tradesApi, user, starkSigner, passportConfig, }) {
1667
+ return withPassportError(async () => {
1668
+ const ethAddress = user.etherKey;
1669
+ const getSignableTradeRequest = {
1670
+ expiration_timestamp: request.expiration_timestamp,
1671
+ fees: request.fees,
1672
+ order_id: request.order_id,
1673
+ user: ethAddress,
1674
+ };
1675
+ const getSignableTradeResponse = await tradesApi.getSignableTrade({
1676
+ getSignableTradeRequest,
1677
+ });
1678
+ const confirmationScreen = new ConfirmationScreen(passportConfig);
1679
+ const confirmationResult = await confirmationScreen.startTransaction(user.accessToken, {
1680
+ transactionType: TransactionTypes.CreateTrade,
1681
+ transactionData: getSignableTradeRequest,
1682
+ });
1683
+ if (!confirmationResult.confirmed) {
1684
+ throw new Error('Transaction rejected by user');
1685
+ }
1686
+ const { payload_hash: payloadHash } = getSignableTradeResponse.data;
1687
+ const starkSignature = await starkSigner.signMessage(payloadHash);
1688
+ const { data: signableResultData } = getSignableTradeResponse;
1689
+ const tradeParams = {
1690
+ createTradeRequest: {
1691
+ include_fees: true,
1692
+ fees: request?.fees,
1693
+ stark_signature: starkSignature,
1694
+ order_id: request?.order_id,
1695
+ fee_info: signableResultData.fee_info,
1696
+ amount_buy: signableResultData.amount_buy,
1697
+ amount_sell: signableResultData.amount_sell,
1698
+ asset_id_buy: signableResultData.asset_id_buy,
1699
+ asset_id_sell: signableResultData.asset_id_sell,
1700
+ expiration_timestamp: signableResultData.expiration_timestamp,
1701
+ nonce: signableResultData.nonce,
1702
+ stark_key: signableResultData.stark_key,
1703
+ vault_id_buy: signableResultData.vault_id_buy,
1704
+ vault_id_sell: signableResultData.vault_id_sell,
1705
+ },
1706
+ };
1707
+ const headers = { Authorization: 'Bearer ' + user.accessToken };
1708
+ const { data: createTradeResponse } = await tradesApi.createTrade(tradeParams, {
1709
+ headers,
1710
+ });
1711
+ return createTradeResponse;
1712
+ }, PassportErrorType.CREATE_TRADE_ERROR);
1713
+ }
1714
+
1715
+ class PassportImxProvider {
1716
+ user;
1717
+ starkSigner;
1718
+ transfersApi;
1719
+ ordersApi;
1720
+ passportConfig;
1721
+ exchangesApi;
1722
+ tradesApi;
1723
+ constructor({ user, starkSigner, passportConfig }) {
1724
+ this.user = user;
1725
+ this.starkSigner = starkSigner;
1726
+ this.passportConfig = passportConfig;
1727
+ const apiConfig = new Configuration({
1728
+ basePath: passportConfig.imxApiBasePath,
1729
+ });
1730
+ this.transfersApi = new TransfersApi(apiConfig);
1731
+ this.ordersApi = new OrdersApi(apiConfig);
1732
+ this.exchangesApi = new ExchangesApi(apiConfig);
1733
+ this.tradesApi = new TradesApi(apiConfig);
1734
+ }
1735
+ async transfer(request) {
1736
+ return transfer({
1737
+ request,
1738
+ user: this.user,
1739
+ starkSigner: this.starkSigner,
1740
+ transfersApi: this.transfersApi,
1741
+ passportConfig: this.passportConfig,
1742
+ });
1743
+ }
1744
+ registerOffchain() {
1745
+ throw new PassportError('Operation not supported', PassportErrorType.OPERATION_NOT_SUPPORTED_ERROR);
1746
+ }
1747
+ isRegisteredOnchain() {
1748
+ throw new PassportError('Operation not supported', PassportErrorType.OPERATION_NOT_SUPPORTED_ERROR);
1749
+ }
1750
+ createOrder(request) {
1751
+ return createOrder({
1752
+ request,
1753
+ user: this.user,
1754
+ starkSigner: this.starkSigner,
1755
+ ordersApi: this.ordersApi,
1756
+ passportConfig: this.passportConfig,
1757
+ });
1758
+ }
1759
+ cancelOrder(request) {
1760
+ return cancelOrder({
1761
+ request,
1762
+ user: this.user,
1763
+ starkSigner: this.starkSigner,
1764
+ ordersApi: this.ordersApi,
1765
+ passportConfig: this.passportConfig,
1766
+ });
1767
+ }
1768
+ createTrade(request) {
1769
+ return createTrade({
1770
+ request,
1771
+ user: this.user,
1772
+ starkSigner: this.starkSigner,
1773
+ tradesApi: this.tradesApi,
1774
+ passportConfig: this.passportConfig,
1775
+ });
1776
+ }
1777
+ batchNftTransfer(request) {
1778
+ return batchNftTransfer({
1779
+ request,
1780
+ user: this.user,
1781
+ starkSigner: this.starkSigner,
1782
+ transfersApi: this.transfersApi,
1783
+ passportConfig: this.passportConfig,
1784
+ });
1785
+ }
1786
+ exchangeTransfer(request) {
1787
+ return exchangeTransfer({
1788
+ request,
1789
+ user: this.user,
1790
+ starkSigner: this.starkSigner,
1791
+ exchangesApi: this.exchangesApi,
1792
+ });
1793
+ }
1794
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1795
+ deposit(deposit) {
1796
+ throw new PassportError('Operation not supported', PassportErrorType.OPERATION_NOT_SUPPORTED_ERROR);
1797
+ }
1798
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1799
+ prepareWithdrawal(request) {
1800
+ throw new PassportError('Operation not supported', PassportErrorType.OPERATION_NOT_SUPPORTED_ERROR);
1801
+ }
1802
+ completeWithdrawal(
1803
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1804
+ starkPublicKey,
1805
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1806
+ token) {
1807
+ throw new PassportError('Operation not supported', PassportErrorType.OPERATION_NOT_SUPPORTED_ERROR);
1808
+ }
1809
+ getAddress() {
1810
+ return Promise.resolve(this.starkSigner.getAddress());
1811
+ }
1812
+ }
1813
+
1814
+ var Networks;
1815
+ (function (Networks) {
1816
+ Networks["PRODUCTION"] = "mainnet";
1817
+ Networks["SANDBOX"] = "goerli";
1818
+ })(Networks || (Networks = {}));
1819
+
1820
+ const validateConfiguration = (configuration, requiredKeys, prefix) => {
1821
+ const missingKeys = requiredKeys
1822
+ .map((key) => !configuration[key] && key)
1823
+ .filter((n) => n)
1824
+ .join(', ');
1825
+ if (missingKeys !== '') {
1826
+ const errorMessage = prefix
1827
+ ? `${prefix} - ${missingKeys} cannot be null`
1828
+ : `${missingKeys} cannot be null`;
1829
+ throw new PassportError(errorMessage, PassportErrorType.INVALID_CONFIGURATION);
1830
+ }
1831
+ };
1832
+ class PassportConfiguration {
1833
+ network;
1834
+ authenticationDomain;
1835
+ passportDomain;
1836
+ magicPublishableApiKey;
1837
+ magicProviderId;
1838
+ imxApiBasePath;
1839
+ oidcConfiguration;
1840
+ baseConfig;
1841
+ constructor({ baseConfig, overrides, ...oidcConfiguration }) {
1842
+ validateConfiguration(oidcConfiguration, [
1843
+ 'clientId',
1844
+ 'logoutRedirectUri',
1845
+ 'redirectUri',
1846
+ ]);
1847
+ this.oidcConfiguration = oidcConfiguration;
1848
+ this.baseConfig = baseConfig;
1849
+ if (overrides) {
1850
+ validateConfiguration(overrides, [
1851
+ 'network',
1852
+ 'authenticationDomain',
1853
+ 'magicPublishableApiKey',
1854
+ 'magicProviderId',
1855
+ 'passportDomain',
1856
+ 'imxApiBasePath',
1857
+ ], 'overrides');
1858
+ this.network = overrides.network;
1859
+ this.authenticationDomain = overrides.authenticationDomain;
1860
+ this.passportDomain = overrides.passportDomain;
1861
+ this.magicPublishableApiKey = overrides.magicPublishableApiKey;
1862
+ this.magicProviderId = overrides.magicProviderId;
1863
+ this.imxApiBasePath = overrides.imxApiBasePath;
1864
+ }
1865
+ else {
1866
+ switch (baseConfig.environment) {
1867
+ case Environment.SANDBOX: {
1868
+ this.network = Networks.SANDBOX;
1869
+ this.authenticationDomain = 'https://auth.immutable.com';
1870
+ this.magicPublishableApiKey = 'pk_live_10F423798A540ED7';
1871
+ this.magicProviderId = 'fSMzaRQ4O7p4fttl7pCyGVtJS_G70P8SNsLXtPPGHo0=';
1872
+ this.passportDomain = 'https://passport.immutable.com';
1873
+ this.imxApiBasePath = 'https://api.x.immutable.com';
1874
+ break;
1875
+ }
1876
+ case Environment.PRODUCTION: {
1877
+ this.network = Networks.PRODUCTION;
1878
+ this.authenticationDomain = 'https://auth.immutable.com';
1879
+ this.magicPublishableApiKey = 'pk_live_10F423798A540ED7';
1880
+ this.magicProviderId = 'fSMzaRQ4O7p4fttl7pCyGVtJS_G70P8SNsLXtPPGHo0=';
1881
+ this.passportDomain = 'https://passport.sandbox.immutable.com';
1882
+ this.imxApiBasePath = 'https://api.sandbox.x.immutable.com';
1883
+ break;
1884
+ }
1885
+ }
1886
+ }
1887
+ }
1888
+ }
1889
+
1890
+ const getStarkSigner = async (signer) => {
1891
+ return withPassportError(async () => {
1892
+ const privateKey = await generateLegacyStarkPrivateKey(signer);
1893
+ return createStarkSigner(privateKey);
1894
+ }, PassportErrorType.WALLET_CONNECTION_ERROR);
1895
+ };
1896
+
1897
+ async function registerPassport({ ethSigner, starkSigner, usersApi }, authorization) {
1898
+ return withPassportError(async () => {
1899
+ const userAddress = await ethSigner.getAddress();
1900
+ const starkPublicKey = await starkSigner.getAddress();
1901
+ const signableResult = await usersApi.getSignableRegistrationOffchain({
1902
+ getSignableRegistrationRequest: {
1903
+ ether_key: userAddress,
1904
+ stark_key: starkPublicKey,
1905
+ },
1906
+ });
1907
+ const { signable_message: signableMessage, payload_hash: payloadHash } = signableResult.data;
1908
+ const ethSignature = await signRaw(signableMessage, ethSigner);
1909
+ const starkSignature = await starkSigner.signMessage(payloadHash);
1910
+ const response = await usersApi.registerPassportUser({
1911
+ authorization: `Bearer ` + authorization,
1912
+ registerPassportUserRequest: {
1913
+ eth_signature: ethSignature,
1914
+ ether_key: userAddress,
1915
+ stark_signature: starkSignature,
1916
+ stark_key: starkPublicKey,
1917
+ },
1918
+ });
1919
+ return response.statusText;
1920
+ }, PassportErrorType.USER_REGISTRATION_ERROR);
1921
+ }
1922
+
1923
+ class Passport {
1924
+ authManager;
1925
+ magicAdapter;
1926
+ config;
1927
+ constructor(passportModuleConfiguration) {
1928
+ const passportConfiguration = new PassportConfiguration(passportModuleConfiguration);
1929
+ this.config = passportConfiguration;
1930
+ this.authManager = new AuthManager(this.config);
1931
+ this.magicAdapter = new MagicAdapter(this.config);
1932
+ }
1933
+ async connectImx() {
1934
+ const user = await this.authManager.login();
1935
+ if (!user.idToken) {
1936
+ throw new PassportError('Failed to initialise', PassportErrorType.WALLET_CONNECTION_ERROR);
1937
+ }
1938
+ const provider = await this.magicAdapter.login(user.idToken);
1939
+ const ethSigner = provider.getSigner();
1940
+ const starkSigner = await getStarkSigner(ethSigner);
1941
+ if (!user.etherKey) {
1942
+ const updatedUser = await this.registerUser(ethSigner, starkSigner, user.accessToken);
1943
+ return new PassportImxProvider({
1944
+ user: updatedUser,
1945
+ starkSigner,
1946
+ passportConfig: this.config,
1947
+ });
1948
+ }
1949
+ const userWithEtherKey = user;
1950
+ return new PassportImxProvider({
1951
+ user: userWithEtherKey,
1952
+ starkSigner,
1953
+ passportConfig: this.config,
1954
+ });
1955
+ }
1956
+ async loginCallback() {
1957
+ return this.authManager.loginCallback();
1958
+ }
1959
+ async logout() {
1960
+ return this.authManager.logout();
1961
+ }
1962
+ async getUserInfo() {
1963
+ const user = await this.authManager.getUser();
1964
+ return user.profile;
1965
+ }
1966
+ async getIdToken() {
1967
+ const user = await this.authManager.getUser();
1968
+ return user.idToken;
1969
+ }
1970
+ async getAccessToken() {
1971
+ const user = await this.authManager.getUser();
1972
+ return user.accessToken;
1973
+ }
1974
+ async registerUser(userAdminKeySigner, starkSigner, jwt) {
1975
+ const configuration = new Configuration({
1976
+ basePath: this.config.imxApiBasePath,
1977
+ });
1978
+ const usersApi = new UsersApi(configuration);
1979
+ await registerPassport({
1980
+ ethSigner: userAdminKeySigner,
1981
+ starkSigner,
1982
+ usersApi,
1983
+ }, jwt);
1984
+ const updatedUser = await this.authManager.requestRefreshTokenAfterRegistration();
1985
+ if (!updatedUser) {
1986
+ throw new PassportError('Failed to get refresh token', PassportErrorType.REFRESH_TOKEN_ERROR);
1987
+ }
1988
+ return updatedUser;
1989
+ }
1990
+ }
1991
+
1992
+ function $parcel$interopDefault(a) {
1993
+ return a && a.__esModule ? a.default : a;
1994
+ }
1995
+
1996
+ const $762782b6c862d954$export$db5daa1b5156ccfe = [
1997
+ {
1998
+ constant: true,
1999
+ inputs: [],
2000
+ name: "name",
2001
+ outputs: [
2002
+ {
2003
+ name: "",
2004
+ type: "string"
2005
+ }
2006
+ ],
2007
+ payable: false,
2008
+ type: "function"
2009
+ },
2010
+ {
2011
+ constant: true,
2012
+ inputs: [],
2013
+ name: "decimals",
2014
+ outputs: [
2015
+ {
2016
+ name: "",
2017
+ type: "uint8"
2018
+ }
2019
+ ],
2020
+ payable: false,
2021
+ type: "function"
2022
+ },
2023
+ {
2024
+ constant: true,
2025
+ inputs: [
2026
+ {
2027
+ name: "_owner",
2028
+ type: "address"
2029
+ }
2030
+ ],
2031
+ name: "balanceOf",
2032
+ outputs: [
2033
+ {
2034
+ name: "balance",
2035
+ type: "uint256"
2036
+ }
2037
+ ],
2038
+ payable: false,
2039
+ type: "function"
2040
+ },
2041
+ {
2042
+ constant: true,
2043
+ inputs: [],
2044
+ name: "symbol",
2045
+ outputs: [
2046
+ {
2047
+ name: "",
2048
+ type: "string"
2049
+ }
2050
+ ],
2051
+ payable: false,
2052
+ type: "function"
2053
+ }
2054
+ ];
2055
+
2056
+
2057
+ let $d176a05e966364ba$export$3bfad4d03ada24c4;
2058
+ (function(ConnectionProviders) {
2059
+ ConnectionProviders["METAMASK"] = "metamask";
2060
+ })($d176a05e966364ba$export$3bfad4d03ada24c4 || ($d176a05e966364ba$export$3bfad4d03ada24c4 = {}));
2061
+
2062
+
2063
+ let $a47e48dd2c04791b$export$c06e1e7429de6283;
2064
+ (function(ChainId) {
2065
+ ChainId[ChainId["ETHEREUM"] = 1] = "ETHEREUM";
2066
+ ChainId[ChainId["GOERLI"] = 5] = "GOERLI";
2067
+ ChainId[ChainId["POLYGON"] = 137] = "POLYGON";
2068
+ })($a47e48dd2c04791b$export$c06e1e7429de6283 || ($a47e48dd2c04791b$export$c06e1e7429de6283 = {}));
2069
+ const $a47e48dd2c04791b$export$f61f4aaec62f6be9 = {
2070
+ [$a47e48dd2c04791b$export$c06e1e7429de6283.ETHEREUM]: {
2071
+ chainIdHex: "0x1",
2072
+ chainName: "Ethereum",
2073
+ rpcUrls: [
2074
+ "https://mainnet.infura.io/v3/"
2075
+ ],
2076
+ nativeCurrency: {
2077
+ name: "Ethereum",
2078
+ symbol: "ETH",
2079
+ decimals: 18
2080
+ },
2081
+ blockExplorerUrls: [
2082
+ "https://etherscan.io/"
2083
+ ]
2084
+ },
2085
+ [$a47e48dd2c04791b$export$c06e1e7429de6283.GOERLI]: {
2086
+ chainIdHex: "0x5",
2087
+ chainName: "Goerli",
2088
+ rpcUrls: [
2089
+ "https://goerli.infura.io/v3/"
2090
+ ],
2091
+ nativeCurrency: {
2092
+ name: "Goerli Eth",
2093
+ symbol: "ETH",
2094
+ decimals: 18
2095
+ },
2096
+ blockExplorerUrls: [
2097
+ "https://goerli.etherscan.io/"
2098
+ ]
2099
+ },
2100
+ [$a47e48dd2c04791b$export$c06e1e7429de6283.POLYGON]: {
2101
+ chainIdHex: "0x89",
2102
+ chainName: "Polygon",
2103
+ rpcUrls: [
2104
+ "https://polygon-rpc.com"
2105
+ ],
2106
+ nativeCurrency: {
2107
+ name: "MATIC",
2108
+ symbol: "MATIC",
2109
+ decimals: 18
2110
+ },
2111
+ blockExplorerUrls: [
2112
+ "https://polygonscan.com/"
2113
+ ]
2114
+ }
2115
+ };
2116
+
2117
+
2118
+ let $08d5ddc39acd6833$export$fd9b17d87f4121d2;
2119
+ (function(TokenFilterTypes) {
2120
+ TokenFilterTypes["SWAP"] = "swap";
2121
+ TokenFilterTypes["BRIDGE"] = "bridge";
2122
+ TokenFilterTypes["ALL"] = "all";
2123
+ })($08d5ddc39acd6833$export$fd9b17d87f4121d2 || ($08d5ddc39acd6833$export$fd9b17d87f4121d2 = {}));
2124
+
2125
+
2126
+
2127
+
2128
+ const $4f91c5f280efe242$export$a130407f3423b97d = {
2129
+ CHECK_CONNECTION: "eth_accounts",
2130
+ CONNECT: "eth_requestAccounts",
2131
+ ADD_NETWORK: "wallet_addEthereumChain",
2132
+ SWITCH_NETWORK: "wallet_switchEthereumChain"
2133
+ };
2134
+ let $4f91c5f280efe242$export$a75605c67ea83a5a;
2135
+ (function(WalletFilterTypes) {
2136
+ WalletFilterTypes["ALL"] = "all";
2137
+ WalletFilterTypes["DESKTOP"] = "desktop";
2138
+ WalletFilterTypes["MOBILE"] = "mobile";
2139
+ })($4f91c5f280efe242$export$a75605c67ea83a5a || ($4f91c5f280efe242$export$a75605c67ea83a5a = {}));
2140
+
2141
+
2142
+
2143
+
2144
+ let $a8bc256d81a5e2c1$export$e3dc0620abde7f5a;
2145
+ (function(CheckoutErrorType) {
2146
+ CheckoutErrorType["CONNECT_PROVIDER_ERROR"] = "CONNECT_PROVIDER_ERROR";
2147
+ CheckoutErrorType["GET_BALANCE_ERROR"] = "GET_BALANCE_ERROR";
2148
+ CheckoutErrorType["GET_ERC20_BALANCE_ERROR"] = "GET_ERC20_BALANCE_ERROR";
2149
+ CheckoutErrorType["METAMASK_PROVIDER_ERROR"] = "METAMASK_PROVIDER_ERROR";
2150
+ CheckoutErrorType["CHAIN_NOT_SUPPORTED_ERROR"] = "CHAIN_NOT_SUPPORTED_ERROR";
2151
+ CheckoutErrorType["PROVIDER_REQUEST_MISSING_ERROR"] = "PROVIDER_REQUEST_MISSING_ERROR";
2152
+ CheckoutErrorType["USER_REJECTED_REQUEST_ERROR"] = "USER_REJECTED_REQUEST_ERROR";
2153
+ CheckoutErrorType["TRANSACTION_ERROR"] = "TRANSACTION_ERROR";
2154
+ })($a8bc256d81a5e2c1$export$e3dc0620abde7f5a || ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a = {}));
2155
+ class $a8bc256d81a5e2c1$export$b722478a3cbfa3bc extends Error {
2156
+ constructor(message, type){
2157
+ super(message);
2158
+ this.type = type;
2159
+ }
2160
+ }
2161
+ const $a8bc256d81a5e2c1$export$bacc563de539c6c3 = async (fn, customError)=>{
2162
+ try {
2163
+ return await fn();
2164
+ } catch (error) {
2165
+ const errorMessage = customError.message || `${error.message}` || "UnknownError";
2166
+ throw new $a8bc256d81a5e2c1$export$b722478a3cbfa3bc(errorMessage, customError.type);
2167
+ }
2168
+ };
2169
+
2170
+
2171
+
2172
+
2173
+
2174
+
2175
+
2176
+ async function $de192de6ef100f9f$export$79f13b4cfaaf0d09(provider) {
2177
+ const network = await provider.getNetwork();
2178
+ if (!Object.values(($a47e48dd2c04791b$export$c06e1e7429de6283)).includes(network.chainId)) // return empty details
2179
+ return {};
2180
+ const chainIdNetworkInfo = ($a47e48dd2c04791b$export$f61f4aaec62f6be9)[network.chainId];
2181
+ const networkInfo = {
2182
+ name: chainIdNetworkInfo.chainName,
2183
+ chainId: parseInt(chainIdNetworkInfo.chainIdHex, 16),
2184
+ nativeCurrency: chainIdNetworkInfo.nativeCurrency
2185
+ };
2186
+ return networkInfo;
2187
+ }
2188
+ async function $de192de6ef100f9f$export$b827d9418aeb5dbd(provider, chainId) {
2189
+ if (!Object.values(($a47e48dd2c04791b$export$c06e1e7429de6283)).includes(chainId)) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(`${chainId} is not a supported chain`, ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).CHAIN_NOT_SUPPORTED_ERROR);
2190
+ if (!provider.provider?.request) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("provider object is missing request function", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).PROVIDER_REQUEST_MISSING_ERROR);
2191
+ // WT-1146 - Refer to the README in this folder for explantion on the switch network flow
2192
+ try {
2193
+ await $de192de6ef100f9f$var$switchNetworkInWallet(provider, chainId);
2194
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2195
+ } catch (err) {
2196
+ if (err.message.includes("Unrecognized chain ID")) try {
2197
+ await $de192de6ef100f9f$var$addNetworkToWallet(provider, chainId);
2198
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2199
+ } catch (err) {
2200
+ throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("user cancelled the add network request", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).USER_REJECTED_REQUEST_ERROR);
2201
+ }
2202
+ else throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("user cancelled the switch network request", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).USER_REJECTED_REQUEST_ERROR);
2203
+ }
2204
+ // we can assume that if the above succeeds then user has successfully
2205
+ // switched to the network specified
2206
+ const newNetwork = ($a47e48dd2c04791b$export$f61f4aaec62f6be9)[chainId];
2207
+ return {
2208
+ network: {
2209
+ name: newNetwork.chainName,
2210
+ chainId: parseInt(newNetwork.chainIdHex, 16),
2211
+ nativeCurrency: newNetwork.nativeCurrency
2212
+ }
2213
+ };
2214
+ }
2215
+ // these functions should not be exported. These functions should be used as part of an exported function e.g switchWalletNetwork() above.
2216
+ // make sure to check if(provider.provider?.request) in the exported function and throw an error
2217
+ async function $de192de6ef100f9f$var$switchNetworkInWallet(provider, chainId) {
2218
+ if (provider.provider?.request) return await provider.provider.request({
2219
+ method: ($4f91c5f280efe242$export$a130407f3423b97d).SWITCH_NETWORK,
2220
+ params: [
2221
+ {
2222
+ chainId: ($a47e48dd2c04791b$export$f61f4aaec62f6be9)[chainId].chainIdHex
2223
+ }
2224
+ ]
2225
+ });
2226
+ }
2227
+ async function $de192de6ef100f9f$var$addNetworkToWallet(provider, chainId) {
2228
+ if (provider.provider?.request) {
2229
+ const addNetwork = {
2230
+ chainId: ($a47e48dd2c04791b$export$f61f4aaec62f6be9)[chainId].chainIdHex,
2231
+ chainName: ($a47e48dd2c04791b$export$f61f4aaec62f6be9)[chainId].chainName,
2232
+ rpcUrls: ($a47e48dd2c04791b$export$f61f4aaec62f6be9)[chainId].rpcUrls,
2233
+ nativeCurrency: ($a47e48dd2c04791b$export$f61f4aaec62f6be9)[chainId].nativeCurrency,
2234
+ blockExplorerUrls: ($a47e48dd2c04791b$export$f61f4aaec62f6be9)[chainId].blockExplorerUrls
2235
+ };
2236
+ return await provider.provider.request({
2237
+ method: ($4f91c5f280efe242$export$a130407f3423b97d).ADD_NETWORK,
2238
+ params: [
2239
+ addNetwork
2240
+ ]
2241
+ });
2242
+ }
2243
+ }
2244
+
2245
+
2246
+
2247
+
2248
+
2249
+ var $cda6003506e4182e$exports = {};
2250
+ $cda6003506e4182e$exports = JSON.parse("[{\"address\":\"0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0\",\"chainId\":137,\"name\":\"Matic\",\"symbol\":\"MATIC\",\"decimals\":18,\"icon\":\"data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 38.4 33.5' style='enable-background:new 0 0 38.4 33.5;' xml:space='preserve'%3E%3Cstyle type='text/css'%3E .st0%7Bfill:%238247E5;%7D%0A%3C/style%3E%3Cg%3E%3Cpath class='st0' d='M29,10.2c-0.7-0.4-1.6-0.4-2.4,0L21,13.5l-3.8,2.1l-5.5,3.3c-0.7,0.4-1.6,0.4-2.4,0L5,16.3 c-0.7-0.4-1.2-1.2-1.2-2.1v-5c0-0.8,0.4-1.6,1.2-2.1l4.3-2.5c0.7-0.4,1.6-0.4,2.4,0L16,7.2c0.7,0.4,1.2,1.2,1.2,2.1v3.3l3.8-2.2V7 c0-0.8-0.4-1.6-1.2-2.1l-8-4.7c-0.7-0.4-1.6-0.4-2.4,0L1.2,5C0.4,5.4,0,6.2,0,7v9.4c0,0.8,0.4,1.6,1.2,2.1l8.1,4.7 c0.7,0.4,1.6,0.4,2.4,0l5.5-3.2l3.8-2.2l5.5-3.2c0.7-0.4,1.6-0.4,2.4,0l4.3,2.5c0.7,0.4,1.2,1.2,1.2,2.1v5c0,0.8-0.4,1.6-1.2,2.1 L29,28.8c-0.7,0.4-1.6,0.4-2.4,0l-4.3-2.5c-0.7-0.4-1.2-1.2-1.2-2.1V21l-3.8,2.2v3.3c0,0.8,0.4,1.6,1.2,2.1l8.1,4.7 c0.7,0.4,1.6,0.4,2.4,0l8.1-4.7c0.7-0.4,1.2-1.2,1.2-2.1V17c0-0.8-0.4-1.6-1.2-2.1L29,10.2z'/%3E%3C/g%3E%3C/svg%3E%0A\",\"tokenFeatures\":[\"swap\",\"bridge\"]},{\"name\":\"Ethereum\",\"symbol\":\"ETH\",\"decimals\":18,\"icon\":\"data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3C!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3E%3Csvg xmlns='http://www.w3.org/2000/svg' xml:space='preserve' width='100%25' height='100%25' version='1.1' shape-rendering='geometricPrecision' text-rendering='geometricPrecision' image-rendering='optimizeQuality' fill-rule='evenodd' clip-rule='evenodd'%0AviewBox='0 0 784.37 1277.39' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:xodm='http://www.corel.com/coreldraw/odm/2003'%3E%3Cg id='Layer_x0020_1'%3E%3Cmetadata id='CorelCorpID_0Corel-Layer'/%3E%3Cg id='_1421394342400'%3E%3Cg%3E%3Cpolygon fill='%23343434' fill-rule='nonzero' points='392.07,0 383.5,29.11 383.5,873.74 392.07,882.29 784.13,650.54 '/%3E%3Cpolygon fill='%238C8C8C' fill-rule='nonzero' points='392.07,0 -0,650.54 392.07,882.29 392.07,472.33 '/%3E%3Cpolygon fill='%233C3C3B' fill-rule='nonzero' points='392.07,956.52 387.24,962.41 387.24,1263.28 392.07,1277.38 784.37,724.89 '/%3E%3Cpolygon fill='%238C8C8C' fill-rule='nonzero' points='392.07,1277.38 392.07,956.52 -0,724.89 '/%3E%3Cpolygon fill='%23141414' fill-rule='nonzero' points='392.07,882.29 784.13,650.54 392.07,472.33 '/%3E%3Cpolygon fill='%23393939' fill-rule='nonzero' points='0,650.54 392.07,882.29 392.07,472.33 '/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A\",\"chainId\":1,\"tokenFeatures\":[\"swap\",\"bridge\"]},{\"address\":\"0xF57e7e7C23978C3cAEC3C3548E3D615c346e79fF\",\"chainId\":1,\"name\":\"Immutable X\",\"symbol\":\"IMX\",\"decimals\":18,\"icon\":\"data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 139 113' style='enable-background:new 0 0 139 113;' xml:space='preserve'%3E%3Cstyle type='text/css'%3E .st0%7Bclip-path:url(%23SVGID_00000053504646934646330740000009134454895836103350_);%7D .st1%7Bfill:%2317B5CB;%7D%0A%3C/style%3E%3Cg%3E%3Cdefs%3E%3Crect id='SVGID_1_' width='139' height='113'/%3E%3C/defs%3E%3CclipPath id='SVGID_00000035518931339590433170000002358037249938198420_'%3E%3Cuse xlink:href='%23SVGID_1_' style='overflow:visible;'/%3E%3C/clipPath%3E%3Cg style='clip-path:url(%23SVGID_00000035518931339590433170000002358037249938198420_);'%3E%3Cpath class='st1' d='M124.1,0h14.6L79.5,67.6c-1.5,1.7-1.6,4.3-0.1,6.1l34.1,39.7H98.3L66.8,76.6l-1.6-2c-1.5-1.7-1.4-4.4,0.1-6.1 L124.1,0z'/%3E%3Cpath class='st1' d='M91.2,73.7c-1-1.1-1.3-2.7-1-4.1c0.3-0.8,0.8-1.6,1.4-2.2l3.9-4.3l43.5,50.3h-13.8 C125.2,113.4,99.7,83.6,91.2,73.7z'/%3E%3Cpath class='st1' d='M15.2,113.4H0l46.6-53.9c1.5-1.7,1.5-4.3,0-6L0.4,0H15l46.5,53.9c1.2,1.6,1.4,3.9,0.1,5.4 C49.4,73.4,15.2,113.4,15.2,113.4z'/%3E%3Cpath class='st1' d='M40.6,0h-14l43.1,49.9c0,0,0.1-0.1,4.9-5.8c1.3-1.5,1.6-3.4,0.1-4.9C65.7,30,40.6,0,40.6,0z'/%3E%3Cpath class='st1' d='M82.6,34.8L112.5,0H98.3L82.7,18.2l-4.5,5.3c-1.5,1.7-1.6,4.3-0.1,6.1C79.2,30.9,82.6,34.8,82.6,34.8z'/%3E%3Cpath class='st1' d='M56.6,78.6l-29.9,34.8h14.1l15.6-18.2l4.5-5.3c1.5-1.7,1.6-4.3,0.1-6.1C59.9,82.5,56.6,78.6,56.6,78.6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A\",\"tokenFeatures\":[\"swap\",\"bridge\"]},{\"address\":\"0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0\",\"chainId\":1,\"name\":\"Matic\",\"symbol\":\"MATIC\",\"decimals\":18,\"icon\":\"data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 38.4 33.5' style='enable-background:new 0 0 38.4 33.5;' xml:space='preserve'%3E%3Cstyle type='text/css'%3E .st0%7Bfill:%238247E5;%7D%0A%3C/style%3E%3Cg%3E%3Cpath class='st0' d='M29,10.2c-0.7-0.4-1.6-0.4-2.4,0L21,13.5l-3.8,2.1l-5.5,3.3c-0.7,0.4-1.6,0.4-2.4,0L5,16.3 c-0.7-0.4-1.2-1.2-1.2-2.1v-5c0-0.8,0.4-1.6,1.2-2.1l4.3-2.5c0.7-0.4,1.6-0.4,2.4,0L16,7.2c0.7,0.4,1.2,1.2,1.2,2.1v3.3l3.8-2.2V7 c0-0.8-0.4-1.6-1.2-2.1l-8-4.7c-0.7-0.4-1.6-0.4-2.4,0L1.2,5C0.4,5.4,0,6.2,0,7v9.4c0,0.8,0.4,1.6,1.2,2.1l8.1,4.7 c0.7,0.4,1.6,0.4,2.4,0l5.5-3.2l3.8-2.2l5.5-3.2c0.7-0.4,1.6-0.4,2.4,0l4.3,2.5c0.7,0.4,1.2,1.2,1.2,2.1v5c0,0.8-0.4,1.6-1.2,2.1 L29,28.8c-0.7,0.4-1.6,0.4-2.4,0l-4.3-2.5c-0.7-0.4-1.2-1.2-1.2-2.1V21l-3.8,2.2v3.3c0,0.8,0.4,1.6,1.2,2.1l8.1,4.7 c0.7,0.4,1.6,0.4,2.4,0l8.1-4.7c0.7-0.4,1.2-1.2,1.2-2.1V17c0-0.8-0.4-1.6-1.2-2.1L29,10.2z'/%3E%3C/g%3E%3C/svg%3E%0A\",\"tokenFeatures\":[\"swap\",\"bridge\"]},{\"name\":\"Ethereum\",\"symbol\":\"ETH\",\"decimals\":18,\"icon\":\"data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3C!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3E%3Csvg xmlns='http://www.w3.org/2000/svg' xml:space='preserve' width='100%25' height='100%25' version='1.1' shape-rendering='geometricPrecision' text-rendering='geometricPrecision' image-rendering='optimizeQuality' fill-rule='evenodd' clip-rule='evenodd'%0AviewBox='0 0 784.37 1277.39' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:xodm='http://www.corel.com/coreldraw/odm/2003'%3E%3Cg id='Layer_x0020_1'%3E%3Cmetadata id='CorelCorpID_0Corel-Layer'/%3E%3Cg id='_1421394342400'%3E%3Cg%3E%3Cpolygon fill='%23343434' fill-rule='nonzero' points='392.07,0 383.5,29.11 383.5,873.74 392.07,882.29 784.13,650.54 '/%3E%3Cpolygon fill='%238C8C8C' fill-rule='nonzero' points='392.07,0 -0,650.54 392.07,882.29 392.07,472.33 '/%3E%3Cpolygon fill='%233C3C3B' fill-rule='nonzero' points='392.07,956.52 387.24,962.41 387.24,1263.28 392.07,1277.38 784.37,724.89 '/%3E%3Cpolygon fill='%238C8C8C' fill-rule='nonzero' points='392.07,1277.38 392.07,956.52 -0,724.89 '/%3E%3Cpolygon fill='%23141414' fill-rule='nonzero' points='392.07,882.29 784.13,650.54 392.07,472.33 '/%3E%3Cpolygon fill='%23393939' fill-rule='nonzero' points='0,650.54 392.07,882.29 392.07,472.33 '/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A\",\"chainId\":5,\"tokenFeatures\":[\"swap\",\"bridge\"]},{\"address\":\"0x1facdd0165489f373255a90304650e15481b2c85\",\"chainId\":5,\"name\":\"Immutable X\",\"symbol\":\"IMX\",\"decimals\":18,\"icon\":\"data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 139 113' style='enable-background:new 0 0 139 113;' xml:space='preserve'%3E%3Cstyle type='text/css'%3E .st0%7Bclip-path:url(%23SVGID_00000053504646934646330740000009134454895836103350_);%7D .st1%7Bfill:%2317B5CB;%7D%0A%3C/style%3E%3Cg%3E%3Cdefs%3E%3Crect id='SVGID_1_' width='139' height='113'/%3E%3C/defs%3E%3CclipPath id='SVGID_00000035518931339590433170000002358037249938198420_'%3E%3Cuse xlink:href='%23SVGID_1_' style='overflow:visible;'/%3E%3C/clipPath%3E%3Cg style='clip-path:url(%23SVGID_00000035518931339590433170000002358037249938198420_);'%3E%3Cpath class='st1' d='M124.1,0h14.6L79.5,67.6c-1.5,1.7-1.6,4.3-0.1,6.1l34.1,39.7H98.3L66.8,76.6l-1.6-2c-1.5-1.7-1.4-4.4,0.1-6.1 L124.1,0z'/%3E%3Cpath class='st1' d='M91.2,73.7c-1-1.1-1.3-2.7-1-4.1c0.3-0.8,0.8-1.6,1.4-2.2l3.9-4.3l43.5,50.3h-13.8 C125.2,113.4,99.7,83.6,91.2,73.7z'/%3E%3Cpath class='st1' d='M15.2,113.4H0l46.6-53.9c1.5-1.7,1.5-4.3,0-6L0.4,0H15l46.5,53.9c1.2,1.6,1.4,3.9,0.1,5.4 C49.4,73.4,15.2,113.4,15.2,113.4z'/%3E%3Cpath class='st1' d='M40.6,0h-14l43.1,49.9c0,0,0.1-0.1,4.9-5.8c1.3-1.5,1.6-3.4,0.1-4.9C65.7,30,40.6,0,40.6,0z'/%3E%3Cpath class='st1' d='M82.6,34.8L112.5,0H98.3L82.7,18.2l-4.5,5.3c-1.5,1.7-1.6,4.3-0.1,6.1C79.2,30.9,82.6,34.8,82.6,34.8z'/%3E%3Cpath class='st1' d='M56.6,78.6l-29.9,34.8h14.1l15.6-18.2l4.5-5.3c1.5-1.7,1.6-4.3,0.1-6.1C59.9,82.5,56.6,78.6,56.6,78.6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A\",\"tokenFeatures\":[\"swap\",\"bridge\"]},{\"address\":\"0x123456789\",\"chainId\":5,\"name\":\"Swap Coin\",\"symbol\":\"SWC\",\"decimals\":18,\"tokenFeatures\":[\"swap\",\"fakeFeature\"]},{\"address\":\"0x123456789\",\"chainId\":5,\"name\":\"Bridge Coin\",\"symbol\":\"BDC\",\"decimals\":18,\"tokenFeatures\":[\"bridge\",\"fakeFeature\"]}]");
2251
+
2252
+
2253
+ const $efe60cea83bfc4e8$export$473cec51305fdae8 = function({ type: type = ($08d5ddc39acd6833$export$fd9b17d87f4121d2).ALL , chainId: chainId , exclude: exclude }) {
2254
+ // todo:For API call, use the CheckoutError with errorType:API_CALL_ERROR?? or any other
2255
+ const filteredTokenList = ((/*@__PURE__*/$parcel$interopDefault($cda6003506e4182e$exports))).filter((token)=>{
2256
+ const chainIdMatches = token.chainId == chainId;
2257
+ const tokenNotExcluded = !exclude?.map((excludeToken)=>excludeToken.address).includes(token.address || "");
2258
+ const allowAllTokens = type === ($08d5ddc39acd6833$export$fd9b17d87f4121d2).ALL;
2259
+ const tokenAllowedForType = token.tokenFeatures.includes(type);
2260
+ return chainIdMatches && tokenNotExcluded && (allowAllTokens || tokenAllowedForType);
2261
+ }).map((token)=>{
2262
+ const { chainId: chainId , tokenFeatures: tokenFeatures , ...tokenInfo } = token;
2263
+ return tokenInfo;
2264
+ });
2265
+ return {
2266
+ tokens: filteredTokenList
2267
+ };
2268
+ };
2269
+
2270
+
2271
+
2272
+
2273
+ const $1564e43dde50bb61$export$df96cd8d56be0ab1 = async (provider, walletAddress)=>{
2274
+ return await ($a8bc256d81a5e2c1$export$bacc563de539c6c3)(async ()=>{
2275
+ const networkInfo = await ($de192de6ef100f9f$export$79f13b4cfaaf0d09)(provider);
2276
+ const balance = await provider.getBalance(walletAddress);
2277
+ return {
2278
+ balance: balance,
2279
+ formattedBalance: (utils).formatUnits(balance, networkInfo.nativeCurrency.decimals),
2280
+ token: networkInfo.nativeCurrency
2281
+ };
2282
+ }, {
2283
+ type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_BALANCE_ERROR
2284
+ });
2285
+ };
2286
+ async function $1564e43dde50bb61$export$60e0fe116a0e6ed0(provider, walletAddress, contractAddress) {
2287
+ return await ($a8bc256d81a5e2c1$export$bacc563de539c6c3)(async ()=>{
2288
+ const contract = new (Contract)(contractAddress, JSON.stringify(($762782b6c862d954$export$db5daa1b5156ccfe)), provider);
2289
+ const name = await contract.name();
2290
+ const symbol = await contract.symbol();
2291
+ const balance = await contract.balanceOf(walletAddress);
2292
+ const decimals = await contract.decimals();
2293
+ const formattedBalance = (utils).formatUnits(balance, decimals);
2294
+ return {
2295
+ balance: balance,
2296
+ formattedBalance: formattedBalance,
2297
+ token: {
2298
+ name: name,
2299
+ symbol: symbol,
2300
+ decimals: decimals,
2301
+ address: contractAddress
2302
+ }
2303
+ };
2304
+ }, {
2305
+ type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).GET_ERC20_BALANCE_ERROR
2306
+ });
2307
+ }
2308
+ const $1564e43dde50bb61$export$fee49741664a4d7e = async (provider, walletAddress, chainId)=>{
2309
+ if (!Object.values(($a47e48dd2c04791b$export$c06e1e7429de6283)).includes(chainId)) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)(`ChainId ${chainId} is not supported`, ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).CHAIN_NOT_SUPPORTED_ERROR);
2310
+ if (!provider.provider?.request) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("provider object is missing request function", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).PROVIDER_REQUEST_MISSING_ERROR);
2311
+ const tokenList = ($efe60cea83bfc4e8$export$473cec51305fdae8)({
2312
+ type: ($08d5ddc39acd6833$export$fd9b17d87f4121d2).ALL,
2313
+ chainId: chainId
2314
+ });
2315
+ const allBalancePromises = [];
2316
+ allBalancePromises.push($1564e43dde50bb61$export$df96cd8d56be0ab1(provider, walletAddress));
2317
+ tokenList.tokens.filter((token)=>token.address).forEach((token)=>allBalancePromises.push($1564e43dde50bb61$export$60e0fe116a0e6ed0(provider, walletAddress, token.address ?? "")));
2318
+ const balanceResults = await Promise.allSettled(allBalancePromises);
2319
+ const getBalanceResults = balanceResults.filter((result)=>result.status === "fulfilled").map((fulfilledResult)=>fulfilledResult.value);
2320
+ return {
2321
+ balances: getBalanceResults
2322
+ };
2323
+ };
2324
+
2325
+
2326
+
2327
+
2328
+
2329
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2330
+
2331
+
2332
+
2333
+ async function $c99672cf2294e839$export$2d040992269b4717(providerPreference) {
2334
+ const provider = await $c99672cf2294e839$var$getWalletProviderForPreference(providerPreference);
2335
+ if (!provider.provider?.request) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("Incompatible provider", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).PROVIDER_REQUEST_MISSING_ERROR);
2336
+ const accounts = await provider.provider.request({
2337
+ method: ($4f91c5f280efe242$export$a130407f3423b97d).CHECK_CONNECTION,
2338
+ params: []
2339
+ });
2340
+ // accounts[0] will have the active account if connected.
2341
+ return {
2342
+ isConnected: accounts && accounts.length > 0,
2343
+ walletAddress: accounts[0] ?? ""
2344
+ };
2345
+ }
2346
+ async function $c99672cf2294e839$export$fba2f6c3656e07c1(params) {
2347
+ const web3Provider = await $c99672cf2294e839$var$getWalletProviderForPreference(params.providerPreference);
2348
+ await ($a8bc256d81a5e2c1$export$bacc563de539c6c3)(async ()=>{
2349
+ if (!web3Provider || !web3Provider?.provider?.request) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("No MetaMask provider installed.", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).METAMASK_PROVIDER_ERROR);
2350
+ // this makes the request to the wallet to connect i.e request eth accounts ('eth_requestAccounts')
2351
+ await web3Provider.provider.request({
2352
+ method: ($4f91c5f280efe242$export$a130407f3423b97d).CONNECT,
2353
+ params: []
2354
+ });
2355
+ }, {
2356
+ type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).USER_REJECTED_REQUEST_ERROR
2357
+ });
2358
+ return web3Provider;
2359
+ }
2360
+ async function $c99672cf2294e839$var$getWalletProviderForPreference(providerPreference) {
2361
+ let web3Provider = null;
2362
+ switch(providerPreference){
2363
+ case ($d176a05e966364ba$export$3bfad4d03ada24c4).METAMASK:
2364
+ web3Provider = await $c99672cf2294e839$var$getMetaMaskProvider();
2365
+ break;
2366
+ default:
2367
+ throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("Provider preference was not detected", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).CONNECT_PROVIDER_ERROR);
2368
+ }
2369
+ return web3Provider;
2370
+ }
2371
+ async function $c99672cf2294e839$var$getMetaMaskProvider() {
2372
+ const provider = await ($a8bc256d81a5e2c1$export$bacc563de539c6c3)(async ()=>{
2373
+ return await (detectEthereumProvider)();
2374
+ }, {
2375
+ type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).METAMASK_PROVIDER_ERROR
2376
+ });
2377
+ if (!provider || !provider.request) throw new ($a8bc256d81a5e2c1$export$b722478a3cbfa3bc)("No MetaMask provider installed.", ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).METAMASK_PROVIDER_ERROR);
2378
+ return new (Web3Provider)(provider);
2379
+ }
2380
+
2381
+
2382
+
2383
+
2384
+
2385
+ var $6f3c55a615003cbf$exports = {};
2386
+ $6f3c55a615003cbf$exports = JSON.parse('[{"connectionProvider":"metamask","icon":"some-icon-url","name":"MetaMask","description":"complete web3 wallet solution","platform":["mobile","desktop"]},{"connectionProvider":"passport","icon":"pp-icon","name":"Passport","description":"Web3 with your email!","platform":["mobile"]},{"connectionProvider":"gamestop","icon":"gme-icon","name":"GameStop","description":"Never stopping the game!","platform":["desktop"]}]');
2387
+
2388
+
2389
+ async function $5cdde2ffe6360fec$export$a822caa90d7eef09({ type: type = ($4f91c5f280efe242$export$a75605c67ea83a5a).ALL , exclude: exclude }) {
2390
+ // todo:For async API call, use the CheckoutError with errorType:API_CALL_ERROR?? or any other
2391
+ const filteredWalletsList = ((/*@__PURE__*/$parcel$interopDefault($6f3c55a615003cbf$exports))).filter((wallet)=>{
2392
+ const walletNotExcluded = !exclude?.map((excludeWallet)=>excludeWallet.connectionProvider).includes(wallet.connectionProvider);
2393
+ const allowAllWallets = type === ($4f91c5f280efe242$export$a75605c67ea83a5a).ALL;
2394
+ const walletsAllowedForType = wallet.platform.includes(type);
2395
+ return walletNotExcluded && (allowAllWallets || walletsAllowedForType);
2396
+ }).map((wallet)=>{
2397
+ const { platform: platform , ...walletInfo } = wallet;
2398
+ return walletInfo;
2399
+ });
2400
+ return {
2401
+ allowedWallets: filteredWalletsList
2402
+ };
2403
+ }
2404
+
2405
+
2406
+
2407
+
2408
+
2409
+
2410
+ const $dbe95599a4661140$export$8e0e7ffc78696d30 = async (params)=>{
2411
+ const { provider: provider , transaction: transaction } = params;
2412
+ return await ($a8bc256d81a5e2c1$export$bacc563de539c6c3)(async ()=>{
2413
+ const transactionResponse = await provider.getSigner().sendTransaction(transaction);
2414
+ return {
2415
+ transactionResponse: transactionResponse
2416
+ };
2417
+ }, {
2418
+ type: ($a8bc256d81a5e2c1$export$e3dc0620abde7f5a).TRANSACTION_ERROR
2419
+ });
2420
+ };
2421
+
2422
+
2423
+
2424
+
2425
+ class $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 {
2426
+ async checkIsWalletConnected(params) {
2427
+ return $c99672cf2294e839$export$2d040992269b4717(params.providerPreference);
2428
+ }
2429
+ async connect(params) {
2430
+ const provider = await $c99672cf2294e839$export$fba2f6c3656e07c1(params);
2431
+ const network = await ($de192de6ef100f9f$export$79f13b4cfaaf0d09)(provider);
2432
+ return {
2433
+ provider: provider,
2434
+ network: network
2435
+ };
2436
+ }
2437
+ async switchNetwork(params) {
2438
+ return await ($de192de6ef100f9f$export$b827d9418aeb5dbd)(params.provider, params.chainId);
2439
+ }
2440
+ async getBalance(params) {
2441
+ if (!params.contractAddress || params.contractAddress === "") return await $1564e43dde50bb61$export$df96cd8d56be0ab1(params.provider, params.walletAddress);
2442
+ return await $1564e43dde50bb61$export$60e0fe116a0e6ed0(params.provider, params.walletAddress, params.contractAddress);
2443
+ }
2444
+ async getAllBalances(params) {
2445
+ return $1564e43dde50bb61$export$fee49741664a4d7e(params.provider, params.walletAddress, params.chainId);
2446
+ }
2447
+ getTokenAllowList(params) {
2448
+ return $efe60cea83bfc4e8$export$473cec51305fdae8(params);
2449
+ }
2450
+ async getWalletsAllowList(params) {
2451
+ return await $5cdde2ffe6360fec$export$a822caa90d7eef09(params);
2452
+ }
2453
+ async sendTransaction(params) {
2454
+ return await $dbe95599a4661140$export$8e0e7ffc78696d30(params);
2455
+ }
2456
+ }
2457
+
2458
+ function $parcel$export(e, n, v, s) {
2459
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
2460
+ }
2461
+ var $88e4c575901cd68c$exports = {};
2462
+
2463
+ $parcel$export($88e4c575901cd68c$exports, "IMTBLWidgetEvents", () => $88e4c575901cd68c$export$5a0ace85cae72d45);
2464
+ let $88e4c575901cd68c$export$5a0ace85cae72d45;
2465
+ (function(IMTBLWidgetEvents) {
2466
+ IMTBLWidgetEvents["IMTBL_CONNECT_WIDGET_EVENT"] = "imtbl-connect-widget";
2467
+ IMTBLWidgetEvents["IMTBL_WALLET_WIDGET_EVENT"] = "imtbl-wallet-widget";
2468
+ IMTBLWidgetEvents["IMTBL_SWAP_WIDGET_EVENT"] = "imtbl-swap-widget";
2469
+ IMTBLWidgetEvents["IMTBL_BRIDGE_WIDGET_EVENT"] = "imtbl-bridge-widget";
2470
+ IMTBLWidgetEvents["IMTBL_BUY_WIDGET_EVENT"] = "imtbl-buy-widget";
2471
+ })($88e4c575901cd68c$export$5a0ace85cae72d45 || ($88e4c575901cd68c$export$5a0ace85cae72d45 = {}));
2472
+
2473
+
2474
+ var $d71a87afc3136184$exports = {};
2475
+
2476
+ $parcel$export($d71a87afc3136184$exports, "ConnectEventType", () => $d71a87afc3136184$export$e72e7f9969a47dd3);
2477
+ let $d71a87afc3136184$export$e72e7f9969a47dd3;
2478
+ (function(ConnectEventType) {
2479
+ ConnectEventType["SUCCESS"] = "success";
2480
+ ConnectEventType["FAILURE"] = "failure";
2481
+ })($d71a87afc3136184$export$e72e7f9969a47dd3 || ($d71a87afc3136184$export$e72e7f9969a47dd3 = {}));
2482
+
2483
+
2484
+ var $9d0f1783d4d36e8a$exports = {};
2485
+
2486
+ $parcel$export($9d0f1783d4d36e8a$exports, "WalletEventType", () => $9d0f1783d4d36e8a$export$d9be06b70b28c742);
2487
+ //wallet widget events
2488
+ let $9d0f1783d4d36e8a$export$d9be06b70b28c742;
2489
+ (function(WalletEventType) {
2490
+ WalletEventType["CLOSE_WIDGET"] = "close-widget";
2491
+ WalletEventType["NETWORK_SWITCH"] = "network-switch";
2492
+ })($9d0f1783d4d36e8a$export$d9be06b70b28c742 || ($9d0f1783d4d36e8a$export$d9be06b70b28c742 = {}));
2493
+
2494
+
2495
+ var $5d497088f13bb116$exports = {};
2496
+
2497
+ $parcel$export($5d497088f13bb116$exports, "SwapEventType", () => $5d497088f13bb116$export$140a49745ab55563);
2498
+ let $5d497088f13bb116$export$140a49745ab55563;
2499
+ (function(SwapEventType) {
2500
+ SwapEventType["SUCCESS"] = "success";
2501
+ SwapEventType["FAILURE"] = "failure";
2502
+ })($5d497088f13bb116$export$140a49745ab55563 || ($5d497088f13bb116$export$140a49745ab55563 = {}));
2503
+
2504
+
2505
+ var $28a5fdc2f5e6c742$exports = {};
2506
+
2507
+ $parcel$export($28a5fdc2f5e6c742$exports, "BridgeEventType", () => $28a5fdc2f5e6c742$export$d1bfa21f7c76447a);
2508
+ let $28a5fdc2f5e6c742$export$d1bfa21f7c76447a;
2509
+ (function(BridgeEventType) {
2510
+ BridgeEventType["CLOSE_WIDGET"] = "close-widget";
2511
+ BridgeEventType["SUCCESS"] = "success";
2512
+ BridgeEventType["FAILURE"] = "failure";
2513
+ })($28a5fdc2f5e6c742$export$d1bfa21f7c76447a || ($28a5fdc2f5e6c742$export$d1bfa21f7c76447a = {}));
2514
+
2515
+
2516
+ var $ede253beebe0de4a$exports = {};
2517
+
2518
+ $parcel$export($ede253beebe0de4a$exports, "BuyEventType", () => $ede253beebe0de4a$export$90db5fe1be5993c1);
2519
+ let $ede253beebe0de4a$export$90db5fe1be5993c1;
2520
+ (function(BuyEventType) {
2521
+ BuyEventType["SUCCESS"] = "success";
2522
+ BuyEventType["FAILURE"] = "failure";
2523
+ BuyEventType["NOT_CONNECTED"] = "not_connected";
2524
+ BuyEventType["CLOSE"] = "close";
2525
+ })($ede253beebe0de4a$export$90db5fe1be5993c1 || ($ede253beebe0de4a$export$90db5fe1be5993c1 = {}));
2526
+
2527
+
2528
+ var $9234b4c577442a97$exports = {};
2529
+
2530
+ $parcel$export($9234b4c577442a97$exports, "Network", () => $9234b4c577442a97$export$95be4ae94445245a);
2531
+ $parcel$export($9234b4c577442a97$exports, "WidgetTheme", () => $9234b4c577442a97$export$c88931fdc51854eb);
2532
+ $parcel$export($9234b4c577442a97$exports, "ConnectionProviders", () => $d176a05e966364ba$export$3bfad4d03ada24c4);
2533
+
2534
+ let $9234b4c577442a97$export$95be4ae94445245a;
2535
+ (function(Network) {
2536
+ Network["ETHEREUM"] = "Ethereum";
2537
+ Network["GOERLI"] = "Goerli";
2538
+ Network["POLYGON"] = "Polygon";
2539
+ })($9234b4c577442a97$export$95be4ae94445245a || ($9234b4c577442a97$export$95be4ae94445245a = {}));
2540
+ let $9234b4c577442a97$export$c88931fdc51854eb;
2541
+ (function(WidgetTheme) {
2542
+ WidgetTheme["LIGHT"] = "light";
2543
+ WidgetTheme["DARK"] = "dark";
2544
+ WidgetTheme["CUSTOM"] = "custom";
2545
+ })($9234b4c577442a97$export$c88931fdc51854eb || ($9234b4c577442a97$export$c88931fdc51854eb = {}));
2546
+
2547
+ export { $28a5fdc2f5e6c742$export$d1bfa21f7c76447a as BridgeEventType, $ede253beebe0de4a$export$90db5fe1be5993c1 as BuyEventType, $a47e48dd2c04791b$export$c06e1e7429de6283 as ChainId, $a8cb37a3fc8eb863$export$1f60ba4ec72508a0 as Checkout, $d71a87afc3136184$export$e72e7f9969a47dd3 as ConnectEventType, $d176a05e966364ba$export$3bfad4d03ada24c4 as ConnectionProviders, Environment, GenericIMXProvider, $88e4c575901cd68c$export$5a0ace85cae72d45 as IMTBLWidgetEvents, ImmutableConfiguration, MetaMaskIMXProvider, $9234b4c577442a97$export$95be4ae94445245a as Network, Passport, PassportConfiguration, PassportError, ProviderConfiguration, StarkExAPIFactory, $5d497088f13bb116$export$140a49745ab55563 as SwapEventType, $08d5ddc39acd6833$export$fd9b17d87f4121d2 as TokenFilterTypes, $9d0f1783d4d36e8a$export$d9be06b70b28c742 as WalletEventType, $4f91c5f280efe242$export$a75605c67ea83a5a as WalletFilterTypes, $9234b4c577442a97$export$c88931fdc51854eb as WidgetTheme };