@imtbl/sdk 1.6.1 → 1.7.1

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 CHANGED
@@ -8,10 +8,10 @@ import * as crypto from 'crypto';
8
8
  import { Magic } from 'magic-sdk';
9
9
  import { OpenIdExtension } from '@magic-ext/oidc';
10
10
  import { JsonRpcProvider, Web3Provider } from '@ethersproject/providers';
11
- import { BigNumber as BigNumber$1, ethers, providers, constants as constants$1, ContractFactory, utils as utils$3, Contract as Contract$1 } from 'ethers';
12
11
  import BN$2 from 'bn.js';
13
12
  import * as encUtils from 'enc-utils';
14
13
  import { EventEmitter } from 'events';
14
+ import { BigNumber as BigNumber$1, ethers, providers, constants as constants$1, ContractFactory, utils as utils$3, Contract as Contract$1 } from 'ethers';
15
15
  import { walletContracts } from '@0xsequence/abi';
16
16
  import { v1 } from '@0xsequence/core';
17
17
  import FormData$2 from 'form-data';
@@ -152,7 +152,7 @@ const flattenProperties$1 = (properties) => {
152
152
  };
153
153
 
154
154
  // WARNING: DO NOT CHANGE THE STRING BELOW. IT GETS REPLACED AT BUILD TIME.
