@openfort/openfort-js 0.7.3 → 0.7.5

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.cjs CHANGED
@@ -9,10 +9,30 @@ var bytes = require('@ethersproject/bytes');
9
9
  var events = require('events');
10
10
  var uuid = require('uuid');
11
11
  var jose = require('jose');
12
+ var crypto = require('crypto');
12
13
  var secp256k1 = require('@noble/curves/secp256k1');
13
14
  var signingKey = require('@ethersproject/signing-key');
14
15
  var transactions = require('@ethersproject/transactions');
15
16
 
17
+ function _interopNamespaceDefault(e) {
18
+ var n = Object.create(null);
19
+ if (e) {
20
+ Object.keys(e).forEach(function (k) {
21
+ if (k !== 'default') {
22
+ var d = Object.getOwnPropertyDescriptor(e, k);
23
+ Object.defineProperty(n, k, d.get ? d : {
24
+ enumerable: true,
25
+ get: function () { return e[k]; }
26
+ });
27
+ }
28
+ });
29
+ }
30
+ n.default = e;
31
+ return Object.freeze(n);
32
+ }
33
+
34
+ var crypto__namespace = /*#__PURE__*/_interopNamespaceDefault(crypto);
35
+
16
36
  exports.EmbeddedState = void 0;
17
37
  (function (EmbeddedState) {
18
38
  EmbeddedState[EmbeddedState["NONE"] = 0] = "NONE";
@@ -59,7 +79,13 @@ exports.OAuthProvider = void 0;
59
79
  (function (OAuthProvider) {
60
80
  OAuthProvider["GOOGLE"] = "google";
61
81
  OAuthProvider["TWITTER"] = "twitter";
82
+ OAuthProvider["FACEBOOK"] = "facebook";
62
83
  })(exports.OAuthProvider || (exports.OAuthProvider = {}));
84
+ var CodeChallengeMethodEnum;
85
+ (function (CodeChallengeMethodEnum) {
86
+ CodeChallengeMethodEnum["PLAIN"] = "plain";
87
+ CodeChallengeMethodEnum["S256"] = "S256";
88
+ })(CodeChallengeMethodEnum || (CodeChallengeMethodEnum = {}));
63
89
 
64
90
  /* tslint:disable */
65
91
  /* eslint-disable */
@@ -1286,13 +1312,13 @@ const AuthenticationApiAxiosParamCreator = function (configuration) {
1286
1312
  /**
1287
1313
  * Start the Email Verification process for a player.
1288
1314
  * @summary Request an Email Verification.
1289
- * @param {RequestResetPasswordRequest} requestResetPasswordRequest
1315
+ * @param {RequestVerifyEmailRequest} requestVerifyEmailRequest
1290
1316
  * @param {*} [options] Override http request option.
1291
1317
  * @throws {RequiredError}
1292
1318
  */
1293
- requestEmailVerification: async (requestResetPasswordRequest, options = {}) => {
1294
- // verify required parameter 'requestResetPasswordRequest' is not null or undefined
1295
- assertParamExists('requestEmailVerification', 'requestResetPasswordRequest', requestResetPasswordRequest);
1319
+ requestEmailVerification: async (requestVerifyEmailRequest, options = {}) => {
1320
+ // verify required parameter 'requestVerifyEmailRequest' is not null or undefined
1321
+ assertParamExists('requestEmailVerification', 'requestVerifyEmailRequest', requestVerifyEmailRequest);
1296
1322
  const localVarPath = `/iam/v1/password/email/request_verification`;
1297
1323
  // use dummy base URL string because the URL constructor only accepts absolute URLs.
1298
1324
  const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@@ -1310,7 +1336,7 @@ const AuthenticationApiAxiosParamCreator = function (configuration) {
1310
1336
  setSearchParams(localVarUrlObj, localVarQueryParameter);
1311
1337
  let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
1312
1338
  localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
1313
- localVarRequestOptions.data = serializeDataIfNeeded(requestResetPasswordRequest, localVarRequestOptions, configuration);
1339
+ localVarRequestOptions.data = serializeDataIfNeeded(requestVerifyEmailRequest, localVarRequestOptions, configuration);
1314
1340
  return {
1315
1341
  url: toPathString(localVarUrlObj),
1316
1342
  options: localVarRequestOptions,
@@ -1511,13 +1537,13 @@ const AuthenticationApiAxiosParamCreator = function (configuration) {
1511
1537
  /**
1512
1538
  * Verify a player\'s email address.
1513
1539
  * @summary Verify an email.
1514
- * @param {ResetPasswordRequest} resetPasswordRequest
1540
+ * @param {VerifyEmailRequest} verifyEmailRequest
1515
1541
  * @param {*} [options] Override http request option.
1516
1542
  * @throws {RequiredError}
1517
1543
  */
1518
- verifyEmail: async (resetPasswordRequest, options = {}) => {
1519
- // verify required parameter 'resetPasswordRequest' is not null or undefined
1520
- assertParamExists('verifyEmail', 'resetPasswordRequest', resetPasswordRequest);
1544
+ verifyEmail: async (verifyEmailRequest, options = {}) => {
1545
+ // verify required parameter 'verifyEmailRequest' is not null or undefined
1546
+ assertParamExists('verifyEmail', 'verifyEmailRequest', verifyEmailRequest);
1521
1547
  const localVarPath = `/iam/v1/password/email/verify`;
1522
1548
  // use dummy base URL string because the URL constructor only accepts absolute URLs.
1523
1549
  const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@@ -1535,7 +1561,7 @@ const AuthenticationApiAxiosParamCreator = function (configuration) {
1535
1561
  setSearchParams(localVarUrlObj, localVarQueryParameter);
1536
1562
  let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
1537
1563
  localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
1538
- localVarRequestOptions.data = serializeDataIfNeeded(resetPasswordRequest, localVarRequestOptions, configuration);
1564
+ localVarRequestOptions.data = serializeDataIfNeeded(verifyEmailRequest, localVarRequestOptions, configuration);
1539
1565
  return {
1540
1566
  url: toPathString(localVarUrlObj),
1541
1567
  options: localVarRequestOptions,
@@ -1767,12 +1793,12 @@ const AuthenticationApiFp = function (configuration) {
1767
1793
  /**
1768
1794
  * Start the Email Verification process for a player.
1769
1795
  * @summary Request an Email Verification.
1770
- * @param {RequestResetPasswordRequest} requestResetPasswordRequest
1796
+ * @param {RequestVerifyEmailRequest} requestVerifyEmailRequest
1771
1797
  * @param {*} [options] Override http request option.
1772
1798
  * @throws {RequiredError}
1773
1799
  */
1774
- async requestEmailVerification(requestResetPasswordRequest, options) {
1775
- const localVarAxiosArgs = await localVarAxiosParamCreator.requestEmailVerification(requestResetPasswordRequest, options);
1800
+ async requestEmailVerification(requestVerifyEmailRequest, options) {
1801
+ const localVarAxiosArgs = await localVarAxiosParamCreator.requestEmailVerification(requestVerifyEmailRequest, options);
1776
1802
  return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
1777
1803
  },
1778
1804
  /**
@@ -1844,12 +1870,12 @@ const AuthenticationApiFp = function (configuration) {
1844
1870
  /**
1845
1871
  * Verify a player\'s email address.
1846
1872
  * @summary Verify an email.
1847
- * @param {ResetPasswordRequest} resetPasswordRequest
1873
+ * @param {VerifyEmailRequest} verifyEmailRequest
1848
1874
  * @param {*} [options] Override http request option.
1849
1875
  * @throws {RequiredError}
1850
1876
  */
1851
- async verifyEmail(resetPasswordRequest, options) {
1852
- const localVarAxiosArgs = await localVarAxiosParamCreator.verifyEmail(resetPasswordRequest, options);
1877
+ async verifyEmail(verifyEmailRequest, options) {
1878
+ const localVarAxiosArgs = await localVarAxiosParamCreator.verifyEmail(verifyEmailRequest, options);
1853
1879
  return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
1854
1880
  },
1855
1881
  /**
@@ -2036,7 +2062,7 @@ class AuthenticationApi extends BaseAPI {
2036
2062
  * @memberof AuthenticationApi
2037
2063
  */
2038
2064
  requestEmailVerification(requestParameters, options) {
2039
- return AuthenticationApiFp(this.configuration).requestEmailVerification(requestParameters.requestResetPasswordRequest, options).then((request) => request(this.axios, this.basePath));
2065
+ return AuthenticationApiFp(this.configuration).requestEmailVerification(requestParameters.requestVerifyEmailRequest, options).then((request) => request(this.axios, this.basePath));
2040
2066
  }
2041
2067
  /**
2042
2068
  * Start the Reset process for a player\'s password.
@@ -2113,7 +2139,7 @@ class AuthenticationApi extends BaseAPI {
2113
2139
  * @memberof AuthenticationApi
2114
2140
  */
2115
2141
  verifyEmail(requestParameters, options) {
2116
- return AuthenticationApiFp(this.configuration).verifyEmail(requestParameters.resetPasswordRequest, options).then((request) => request(this.axios, this.basePath));
2142
+ return AuthenticationApiFp(this.configuration).verifyEmail(requestParameters.verifyEmailRequest, options).then((request) => request(this.axios, this.basePath));
2117
2143
  }
2118
2144
  /**
2119
2145
  * The endpoint verifies the token generated by OAuth provider and retrieves a corresponding player. Returns the latest 10 transaction intents for the player.
@@ -4504,12 +4530,42 @@ var SignerType;
4504
4530
 
4505
4531
  const isBrowser = () => typeof document !== 'undefined';
4506
4532
 
4533
+ const KEY_PKCE_STATE = 'pkce_state';
4534
+ const KEY_PKCE_VERIFIER = 'pkce_verifier';
4535
+ class DeviceCredentialsManager {
4536
+ savePKCEData(data) {
4537
+ localStorage.setItem(KEY_PKCE_STATE, data.state);
4538
+ localStorage.setItem(KEY_PKCE_VERIFIER, data.verifier);
4539
+ }
4540
+ getPKCEData() {
4541
+ const state = localStorage.getItem(KEY_PKCE_STATE);
4542
+ const verifier = localStorage.getItem(KEY_PKCE_VERIFIER);
4543
+ if (state && verifier) {
4544
+ return { state, verifier };
4545
+ }
4546
+ return null;
4547
+ }
4548
+ }
4549
+
4550
+ function base64URLEncode(str) {
4551
+ return str.toString('base64')
4552
+ .replace(/\+/g, '-')
4553
+ .replace(/\//g, '_')
4554
+ .replace(/=/g, '');
4555
+ }
4556
+ function sha256(buffer) {
4557
+ return crypto__namespace.createHash('sha256').update(buffer).digest();
4558
+ }
4507
4559
  class AuthManager {
4508
4560
  config;
4561
+ deviceCredentialsManager;
4562
+ instanceManager;
4509
4563
  backendApiClients;
4510
- constructor(config, backendApiClients) {
4564
+ constructor(config, backendApiClients, instanceManager) {
4511
4565
  this.config = config;
4566
+ this.deviceCredentialsManager = new DeviceCredentialsManager();
4512
4567
  this.backendApiClients = backendApiClients;
4568
+ this.instanceManager = instanceManager;
4513
4569
  }
4514
4570
  async initOAuth(provider, usePooling, options) {
4515
4571
  const request = {
@@ -4520,7 +4576,7 @@ class AuthManager {
4520
4576
  },
4521
4577
  };
4522
4578
  const result = await this.backendApiClients.authenticationApi.initOAuth(request);
4523
- if (isBrowser() && !options?.skipBrowserRedirect) {
4579
+ if (isBrowser() && options?.skipBrowserRedirect) {
4524
4580
  window.location.assign(result.data.url);
4525
4581
  }
4526
4582
  return {
@@ -4557,6 +4613,13 @@ class AuthManager {
4557
4613
  // eslint-disable-next-line no-await-in-loop
4558
4614
  const response = await this.backendApiClients.authenticationApi.poolOAuth(request);
4559
4615
  if (response.status === 200) {
4616
+ this.instanceManager.setAccessToken({
4617
+ token: response.data.token,
4618
+ thirdPartyProvider: null,
4619
+ thirdPartyTokenType: null,
4620
+ });
4621
+ this.instanceManager.setRefreshToken(response.data.refreshToken);
4622
+ this.instanceManager.setPlayerID(response.data.player.id);
4560
4623
  return response.data;
4561
4624
  }
4562
4625
  }
@@ -4573,7 +4636,7 @@ class AuthManager {
4573
4636
  }
4574
4637
  throw new Error('Failed to pool OAuth, try again later');
4575
4638
  }
4576
- // Deprecated
4639
+ // @deprecated
4577
4640
  async authenticateOAuth(provider, token, tokenType) {
4578
4641
  const request = {
4579
4642
  authenticateOAuthRequest: {
@@ -4631,6 +4694,83 @@ class AuthManager {
4631
4694
  const response = await this.backendApiClients.authenticationApi.loginEmailPassword(request);
4632
4695
  return response.data;
4633
4696
  }
4697
+ async requestResetPassword(email, redirectUrl) {
4698
+ const verifier = base64URLEncode(crypto__namespace.randomBytes(32));
4699
+ const challenge = base64URLEncode(sha256(verifier));
4700
+ // https://auth0.com/docs/secure/attack-protection/state-parameters
4701
+ const state = base64URLEncode(crypto__namespace.randomBytes(32));
4702
+ this.deviceCredentialsManager.savePKCEData({ state, verifier });
4703
+ const request = {
4704
+ requestResetPasswordRequest: {
4705
+ email,
4706
+ redirectUrl,
4707
+ challenge: {
4708
+ codeChallenge: challenge,
4709
+ method: CodeChallengeMethodEnum.S256,
4710
+ },
4711
+ },
4712
+ };
4713
+ await this.backendApiClients.authenticationApi.requestResetPassword(request);
4714
+ }
4715
+ async resetPassword(email, password, state) {
4716
+ const pkceData = this.deviceCredentialsManager.getPKCEData();
4717
+ if (!pkceData) {
4718
+ throw new Error('No code verifier or state for PKCE');
4719
+ }
4720
+ if (state !== pkceData.state) {
4721
+ throw new Error('Provided state does not match stored state');
4722
+ }
4723
+ const request = {
4724
+ resetPasswordRequest: {
4725
+ email,
4726
+ password,
4727
+ state,
4728
+ challenge: {
4729
+ codeVerifier: pkceData.verifier,
4730
+ method: CodeChallengeMethodEnum.S256,
4731
+ },
4732
+ },
4733
+ };
4734
+ await this.backendApiClients.authenticationApi.resetPassword(request);
4735
+ }
4736
+ async requestEmailVerification(email, redirectUrl) {
4737
+ const verifier = base64URLEncode(crypto__namespace.randomBytes(32));
4738
+ const challenge = base64URLEncode(sha256(verifier));
4739
+ // https://auth0.com/docs/secure/attack-protection/state-parameters
4740
+ const state = base64URLEncode(crypto__namespace.randomBytes(32));
4741
+ this.deviceCredentialsManager.savePKCEData({ state, verifier });
4742
+ const request = {
4743
+ requestVerifyEmailRequest: {
4744
+ email,
4745
+ redirectUrl,
4746
+ challenge: {
4747
+ codeChallenge: challenge,
4748
+ method: CodeChallengeMethodEnum.S256,
4749
+ },
4750
+ },
4751
+ };
4752
+ await this.backendApiClients.authenticationApi.requestEmailVerification(request);
4753
+ }
4754
+ async verifyEmail(email, state) {
4755
+ const pkceData = this.deviceCredentialsManager.getPKCEData();
4756
+ if (!pkceData) {
4757
+ throw new Error('No code verifier or state for PKCE');
4758
+ }
4759
+ if (state !== pkceData.state) {
4760
+ throw new Error('Provided state does not match stored state');
4761
+ }
4762
+ const request = {
4763
+ verifyEmailRequest: {
4764
+ email,
4765
+ token: state,
4766
+ challenge: {
4767
+ codeVerifier: pkceData.verifier,
4768
+ method: CodeChallengeMethodEnum.S256,
4769
+ },
4770
+ },
4771
+ };
4772
+ await this.backendApiClients.authenticationApi.verifyEmail(request);
4773
+ }
4634
4774
  async signupEmailPassword(email, password, name) {
4635
4775
  const request = {
4636
4776
  signupRequest: {
@@ -4642,23 +4782,6 @@ class AuthManager {
4642
4782
  const response = await this.backendApiClients.authenticationApi.signupEmailPassword(request);
4643
4783
  return response.data;
4644
4784
  }
4645
- async getJWK() {
4646
- const request = {
4647
- publishableKey: this.config.baseConfiguration.publishableKey,
4648
- };
4649
- const response = await this.backendApiClients.authenticationApi.getJwks(request);
4650
- if (response.data.keys.length === 0) {
4651
- throw new Error('No keys found');
4652
- }
4653
- const jwtKey = response.data.keys[0];
4654
- return {
4655
- kty: jwtKey.kty,
4656
- crv: jwtKey.crv,
4657
- x: jwtKey.x,
4658
- y: jwtKey.y,
4659
- alg: jwtKey.alg,
4660
- };
4661
- }
4662
4785
  async validateCredentials(accessToken, refreshToken, jwk) {
4663
4786
  try {
4664
4787
  const key = (await jose.importJWK({
@@ -4721,7 +4844,6 @@ const accountTypeStorageKey = 'openfort.account_type';
4721
4844
  const accountAddressStorageKey = 'openfort.account_address';
4722
4845
 
4723
4846
  class InstanceManager {
4724
- authManager;
4725
4847
  authToken = null;
4726
4848
  refreshToken = null;
4727
4849
  signerType = null;
@@ -4734,12 +4856,15 @@ class InstanceManager {
4734
4856
  temporalStorage;
4735
4857
  persistentStorage;
4736
4858
  secureStorage;
4859
+ config;
4860
+ backendApiClients;
4737
4861
  playerId = null;
4738
- constructor(temporalStorage, persistentStorage, secureStorage, authManager) {
4862
+ constructor(temporalStorage, persistentStorage, secureStorage, config, backendApiClients) {
4739
4863
  this.temporalStorage = temporalStorage;
4740
4864
  this.persistentStorage = persistentStorage;
4741
4865
  this.secureStorage = secureStorage;
4742
- this.authManager = authManager;
4866
+ this.config = config;
4867
+ this.backendApiClients = backendApiClients;
4743
4868
  }
4744
4869
  getAccessToken() {
4745
4870
  if (!this.authToken) {
@@ -4851,7 +4976,21 @@ class InstanceManager {
4851
4976
  }
4852
4977
  }
4853
4978
  if (!this.jwk) {
4854
- this.jwk = await this.authManager.getJWK();
4979
+ const request = {
4980
+ publishableKey: this.config.baseConfiguration.publishableKey,
4981
+ };
4982
+ const response = await this.backendApiClients.authenticationApi.getJwks(request);
4983
+ if (response.data.keys.length === 0) {
4984
+ throw new Error('No keys found');
4985
+ }
4986
+ const jwtKey = response.data.keys[0];
4987
+ this.jwk = {
4988
+ kty: jwtKey.kty,
4989
+ crv: jwtKey.crv,
4990
+ x: jwtKey.x,
4991
+ y: jwtKey.y,
4992
+ alg: jwtKey.alg,
4993
+ };
4855
4994
  }
4856
4995
  return this.jwk;
4857
4996
  }
@@ -5545,15 +5684,15 @@ class Openfort {
5545
5684
  signer;
5546
5685
  authManager;
5547
5686
  config;
5548
- instanceManager;
5549
5687
  backendApiClients;
5688
+ instanceManager;
5550
5689
  iframeManager;
5551
5690
  openfortEventEmitter;
5552
5691
  constructor(sdkConfiguration) {
5553
5692
  this.config = new SDKConfiguration(sdkConfiguration);
5554
5693
  this.backendApiClients = new BackendApiClients(this.config.openfortAPIConfig);
5555
- this.authManager = new AuthManager(this.config, this.backendApiClients);
5556
- this.instanceManager = new InstanceManager(new SessionStorage(), new LocalStorage(), new LocalStorage(), this.authManager);
5694
+ this.instanceManager = new InstanceManager(new SessionStorage(), new LocalStorage(), new LocalStorage(), this.config, this.backendApiClients);
5695
+ this.authManager = new AuthManager(this.config, this.backendApiClients, this.instanceManager);
5557
5696
  this.openfortEventEmitter = new TypedEventEmitter();
5558
5697
  this.iframeManager = new IframeManager(this.config);
5559
5698
  }
@@ -5690,8 +5829,21 @@ class Openfort {
5690
5829
  });
5691
5830
  return result;
5692
5831
  }
5832
+ async requestEmailVerification(email, redirectUrl) {
5833
+ await this.authManager.requestEmailVerification(email, redirectUrl);
5834
+ }
5835
+ async resetPassword(email, password, state) {
5836
+ await this.authManager.resetPassword(email, password, state);
5837
+ }
5838
+ async requestResetPassword(email, redirectUrl) {
5839
+ await this.authManager.requestResetPassword(email, redirectUrl);
5840
+ }
5841
+ async verifyEmail(email, state) {
5842
+ await this.authManager.verifyEmail(email, state);
5843
+ }
5693
5844
  async initOAuth(provider, usePooling, options) {
5694
- return await this.authManager.initOAuth(provider, usePooling, options);
5845
+ const authResponse = await this.authManager.initOAuth(provider, usePooling, options);
5846
+ return authResponse;
5695
5847
  }
5696
5848
  async initLinkOAuth(provider, playerToken, usePooling, options) {
5697
5849
  return await this.authManager.initLinkOAuth(provider, playerToken, usePooling, options);
@@ -5699,6 +5851,7 @@ class Openfort {
5699
5851
  async poolOAuth(key) {
5700
5852
  return await this.authManager.poolOAuth(key);
5701
5853
  }
5854
+ // @deprecated
5702
5855
  async authenticateWithOAuth(provider, token, tokenType) {
5703
5856
  this.instanceManager.removeAccessToken();
5704
5857
  this.instanceManager.removeRefreshToken();
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { SessionKey, AuthResponse, OAuthProvider as OAuthProvider$1, InitializeOAuthOptions as InitializeOAuthOptions$1, InitAuthResponse, TokenType as TokenType$1, SIWEInitResponse, ThirdPartyOAuthProvider as ThirdPartyOAuthProvider$1, AuthPlayerResponse as AuthPlayerResponse$1, TransactionIntentResponse as TransactionIntentResponse$1, SessionResponse as SessionResponse$1, EmbeddedState as EmbeddedState$1, SDKOverrides as SDKOverrides$1 } from 'types';
1
+ import { SessionKey, AuthResponse, OAuthProvider as OAuthProvider$1, InitializeOAuthOptions as InitializeOAuthOptions$1, InitAuthResponse, TokenType as TokenType$1, SIWEInitResponse, ThirdPartyOAuthProvider as ThirdPartyOAuthProvider$1, AuthPlayerResponse as AuthPlayerResponse$1, Auth, TransactionIntentResponse as TransactionIntentResponse$1, SessionResponse as SessionResponse$1, EmbeddedState as EmbeddedState$1, SDKOverrides as SDKOverrides$1 } from 'types';
2
2
  import { SDKConfiguration as SDKConfiguration$1 } from 'config';
3
3
  import { Provider as Provider$1 } from 'evm/types';
4
4
 
@@ -71,8 +71,8 @@ declare class Openfort {
71
71
  private signer?;
72
72
  private readonly authManager;
73
73
  private readonly config;
74
- private readonly instanceManager;
75
74
  private readonly backendApiClients;
75
+ private readonly instanceManager;
76
76
  private readonly iframeManager;
77
77
  private readonly openfortEventEmitter;
78
78
  constructor(sdkConfiguration: SDKConfiguration$1);
@@ -87,6 +87,10 @@ declare class Openfort {
87
87
  private newEmbeddedSigner;
88
88
  loginWithEmailPassword(email: string, password: string): Promise<AuthResponse>;
89
89
  signUpWithEmailPassword(email: string, password: string, name?: string): Promise<AuthResponse>;
90
+ requestEmailVerification(email: string, redirectUrl: string): Promise<void>;
91
+ resetPassword(email: string, password: string, state: string): Promise<void>;
92
+ requestResetPassword(email: string, redirectUrl: string): Promise<void>;
93
+ verifyEmail(email: string, state: string): Promise<void>;
90
94
  initOAuth(provider: OAuthProvider$1, usePooling?: boolean, options?: InitializeOAuthOptions$1): Promise<InitAuthResponse>;
91
95
  initLinkOAuth(provider: OAuthProvider$1, playerToken: string, usePooling?: boolean, options?: InitializeOAuthOptions$1): Promise<InitAuthResponse>;
92
96
  poolOAuth(key: string): Promise<AuthResponse>;
@@ -94,7 +98,7 @@ declare class Openfort {
94
98
  initSIWE(address: string): Promise<SIWEInitResponse>;
95
99
  authenticateWithThirdPartyProvider(provider: ThirdPartyOAuthProvider$1, token: string, tokenType: TokenType$1): Promise<AuthPlayerResponse$1>;
96
100
  authenticateWithSIWE(signature: string, message: string, walletClientType: string, connectorType: string): Promise<AuthResponse>;
97
- private storeCredentials;
101
+ storeCredentials(auth: Auth): void;
98
102
  sendSignatureTransactionIntentRequest(transactionIntentId: string, userOperationHash?: string | null, signature?: string | null): Promise<TransactionIntentResponse$1>;
99
103
  signMessage(message: string | Uint8Array): Promise<string>;
100
104
  signTypedData(domain: TypedDataDomain, types: Record<string, Array<TypedDataField>>, value: Record<string, any>): Promise<string>;
@@ -106,7 +110,7 @@ declare class Openfort {
106
110
  isAuthenticated(): Promise<boolean>;
107
111
  getAccessToken(): string | null;
108
112
  isLoaded(): boolean;
109
- private validateAndRefreshToken;
113
+ validateAndRefreshToken(): Promise<void>;
110
114
  }
111
115
 
112
116
  declare enum ShieldAuthProvider {
@@ -176,11 +180,13 @@ declare const AUTH_PROVIDER: {
176
180
  readonly supabase: "supabase";
177
181
  readonly custom: "custom";
178
182
  readonly oidc: "oidc";
183
+ readonly facebook: "facebook";
179
184
  };
180
185
  type AuthProvider = typeof AUTH_PROVIDER[keyof typeof AUTH_PROVIDER];
181
186
  declare enum OAuthProvider {
182
187
  GOOGLE = "google",
183
- TWITTER = "twitter"
188
+ TWITTER = "twitter",
189
+ FACEBOOK = "facebook"
184
190
  }
185
191
  interface NextActionPayload {
186
192
  'userOp'?: any;
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ import { hexlify, joinSignature, arrayify } from '@ethersproject/bytes';
5
5
  import { EventEmitter } from 'events';
6
6
  import { v4 } from 'uuid';
7
7
  import { importJWK, jwtVerify, errors } from 'jose';
8
+ import * as crypto from 'crypto';
8
9
  import { secp256k1 } from '@noble/curves/secp256k1';
9
10
  import { SigningKey } from '@ethersproject/signing-key';
10
11
  import { computeAddress } from '@ethersproject/transactions';
@@ -55,7 +56,13 @@ var OAuthProvider;
55
56
  (function (OAuthProvider) {
56
57
  OAuthProvider["GOOGLE"] = "google";
57
58
  OAuthProvider["TWITTER"] = "twitter";
59
+ OAuthProvider["FACEBOOK"] = "facebook";
58
60
  })(OAuthProvider || (OAuthProvider = {}));
61
+ var CodeChallengeMethodEnum;
62
+ (function (CodeChallengeMethodEnum) {
63
+ CodeChallengeMethodEnum["PLAIN"] = "plain";
64
+ CodeChallengeMethodEnum["S256"] = "S256";
65
+ })(CodeChallengeMethodEnum || (CodeChallengeMethodEnum = {}));
59
66
 
60
67
  /* tslint:disable */
61
68
  /* eslint-disable */
@@ -1282,13 +1289,13 @@ const AuthenticationApiAxiosParamCreator = function (configuration) {
1282
1289
  /**
1283
1290
  * Start the Email Verification process for a player.
1284
1291
  * @summary Request an Email Verification.
1285
- * @param {RequestResetPasswordRequest} requestResetPasswordRequest
1292
+ * @param {RequestVerifyEmailRequest} requestVerifyEmailRequest
1286
1293
  * @param {*} [options] Override http request option.
1287
1294
  * @throws {RequiredError}
1288
1295
  */
1289
- requestEmailVerification: async (requestResetPasswordRequest, options = {}) => {
1290
- // verify required parameter 'requestResetPasswordRequest' is not null or undefined
1291
- assertParamExists('requestEmailVerification', 'requestResetPasswordRequest', requestResetPasswordRequest);
1296
+ requestEmailVerification: async (requestVerifyEmailRequest, options = {}) => {
1297
+ // verify required parameter 'requestVerifyEmailRequest' is not null or undefined
1298
+ assertParamExists('requestEmailVerification', 'requestVerifyEmailRequest', requestVerifyEmailRequest);
1292
1299
  const localVarPath = `/iam/v1/password/email/request_verification`;
1293
1300
  // use dummy base URL string because the URL constructor only accepts absolute URLs.
1294
1301
  const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@@ -1306,7 +1313,7 @@ const AuthenticationApiAxiosParamCreator = function (configuration) {
1306
1313
  setSearchParams(localVarUrlObj, localVarQueryParameter);
1307
1314
  let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
1308
1315
  localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
1309
- localVarRequestOptions.data = serializeDataIfNeeded(requestResetPasswordRequest, localVarRequestOptions, configuration);
1316
+ localVarRequestOptions.data = serializeDataIfNeeded(requestVerifyEmailRequest, localVarRequestOptions, configuration);
1310
1317
  return {
1311
1318
  url: toPathString(localVarUrlObj),
1312
1319
  options: localVarRequestOptions,
@@ -1507,13 +1514,13 @@ const AuthenticationApiAxiosParamCreator = function (configuration) {
1507
1514
  /**
1508
1515
  * Verify a player\'s email address.
1509
1516
  * @summary Verify an email.
1510
- * @param {ResetPasswordRequest} resetPasswordRequest
1517
+ * @param {VerifyEmailRequest} verifyEmailRequest
1511
1518
  * @param {*} [options] Override http request option.
1512
1519
  * @throws {RequiredError}
1513
1520
  */
1514
- verifyEmail: async (resetPasswordRequest, options = {}) => {
1515
- // verify required parameter 'resetPasswordRequest' is not null or undefined
1516
- assertParamExists('verifyEmail', 'resetPasswordRequest', resetPasswordRequest);
1521
+ verifyEmail: async (verifyEmailRequest, options = {}) => {
1522
+ // verify required parameter 'verifyEmailRequest' is not null or undefined
1523
+ assertParamExists('verifyEmail', 'verifyEmailRequest', verifyEmailRequest);
1517
1524
  const localVarPath = `/iam/v1/password/email/verify`;
1518
1525
  // use dummy base URL string because the URL constructor only accepts absolute URLs.
1519
1526
  const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@@ -1531,7 +1538,7 @@ const AuthenticationApiAxiosParamCreator = function (configuration) {
1531
1538
  setSearchParams(localVarUrlObj, localVarQueryParameter);
1532
1539
  let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
1533
1540
  localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
1534
- localVarRequestOptions.data = serializeDataIfNeeded(resetPasswordRequest, localVarRequestOptions, configuration);
1541
+ localVarRequestOptions.data = serializeDataIfNeeded(verifyEmailRequest, localVarRequestOptions, configuration);
1535
1542
  return {
1536
1543
  url: toPathString(localVarUrlObj),
1537
1544
  options: localVarRequestOptions,
@@ -1763,12 +1770,12 @@ const AuthenticationApiFp = function (configuration) {
1763
1770
  /**
1764
1771
  * Start the Email Verification process for a player.
1765
1772
  * @summary Request an Email Verification.
1766
- * @param {RequestResetPasswordRequest} requestResetPasswordRequest
1773
+ * @param {RequestVerifyEmailRequest} requestVerifyEmailRequest
1767
1774
  * @param {*} [options] Override http request option.
1768
1775
  * @throws {RequiredError}
1769
1776
  */
1770
- async requestEmailVerification(requestResetPasswordRequest, options) {
1771
- const localVarAxiosArgs = await localVarAxiosParamCreator.requestEmailVerification(requestResetPasswordRequest, options);
1777
+ async requestEmailVerification(requestVerifyEmailRequest, options) {
1778
+ const localVarAxiosArgs = await localVarAxiosParamCreator.requestEmailVerification(requestVerifyEmailRequest, options);
1772
1779
  return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
1773
1780
  },
1774
1781
  /**
@@ -1840,12 +1847,12 @@ const AuthenticationApiFp = function (configuration) {
1840
1847
  /**
1841
1848
  * Verify a player\'s email address.
1842
1849
  * @summary Verify an email.
1843
- * @param {ResetPasswordRequest} resetPasswordRequest
1850
+ * @param {VerifyEmailRequest} verifyEmailRequest
1844
1851
  * @param {*} [options] Override http request option.
1845
1852
  * @throws {RequiredError}
1846
1853
  */
1847
- async verifyEmail(resetPasswordRequest, options) {
1848
- const localVarAxiosArgs = await localVarAxiosParamCreator.verifyEmail(resetPasswordRequest, options);
1854
+ async verifyEmail(verifyEmailRequest, options) {
1855
+ const localVarAxiosArgs = await localVarAxiosParamCreator.verifyEmail(verifyEmailRequest, options);
1849
1856
  return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
1850
1857
  },
1851
1858
  /**
@@ -2032,7 +2039,7 @@ class AuthenticationApi extends BaseAPI {
2032
2039
  * @memberof AuthenticationApi
2033
2040
  */
2034
2041
  requestEmailVerification(requestParameters, options) {
2035
- return AuthenticationApiFp(this.configuration).requestEmailVerification(requestParameters.requestResetPasswordRequest, options).then((request) => request(this.axios, this.basePath));
2042
+ return AuthenticationApiFp(this.configuration).requestEmailVerification(requestParameters.requestVerifyEmailRequest, options).then((request) => request(this.axios, this.basePath));
2036
2043
  }
2037
2044
  /**
2038
2045
  * Start the Reset process for a player\'s password.
@@ -2109,7 +2116,7 @@ class AuthenticationApi extends BaseAPI {
2109
2116
  * @memberof AuthenticationApi
2110
2117
  */
2111
2118
  verifyEmail(requestParameters, options) {
2112
- return AuthenticationApiFp(this.configuration).verifyEmail(requestParameters.resetPasswordRequest, options).then((request) => request(this.axios, this.basePath));
2119
+ return AuthenticationApiFp(this.configuration).verifyEmail(requestParameters.verifyEmailRequest, options).then((request) => request(this.axios, this.basePath));
2113
2120
  }
2114
2121
  /**
2115
2122
  * The endpoint verifies the token generated by OAuth provider and retrieves a corresponding player. Returns the latest 10 transaction intents for the player.
@@ -4500,12 +4507,42 @@ var SignerType;
4500
4507
 
4501
4508
  const isBrowser = () => typeof document !== 'undefined';
4502
4509
 
4510
+ const KEY_PKCE_STATE = 'pkce_state';
4511
+ const KEY_PKCE_VERIFIER = 'pkce_verifier';
4512
+ class DeviceCredentialsManager {
4513
+ savePKCEData(data) {
4514
+ localStorage.setItem(KEY_PKCE_STATE, data.state);
4515
+ localStorage.setItem(KEY_PKCE_VERIFIER, data.verifier);
4516
+ }
4517
+ getPKCEData() {
4518
+ const state = localStorage.getItem(KEY_PKCE_STATE);
4519
+ const verifier = localStorage.getItem(KEY_PKCE_VERIFIER);
4520
+ if (state && verifier) {
4521
+ return { state, verifier };
4522
+ }
4523
+ return null;
4524
+ }
4525
+ }
4526
+
4527
+ function base64URLEncode(str) {
4528
+ return str.toString('base64')
4529
+ .replace(/\+/g, '-')
4530
+ .replace(/\//g, '_')
4531
+ .replace(/=/g, '');
4532
+ }
4533
+ function sha256(buffer) {
4534
+ return crypto.createHash('sha256').update(buffer).digest();
4535
+ }
4503
4536
  class AuthManager {
4504
4537
  config;
4538
+ deviceCredentialsManager;
4539
+ instanceManager;
4505
4540
  backendApiClients;
4506
- constructor(config, backendApiClients) {
4541
+ constructor(config, backendApiClients, instanceManager) {
4507
4542
  this.config = config;
4543
+ this.deviceCredentialsManager = new DeviceCredentialsManager();
4508
4544
  this.backendApiClients = backendApiClients;
4545
+ this.instanceManager = instanceManager;
4509
4546
  }
4510
4547
  async initOAuth(provider, usePooling, options) {
4511
4548
  const request = {
@@ -4516,7 +4553,7 @@ class AuthManager {
4516
4553
  },
4517
4554
  };
4518
4555
  const result = await this.backendApiClients.authenticationApi.initOAuth(request);
4519
- if (isBrowser() && !options?.skipBrowserRedirect) {
4556
+ if (isBrowser() && options?.skipBrowserRedirect) {
4520
4557
  window.location.assign(result.data.url);
4521
4558
  }
4522
4559
  return {
@@ -4553,6 +4590,13 @@ class AuthManager {
4553
4590
  // eslint-disable-next-line no-await-in-loop
4554
4591
  const response = await this.backendApiClients.authenticationApi.poolOAuth(request);
4555
4592
  if (response.status === 200) {
4593
+ this.instanceManager.setAccessToken({
4594
+ token: response.data.token,
4595
+ thirdPartyProvider: null,
4596
+ thirdPartyTokenType: null,
4597
+ });
4598
+ this.instanceManager.setRefreshToken(response.data.refreshToken);
4599
+ this.instanceManager.setPlayerID(response.data.player.id);
4556
4600
  return response.data;
4557
4601
  }
4558
4602
  }
@@ -4569,7 +4613,7 @@ class AuthManager {
4569
4613
  }
4570
4614
  throw new Error('Failed to pool OAuth, try again later');
4571
4615
  }
4572
- // Deprecated
4616
+ // @deprecated
4573
4617
  async authenticateOAuth(provider, token, tokenType) {
4574
4618
  const request = {
4575
4619
  authenticateOAuthRequest: {
@@ -4627,6 +4671,83 @@ class AuthManager {
4627
4671
  const response = await this.backendApiClients.authenticationApi.loginEmailPassword(request);
4628
4672
  return response.data;
4629
4673
  }
4674
+ async requestResetPassword(email, redirectUrl) {
4675
+ const verifier = base64URLEncode(crypto.randomBytes(32));
4676
+ const challenge = base64URLEncode(sha256(verifier));
4677
+ // https://auth0.com/docs/secure/attack-protection/state-parameters
4678
+ const state = base64URLEncode(crypto.randomBytes(32));
4679
+ this.deviceCredentialsManager.savePKCEData({ state, verifier });
4680
+ const request = {
4681
+ requestResetPasswordRequest: {
4682
+ email,
4683
+ redirectUrl,
4684
+ challenge: {
4685
+ codeChallenge: challenge,
4686
+ method: CodeChallengeMethodEnum.S256,
4687
+ },
4688
+ },
4689
+ };
4690
+ await this.backendApiClients.authenticationApi.requestResetPassword(request);
4691
+ }
4692
+ async resetPassword(email, password, state) {
4693
+ const pkceData = this.deviceCredentialsManager.getPKCEData();
4694
+ if (!pkceData) {
4695
+ throw new Error('No code verifier or state for PKCE');
4696
+ }
4697
+ if (state !== pkceData.state) {
4698
+ throw new Error('Provided state does not match stored state');
4699
+ }
4700
+ const request = {
4701
+ resetPasswordRequest: {
4702
+ email,
4703
+ password,
4704
+ state,
4705
+ challenge: {
4706
+ codeVerifier: pkceData.verifier,
4707
+ method: CodeChallengeMethodEnum.S256,
4708
+ },
4709
+ },
4710
+ };
4711
+ await this.backendApiClients.authenticationApi.resetPassword(request);
4712
+ }
4713
+ async requestEmailVerification(email, redirectUrl) {
4714
+ const verifier = base64URLEncode(crypto.randomBytes(32));
4715
+ const challenge = base64URLEncode(sha256(verifier));
4716
+ // https://auth0.com/docs/secure/attack-protection/state-parameters
4717
+ const state = base64URLEncode(crypto.randomBytes(32));
4718
+ this.deviceCredentialsManager.savePKCEData({ state, verifier });
4719
+ const request = {
4720
+ requestVerifyEmailRequest: {
4721
+ email,
4722
+ redirectUrl,
4723
+ challenge: {
4724
+ codeChallenge: challenge,
4725
+ method: CodeChallengeMethodEnum.S256,
4726
+ },
4727
+ },
4728
+ };
4729
+ await this.backendApiClients.authenticationApi.requestEmailVerification(request);
4730
+ }
4731
+ async verifyEmail(email, state) {
4732
+ const pkceData = this.deviceCredentialsManager.getPKCEData();
4733
+ if (!pkceData) {
4734
+ throw new Error('No code verifier or state for PKCE');
4735
+ }
4736
+ if (state !== pkceData.state) {
4737
+ throw new Error('Provided state does not match stored state');
4738
+ }
4739
+ const request = {
4740
+ verifyEmailRequest: {
4741
+ email,
4742
+ token: state,
4743
+ challenge: {
4744
+ codeVerifier: pkceData.verifier,
4745
+ method: CodeChallengeMethodEnum.S256,
4746
+ },
4747
+ },
4748
+ };
4749
+ await this.backendApiClients.authenticationApi.verifyEmail(request);
4750
+ }
4630
4751
  async signupEmailPassword(email, password, name) {
4631
4752
  const request = {
4632
4753
  signupRequest: {
@@ -4638,23 +4759,6 @@ class AuthManager {
4638
4759
  const response = await this.backendApiClients.authenticationApi.signupEmailPassword(request);
4639
4760
  return response.data;
4640
4761
  }
4641
- async getJWK() {
4642
- const request = {
4643
- publishableKey: this.config.baseConfiguration.publishableKey,
4644
- };
4645
- const response = await this.backendApiClients.authenticationApi.getJwks(request);
4646
- if (response.data.keys.length === 0) {
4647
- throw new Error('No keys found');
4648
- }
4649
- const jwtKey = response.data.keys[0];
4650
- return {
4651
- kty: jwtKey.kty,
4652
- crv: jwtKey.crv,
4653
- x: jwtKey.x,
4654
- y: jwtKey.y,
4655
- alg: jwtKey.alg,
4656
- };
4657
- }
4658
4762
  async validateCredentials(accessToken, refreshToken, jwk) {
4659
4763
  try {
4660
4764
  const key = (await importJWK({
@@ -4717,7 +4821,6 @@ const accountTypeStorageKey = 'openfort.account_type';
4717
4821
  const accountAddressStorageKey = 'openfort.account_address';
4718
4822
 
4719
4823
  class InstanceManager {
4720
- authManager;
4721
4824
  authToken = null;
4722
4825
  refreshToken = null;
4723
4826
  signerType = null;
@@ -4730,12 +4833,15 @@ class InstanceManager {
4730
4833
  temporalStorage;
4731
4834
  persistentStorage;
4732
4835
  secureStorage;
4836
+ config;
4837
+ backendApiClients;
4733
4838
  playerId = null;
4734
- constructor(temporalStorage, persistentStorage, secureStorage, authManager) {
4839
+ constructor(temporalStorage, persistentStorage, secureStorage, config, backendApiClients) {
4735
4840
  this.temporalStorage = temporalStorage;
4736
4841
  this.persistentStorage = persistentStorage;
4737
4842
  this.secureStorage = secureStorage;
4738
- this.authManager = authManager;
4843
+ this.config = config;
4844
+ this.backendApiClients = backendApiClients;
4739
4845
  }
4740
4846
  getAccessToken() {
4741
4847
  if (!this.authToken) {
@@ -4847,7 +4953,21 @@ class InstanceManager {
4847
4953
  }
4848
4954
  }
4849
4955
  if (!this.jwk) {
4850
- this.jwk = await this.authManager.getJWK();
4956
+ const request = {
4957
+ publishableKey: this.config.baseConfiguration.publishableKey,
4958
+ };
4959
+ const response = await this.backendApiClients.authenticationApi.getJwks(request);
4960
+ if (response.data.keys.length === 0) {
4961
+ throw new Error('No keys found');
4962
+ }
4963
+ const jwtKey = response.data.keys[0];
4964
+ this.jwk = {
4965
+ kty: jwtKey.kty,
4966
+ crv: jwtKey.crv,
4967
+ x: jwtKey.x,
4968
+ y: jwtKey.y,
4969
+ alg: jwtKey.alg,
4970
+ };
4851
4971
  }
4852
4972
  return this.jwk;
4853
4973
  }
@@ -5541,15 +5661,15 @@ class Openfort {
5541
5661
  signer;
5542
5662
  authManager;
5543
5663
  config;
5544
- instanceManager;
5545
5664
  backendApiClients;
5665
+ instanceManager;
5546
5666
  iframeManager;
5547
5667
  openfortEventEmitter;
5548
5668
  constructor(sdkConfiguration) {
5549
5669
  this.config = new SDKConfiguration(sdkConfiguration);
5550
5670
  this.backendApiClients = new BackendApiClients(this.config.openfortAPIConfig);
5551
- this.authManager = new AuthManager(this.config, this.backendApiClients);
5552
- this.instanceManager = new InstanceManager(new SessionStorage(), new LocalStorage(), new LocalStorage(), this.authManager);
5671
+ this.instanceManager = new InstanceManager(new SessionStorage(), new LocalStorage(), new LocalStorage(), this.config, this.backendApiClients);
5672
+ this.authManager = new AuthManager(this.config, this.backendApiClients, this.instanceManager);
5553
5673
  this.openfortEventEmitter = new TypedEventEmitter();
5554
5674
  this.iframeManager = new IframeManager(this.config);
5555
5675
  }
@@ -5686,8 +5806,21 @@ class Openfort {
5686
5806
  });
5687
5807
  return result;
5688
5808
  }
5809
+ async requestEmailVerification(email, redirectUrl) {
5810
+ await this.authManager.requestEmailVerification(email, redirectUrl);
5811
+ }
5812
+ async resetPassword(email, password, state) {
5813
+ await this.authManager.resetPassword(email, password, state);
5814
+ }
5815
+ async requestResetPassword(email, redirectUrl) {
5816
+ await this.authManager.requestResetPassword(email, redirectUrl);
5817
+ }
5818
+ async verifyEmail(email, state) {
5819
+ await this.authManager.verifyEmail(email, state);
5820
+ }
5689
5821
  async initOAuth(provider, usePooling, options) {
5690
- return await this.authManager.initOAuth(provider, usePooling, options);
5822
+ const authResponse = await this.authManager.initOAuth(provider, usePooling, options);
5823
+ return authResponse;
5691
5824
  }
5692
5825
  async initLinkOAuth(provider, playerToken, usePooling, options) {
5693
5826
  return await this.authManager.initLinkOAuth(provider, playerToken, usePooling, options);
@@ -5695,6 +5828,7 @@ class Openfort {
5695
5828
  async poolOAuth(key) {
5696
5829
  return await this.authManager.poolOAuth(key);
5697
5830
  }
5831
+ // @deprecated
5698
5832
  async authenticateWithOAuth(provider, token, tokenType) {
5699
5833
  this.instanceManager.removeAccessToken();
5700
5834
  this.instanceManager.removeRefreshToken();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfort/openfort-js",
3
- "version": "0.7.3",
3
+ "version": "0.7.5",
4
4
  "author": "Openfort (https://www.openfort.xyz)",
5
5
  "bugs": "https://github.com/openfort-xyz/openfort-js/issues",
6
6
  "repository": "openfort-xyz/openfort-js.git",