@imtbl/sdk 1.12.2 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/passport.js CHANGED
@@ -2,7 +2,7 @@ import globalAxios$1, { isAxiosError as isAxiosError$1 } from 'axios';
2
2
  import { ImmutableX, Config, generateLegacyStarkPrivateKey, createStarkSigner } from '@imtbl/core-sdk';
3
3
  import { memorise } from 'lru-memorise';
4
4
  import { getGlobalisedValue as getGlobalisedValue$1 } from 'global-const';
5
- import { UserManager, User, InMemoryWebStorage, WebStorageStateStore } from 'oidc-client-ts';
5
+ import { UserManager, User, ErrorTimeout, ErrorResponse, InMemoryWebStorage, WebStorageStateStore } from 'oidc-client-ts';
6
6
  import jwt_decode from 'jwt-decode';
7
7
  import * as crypto from 'crypto';
8
8
  import { Magic } from 'magic-sdk';
@@ -9346,7 +9346,7 @@ class MultiRollupApiClients {
9346
9346
  }
9347
9347
 
9348
9348
  // eslint-disable-next-line @typescript-eslint/naming-convention
9349
- const defaultHeaders = { 'x-sdk-version': 'ts-immutable-sdk-1.12.2' };
9349
+ const defaultHeaders = { 'x-sdk-version': 'ts-immutable-sdk-1.13.0' };
9350
9350
  const createConfig = ({ basePath, headers, }) => {
9351
9351
  if (!basePath.trim()) {
9352
9352
  throw Error('basePath can not be empty');
@@ -9525,7 +9525,7 @@ const flattenProperties = (properties) => {
9525
9525
  };
9526
9526
 
9527
9527
  // WARNING: DO NOT CHANGE THE STRING BELOW. IT GETS REPLACED AT BUILD TIME.
9528
- const SDK_VERSION = '1.12.2';
9528
+ const SDK_VERSION = '1.13.0';
9529
9529
  const getReferrer = () => {
9530
9530
  if (isNode()) {
9531
9531
  return '';
@@ -9744,7 +9744,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
9744
9744
  chainID,
9745
9745
  coreContractAddress,
9746
9746
  registrationContractAddress,
9747
- sdkVersion: 'ts-immutable-sdk-1.12.2',
9747
+ sdkVersion: 'ts-immutable-sdk-1.13.0',
9748
9748
  });
9749
9749
  /**
9750
9750
  * Sets `sdkVersion` at the time of build
@@ -14357,6 +14357,13 @@ function isTokenExpired(oidcUser) {
14357
14357
  return isIdTokenExpired(idToken);
14358
14358
  }
14359
14359
 
14360
+ var PassportEvents;
14361
+ (function (PassportEvents) {
14362
+ PassportEvents["LOGGED_OUT"] = "loggedOut";
14363
+ })(PassportEvents || (PassportEvents = {}));
14364
+ const isUserZkEvm = (user) => !!user.zkEvm;
14365
+ const isUserImx = (user) => !!user.imx;
14366
+
14360
14367
  const formUrlEncodedHeader = {
14361
14368
  headers: {
14362
14369
  'Content-Type': 'application/x-www-form-urlencoded',
@@ -14408,8 +14415,8 @@ function sha256(buffer) {
14408
14415
  }
14409
14416
  class AuthManager {
14410
14417
  userManager;
14411
- config;
14412
14418
  deviceCredentialsManager;
14419
+ config;
14413
14420
  logoutMode;
14414
14421
  /**
14415
14422
  * Promise that is used to prevent multiple concurrent calls to the refresh token endpoint.
@@ -14639,6 +14646,12 @@ class AuthManager {
14639
14646
  async logoutSilentCallback(url) {
14640
14647
  return this.userManager.signoutSilentCallback(url);
14641
14648
  }
14649
+ forceUserRefreshInBackground() {
14650
+ this.refreshTokenAndUpdatePromise().catch((error) => {
14651
+ // eslint-disable-next-line no-console
14652
+ console.warn('Failed to refresh user token', error);
14653
+ });
14654
+ }
14642
14655
  async forceUserRefresh() {
14643
14656
  return this.refreshTokenAndUpdatePromise();
14644
14657
  }
@@ -14660,7 +14673,19 @@ class AuthManager {
14660
14673
  resolve(null);
14661
14674
  }
14662
14675
  catch (err) {
14663
- reject(err);
14676
+ let passportErrorType = PassportErrorType.AUTHENTICATION_ERROR;
14677
+ let errorMessage = 'Failed to refresh token';
14678
+ if (err instanceof ErrorTimeout) {
14679
+ passportErrorType = PassportErrorType.SILENT_LOGIN_ERROR;
14680
+ }
14681
+ else if (err instanceof ErrorResponse) {
14682
+ passportErrorType = PassportErrorType.NOT_LOGGED_IN_ERROR;
14683
+ errorMessage = `${err.message}: ${err.error_description}`;
14684
+ }
14685
+ else if (err instanceof Error) {
14686
+ errorMessage = err.message;
14687
+ }
14688
+ reject(new PassportError(errorMessage, passportErrorType));
14664
14689
  }
14665
14690
  finally {
14666
14691
  this.refreshingPromise = null; // Reset the promise after completion
@@ -14669,22 +14694,56 @@ class AuthManager {
14669
14694
  return this.refreshingPromise;
14670
14695
  }
14671
14696
  /**
14672
- * Get the user from the cache or refresh the token if it's expired.
14673
- * return null if there's no refresh token.
14697
+ *
14698
+ * @param typeAssertion {(user: User) => boolean} - Optional. If provided, then the User will be checked against
14699
+ * the typeAssertion. If the user meets the requirements, then it will be typed as T and returned. If the User
14700
+ * does NOT meet the type assertion, then execution will continue, and we will attempt to obtain a User that does
14701
+ * meet the type assertion.
14702
+ *
14703
+ * This function will attempt to obtain a User in the following order:
14704
+ * 1. If the User is currently refreshing, wait for the refresh to complete.
14705
+ * 2. Attempt to obtain a User from storage that has not expired.
14706
+ * 3. Attempt to refresh the User if a refresh token is present.
14707
+ * 4. Return null if no valid User can be obtained.
14674
14708
  */
14675
- async getUser() {
14676
- return withPassportError(async () => {
14677
- const oidcUser = await this.userManager.getUser();
14678
- if (!oidcUser)
14679
- return null;
14680
- if (!isTokenExpired(oidcUser)) {
14681
- return AuthManager.mapOidcUserToDomainModel(oidcUser);
14682
- }
14683
- if (oidcUser.refresh_token) {
14684
- return this.refreshTokenAndUpdatePromise();
14709
+ async getUser(typeAssertion = (user) => true) {
14710
+ if (this.refreshingPromise) {
14711
+ const user = await this.refreshingPromise;
14712
+ if (user && typeAssertion(user)) {
14713
+ return user;
14685
14714
  }
14686
14715
  return null;
14687
- }, PassportErrorType.NOT_LOGGED_IN_ERROR);
14716
+ }
14717
+ const oidcUser = await this.userManager.getUser();
14718
+ if (!oidcUser)
14719
+ return null;
14720
+ if (!isTokenExpired(oidcUser)) {
14721
+ const user = AuthManager.mapOidcUserToDomainModel(oidcUser);
14722
+ if (user && typeAssertion(user)) {
14723
+ return user;
14724
+ }
14725
+ }
14726
+ if (oidcUser.refresh_token) {
14727
+ const user = await this.refreshTokenAndUpdatePromise();
14728
+ if (user && typeAssertion(user)) {
14729
+ return user;
14730
+ }
14731
+ }
14732
+ return null;
14733
+ }
14734
+ async getUserZkEvm() {
14735
+ const user = await this.getUser(isUserZkEvm);
14736
+ if (!user) {
14737
+ throw new Error('Failed to obtain a User with the required ZkEvm attributes');
14738
+ }
14739
+ return user;
14740
+ }
14741
+ async getUserImx() {
14742
+ const user = await this.getUser(isUserImx);
14743
+ if (!user) {
14744
+ throw new Error('Failed to obtain a User with the required IMX attributes');
14745
+ }
14746
+ return user;
14688
14747
  }
14689
14748
  }
14690
14749
 
@@ -14753,11 +14812,6 @@ const getStarkSigner = async (signer) => withPassportError(async () => {
14753
14812
  return createStarkSigner(privateKey);
14754
14813
  }, PassportErrorType.WALLET_CONNECTION_ERROR);
14755
14814
 
14756
- var PassportEvents;
14757
- (function (PassportEvents) {
14758
- PassportEvents["LOGGED_OUT"] = "loggedOut";
14759
- })(PassportEvents || (PassportEvents = {}));
14760
-
14761
14815
  async function exchangeTransfer({ user, starkSigner, request, exchangesApi, }) {
14762
14816
  return withPassportError(async () => {
14763
14817
  const { ethAddress } = user.imx;
@@ -15144,7 +15198,7 @@ class PassportImxProvider {
15144
15198
  * @see getAuthenticatedUserAndSigners
15145
15199
  *
15146
15200
  */
15147
- async initialiseSigners() {
15201
+ initialiseSigners() {
15148
15202
  const generateSigners = async () => {
15149
15203
  const user = await this.authManager.getUser();
15150
15204
  // The user will be present because the factory validates it
@@ -15183,7 +15237,6 @@ class PassportImxProvider {
15183
15237
  }
15184
15238
  async getRegisteredImxUserAndSigners() {
15185
15239
  const { user, starkSigner, ethSigner } = await this.getAuthenticatedUserAndSigners();
15186
- const isUserImx = (oidcUser) => oidcUser?.imx !== undefined;
15187
15240
  if (!isUserImx(user)) {
15188
15241
  throw new PassportError('User has not been registered with StarkEx', PassportErrorType.USER_NOT_REGISTERED_ERROR);
15189
15242
  }
@@ -15753,11 +15806,11 @@ class RelayerClient {
15753
15806
  jsonrpc: '2.0',
15754
15807
  ...request,
15755
15808
  };
15756
- const user = await this.authManager.getUser();
15809
+ const user = await this.authManager.getUserZkEvm();
15757
15810
  const response = await fetch(`${this.config.relayerUrl}/v1/transactions`, {
15758
15811
  method: 'POST',
15759
15812
  headers: {
15760
- Authorization: `Bearer ${user?.accessToken}`,
15813
+ Authorization: `Bearer ${user.accessToken}`,
15761
15814
  'Content-Type': 'application/json',
15762
15815
  },
15763
15816
  body: JSON.stringify(body),
@@ -15863,7 +15916,7 @@ async function registerZkEvmUser({ authManager, ethSigner, multiRollupApiClients
15863
15916
  throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, `Chain name does not exist on for chain id ${network.chainId}`);
15864
15917
  }
15865
15918
  try {
15866
- await multiRollupApiClients.passportApi.createCounterfactualAddressV2({
15919
+ const registrationResponse = await multiRollupApiClients.passportApi.createCounterfactualAddressV2({
15867
15920
  chainName,
15868
15921
  createCounterfactualAddressRequest: {
15869
15922
  ethereum_address: ethereumAddress,
@@ -15872,15 +15925,12 @@ async function registerZkEvmUser({ authManager, ethSigner, multiRollupApiClients
15872
15925
  }, {
15873
15926
  headers: { Authorization: `Bearer ${accessToken}` },
15874
15927
  });
15928
+ authManager.forceUserRefreshInBackground();
15929
+ return registrationResponse.data.counterfactual_address;
15875
15930
  }
15876
15931
  catch (error) {
15877
15932
  throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, `Failed to create counterfactual address: ${error}`);
15878
15933
  }
15879
- const user = await authManager.forceUserRefresh();
15880
- if (!user?.zkEvm) {
15881
- throw new JsonRpcError(RpcErrorCode.INTERNAL_ERROR, 'Failed to refresh user details');
15882
- }
15883
- return user;
15884
15934
  }
15885
15935
 
15886
15936
  const transactionRejectedCrossSdkBridgeError = 'Transaction requires confirmation but this functionality is not'
@@ -15942,7 +15992,7 @@ class GuardianClient {
15942
15992
  const finallyFn = () => {
15943
15993
  this.confirmationScreen.closeWindow();
15944
15994
  };
15945
- const user = await this.authManager.getUser();
15995
+ const user = await this.authManager.getUserImx();
15946
15996
  const headers = { Authorization: `Bearer ${user.accessToken}` };
15947
15997
  const transactionRes = await retryWithDelay(async () => this.transactionAPI.getTransactionByID({
15948
15998
  transactionID: payloadHash,
@@ -15972,7 +16022,7 @@ class GuardianClient {
15972
16022
  }
15973
16023
  }
15974
16024
  async evaluateEVMTransaction({ chainId, nonce, metaTransactions, }) {
15975
- const user = await this.authManager.getUser();
16025
+ const user = await this.authManager.getUserZkEvm();
15976
16026
  const headers = { Authorization: `Bearer ${user.accessToken}` };
15977
16027
  const guardianTransactions = transformGuardianTransactions(metaTransactions);
15978
16028
  try {
@@ -16006,7 +16056,7 @@ class GuardianClient {
16006
16056
  throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, transactionRejectedCrossSdkBridgeError);
16007
16057
  }
16008
16058
  if (confirmationRequired && !!transactionId) {
16009
- const user = await this.authManager.getUser();
16059
+ const user = await this.authManager.getUserZkEvm();
16010
16060
  const confirmationResult = await this.confirmationScreen.requestConfirmation(transactionId, user.zkEvm.ethAddress, TransactionApprovalRequestChainTypeEnum.Evm, chainId);
16011
16061
  if (!confirmationResult.confirmed) {
16012
16062
  throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, 'Transaction rejected by user');
@@ -16018,7 +16068,7 @@ class GuardianClient {
16018
16068
  }
16019
16069
  async evaluateMessage({ chainID, payload }) {
16020
16070
  try {
16021
- const user = await this.authManager.getUser();
16071
+ const user = await this.authManager.getUserZkEvm();
16022
16072
  if (user === null) {
16023
16073
  throw new PassportError('evaluateMessage requires a valid ID token or refresh token. Please log in first', PassportErrorType.NOT_LOGGED_IN_ERROR);
16024
16074
  }
@@ -16036,7 +16086,7 @@ class GuardianClient {
16036
16086
  throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, transactionRejectedCrossSdkBridgeError);
16037
16087
  }
16038
16088
  if (confirmationRequired && !!messageId) {
16039
- const user = await this.authManager.getUser();
16089
+ const user = await this.authManager.getUserZkEvm();
16040
16090
  const confirmationResult = await this.confirmationScreen.requestMessageConfirmation(messageId, user.zkEvm.ethAddress);
16041
16091
  if (!confirmationResult.confirmed) {
16042
16092
  throw new JsonRpcError(RpcErrorCode.TRANSACTION_REJECTED, 'Signature rejected by user');
@@ -16253,7 +16303,7 @@ class ZkEvmProvider {
16253
16303
  * @see #getSigner
16254
16304
  *
16255
16305
  */
16256
- async #initialiseEthSigner(user) {
16306
+ #initialiseEthSigner(user) {
16257
16307
  const generateSigner = async () => {
16258
16308
  const magicRpcProvider = await this.#magicAdapter.login(user.idToken);
16259
16309
  const web3Provider = new Web3Provider(magicRpcProvider);
@@ -16292,14 +16342,13 @@ class ZkEvmProvider {
16292
16342
  this.#initialiseEthSigner(user);
16293
16343
  if (!isZkEvmUser(user)) {
16294
16344
  const ethSigner = await this.#getSigner();
16295
- const userZkEvm = await registerZkEvmUser({
16345
+ this.#zkEvmAddress = await registerZkEvmUser({
16296
16346
  ethSigner,
16297
16347
  authManager: this.#authManager,
16298
16348
  multiRollupApiClients: this.#multiRollupApiClients,
16299
16349
  accessToken: user.accessToken,
16300
16350
  jsonRpcProvider: this.#jsonRpcProvider,
16301
16351
  });
16302
- this.#zkEvmAddress = userZkEvm.zkEvm.ethAddress;
16303
16352
  }
16304
16353
  else {
16305
16354
  this.#zkEvmAddress = user.zkEvm.ethAddress;
package/dist/x.js CHANGED
@@ -136,7 +136,7 @@ const flattenProperties = (properties) => {
136
136
  };
137
137
 
138
138
  // WARNING: DO NOT CHANGE THE STRING BELOW. IT GETS REPLACED AT BUILD TIME.
139
- const SDK_VERSION = '1.12.2';
139
+ const SDK_VERSION = '1.13.0';
140
140
  const getReferrer = () => {
141
141
  if (isNode()) {
142
142
  return '';
@@ -334,7 +334,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
334
334
  chainID,
335
335
  coreContractAddress,
336
336
  registrationContractAddress,
337
- sdkVersion: 'ts-immutable-sdk-1.12.2',
337
+ sdkVersion: 'ts-immutable-sdk-1.13.0',
338
338
  });
339
339
  /**
340
340
  * Sets `sdkVersion` at the time of build
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@imtbl/sdk",
3
3
  "description": "Immutable Unified SDK",
4
- "version": "1.12.2",
4
+ "version": "1.13.0",
5
5
  "author": "Immutable",
6
6
  "browser": "./dist/index.browser.js",
7
7
  "bugs": "https://github.com/immutable/ts-immutable-sdk/issues",