155
- const SDK_VERSION$1 = '1.6.1';
155
+ const SDK_VERSION$1 = '1.7.1';
156
156
  const getReferrer$1 = () => {
157
157
  if (isNode$1()) {
158
158
  return '';
@@ -11275,7 +11275,7 @@ class MultiRollupApiClients {
11275
11275
  }
11276
11276
 
11277
11277
  // eslint-disable-next-line @typescript-eslint/naming-convention
11278
- const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-1.6.1' };
11278
+ const defaultHeaders$1 = { 'x-sdk-version': 'ts-immutable-sdk-1.7.1' };
11279
11279
  const createConfig = ({ basePath, headers, }) => {
11280
11280
  if (!basePath.trim()) {
11281
11281
  throw Error('basePath can not be empty');
@@ -11347,7 +11347,7 @@ class APIError extends Error {
11347
11347
 
11348
11348
  /* eslint-disable implicit-arrow-linebreak */
11349
11349
  const defaultHeaders = {
11350
- sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-1.6.1',
11350
+ sdkVersion: 'ts-immutable-sdk-multi-rollup-api-client-1.7.1',
11351
11351
  };
11352
11352
  /**
11353
11353
  * createAPIConfiguration to create a custom Configuration
@@ -11780,7 +11780,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
11780
11780
  chainID,
11781
11781
  coreContractAddress,
11782
11782
  registrationContractAddress,
11783
- sdkVersion: 'ts-immutable-sdk-1.6.1',
11783
+ sdkVersion: 'ts-immutable-sdk-1.7.1',
11784
11784
  });
11785
11785
  /**
11786
11786
  * Sets `sdkVersion` at the time of build
@@ -12283,6 +12283,78 @@ class IMXClient {
12283
12283
  }
12284
12284
  }
12285
12285
 
12286
+ // used to sign message with L1 keys. Used for registration
12287
+ function serializeEthSignature(sig) {
12288
+ // This is because golang appends a recovery param
12289
+ // https://github.com/ethers-io/ethers.js/issues/823
12290
+ return encUtils.addHexPrefix(encUtils.padLeft(sig.r.toString(16), 64)
12291
+ + encUtils.padLeft(sig.s.toString(16), 64)
12292
+ + encUtils.padLeft(sig.recoveryParam?.toString(16) || '', 2));
12293
+ }
12294
+ function importRecoveryParam(v) {
12295
+ const isValidBigNumber = new BN$2(v, 16).cmp(new BN$2(27)) !== -1
12296
+ ? new BN$2(v, 16).sub(new BN$2(27)).toNumber()
12297
+ : new BN$2(v, 16).toNumber();
12298
+ return v.trim()
12299
+ ? isValidBigNumber
12300
+ : undefined;
12301
+ }
12302
+ // used chained with serializeEthSignature. serializeEthSignature(deserializeSignature(...))
12303
+ function deserializeSignature(sig, size = 64) {
12304
+ const removedHexPrefixSig = encUtils.removeHexPrefix(sig);
12305
+ return {
12306
+ r: new BN$2(removedHexPrefixSig.substring(0, size), 'hex'),
12307
+ s: new BN$2(removedHexPrefixSig.substring(size, size * 2), 'hex'),
12308
+ recoveryParam: importRecoveryParam(removedHexPrefixSig.substring(size * 2, size * 2 + 2)),
12309
+ };
12310
+ }
12311
+ async function signRaw(payload, signer) {
12312
+ const signature = deserializeSignature(await signer.signMessage(payload));
12313
+ return serializeEthSignature(signature);
12314
+ }
12315
+ async function signMessage$1(message, signer) {
12316
+ const ethAddress = await signer.getAddress();
12317
+ const ethSignature = await signRaw(message, signer);
12318
+ return {
12319
+ message,
12320
+ ethAddress,
12321
+ ethSignature,
12322
+ };
12323
+ }
12324
+
12325
+ /**
12326
+ * Helper method to convert token type to a SignableToken type
12327
+ * @param token - the token type to convert to a SignableToken type
12328
+ * @returns the converted SignableToken
12329
+ */
12330
+ function convertToSignableToken(token) {
12331
+ switch (token.type) {
12332
+ case 'ERC721':
12333
+ return {
12334
+ type: 'ERC721',
12335
+ data: {
12336
+ token_id: token.tokenId,
12337
+ token_address: token.tokenAddress,
12338
+ },
12339
+ };
12340
+ case 'ERC20':
12341
+ return {
12342
+ type: 'ERC20',
12343
+ data: {
12344
+ token_address: token.tokenAddress,
12345
+ },
12346
+ };
12347
+ case 'ETH':
12348
+ default:
12349
+ return {
12350
+ type: 'ETH',
12351
+ data: {
12352
+ decimals: 18,
12353
+ },
12354
+ };
12355
+ }
12356
+ }
12357
+
12286
12358
  function bind$1(fn, thisArg) {
12287
12359
  return function wrap() {
12288
12360
  return fn.apply(thisArg, arguments);
@@ -16198,78 +16270,6 @@ const TransactionApprovalRequestChainTypeEnum = {
16198
16270
  Evm: 'evm'
16199
16271
  };
16200
16272
 
16201
- // used to sign message with L1 keys. Used for registration
16202
- function serializeEthSignature(sig) {
16203
- // This is because golang appends a recovery param
16204
- // https://github.com/ethers-io/ethers.js/issues/823
16205
- return encUtils.addHexPrefix(encUtils.padLeft(sig.r.toString(16), 64)
16206
- + encUtils.padLeft(sig.s.toString(16), 64)
16207
- + encUtils.padLeft(sig.recoveryParam?.toString(16) || '', 2));
16208
- }
16209
- function importRecoveryParam(v) {
16210
- const isValidBigNumber = new BN$2(v, 16).cmp(new BN$2(27)) !== -1
16211
- ? new BN$2(v, 16).sub(new BN$2(27)).toNumber()
16212
- : new BN$2(v, 16).toNumber();
16213
- return v.trim()
16214
- ? isValidBigNumber
16215
- : undefined;
16216
- }
16217
- // used chained with serializeEthSignature. serializeEthSignature(deserializeSignature(...))
16218
- function deserializeSignature(sig, size = 64) {
16219
- const removedHexPrefixSig = encUtils.removeHexPrefix(sig);
16220
- return {
16221
- r: new BN$2(removedHexPrefixSig.substring(0, size), 'hex'),
16222
- s: new BN$2(removedHexPrefixSig.substring(size, size * 2), 'hex'),
16223
- recoveryParam: importRecoveryParam(removedHexPrefixSig.substring(size * 2, size * 2 + 2)),
16224
- };
16225
- }
16226
- async function signRaw(payload, signer) {
16227
- const signature = deserializeSignature(await signer.signMessage(payload));
16228
- return serializeEthSignature(signature);
16229
- }
16230
- async function signMessage$1(message, signer) {
16231
- const ethAddress = await signer.getAddress();
16232
- const ethSignature = await signRaw(message, signer);
16233
- return {
16234
- message,
16235
- ethAddress,
16236
- ethSignature,
16237
- };
16238
- }
16239
-
16240
- /**
16241
- * Helper method to convert token type to a SignableToken type
16242
- * @param token - the token type to convert to a SignableToken type
16243
- * @returns the converted SignableToken
16244
- */
16245
- function convertToSignableToken(token) {
16246
- switch (token.type) {
16247
- case 'ERC721':
16248
- return {
16249
- type: 'ERC721',
16250
- data: {
16251
- token_id: token.tokenId,
16252
- token_address: token.tokenAddress,
16253
- },
16254
- };
16255
- case 'ERC20':
16256
- return {
16257
- type: 'ERC20',
16258
- data: {
16259
- token_address: token.tokenAddress,
16260
- },
16261
- };
16262
- case 'ETH':
16263
- default:
16264
- return {
16265
- type: 'ETH',
16266
- data: {
16267
- decimals: 18,
16268
- },
16269
- };
16270
- }
16271
- }
16272
-
16273
16273
  var PassportErrorType;
16274
16274
  (function (PassportErrorType) {
16275
16275
  PassportErrorType["AUTHENTICATION_ERROR"] = "AUTHENTICATION_ERROR";
@@ -16523,6 +16523,17 @@ class AuthManager {
16523
16523
  return AuthManager.mapOidcUserToDomainModel(oidcUser);
16524
16524
  }, PassportErrorType.AUTHENTICATION_ERROR);
16525
16525
  }
16526
+ async getUserOrLogin() {
16527
+ let user = null;
16528
+ try {
16529
+ user = await this.getUser();
16530
+ }
16531
+ catch (err) {
16532
+ // eslint-disable-next-line no-console
16533
+ console.warn('failed to retrieve a cached user session:', err);
16534
+ }
16535
+ return user || this.login();
16536
+ }
16526
16537
  async loginCallback() {
16527
16538
  return withPassportError(async () => this.userManager.signinPopupCallback(), PassportErrorType.AUTHENTICATION_ERROR);
16528
16539
  }
@@ -16770,227 +16781,6 @@ const getStarkSigner = async (signer) => withPassportError(async () => {
16770
16781
  return createStarkSigner(privateKey);
16771
16782
  }, PassportErrorType.WALLET_CONNECTION_ERROR);
16772
16783
 
16773
- const POLL_INTERVAL = 1 * 1000; // every 1 second
16774
- const MAX_RETRIES = 3;
16775
- const wait = (ms) => new Promise((resolve) => {
16776
- setTimeout(() => resolve(), ms);
16777
- });
16778
- const retryWithDelay = async (fn, options) => {
16779
- const { retries = MAX_RETRIES, interval = POLL_INTERVAL, finalErr = Error('Retry failed'), finallyFn = () => { }, } = options || {};
16780
- try {
16781
- return await fn();
16782
- }
16783
- catch (err) {
16784
- if (retries <= 0) {
16785
- return Promise.reject(finalErr);
16786
- }
16787
- await wait(interval);
16788
- return retryWithDelay(fn, { retries: retries - 1, finalErr, finallyFn });
16789
- }
16790
- finally {
16791
- if (retries <= 0) {
16792
- finallyFn();
16793
- }
16794
- }
16795
- };
16796
-
16797
- /**
16798
- * ProviderErrors should take priority over RpcErrorCodes
16799
- * https://eips.ethereum.org/EIPS/eip-1193#provider-errors
16800
- * https://eips.ethereum.org/EIPS/eip-1474#error-codes
16801
- */
16802
- var ProviderErrorCode;
16803
- (function (ProviderErrorCode) {
16804
- ProviderErrorCode[ProviderErrorCode["USER_REJECTED_REQUEST"] = 4001] = "USER_REJECTED_REQUEST";
16805
- ProviderErrorCode[ProviderErrorCode["UNAUTHORIZED"] = 4100] = "UNAUTHORIZED";
16806
- ProviderErrorCode[ProviderErrorCode["UNSUPPORTED_METHOD"] = 4200] = "UNSUPPORTED_METHOD";
16807
- ProviderErrorCode[ProviderErrorCode["DISCONNECTED"] = 4900] = "DISCONNECTED";
16808
- })(ProviderErrorCode || (ProviderErrorCode = {}));
16809
- var RpcErrorCode;
16810
- (function (RpcErrorCode) {
16811
- RpcErrorCode[RpcErrorCode["RPC_SERVER_ERROR"] = -32000] = "RPC_SERVER_ERROR";
16812
- RpcErrorCode[RpcErrorCode["INVALID_REQUEST"] = -32600] = "INVALID_REQUEST";
16813
- RpcErrorCode[RpcErrorCode["METHOD_NOT_FOUND"] = -32601] = "METHOD_NOT_FOUND";
16814
- RpcErrorCode[RpcErrorCode["INVALID_PARAMS"] = -32602] = "INVALID_PARAMS";
16815
- RpcErrorCode[RpcErrorCode["INTERNAL_ERROR"] = -32603] = "INTERNAL_ERROR";
16816
- RpcErrorCode[RpcErrorCode["PARSE_ERROR"] = -32700] = "PARSE_ERROR";
16817
- RpcErrorCode[RpcErrorCode["TRANSACTION_REJECTED"] = -32003] = "TRANSACTION_REJECTED";
16818
- })(RpcErrorCode || (RpcErrorCode = {}));
16819
- class JsonRpcError extends Error {
16820
- message;
16821
- code;
16822
- constructor(code, message) {
16823
- super(message);
16824
- this.message = message;
16825
- this.code = code;
16826
- }
16827
- }
16828
-
16829
- const transactionRejectedCrossSdkBridgeError = 'Transaction requires confirmation but this functionality is not'
16830
- + ' supported in this environment. Please contact Immutable support if you need to enable this feature.';
16831
- const convertBigNumberishToString = (value) => BigNumber$1.from(value).toString();
16832
- const transformGuardianTransactions = (txs) => {
16833
- try {
16834
- return txs.map((t) => ({
16835
- delegateCall: t.delegateCall === true,
16836
- revertOnError: t.revertOnError === true,
16837
- gasLimit: t.gasLimit ? convertBigNumberishToString(t.gasLimit) : '0',
16838
- target: t.to ?? ethers.constants.AddressZero,
16839
- value: t.value ? convertBigNumberishToString(t.value) : '0',
16840
- data: t.data ? t.data.toString() : '0x',
16841
- }));
16842
- }
16843
- catch (error) {
16844
- const errorMessage = error instanceof Error ? error.message : String(error);
16845
- throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, `Transaction failed to parsing: ${errorMessage}`);
16846
- }
16847
- };
16848
- class GuardianClient {
16849
- transactionAPI;
16850
- messageAPI;
16851
- confirmationScreen;
16852
- crossSdkBridgeEnabled;
16853
- authManager;
16854
- constructor({ confirmationScreen, config, authManager }) {
16855
- const guardianConfiguration = new Configuration({ basePath: config.imxPublicApiDomain });
16856
- this.confirmationScreen = confirmationScreen;
16857
- this.crossSdkBridgeEnabled = config.crossSdkBridgeEnabled;
16858
- this.messageAPI = new MessagesApi(guardianConfiguration);
16859
- this.transactionAPI = new TransactionsApi(guardianConfiguration);
16860
- this.authManager = authManager;
16861
- }
16862
- /**
16863
- * Open confirmation screen and close it automatically if the
16864
- * underlying task fails.
16865
- */
16866
- withConfirmationScreen(popupWindowSize) {
16867
- return (task) => this.withConfirmationScreenTask(popupWindowSize)(task)();
16868
- }
16869
- withConfirmationScreenTask(popupWindowSize) {
16870
- return (task) => async () => {
16871
- this.confirmationScreen.loading(popupWindowSize);
16872
- try {
16873
- return await task();
16874
- }
16875
- catch (err) {
16876
- this.confirmationScreen.closeWindow();
16877
- throw err;
16878
- }
16879
- };
16880
- }
16881
- withDefaultConfirmationScreenTask(task) {
16882
- return this.withConfirmationScreenTask()(task);
16883
- }
16884
- async evaluateImxTransaction({ payloadHash }) {
16885
- const finallyFn = () => {
16886
- this.confirmationScreen.closeWindow();
16887
- };
16888
- const user = await this.authManager.getUser();
16889
- const headers = { Authorization: `Bearer ${user.accessToken}` };
16890
- const transactionRes = await retryWithDelay(async () => this.transactionAPI.getTransactionByID({
16891
- transactionID: payloadHash,
16892
- chainType: 'starkex',
16893
- }, { headers }), { finallyFn });
16894
- if (!transactionRes.data.id) {
16895
- throw new Error("Transaction doesn't exists");
16896
- }
16897
- const evaluateImxRes = await this.transactionAPI.evaluateTransaction({
16898
- id: payloadHash,
16899
- transactionEvaluationRequest: {
16900
- chainType: 'starkex',
16901
- },
16902
- }, { headers });
16903
- const { confirmationRequired } = evaluateImxRes.data;
16904
- if (confirmationRequired) {
16905
- if (this.crossSdkBridgeEnabled) {
16906
- throw new Error(transactionRejectedCrossSdkBridgeError);
16907
- }
16908
- const confirmationResult = await this.confirmationScreen.requestConfirmation(payloadHash, user.imx.ethAddress, TransactionApprovalRequestChainTypeEnum.Starkex);
16909
- if (!confirmationResult.confirmed) {
16910
- throw new Error('Transaction rejected by user');
16911
- }
16912
- }
16913
- else {
16914
- this.confirmationScreen.closeWindow();
16915
- }
16916
- }
16917
- async evaluateEVMTransaction({ chainId, nonce, metaTransactions, }) {
16918
- const user = await this.authManager.getUser();
16919
- const headers = { Authorization: `Bearer ${user.accessToken}` };
16920
- const guardianTransactions = transformGuardianTransactions(metaTransactions);
16921
- try {
16922
- const transactionEvaluationResponseAxiosResponse = await this.transactionAPI.evaluateTransaction({
16923
- id: 'evm',
16924
- transactionEvaluationRequest: {
16925
- chainType: 'evm',
16926
- chainId,
16927
- transactionData: {
16928
- nonce,
16929
- userAddress: user.zkEvm.ethAddress,
16930
- metaTransactions: guardianTransactions,
16931
- },
16932
- },
16933
- }, { headers });
16934
- return transactionEvaluationResponseAxiosResponse.data;
16935
- }
16936
- catch (error) {
16937
- const errorMessage = error instanceof Error ? error.message : String(error);
16938
- throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, `Transaction failed to validate with error: ${errorMessage}`);
16939
- }
16940
- }
16941
- async validateEVMTransaction({ chainId, nonce, metaTransactions, }) {
16942
- const transactionEvaluationResponse = await this.evaluateEVMTransaction({
16943
- chainId,
16944
- nonce,
16945
- metaTransactions,
16946
- });
16947
- const { confirmationRequired, transactionId } = transactionEvaluationResponse;
16948
- if (confirmationRequired && this.crossSdkBridgeEnabled) {
16949
- throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, transactionRejectedCrossSdkBridgeError);
16950
- }
16951
- if (confirmationRequired && !!transactionId) {
16952
- const user = await this.authManager.getUser();
16953
- const confirmationResult = await this.confirmationScreen.requestConfirmation(transactionId, user.zkEvm.ethAddress, TransactionApprovalRequestChainTypeEnum.Evm, chainId);
16954
- if (!confirmationResult.confirmed) {
16955
- throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, 'Transaction rejected by user');
16956
- }
16957
- }
16958
- else {
16959
- this.confirmationScreen.closeWindow();
16960
- }
16961
- }
16962
- async evaluateMessage({ chainID, payload }) {
16963
- try {
16964
- const user = await this.authManager.getUser();
16965
- if (user === null) {
16966
- throw new PassportError('evaluateMessage requires a valid ID token or refresh token. Please log in first', PassportErrorType.NOT_LOGGED_IN_ERROR);
16967
- }
16968
- const messageEvalResponse = await this.messageAPI.evaluateMessage({ messageEvaluationRequest: { chainID, payload } }, { headers: { Authorization: `Bearer ${user.accessToken}` } });
16969
- return messageEvalResponse.data;
16970
- }
16971
- catch (error) {
16972
- const errorMessage = error instanceof Error ? error.message : String(error);
16973
- throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, `Message failed to validate with error: ${errorMessage}`);
16974
- }
16975
- }
16976
- async validateMessage({ chainID, payload }) {
16977
- const { messageId, confirmationRequired } = await this.evaluateMessage({ chainID, payload });
16978
- if (confirmationRequired && this.crossSdkBridgeEnabled) {
16979
- throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, transactionRejectedCrossSdkBridgeError);
16980
- }
16981
- if (confirmationRequired && !!messageId) {
16982
- const user = await this.authManager.getUser();
16983
- const confirmationResult = await this.confirmationScreen.requestMessageConfirmation(messageId, user.zkEvm.ethAddress);
16984
- if (!confirmationResult.confirmed) {
16985
- throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, 'Signature rejected by user');
16986
- }
16987
- }
16988
- else {
16989
- this.confirmationScreen.closeWindow();
16990
- }
16991
- }
16992
- }
16993
-
16994
16784
  var PassportEvents;
16995
16785
  (function (PassportEvents) {
16996
16786
  PassportEvents["LOGGED_OUT"] = "loggedOut";
@@ -17289,6 +17079,30 @@ async function batchNftTransfer({ user, starkSigner, request, transfersApi, guar
17289
17079
  }), PassportErrorType.TRANSFER_ERROR);
17290
17080
  }
17291
17081
 
17082
+ const POLL_INTERVAL = 1 * 1000; // every 1 second
17083
+ const MAX_RETRIES = 3;
17084
+ const wait = (ms) => new Promise((resolve) => {
17085
+ setTimeout(() => resolve(), ms);
17086
+ });
17087
+ const retryWithDelay = async (fn, options) => {
17088
+ const { retries = MAX_RETRIES, interval = POLL_INTERVAL, finalErr = Error('Retry failed'), finallyFn = () => { }, } = options || {};
17089
+ try {
17090
+ return await fn();
17091
+ }
17092
+ catch (err) {
17093
+ if (retries <= 0) {
17094
+ return Promise.reject(finalErr);
17095
+ }
17096
+ await wait(interval);
17097
+ return retryWithDelay(fn, { retries: retries - 1, finalErr, finallyFn });
17098
+ }
17099
+ finally {
17100
+ if (retries <= 0) {
17101
+ finallyFn();
17102
+ }
17103
+ }
17104
+ };
17105
+
17292
17106
  async function forceUserRefresh(authManager) {
17293
17107
  // User metadata is updated asynchronously. Poll userinfo endpoint until it is updated.
17294
17108
  await retryWithDelay(async () => {
@@ -17334,16 +17148,12 @@ class PassportImxProvider {
17334
17148
  */
17335
17149
  signers;
17336
17150
  signerInitialisationError;
17337
- constructor({ authManager, immutableXClient, confirmationScreen, config, passportEventEmitter, magicAdapter, imxApiClients, }) {
17151
+ constructor({ authManager, immutableXClient, passportEventEmitter, magicAdapter, imxApiClients, guardianClient, }) {
17338
17152
  this.authManager = authManager;
17339
17153
  this.immutableXClient = immutableXClient;
17340
- this.guardianClient = new GuardianClient({
17341
- confirmationScreen,
17342
- config,
17343
- authManager,
17344
- });
17345
17154
  this.magicAdapter = magicAdapter;
17346
17155
  this.imxApiClients = imxApiClients;
17156
+ this.guardianClient = guardianClient;
17347
17157
  this.initialiseSigners();
17348
17158
  passportEventEmitter.on(PassportEvents.LOGGED_OUT, this.handleLogout);
17349
17159
  }
@@ -17506,33 +17316,21 @@ class PassportImxProvider {
17506
17316
 
17507
17317
  class PassportImxProviderFactory {
17508
17318
  authManager;
17509
- config;
17510
- confirmationScreen;
17511
17319
  immutableXClient;
17512
17320
  magicAdapter;
17513
17321
  passportEventEmitter;
17514
17322
  imxApiClients;
17515
- constructor({ authManager, config, confirmationScreen, immutableXClient, magicAdapter, passportEventEmitter, imxApiClients, }) {
17323
+ guardianClient;
17324
+ constructor({ authManager, immutableXClient, magicAdapter, passportEventEmitter, imxApiClients, guardianClient, }) {
17516
17325
  this.authManager = authManager;
17517
- this.config = config;
17518
- this.confirmationScreen = confirmationScreen;
17519
17326
  this.immutableXClient = immutableXClient;
17520
17327
  this.magicAdapter = magicAdapter;
17521
17328
  this.passportEventEmitter = passportEventEmitter;
17522
17329
  this.imxApiClients = imxApiClients;
17330
+ this.guardianClient = guardianClient;
17523
17331
  }
17524
17332
  async getProvider() {
17525
- let user = null;
17526
- try {
17527
- user = await this.authManager.getUser();
17528
- }
17529
- catch (e) {
17530
- // eslint-disable-next-line no-console
17531
- console.warn(e);
17532
- }
17533
- if (!user) {
17534
- user = await this.authManager.login();
17535
- }
17333
+ const user = await this.authManager.getUserOrLogin();
17536
17334
  return this.createProviderInstance(user);
17537
17335
  }
17538
17336
  async getProviderSilent() {
@@ -17547,13 +17345,12 @@ class PassportImxProviderFactory {
17547
17345
  throw new PassportError('Failed to initialise', PassportErrorType.WALLET_CONNECTION_ERROR);
17548
17346
  }
17549
17347
  return new PassportImxProvider({
17550
- config: this.config,
17551
17348
  authManager: this.authManager,
17552
17349
  immutableXClient: this.immutableXClient,
17553
- confirmationScreen: this.confirmationScreen,
17554
17350
  passportEventEmitter: this.passportEventEmitter,
17555
17351
  magicAdapter: this.magicAdapter,
17556
17352
  imxApiClients: this.imxApiClients,
17353
+ guardianClient: this.guardianClient,
17557
17354
  });
17558
17355
  }
17559
17356
  }
@@ -18048,6 +17845,38 @@ class RelayerClient {
18048
17845
  }
18049
17846
  }
18050
17847
 
17848
+ /**
17849
+ * ProviderErrors should take priority over RpcErrorCodes
17850
+ * https://eips.ethereum.org/EIPS/eip-1193#provider-errors
17851
+ * https://eips.ethereum.org/EIPS/eip-1474#error-codes
17852
+ */
17853
+ var ProviderErrorCode;
17854
+ (function (ProviderErrorCode) {
17855
+ ProviderErrorCode[ProviderErrorCode["USER_REJECTED_REQUEST"] = 4001] = "USER_REJECTED_REQUEST";
17856
+ ProviderErrorCode[ProviderErrorCode["UNAUTHORIZED"] = 4100] = "UNAUTHORIZED";
17857
+ ProviderErrorCode[ProviderErrorCode["UNSUPPORTED_METHOD"] = 4200] = "UNSUPPORTED_METHOD";
17858
+ ProviderErrorCode[ProviderErrorCode["DISCONNECTED"] = 4900] = "DISCONNECTED";
17859
+ })(ProviderErrorCode || (ProviderErrorCode = {}));
17860
+ var RpcErrorCode;
17861
+ (function (RpcErrorCode) {
17862
+ RpcErrorCode[RpcErrorCode["RPC_SERVER_ERROR"] = -32000] = "RPC_SERVER_ERROR";
17863
+ RpcErrorCode[RpcErrorCode["INVALID_REQUEST"] = -32600] = "INVALID_REQUEST";
17864
+ RpcErrorCode[RpcErrorCode["METHOD_NOT_FOUND"] = -32601] = "METHOD_NOT_FOUND";
17865
+ RpcErrorCode[RpcErrorCode["INVALID_PARAMS"] = -32602] = "INVALID_PARAMS";
17866
+ RpcErrorCode[RpcErrorCode["INTERNAL_ERROR"] = -32603] = "INTERNAL_ERROR";
17867
+ RpcErrorCode[RpcErrorCode["PARSE_ERROR"] = -32700] = "PARSE_ERROR";
17868
+ RpcErrorCode[RpcErrorCode["TRANSACTION_REJECTED"] = -32003] = "TRANSACTION_REJECTED";
17869
+ })(RpcErrorCode || (RpcErrorCode = {}));
17870
+ class JsonRpcError extends Error {
17871
+ message;
17872
+ code;
17873
+ constructor(code, message) {
17874
+ super(message);
17875
+ this.message = message;
17876
+ this.code = code;
17877
+ }
17878
+ }
17879
+
18051
17880
  const MESSAGE_TO_SIGN = 'Only sign this message from Immutable Passport';
18052
17881
  async function registerZkEvmUser({ authManager, magicProvider, multiRollupApiClients, accessToken, jsonRpcProvider, }) {
18053
17882
  const web3Provider = new Web3Provider(magicProvider);
@@ -18082,17 +17911,7 @@ async function registerZkEvmUser({ authManager, magicProvider, multiRollupApiCli
18082
17911
  }
18083
17912
 
18084
17913
  const loginZkEvmUser = async ({ authManager, magicAdapter, multiRollupApiClients, jsonRpcProvider, }) => {
18085
- let user = null;
18086
- try {
18087
- user = await authManager.getUser();
18088
- }
18089
- catch (err) {
18090
- // eslint-disable-next-line no-console
18091
- console.warn('eth_requestAccounts` failed to retrieve a cached user session:', err);
18092
- }
18093
- if (!user) {
18094
- user = await authManager.login();
18095
- }
17914
+ const user = await authManager.getUserOrLogin();
18096
17915
  if (!user.idToken) {
18097
17916
  throw new Error('User is missing idToken');
18098
17917
  }
@@ -18117,6 +17936,171 @@ const loginZkEvmUser = async ({ authManager, magicAdapter, multiRollupApiClients
18117
17936
  };
18118
17937
  };
18119
17938
 
17939
+ const transactionRejectedCrossSdkBridgeError = 'Transaction requires confirmation but this functionality is not'
17940
+ + ' supported in this environment. Please contact Immutable support if you need to enable this feature.';
17941
+ const convertBigNumberishToString = (value) => BigNumber$1.from(value).toString();
17942
+ const transformGuardianTransactions = (txs) => {
17943
+ try {
17944
+ return txs.map((t) => ({
17945
+ delegateCall: t.delegateCall === true,
17946
+ revertOnError: t.revertOnError === true,
17947
+ gasLimit: t.gasLimit ? convertBigNumberishToString(t.gasLimit) : '0',
17948
+ target: t.to ?? ethers.constants.AddressZero,
17949
+ value: t.value ? convertBigNumberishToString(t.value) : '0',
17950
+ data: t.data ? t.data.toString() : '0x',
17951
+ }));
17952
+ }
17953
+ catch (error) {
17954
+ const errorMessage = error instanceof Error ? error.message : String(error);
17955
+ throw new JsonRpcError(RpcErrorCode.INVALID_PARAMS, `Transaction failed to parsing: ${errorMessage}`);
17956
+ }
17957
+ };
17958
+ class GuardianClient {
17959
+ transactionAPI;
17960
+ messageAPI;
17961
+ confirmationScreen;
17962
+ crossSdkBridgeEnabled;
17963
+ authManager;
17964
+ constructor({ confirmationScreen, config, authManager }) {
17965
+ const guardianConfiguration = new Configuration({ basePath: config.imxPublicApiDomain });
17966
+ this.confirmationScreen = confirmationScreen;
17967
+ this.crossSdkBridgeEnabled = config.crossSdkBridgeEnabled;
17968
+ this.messageAPI = new MessagesApi(guardianConfiguration);
17969
+ this.transactionAPI = new TransactionsApi(guardianConfiguration);
17970
+ this.authManager = authManager;
17971
+ }
17972
+ /**
17973
+ * Open confirmation screen and close it automatically if the
17974
+ * underlying task fails.
17975
+ */
17976
+ withConfirmationScreen(popupWindowSize) {
17977
+ return (task) => this.withConfirmationScreenTask(popupWindowSize)(task)();
17978
+ }
17979
+ withConfirmationScreenTask(popupWindowSize) {
17980
+ return (task) => async () => {
17981
+ this.confirmationScreen.loading(popupWindowSize);
17982
+ try {
17983
+ return await task();
17984
+ }
17985
+ catch (err) {
17986
+ this.confirmationScreen.closeWindow();
17987
+ throw err;
17988
+ }
17989
+ };
17990
+ }
17991
+ withDefaultConfirmationScreenTask(task) {
17992
+ return this.withConfirmationScreenTask()(task);
17993
+ }
17994
+ async evaluateImxTransaction({ payloadHash }) {
17995
+ const finallyFn = () => {
17996
+ this.confirmationScreen.closeWindow();
17997
+ };
17998
+ const user = await this.authManager.getUser();
17999
+ const headers = { Authorization: `Bearer ${user.accessToken}` };
18000
+ const transactionRes = await retryWithDelay(async () => this.transactionAPI.getTransactionByID({
18001
+ transactionID: payloadHash,
18002
+ chainType: 'starkex',
18003
+ }, { headers }), { finallyFn });
18004
+ if (!transactionRes.data.id) {
18005
+ throw new Error("Transaction doesn't exists");
18006
+ }
18007
+ const evaluateImxRes = await this.transactionAPI.evaluateTransaction({
18008
+ id: payloadHash,
18009
+ transactionEvaluationRequest: {
18010
+ chainType: 'starkex',
18011
+ },
18012
+ }, { headers });
18013
+ const { confirmationRequired } = evaluateImxRes.data;
18014
+ if (confirmationRequired) {
18015
+ if (this.crossSdkBridgeEnabled) {
18016
+ throw new Error(transactionRejectedCrossSdkBridgeError);
18017
+ }
18018
+ const confirmationResult = await this.confirmationScreen.requestConfirmation(payloadHash, user.imx.ethAddress, TransactionApprovalRequestChainTypeEnum.Starkex);
18019
+ if (!confirmationResult.confirmed) {
18020
+ throw new Error('Transaction rejected by user');
18021
+ }
18022
+ }
18023
+ else {
18024
+ this.confirmationScreen.closeWindow();
18025
+ }
18026
+ }
18027
+ async evaluateEVMTransaction({ chainId, nonce, metaTransactions, }) {
18028
+ const user = await this.authManager.getUser();
18029
+ const headers = { Authorization: `Bearer ${user.accessToken}` };
18030
+ const guardianTransactions = transformGuardianTransactions(metaTransactions);
18031
+ try {
18032
+ const transactionEvaluationResponseAxiosResponse = await this.transactionAPI.evaluateTransaction({
18033
+ id: 'evm',
18034
+ transactionEvaluationRequest: {
18035
+ chainType: 'evm',
18036
+ chainId,
18037
+ transactionData: {
18038
+ nonce,
18039
+ userAddress: user.zkEvm.ethAddress,
18040
+ metaTransactions: guardianTransactions,
18041
+ },
18042
+ },
18043
+ }, { headers });
18044
+ return transactionEvaluationResponseAxiosResponse.data;
18045
+ }
18046
+ catch (error) {
18047
+ const errorMessage = error instanceof Error ? error.message : String(error);
18048
+ throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, `Transaction failed to validate with error: ${errorMessage}`);
18049
+ }
18050
+ }
18051
+ async validateEVMTransaction({ chainId, nonce, metaTransactions, }) {
18052
+ const transactionEvaluationResponse = await this.evaluateEVMTransaction({
18053
+ chainId,
18054
+ nonce,
18055
+ metaTransactions,
18056
+ });
18057
+ const { confirmationRequired, transactionId } = transactionEvaluationResponse;
18058
+ if (confirmationRequired && this.crossSdkBridgeEnabled) {
18059
+ throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, transactionRejectedCrossSdkBridgeError);
18060
+ }
18061
+ if (confirmationRequired && !!transactionId) {
18062
+ const user = await this.authManager.getUser();
18063
+ const confirmationResult = await this.confirmationScreen.requestConfirmation(transactionId, user.zkEvm.ethAddress, TransactionApprovalRequestChainTypeEnum.Evm, chainId);
18064
+ if (!confirmationResult.confirmed) {
18065
+ throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, 'Transaction rejected by user');
18066
+ }
18067
+ }
18068
+ else {
18069
+ this.confirmationScreen.closeWindow();
18070
+ }
18071
+ }
18072
+ async evaluateMessage({ chainID, payload }) {
18073
+ try {
18074
+ const user = await this.authManager.getUser();
18075
+ if (user === null) {
18076
+ throw new PassportError('evaluateMessage requires a valid ID token or refresh token. Please log in first', PassportErrorType.NOT_LOGGED_IN_ERROR);
18077
+ }
18078
+ const messageEvalResponse = await this.messageAPI.evaluateMessage({ messageEvaluationRequest: { chainID, payload } }, { headers: { Authorization: `Bearer ${user.accessToken}` } });
18079
+ return messageEvalResponse.data;
18080
+ }
18081
+ catch (error) {
18082
+ const errorMessage = error instanceof Error ? error.message : String(error);
18083
+ throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, `Message failed to validate with error: ${errorMessage}`);
18084
+ }
18085
+ }
18086
+ async validateMessage({ chainID, payload }) {
18087
+ const { messageId, confirmationRequired } = await this.evaluateMessage({ chainID, payload });
18088
+ if (confirmationRequired && this.crossSdkBridgeEnabled) {
18089
+ throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, transactionRejectedCrossSdkBridgeError);
18090
+ }
18091
+ if (confirmationRequired && !!messageId) {
18092
+ const user = await this.authManager.getUser();
18093
+ const confirmationResult = await this.confirmationScreen.requestMessageConfirmation(messageId, user.zkEvm.ethAddress);
18094
+ if (!confirmationResult.confirmed) {
18095
+ throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, 'Signature rejected by user');
18096
+ }
18097
+ }
18098
+ else {
18099
+ this.confirmationScreen.closeWindow();
18100
+ }
18101
+ }
18102
+ }
18103
+
18120
18104
  const MAX_TRANSACTION_HASH_RETRIEVAL_RETRIES = 30;
18121
18105
  const TRANSACTION_HASH_RETRIEVAL_WAIT = 1000;
18122
18106
  const getMetaTransactions = async (metaTransaction, nonce, chainId, walletAddress, signer, relayerClient) => {
@@ -18261,7 +18245,6 @@ const signTypedDataV4 = async ({ params, method, magicProvider, jsonRpcProvider,
18261
18245
  class ZkEvmProvider {
18262
18246
  authManager;
18263
18247
  config;
18264
- confirmationScreen;
18265
18248
  magicAdapter;
18266
18249
  multiRollupApiClients;
18267
18250
  jsonRpcProvider; // Used for read
@@ -18271,11 +18254,11 @@ class ZkEvmProvider {
18271
18254
  magicProvider; // Used for signing
18272
18255
  zkevmAddress;
18273
18256
  isPassport = true;
18274
- constructor({ authManager, magicAdapter, config, confirmationScreen, multiRollupApiClients, passportEventEmitter, }) {
18257
+ constructor({ authManager, magicAdapter, config, multiRollupApiClients, passportEventEmitter, guardianClient, }) {
18275
18258
  this.authManager = authManager;
18276
18259
  this.magicAdapter = magicAdapter;
18277
18260
  this.config = config;
18278
- this.confirmationScreen = confirmationScreen;
18261
+ this.guardianClient = guardianClient;
18279
18262
  if (config.crossSdkBridgeEnabled) {
18280
18263
  // JsonRpcProvider by default sets the referrer as "client".
18281
18264
  // On Unreal 4 this errors as the browser used is expecting a valid URL.
@@ -18295,7 +18278,6 @@ class ZkEvmProvider {
18295
18278
  const shouldEmitAccountsChanged = this.isLoggedIn();
18296
18279
  this.magicProvider = undefined;
18297
18280
  this.relayerClient = undefined;
18298
- this.guardianClient = undefined;
18299
18281
  if (shouldEmitAccountsChanged) {
18300
18282
  this.eventEmitter.emit(ProviderEvent.ACCOUNTS_CHANGED, []);
18301
18283
  }
@@ -18303,8 +18285,7 @@ class ZkEvmProvider {
18303
18285
  isLoggedIn() {
18304
18286
  return this.magicProvider !== undefined
18305
18287
  && this.zkevmAddress !== undefined
18306
- && this.relayerClient !== undefined
18307
- && this.guardianClient !== undefined;
18288
+ && this.relayerClient !== undefined;
18308
18289
  }
18309
18290
  async performRequest(request) {
18310
18291
  switch (request.method) {
@@ -18314,7 +18295,6 @@ class ZkEvmProvider {
18314
18295
  }
18315
18296
  const { magicProvider, user } = await loginZkEvmUser({
18316
18297
  authManager: this.authManager,
18317
- config: this.config,
18318
18298
  magicAdapter: this.magicAdapter,
18319
18299
  multiRollupApiClients: this.multiRollupApiClients,
18320
18300
  jsonRpcProvider: this.jsonRpcProvider,
@@ -18325,11 +18305,6 @@ class ZkEvmProvider {
18325
18305
  jsonRpcProvider: this.jsonRpcProvider,
18326
18306
  authManager: this.authManager,
18327
18307
  });
18328
- this.guardianClient = new GuardianClient({
18329
- confirmationScreen: this.confirmationScreen,
18330
- config: this.config,
18331
- authManager: this.authManager,
18332
- });
18333
18308
  this.zkevmAddress = user.zkEvm.ethAddress;
18334
18309
  this.eventEmitter.emit(ProviderEvent.ACCOUNTS_CHANGED, [user.zkEvm.ethAddress]);
18335
18310
  return [user.zkEvm.ethAddress];
@@ -18508,15 +18483,19 @@ const buildPrivateVars = (passportModuleConfiguration) => {
18508
18483
  const immutableXClient = passportModuleConfiguration.overrides
18509
18484
  ? passportModuleConfiguration.overrides.immutableXClient
18510
18485
  : new IMXClient({ baseConfig: passportModuleConfiguration.baseConfig });
18486
+ const guardianClient = new GuardianClient({
18487
+ confirmationScreen,
18488
+ config,
18489
+ authManager,
18490
+ });
18511
18491
  const imxApiClients = buildImxApiClients(passportModuleConfiguration);
18512
18492
  const passportImxProviderFactory = new PassportImxProviderFactory({
18513
18493
  authManager,
18514
- config,
18515
- confirmationScreen,
18516
18494
  immutableXClient,
18517
18495
  magicAdapter,
18518
18496
  passportEventEmitter,
18519
18497
  imxApiClients,
18498
+ guardianClient,
18520
18499
  });
18521
18500
  return {
18522
18501
  config,
@@ -18527,6 +18506,7 @@ const buildPrivateVars = (passportModuleConfiguration) => {
18527
18506
  multiRollupApiClients,
18528
18507
  passportEventEmitter,
18529
18508
  passportImxProviderFactory,
18509
+ guardianClient,
18530
18510
  };
18531
18511
  };
18532
18512
  class Passport {
@@ -18538,6 +18518,7 @@ class Passport {
18538
18518
  multiRollupApiClients;
18539
18519
  passportImxProviderFactory;
18540
18520
  passportEventEmitter;
18521
+ guardianClient;
18541
18522
  constructor(passportModuleConfiguration) {
18542
18523
  const privateVars = buildPrivateVars(passportModuleConfiguration);
18543
18524
  this.config = privateVars.config;
@@ -18548,6 +18529,7 @@ class Passport {
18548
18529
  this.multiRollupApiClients = privateVars.multiRollupApiClients;
18549
18530
  this.passportEventEmitter = privateVars.passportEventEmitter;
18550
18531
  this.passportImxProviderFactory = privateVars.passportImxProviderFactory;
18532
+ this.guardianClient = privateVars.guardianClient;
18551
18533
  setPassportClientId(passportModuleConfiguration.clientId);
18552
18534
  track('passport', 'initialised');
18553
18535
  }
@@ -18567,8 +18549,8 @@ class Passport {
18567
18549
  authManager: this.authManager,
18568
18550
  magicAdapter: this.magicAdapter,
18569
18551
  config: this.config,
18570
- confirmationScreen: this.confirmationScreen,
18571
18552
  multiRollupApiClients: this.multiRollupApiClients,
18553
+ guardianClient: this.guardianClient,
18572
18554
  });
18573
18555
  }
18574
18556
  /**
@@ -37434,7 +37416,7 @@ const flattenProperties = (properties) => {
37434
37416
  };
37435
37417
 
37436
37418
  // WARNING: DO NOT CHANGE THE STRING BELOW. IT GETS REPLACED AT BUILD TIME.
37437
- const SDK_VERSION = '1.6.1';
37419
+ const SDK_VERSION = '1.7.1';
37438
37420
  const getReferrer = () => {
37439
37421
  if (isNode()) {
37440
37422
  return '';
@@ -42601,7 +42583,7 @@ const IMMUTABLE_ZKVEM_GAS_OVERRIDES = {
42601
42583
  maxPriorityFeePerGas: BigNumber$1.from(10e9),
42602
42584
  };
42603
42585
 
42604
- const SDK_VERSION_MARKER = '1.6.1';
42586
+ const SDK_VERSION_MARKER = '1.7.1';
42605
42587
  // This SDK version is replaced by the `yarn build` command ran on the root level
42606
42588
  const globalPackageVersion = () => SDK_VERSION_MARKER;
42607
42589
 
@@ -46115,13 +46097,15 @@ class FiatRampService {
46115
46097
  const productsAvailed = 'productsAvailed=buy';
46116
46098
  const exchangeScreenTitle = 'exchangeScreenTitle=Buy';
46117
46099
  const themeColor = 'themeColor=0D0D0D';
46100
+ const defaultFiat = 'defaultFiatAmount=50&defaultFiatCurrency=usd';
46118
46101
  widgetUrl += `${transakPublishableKey}&`
46119
46102
  + `${zkevmNetwork}&`
46120
46103
  + `${defaultPaymentMethod}&`
46121
46104
  + `${disableBankTransfer}&`
46122
46105
  + `${productsAvailed}&`
46123
46106
  + `${exchangeScreenTitle}&`
46124
- + `${themeColor}`;
46107
+ + `${themeColor}&`
46108
+ + `${defaultFiat}`;
46125
46109
  if (params.isPassport && params.email) {
46126
46110
  const encodedEmail = encodeURIComponent(params.email);
46127
46111
  widgetUrl += `&email=${encodedEmail}&isAutoFillUserData=true&disableWalletAddressForm=true`;
@@ -46135,6 +46119,9 @@ class FiatRampService {
46135
46119
  if (params.walletAddress) {
46136
46120
  widgetUrl += `&walletAddress=${params.walletAddress}`;
46137
46121
  }
46122
+ if (params.allowedTokens) {
46123
+ widgetUrl += `&cryptoCurrencyList=${params.allowedTokens?.join(',').toLowerCase()}`;
46124
+ }
46138
46125
  return widgetUrl;
46139
46126
  }
46140
46127
  }
@@ -46581,6 +46568,7 @@ class Checkout {
46581
46568
  tokenAmount = params.tokenAmount;
46582
46569
  tokenSymbol = token.symbol;
46583
46570
  }
46571
+ const allowedTokens = tokenList?.tokens?.filter((t) => t.symbol).map((t) => t.symbol);
46584
46572
  return await this.fiatRampService.createWidgetUrl({
46585
46573
  exchangeType: params.exchangeType,
46586
46574
  isPassport,
@@ -46588,6 +46576,7 @@ class Checkout {
46588
46576
  tokenAmount,
46589
46577
  tokenSymbol,
46590
46578
  email,
46579
+ allowedTokens,
46591
46580
  });
46592
46581
  }
46593
46582
  /**