@openfort/openfort-js 1.1.4 → 1.1.6
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/cjs/sdk/src/api/embeddedWallet.cjs +1 -1
- package/dist/cjs/sdk/src/core/config/config.cjs +1 -1
- package/dist/cjs/sdk/src/core/openfort.cjs +1 -1
- package/dist/cjs/sdk/src/core/passkey/errors.cjs +1 -0
- package/dist/cjs/sdk/src/core/passkey/handler.cjs +1 -0
- package/dist/cjs/sdk/src/core/passkey/utils.cjs +1 -0
- package/dist/cjs/sdk/src/index.cjs +1 -1
- package/dist/cjs/sdk/src/version.cjs +1 -1
- package/dist/cjs/sdk/src/wallets/embedded.cjs +1 -1
- package/dist/index.d.cts +175 -51
- package/dist/index.d.ts +175 -51
- package/dist/sdk/src/api/embeddedWallet.js +1 -1
- package/dist/sdk/src/core/config/config.js +1 -1
- package/dist/sdk/src/core/openfort.js +1 -1
- package/dist/sdk/src/core/passkey/errors.js +1 -0
- package/dist/sdk/src/core/passkey/handler.js +1 -0
- package/dist/sdk/src/core/passkey/utils.js +1 -0
- package/dist/sdk/src/index.js +1 -1
- package/dist/sdk/src/version.js +1 -1
- package/dist/sdk/src/wallets/embedded.js +1 -1
- package/package.json +1 -3
- package/dist/cjs/sdk/src/core/configuration/passkey.cjs +0 -1
- package/dist/sdk/src/core/configuration/passkey.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("../../../packages/internal/openapi-clients/dist/index.cjs"),r=require("../core/configuration/passkey.cjs"),t=require("../core/config/config.cjs"),s=require("../core/configuration/account.cjs"),a=require("../core/configuration/authentication.cjs"),i=require("../core/errors/authErrorCodes.cjs"),n=require("../core/errors/openfortError.cjs"),o=require("../core/errors/withApiError.cjs"),d=require("../types/types.cjs"),c=require("../utils/debug.cjs"),g=require("../wallets/embedded.cjs"),h=require("../wallets/evm/evmProvider.cjs");require("../wallets/evm/types.cjs");var u=require("../wallets/evm/provider/eip6963.cjs"),y=require("../wallets/evm/walletHelpers.cjs"),l=require("../wallets/iframeManager.cjs"),m=require("../wallets/messaging/ReactNativeMessenger.cjs");require("../wallets/messaging/browserMessenger/backwardCompatibility.cjs");var p=require("../wallets/messaging/browserMessenger/messengers/WindowMessenger.cjs");exports.EmbeddedWalletApi=class{storage;validateAndRefreshToken;ensureInitialized;eventEmitter;passkeyHandler;iframeManager=null;iframeManagerPromise=null;signer=null;signerPromise=null;provider=null;messagePoster=null;messenger=null;constructor(e,r,t,s,a){this.storage=e,this.validateAndRefreshToken=r,this.ensureInitialized=t,this.eventEmitter=s,this.passkeyHandler=a,this.eventEmitter.on(d.OpenfortEvents.ON_LOGOUT,()=>{c.debugLog("Handling logout event in EmbeddedWalletApi"),this.handleLogout()})}get backendApiClients(){const r=t.SDKConfiguration.getInstance();if(!r)throw new n.ConfigurationError("Configuration not found");return new e.BackendApiClients({basePath:r.backendUrl,accessToken:r.baseConfiguration.publishableKey,nativeAppIdentifier:r.nativeAppIdentifier})}async getIframeManager(){if(c.debugLog("[HANDSHAKE DEBUG] getIframeManager called"),this.iframeManager&&this.iframeManager.hasFailed&&(c.debugLog("[HANDSHAKE DEBUG] Existing iframeManager has failed, clearing for recreation"),this.messenger&&(this.messenger.destroy(),this.messenger=null),this.iframeManager=null),this.iframeManager)return c.debugLog("[HANDSHAKE DEBUG] Returning existing iframeManager instance"),this.iframeManager;if(this.iframeManagerPromise)return c.debugLog("[HANDSHAKE DEBUG] Returning existing iframeManagerPromise"),this.iframeManagerPromise;c.debugLog("[HANDSHAKE DEBUG] Creating new iframeManager"),this.iframeManagerPromise=this.createIframeManager();try{return c.debugLog("[HANDSHAKE DEBUG] Awaiting iframeManager creation"),this.iframeManager=await this.iframeManagerPromise,c.debugLog("[HANDSHAKE DEBUG] IframeManager created successfully"),this.iframeManagerPromise=null,this.iframeManager}catch(e){throw c.debugLog("[HANDSHAKE DEBUG] Error creating iframeManager:",e),this.iframeManagerPromise=null,this.messenger&&(this.messenger.destroy(),this.messenger=null),this.iframeManager=null,e}}async createIframeManager(){c.debugLog("[HANDSHAKE DEBUG] createIframeManager starting");const e=t.SDKConfiguration.getInstance();if(!e)throw c.debugLog("[HANDSHAKE DEBUG] Configuration not found"),new n.ConfigurationError("Configuration not found");let r;if(c.debugLog("[HANDSHAKE DEBUG] Configuration found"),this.messagePoster)c.debugLog("[HANDSHAKE DEBUG] Creating ReactNativeMessenger with messagePoster"),this.messenger&&(c.debugLog("[HANDSHAKE DEBUG] Destroying old messenger before creating new one"),this.messenger.destroy()),this.messenger=new m.ReactNativeMessenger(this.messagePoster),c.debugLog("[HANDSHAKE DEBUG] Created new ReactNativeMessenger instance"),r=this.messenger;else{c.debugLog("[HANDSHAKE DEBUG] Creating WindowMessenger for browser mode");const t=this.createIframe(e.iframeUrl),s=new URL(e.iframeUrl).origin;r=new p({remoteWindow:t.contentWindow,allowedOrigins:[s]}),c.debugLog("[HANDSHAKE DEBUG] Created WindowMessenger")}return c.debugLog("[HANDSHAKE DEBUG] Creating IframeManager instance"),new l.IframeManager(e,this.storage,r)}async ensureSigner(){if(this.iframeManager&&this.iframeManager.hasFailed&&(c.debugLog("IframeManager has failed, clearing signer for recreation"),this.signer=null),this.signer)return this.signer;if(this.signerPromise)return this.signerPromise;this.signerPromise=this.createSigner();try{return this.signer=await this.signerPromise,this.signer}catch(e){throw this.signerPromise=null,e}finally{this.signerPromise=null}}async createSigner(){const e=await this.getIframeManager();return new g.EmbeddedSigner(e,this.storage,this.backendApiClients,this.passkeyHandler,this.eventEmitter)}createIframe(e){if("undefined"==typeof document)throw new n.ConfigurationError("Document is not available. Please provide a message poster for non-browser environments.");const r=document.getElementById("openfort-iframe");r&&r.remove();const t=document.createElement("iframe");return t.style.display="none",t.id="openfort-iframe",t.src=e,document.body.appendChild(t),t}async getPasskeyKey(e){const r=await a.Authentication.fromStorage(this.storage);return await this.passkeyHandler.deriveAndExportKey({id:e,seed:r?.userId??""})}async getEntropy(e){switch(e.recoveryMethod){case d.RecoveryMethod.PASSWORD:return{recoveryPassword:e.password};case d.RecoveryMethod.AUTOMATIC:return{encryptionSession:e.encryptionSession};case d.RecoveryMethod.PASSKEY:return{passkey:e.passkeyInfo?{id:e.passkeyInfo.passkeyId,key:e.passkeyInfo.passkeyKey||await this.getPasskeyKey(e.passkeyInfo.passkeyId)}:{}};default:throw new n.ConfigurationError("Invalid recovery method")}}async configure(e){await this.validateAndRefreshToken();const r=e.recoveryParams??{recoveryMethod:d.RecoveryMethod.AUTOMATIC},[t,a]=await Promise.all([this.ensureSigner(),this.getEntropy(r)]),i={chainId:e.chainId,entropy:a,accountType:e.accountType??d.AccountTypeEnum.SMART_ACCOUNT,chainType:e.chainType??d.ChainTypeEnum.EVM,getPasskeyKeyFn:async e=>this.getPasskeyKey(e)},n=await t.configure(i);return{id:n.id,chainId:n.chainId,address:n.address,ownerAddress:n.ownerAddress,chainType:n.chainType,accountType:n.accountType,implementationType:n.implementationType,factoryAddress:n.factoryAddress,salt:n.salt,createdAt:n.createdAt,implementationAddress:n.implementationAddress,recoveryMethod:s.Account.parseRecoveryMethod(n.recoveryMethod),recoveryMethodDetails:n.recoveryMethodDetails}}async create(e){await this.validateAndRefreshToken();const t=e.recoveryParams??{recoveryMethod:d.RecoveryMethod.AUTOMATIC},o=await a.Authentication.fromStorage(this.storage);if(!o)throw new n.SessionError(i.OPENFORT_AUTH_ERROR_CODES.NOT_LOGGED_IN,"missing authentication");if(t.recoveryMethod===d.RecoveryMethod.PASSKEY){const e=await this.passkeyHandler.createPasskey({id:r.PasskeyHandler.randomPasskeyName(),displayName:"Openfort - Embedded Wallet",seed:o?.userId});t.passkeyInfo={passkeyId:e.id,passkeyKey:e.key}}const[c,g]=await Promise.all([this.ensureSigner(),this.getEntropy(t)]),h=await c.create({accountType:e.accountType,chainType:e.chainType,chainId:e.chainId,entropy:g}),u={id:h.id,chainId:h.chainId,address:h.address,ownerAddress:h.ownerAddress,chainType:h.chainType,accountType:h.accountType,implementationType:h.implementationType,factoryAddress:h.factoryAddress,salt:h.salt,createdAt:h.createdAt,implementationAddress:h.implementationAddress,recoveryMethod:s.Account.parseRecoveryMethod(h.recoveryMethod),recoveryMethodDetails:h.recoveryMethodDetails};return this.eventEmitter.emit(d.OpenfortEvents.ON_EMBEDDED_WALLET_CREATED,u),u}async recover(e){await this.validateAndRefreshToken();const r=e.recoveryParams??{recoveryMethod:d.RecoveryMethod.AUTOMATIC};if(r.recoveryMethod===d.RecoveryMethod.PASSKEY){if(!r.passkeyInfo?.passkeyId)throw new n.ConfigurationError("Passkey ID must be provided for passkey recovery");r.passkeyInfo={passkeyId:r.passkeyInfo.passkeyId}}const[t,a]=await Promise.all([this.ensureSigner(),this.getEntropy(r)]),i=await t.recover({account:e.account,entropy:a}),o={id:i.id,chainId:i.chainId,implementationAddress:i.implementationAddress,factoryAddress:i.factoryAddress,salt:i.salt,address:i.address,ownerAddress:i.ownerAddress,chainType:i.chainType,accountType:i.accountType,implementationType:i.implementationType,createdAt:i.createdAt,recoveryMethod:s.Account.parseRecoveryMethod(i.recoveryMethod),recoveryMethodDetails:i.recoveryMethodDetails};return this.eventEmitter.emit(d.OpenfortEvents.ON_EMBEDDED_WALLET_RECOVERED,o),o}async signMessage(e,r){await this.validateAndRefreshToken();const t=await this.ensureSigner(),{hashMessage:a=!0,arrayifyMessage:i=!1}=r||{},n=await s.Account.fromStorage(this.storage);return await t.sign(e,i,a,n?.chainType)}async signTypedData(e,r,t){await this.validateAndRefreshToken();const a=await this.ensureSigner(),o=await s.Account.fromStorage(this.storage);if(!o)throw new n.SignerError(i.OPENFORT_AUTH_ERROR_CODES.MISSING_SIGNER,"No account found");const d={...r};delete d.EIP712Domain;const{_TypedDataEncoder:c}=await import("@ethersproject/hash"),g=c.hash(e,d,t);return await y.signMessage({hash:g,implementationType:o.implementationType||o.type,chainId:Number(o.chainId),signer:a,address:o.address,ownerAddress:o.ownerAddress,factoryAddress:o.factoryAddress,salt:o.salt})}async exportPrivateKey(){await this.validateAndRefreshToken();const e=await this.ensureSigner();return await e.export()}async setRecoveryMethod(e,t){await this.validateAndRefreshToken();const o=await this.ensureSigner(),c=await a.Authentication.fromStorage(this.storage);if(!c)throw new n.SessionError(i.OPENFORT_AUTH_ERROR_CODES.NOT_LOGGED_IN,"missing authentication");let g,h,u,y;if(e.recoveryMethod===d.RecoveryMethod.PASSKEY){const e=await s.Account.fromStorage(this.storage);if(!e)throw new n.ConfigurationError("missing account");const r=e?.recoveryMethodDetails?.passkeyId;if(!r)throw new n.ConfigurationError("missing passkey id for account");u={passkeyId:r,passkeyKey:await this.passkeyHandler.deriveAndExportKey({id:r,seed:c.userId})}}else if(t.recoveryMethod===d.RecoveryMethod.PASSKEY){const e=await this.passkeyHandler.createPasskey({id:r.PasskeyHandler.randomPasskeyName(),displayName:"Openfort - Embedded Wallet",seed:c.userId});u={passkeyId:e.id,passkeyKey:e.key},y={passkeyId:e.id}}if(e.recoveryMethod===d.RecoveryMethod.PASSWORD?g=e.password:t.recoveryMethod===d.RecoveryMethod.PASSWORD&&(g=t.password),e.recoveryMethod===d.RecoveryMethod.AUTOMATIC?h=e.encryptionSession:t.recoveryMethod===d.RecoveryMethod.AUTOMATIC&&(h=t.encryptionSession),!g&&!h)throw new n.ConfigurationError("Password or encryption session is not provided");await o.setRecoveryMethod({recoveryMethod:t.recoveryMethod,recoveryPassword:g,encryptionSession:h,passkeyInfo:u});const l=await s.Account.fromStorage(this.storage);l&&new s.Account({...l,recoveryMethod:t.recoveryMethod,recoveryMethodDetails:y}).save(this.storage)}async get(){await this.validateAndRefreshToken();const e=await s.Account.fromStorage(this.storage);if(!e)throw new n.SignerError(i.OPENFORT_AUTH_ERROR_CODES.MISSING_SIGNER,"No signer configured");if(!await a.Authentication.fromStorage(this.storage))throw new n.SessionError(i.OPENFORT_AUTH_ERROR_CODES.NOT_LOGGED_IN,"No access token found");return{id:e.id,chainId:e.chainId,address:e.address,ownerAddress:e.ownerAddress,factoryAddress:e.factoryAddress,salt:e.salt,chainType:e.chainType,accountType:e.accountType,implementationAddress:e.implementationAddress,implementationType:e.implementationType,createdAt:e.createdAt,recoveryMethod:s.Account.parseRecoveryMethod(e.recoveryMethod),recoveryMethodDetails:e.recoveryMethodDetails}}async list(e){await this.validateAndRefreshToken();const r={accountType:d.AccountTypeEnum.SMART_ACCOUNT,...e},c=t.SDKConfiguration.getInstance();if(!c)throw new n.ConfigurationError("Configuration not found");const g=await a.Authentication.fromStorage(this.storage);if(!g)throw new n.SessionError(i.OPENFORT_AUTH_ERROR_CODES.NOT_LOGGED_IN,"No access token found");return await this.validateAndRefreshToken(),o.withApiError(async()=>(await this.backendApiClients.accountsV2Api.getAccountsV2(r,{headers:g.thirdPartyProvider?{authorization:`Bearer ${c.baseConfiguration.publishableKey}`,"x-player-token":g.token,"x-auth-provider":g.thirdPartyProvider,"x-token-type":g.thirdPartyTokenType}:{authorization:`Bearer ${g.token}`,"x-project-key":c.baseConfiguration.publishableKey}})).data.data.map(e=>({chainType:e.chainType,id:e.id,address:e.address,active:e.smartAccount?.active,ownerAddress:e.ownerAddress,factoryAddress:e.smartAccount?.factoryAddress,salt:e.smartAccount?.salt,accountType:e.accountType,implementationAddress:e.smartAccount?.implementationAddress,createdAt:e.createdAt,implementationType:e.smartAccount?.implementationType,chainId:e.chainId,recoveryMethod:s.Account.parseRecoveryMethod(e.recoveryMethod),recoveryMethodDetails:e.recoveryMethodDetails})),{context:"list"})}async getEmbeddedState(){try{if(!await a.Authentication.fromStorage(this.storage))return d.EmbeddedState.UNAUTHENTICATED;return await s.Account.fromStorage(this.storage)?d.EmbeddedState.READY:d.EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED}catch(e){return c.debugLog("Failed to get embedded state:",e),d.EmbeddedState.UNAUTHENTICATED}}async getEthereumProvider(e){await this.ensureInitialized();const r={announceProvider:!0,...e},t=await a.Authentication.fromStorage(this.storage),i=await s.Account.fromStorage(this.storage);return this.provider?this.provider&&r.policy&&this.provider.updatePolicy(r.policy):(this.provider=new h.EvmProvider({storage:this.storage,openfortEventEmitter:this.eventEmitter,ensureSigner:this.ensureSigner.bind(this),account:i||void 0,authentication:t||void 0,backendApiClients:this.backendApiClients,policyId:r.policy,validateAndRefreshSession:this.validateAndRefreshToken.bind(this),chains:r.chains}),r.announceProvider&&u.announceProvider({info:{...u.openfortProviderInfo,...r.providerInfo},provider:this.provider})),this.provider}async ping(e){try{e>0&&await new Promise(r=>{setTimeout(r,e)});const r=await this.getIframeManager();if(!r.isLoaded())return!1;const t=await a.Authentication.fromStorage(this.storage);if(t)try{return await r.getCurrentDevice(t.userId),!0}catch(e){return!1}return r.isLoaded()}catch(e){return c.debugLog("Ping failed:",e),!1}}getURL(){const e=t.SDKConfiguration.getInstance();if(!e)throw new n.ConfigurationError("Configuration not found");return e.iframeUrl}async setMessagePoster(e){if(!e||"function"!=typeof e.postMessage)throw new n.ConfigurationError("Invalid message poster");this.messagePoster=e,this.messenger&&this.messenger.destroy(),this.iframeManager&&this.iframeManager.destroy(),this.signer=null,this.signerPromise=null,this.iframeManager=null,this.iframeManagerPromise=null,this.messenger=null}async handleLogout(){if("undefined"==typeof document&&!this.messagePoster)return c.debugLog("Skipping signer disconnect: no messagePoster available in non-browser environment"),this.provider=null,this.messenger=null,this.iframeManager=null,this.iframeManagerPromise=null,this.signer=null,void(this.signerPromise=null);const e=await this.ensureSigner();await e.disconnect(),this.provider=null,this.messenger=null,this.iframeManager=null,this.iframeManagerPromise=null,this.signer=null,this.signerPromise=null}async onMessage(e){if(!e||"object"!=typeof e)return void c.debugLog("Invalid message received:",e);c.debugLog("[HANDSHAKE DEBUG] EmbeddedWalletApi onMessage:",e);const r="penpal"===e.namespace&&"SYN"===e.type||e.penpal&&"string"==typeof e.penpal;if(r&&this.messenger&&this.messagePoster)return c.debugLog("[HANDSHAKE DEBUG] Passing message directly to existing ReactNativeMessenger"),void this.messenger.handleMessage(e);const t=await this.getIframeManager();c.debugLog(`[HANDSHAKE DEBUG] IframeManager obtained, isLoaded: ${t.isLoaded()}`),r&&!t.isLoaded()&&c.debugLog("[HANDSHAKE DEBUG] Received penpal message before connection initialized, setting up connection..."),c.debugLog("[HANDSHAKE DEBUG] Calling iframeManager.onMessage"),await t.onMessage(e),c.debugLog("[HANDSHAKE DEBUG] iframeManager.onMessage completed")}isReady(){return this.iframeManager?.isLoaded()||!1}};
|
|
1
|
+
"use strict";var e=require("../../../packages/internal/openapi-clients/dist/index.cjs"),r=require("../core/errors/openfortError.cjs"),t=require("../core/passkey/handler.cjs"),a=require("../core/config/config.cjs"),s=require("../core/configuration/account.cjs"),i=require("../core/configuration/authentication.cjs"),n=require("../core/errors/authErrorCodes.cjs"),o=require("../core/errors/withApiError.cjs"),d=require("../types/types.cjs"),c=require("../utils/debug.cjs"),g=require("../wallets/embedded.cjs"),h=require("../wallets/evm/evmProvider.cjs");require("../wallets/evm/types.cjs");var u=require("../wallets/evm/provider/eip6963.cjs"),y=require("../wallets/evm/walletHelpers.cjs"),l=require("../wallets/iframeManager.cjs"),m=require("../wallets/messaging/ReactNativeMessenger.cjs");require("../wallets/messaging/browserMessenger/backwardCompatibility.cjs");var f=require("../wallets/messaging/browserMessenger/messengers/WindowMessenger.cjs");exports.EmbeddedWalletApi=class{storage;validateAndRefreshToken;ensureInitialized;eventEmitter;passkeyHandler;iframeManager=null;iframeManagerPromise=null;signer=null;signerPromise=null;provider=null;messagePoster=null;messenger=null;constructor(e,r,t,a,s){this.storage=e,this.validateAndRefreshToken=r,this.ensureInitialized=t,this.eventEmitter=a,this.passkeyHandler=s,this.eventEmitter.on(d.OpenfortEvents.ON_LOGOUT,()=>{c.debugLog("Handling logout event in EmbeddedWalletApi"),this.handleLogout()})}get backendApiClients(){const t=a.SDKConfiguration.getInstance();if(!t)throw new r.ConfigurationError("Configuration not found");return new e.BackendApiClients({basePath:t.backendUrl,accessToken:t.baseConfiguration.publishableKey,nativeAppIdentifier:t.nativeAppIdentifier})}async getIframeManager(){if(c.debugLog("[HANDSHAKE DEBUG] getIframeManager called"),this.iframeManager&&this.iframeManager.hasFailed&&(c.debugLog("[HANDSHAKE DEBUG] Existing iframeManager has failed, clearing for recreation"),this.messenger&&(this.messenger.destroy(),this.messenger=null),this.iframeManager=null),this.iframeManager)return c.debugLog("[HANDSHAKE DEBUG] Returning existing iframeManager instance"),this.iframeManager;if(this.iframeManagerPromise)return c.debugLog("[HANDSHAKE DEBUG] Returning existing iframeManagerPromise"),this.iframeManagerPromise;c.debugLog("[HANDSHAKE DEBUG] Creating new iframeManager"),this.iframeManagerPromise=this.createIframeManager();try{return c.debugLog("[HANDSHAKE DEBUG] Awaiting iframeManager creation"),this.iframeManager=await this.iframeManagerPromise,c.debugLog("[HANDSHAKE DEBUG] IframeManager created successfully"),this.iframeManagerPromise=null,this.iframeManager}catch(e){throw c.debugLog("[HANDSHAKE DEBUG] Error creating iframeManager:",e),this.iframeManagerPromise=null,this.messenger&&(this.messenger.destroy(),this.messenger=null),this.iframeManager=null,e}}async createIframeManager(){c.debugLog("[HANDSHAKE DEBUG] createIframeManager starting");const e=a.SDKConfiguration.getInstance();if(!e)throw c.debugLog("[HANDSHAKE DEBUG] Configuration not found"),new r.ConfigurationError("Configuration not found");let t;if(c.debugLog("[HANDSHAKE DEBUG] Configuration found"),this.messagePoster)c.debugLog("[HANDSHAKE DEBUG] Creating ReactNativeMessenger with messagePoster"),this.messenger&&(c.debugLog("[HANDSHAKE DEBUG] Destroying old messenger before creating new one"),this.messenger.destroy()),this.messenger=new m.ReactNativeMessenger(this.messagePoster),c.debugLog("[HANDSHAKE DEBUG] Created new ReactNativeMessenger instance"),t=this.messenger;else{c.debugLog("[HANDSHAKE DEBUG] Creating WindowMessenger for browser mode");const r=this.createIframe(e.iframeUrl),a=new URL(e.iframeUrl).origin;t=new f({remoteWindow:r.contentWindow,allowedOrigins:[a]}),c.debugLog("[HANDSHAKE DEBUG] Created WindowMessenger")}return c.debugLog("[HANDSHAKE DEBUG] Creating IframeManager instance"),new l.IframeManager(e,this.storage,t)}async ensureSigner(){if(this.iframeManager&&this.iframeManager.hasFailed&&(c.debugLog("IframeManager has failed, clearing signer for recreation"),this.signer=null),this.signer)return this.signer;if(this.signerPromise)return this.signerPromise;this.signerPromise=this.createSigner();try{return this.signer=await this.signerPromise,this.signer}catch(e){throw this.signerPromise=null,e}finally{this.signerPromise=null}}async createSigner(){const e=await this.getIframeManager();await e.initialize();return new g.EmbeddedSigner(e,this.storage,this.backendApiClients,this.passkeyHandler,this.eventEmitter)}createIframe(e){if("undefined"==typeof document)throw new r.ConfigurationError("Document is not available. Please provide a message poster for non-browser environments.");const t=document.getElementById("openfort-iframe");t&&t.remove();const a=document.createElement("iframe");return a.style.display="none",a.id="openfort-iframe",a.src=e,document.body.appendChild(a),a}async getPasskeyKey(e){const t=await i.Authentication.fromStorage(this.storage);if(!t?.userId)throw new r.AuthenticationError("auth","User is required for passkey key derivation. Logout and login again.",401);return this.passkeyHandler.deriveAndExportKey({id:e,seed:t.userId})}async getEntropy(e){switch(e.recoveryMethod){case d.RecoveryMethod.PASSWORD:return{recoveryPassword:e.password};case d.RecoveryMethod.AUTOMATIC:return{encryptionSession:e.encryptionSession};case d.RecoveryMethod.PASSKEY:return{passkey:e.passkeyInfo?{id:e.passkeyInfo.passkeyId,key:e.passkeyInfo.passkeyKey||await this.getPasskeyKey(e.passkeyInfo.passkeyId)}:{}};default:throw new r.ConfigurationError("Invalid recovery method")}}async configure(e){await this.validateAndRefreshToken();const r=e.recoveryParams??{recoveryMethod:d.RecoveryMethod.AUTOMATIC},[t,a]=await Promise.all([this.ensureSigner(),this.getEntropy(r)]),i={chainId:e.chainId,entropy:a,accountType:e.accountType??d.AccountTypeEnum.SMART_ACCOUNT,chainType:e.chainType??d.ChainTypeEnum.EVM,getPasskeyKeyFn:async e=>this.getPasskeyKey(e)},n=await t.configure(i);return{id:n.id,chainId:n.chainId,address:n.address,ownerAddress:n.ownerAddress,chainType:n.chainType,accountType:n.accountType,implementationType:n.implementationType,factoryAddress:n.factoryAddress,salt:n.salt,createdAt:n.createdAt,implementationAddress:n.implementationAddress,recoveryMethod:s.Account.parseRecoveryMethod(n.recoveryMethod),recoveryMethodDetails:n.recoveryMethodDetails}}async create(e){await this.validateAndRefreshToken();const o=e.recoveryParams??{recoveryMethod:d.RecoveryMethod.AUTOMATIC},c=await i.Authentication.fromStorage(this.storage);if(!c)throw new r.SessionError(n.OPENFORT_AUTH_ERROR_CODES.NOT_LOGGED_IN,"missing authentication");if(o.recoveryMethod===d.RecoveryMethod.PASSKEY){if(!c.userId)throw new r.ConfigurationError("User ID is required for passkey creation");const e=await this.passkeyHandler.createPasskey({id:t.PasskeyHandler.randomPasskeyName(),displayName:a.SDKConfiguration.getInstance()?.passkeyDisplayName??"Openfort - Embedded Wallet",seed:c.userId});if(!e.key)throw new r.ConfigurationError("Passkey creation failed: no key material returned");o.passkeyInfo={passkeyId:e.id,passkeyKey:e.key}}const[g,h]=await Promise.all([this.ensureSigner(),this.getEntropy(o)]),u=await g.create({accountType:e.accountType,chainType:e.chainType,chainId:e.chainId,entropy:h}),y={id:u.id,chainId:u.chainId,address:u.address,ownerAddress:u.ownerAddress,chainType:u.chainType,accountType:u.accountType,implementationType:u.implementationType,factoryAddress:u.factoryAddress,salt:u.salt,createdAt:u.createdAt,implementationAddress:u.implementationAddress,recoveryMethod:s.Account.parseRecoveryMethod(u.recoveryMethod),recoveryMethodDetails:u.recoveryMethodDetails};return this.eventEmitter.emit(d.OpenfortEvents.ON_EMBEDDED_WALLET_CREATED,y),y}async recover(e){await this.validateAndRefreshToken();const t=e.recoveryParams??{recoveryMethod:d.RecoveryMethod.AUTOMATIC};if(t.recoveryMethod===d.RecoveryMethod.PASSKEY){if(!t.passkeyInfo?.passkeyId)throw new r.ConfigurationError("Passkey ID must be provided for passkey recovery");t.passkeyInfo={passkeyId:t.passkeyInfo.passkeyId}}const[a,i]=await Promise.all([this.ensureSigner(),this.getEntropy(t)]),n=await a.recover({account:e.account,entropy:i}),o={id:n.id,chainId:n.chainId,implementationAddress:n.implementationAddress,factoryAddress:n.factoryAddress,salt:n.salt,address:n.address,ownerAddress:n.ownerAddress,chainType:n.chainType,accountType:n.accountType,implementationType:n.implementationType,createdAt:n.createdAt,recoveryMethod:s.Account.parseRecoveryMethod(n.recoveryMethod),recoveryMethodDetails:n.recoveryMethodDetails};return this.eventEmitter.emit(d.OpenfortEvents.ON_EMBEDDED_WALLET_RECOVERED,o),o}async signMessage(e,r){await this.validateAndRefreshToken();const t=await this.ensureSigner(),{hashMessage:a=!0,arrayifyMessage:i=!1}=r||{},n=await s.Account.fromStorage(this.storage);return await t.sign(e,i,a,n?.chainType)}async signTypedData(e,t,a){await this.validateAndRefreshToken();const i=await this.ensureSigner(),o=await s.Account.fromStorage(this.storage);if(!o)throw new r.SignerError(n.OPENFORT_AUTH_ERROR_CODES.MISSING_SIGNER,"No account found");const d={...t};delete d.EIP712Domain;const{_TypedDataEncoder:c}=await import("@ethersproject/hash"),g=c.hash(e,d,a);return await y.signMessage({hash:g,implementationType:o.implementationType||o.type,chainId:Number(o.chainId),signer:i,address:o.address,ownerAddress:o.ownerAddress,factoryAddress:o.factoryAddress,salt:o.salt})}async exportPrivateKey(){await this.validateAndRefreshToken();const e=await this.ensureSigner();return await e.export()}async setRecoveryMethod(e,o){await this.validateAndRefreshToken();const c=await this.ensureSigner(),g=await i.Authentication.fromStorage(this.storage);if(!g)throw new r.SessionError(n.OPENFORT_AUTH_ERROR_CODES.NOT_LOGGED_IN,"missing authentication");let h,u,y,l;if(e.recoveryMethod===d.RecoveryMethod.PASSKEY){const e=await s.Account.fromStorage(this.storage);if(!e)throw new r.ConfigurationError("missing account");const t=e?.recoveryMethodDetails?.passkeyId;if(!t)throw new r.ConfigurationError("missing passkey id for account");if(!g.userId)throw new r.ConfigurationError("User ID is required for passkey key derivation");y={passkeyId:t,passkeyKey:await this.passkeyHandler.deriveAndExportKey({id:t,seed:g.userId})}}else if(o.recoveryMethod===d.RecoveryMethod.PASSKEY){if(!g.userId)throw new r.ConfigurationError("User ID is required for passkey creation");const e=await this.passkeyHandler.createPasskey({id:t.PasskeyHandler.randomPasskeyName(),displayName:a.SDKConfiguration.getInstance()?.passkeyDisplayName??"Openfort - Embedded Wallet",seed:g.userId});if(!e.key)throw new r.ConfigurationError("Passkey creation failed: no key material returned");y={passkeyId:e.id,passkeyKey:e.key},l={passkeyId:e.id}}if(e.recoveryMethod===d.RecoveryMethod.PASSWORD?h=e.password:o.recoveryMethod===d.RecoveryMethod.PASSWORD&&(h=o.password),e.recoveryMethod===d.RecoveryMethod.AUTOMATIC?u=e.encryptionSession:o.recoveryMethod===d.RecoveryMethod.AUTOMATIC&&(u=o.encryptionSession),!h&&!u)throw new r.ConfigurationError("Password or encryption session is not provided");await c.setRecoveryMethod({recoveryMethod:o.recoveryMethod,recoveryPassword:h,encryptionSession:u,passkeyInfo:y});const m=await s.Account.fromStorage(this.storage);m&&new s.Account({...m,recoveryMethod:o.recoveryMethod,recoveryMethodDetails:l}).save(this.storage)}async get(){await this.validateAndRefreshToken();const e=await s.Account.fromStorage(this.storage);if(!e)throw new r.SignerError(n.OPENFORT_AUTH_ERROR_CODES.MISSING_SIGNER,"No signer configured");if(!await i.Authentication.fromStorage(this.storage))throw new r.SessionError(n.OPENFORT_AUTH_ERROR_CODES.NOT_LOGGED_IN,"No access token found");return{id:e.id,chainId:e.chainId,address:e.address,ownerAddress:e.ownerAddress,factoryAddress:e.factoryAddress,salt:e.salt,chainType:e.chainType,accountType:e.accountType,implementationAddress:e.implementationAddress,implementationType:e.implementationType,createdAt:e.createdAt,recoveryMethod:s.Account.parseRecoveryMethod(e.recoveryMethod),recoveryMethodDetails:e.recoveryMethodDetails}}async list(e){await this.validateAndRefreshToken();const t={accountType:d.AccountTypeEnum.SMART_ACCOUNT,...e},c=a.SDKConfiguration.getInstance();if(!c)throw new r.ConfigurationError("Configuration not found");const g=await i.Authentication.fromStorage(this.storage);if(!g)throw new r.SessionError(n.OPENFORT_AUTH_ERROR_CODES.NOT_LOGGED_IN,"No access token found");return await this.validateAndRefreshToken(),o.withApiError(async()=>(await this.backendApiClients.accountsV2Api.getAccountsV2(t,{headers:g.thirdPartyProvider?{authorization:`Bearer ${c.baseConfiguration.publishableKey}`,"x-player-token":g.token,"x-auth-provider":g.thirdPartyProvider,"x-token-type":g.thirdPartyTokenType}:{authorization:`Bearer ${g.token}`,"x-project-key":c.baseConfiguration.publishableKey}})).data.data.map(e=>({chainType:e.chainType,id:e.id,address:e.address,active:e.smartAccount?.active,ownerAddress:e.ownerAddress,factoryAddress:e.smartAccount?.factoryAddress,salt:e.smartAccount?.salt,accountType:e.accountType,implementationAddress:e.smartAccount?.implementationAddress,createdAt:e.createdAt,implementationType:e.smartAccount?.implementationType,chainId:e.chainId,recoveryMethod:s.Account.parseRecoveryMethod(e.recoveryMethod),recoveryMethodDetails:e.recoveryMethodDetails})),{context:"list"})}async getEmbeddedState(){try{if(!await i.Authentication.fromStorage(this.storage))return d.EmbeddedState.UNAUTHENTICATED;return await s.Account.fromStorage(this.storage)?d.EmbeddedState.READY:d.EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED}catch(e){return c.debugLog("Failed to get embedded state:",e),d.EmbeddedState.UNAUTHENTICATED}}async getEthereumProvider(e){await this.ensureInitialized();const r={announceProvider:!0,...e},t=await i.Authentication.fromStorage(this.storage),a=await s.Account.fromStorage(this.storage);return this.provider?this.provider&&r.policy&&this.provider.updatePolicy(r.policy):(this.provider=new h.EvmProvider({storage:this.storage,openfortEventEmitter:this.eventEmitter,ensureSigner:this.ensureSigner.bind(this),account:a||void 0,authentication:t||void 0,backendApiClients:this.backendApiClients,policyId:r.policy,validateAndRefreshSession:this.validateAndRefreshToken.bind(this),chains:r.chains}),r.announceProvider&&u.announceProvider({info:{...u.openfortProviderInfo,...r.providerInfo},provider:this.provider})),this.provider}async ping(e){try{e>0&&await new Promise(r=>{setTimeout(r,e)});const r=await this.getIframeManager();if(!r.isLoaded())return!1;const t=await i.Authentication.fromStorage(this.storage);if(t)try{return await r.getCurrentDevice(t.userId),!0}catch(e){return!1}return r.isLoaded()}catch(e){return c.debugLog("Ping failed:",e),!1}}getURL(){const e=a.SDKConfiguration.getInstance();if(!e)throw new r.ConfigurationError("Configuration not found");return e.iframeUrl}async setMessagePoster(e){if(!e||"function"!=typeof e.postMessage)throw new r.ConfigurationError("Invalid message poster");this.messagePoster=e,this.messenger&&this.messenger.destroy(),this.iframeManager&&this.iframeManager.destroy(),this.signer=null,this.signerPromise=null,this.iframeManager=null,this.iframeManagerPromise=null,this.messenger=null}async handleLogout(){if("undefined"==typeof document&&!this.messagePoster)return c.debugLog("Skipping signer disconnect: no messagePoster available in non-browser environment"),this.provider=null,this.messenger=null,this.iframeManager=null,this.iframeManagerPromise=null,this.signer=null,void(this.signerPromise=null);const e=await this.ensureSigner();await e.disconnect(),this.provider=null,this.messenger=null,this.iframeManager=null,this.iframeManagerPromise=null,this.signer=null,this.signerPromise=null}async onMessage(e){if(!e||"object"!=typeof e)return void c.debugLog("Invalid message received:",e);c.debugLog("[HANDSHAKE DEBUG] EmbeddedWalletApi onMessage:",e);const r="penpal"===e.namespace&&"SYN"===e.type||e.penpal&&"string"==typeof e.penpal;if(r&&this.messenger&&this.messagePoster)return c.debugLog("[HANDSHAKE DEBUG] Passing message directly to existing ReactNativeMessenger"),void this.messenger.handleMessage(e);const t=await this.getIframeManager();c.debugLog(`[HANDSHAKE DEBUG] IframeManager obtained, isLoaded: ${t.isLoaded()}`),r&&!t.isLoaded()&&c.debugLog("[HANDSHAKE DEBUG] Received penpal message before connection initialized, setting up connection..."),c.debugLog("[HANDSHAKE DEBUG] Calling iframeManager.onMessage"),await t.onMessage(e),c.debugLog("[HANDSHAKE DEBUG] iframeManager.onMessage completed")}isReady(){return this.iframeManager?.isLoaded()||!1}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("../../utils/crypto.cjs");class
|
|
1
|
+
"use strict";var e=require("../../utils/crypto.cjs");class s{baseConfiguration;shieldConfiguration;thirdPartyAuth;shieldUrl;iframeUrl;backendUrl;storage;passkeyRpId;passkeyRpName;passkeyDisplayName;nativeAppIdentifier;debug;static instance=null;constructor({baseConfiguration:i,shieldConfiguration:t,overrides:a,thirdPartyAuth:r,debug:p}){this.shieldConfiguration=t,this.baseConfiguration=i,this.backendUrl=a?.backendUrl||"https://api.openfort.io",this.iframeUrl=a?.iframeUrl||"https://embed.openfort.io",this.iframeUrl=`${this.iframeUrl}/iframe/${this.baseConfiguration.publishableKey}`,this.debug=p,t?.debug&&(this.iframeUrl=`${this.iframeUrl}?debug=true`),this.shieldUrl=a?.shieldUrl||"https://shield.openfort.io",this.storage=a?.storage,this.thirdPartyAuth=r,this.passkeyRpId=t?.passkeyRpId,this.passkeyRpName=t?.passkeyRpName,this.passkeyDisplayName=t?.passkeyDisplayName,this.nativeAppIdentifier=i.nativeAppIdentifier,a?.crypto?.digest&&e.setCryptoDigestOverride(a.crypto.digest),s.instance=this}static getInstance(){return s.instance}}exports.OpenfortConfiguration=class{publishableKey;nativeAppIdentifier;constructor(e){this.publishableKey=e.publishableKey,this.nativeAppIdentifier=e.nativeAppIdentifier}},exports.SDKConfiguration=s,exports.ShieldConfiguration=class{shieldPublishableKey;shieldEncryptionKey;debug=!1;passkeyRpId;passkeyRpName;passkeyDisplayName;constructor(e){this.shieldPublishableKey=e.shieldPublishableKey,this.debug=e.shieldDebug||!1,this.passkeyRpId=e.passkeyRpId,this.passkeyRpName=e.passkeyRpName,this.passkeyDisplayName=e.passkeyDisplayName}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("../../../packages/internal/openapi-clients/dist/index.cjs"),t=require("../api/auth.cjs"),i=require("../api/embeddedWallet.cjs"),n=require("../api/proxy.cjs"),a=require("../api/user.cjs"),r=require("../auth/authManager.cjs"),s=require("../storage/istorage.cjs"),o=require("../storage/lazyStorage.cjs"),h=require("../utils/typedEventEmitter.cjs"),l=require("./config/config.cjs"),c=require("./
|
|
1
|
+
"use strict";var e=require("../../../packages/internal/openapi-clients/dist/index.cjs"),t=require("../api/auth.cjs"),i=require("../api/embeddedWallet.cjs"),n=require("../api/proxy.cjs"),a=require("../api/user.cjs"),r=require("../auth/authManager.cjs"),s=require("../storage/istorage.cjs"),o=require("../storage/lazyStorage.cjs"),h=require("../utils/typedEventEmitter.cjs"),l=require("./config/config.cjs"),c=require("./errors/authErrorCodes.cjs"),u=require("./errors/openfortError.cjs"),d=require("./errors/sentry.cjs"),g=require("./openfortInternal.cjs"),f=require("./passkey/handler.cjs");class p{storage;iAuthManager=null;openfortInternal;initPromise;asyncInitPromise=null;authInstance;embeddedWalletInstance;userInstance;proxyInstance;configuration;eventEmitter;iPasskeyHandler;static globalEventEmitter=null;get auth(){if(!this.authInstance)throw new u.ConfigurationError("Openfort SDK not initialized. Please await waitForInitialization() before accessing auth.");return this.authInstance}get embeddedWallet(){if(!this.embeddedWalletInstance)throw new u.ConfigurationError("Openfort SDK not initialized. Please await waitForInitialization() before accessing embeddedWallet.");return this.embeddedWalletInstance}get user(){if(!this.userInstance)throw new u.ConfigurationError("Openfort SDK not initialized. Please await waitForInitialization() before accessing user.");return this.userInstance}get proxy(){if(!this.proxyInstance)throw new u.ConfigurationError("Openfort SDK not initialized. Please await waitForInitialization() before accessing proxy.");return this.proxyInstance}initializeSynchronously(){try{this.iAuthManager=new r.AuthManager,this.openfortInternal=new g.OpenfortInternal(this.storage,this.authManager,this.eventEmitter),this.authInstance=new t.AuthApi(this.storage,this.authManager,this.validateAndRefreshToken.bind(this),this.ensureInitialized.bind(this),this.eventEmitter),this.embeddedWalletInstance=new i.EmbeddedWalletApi(this.storage,this.validateAndRefreshToken.bind(this),this.ensureInitialized.bind(this),this.eventEmitter,this.passkeyHandler),this.userInstance=new a.UserApi(this.storage,this.authManager,this.validateAndRefreshToken.bind(this)),this.proxyInstance=new n.ProxyApi(this.storage,this.backendApiClients,this.validateAndRefreshToken.bind(this),this.ensureInitialized.bind(this),async()=>{if(!this.embeddedWalletInstance)throw new u.SignerError(c.OPENFORT_AUTH_ERROR_CODES.MISSING_SIGNER,"Embedded wallet not initialized");const e=this.embeddedWalletInstance;return t=>e.signMessage(t,{hashMessage:!0,arrayifyMessage:!0})})}catch(e){throw new u.ConfigurationError("Openfort SDK synchronous initialization failed")}}constructor(e){if(this.configuration=new l.SDKConfiguration(e),this.storage=new o.LazyStorage(this.configuration.baseConfiguration.publishableKey,this.configuration.storage),this.eventEmitter=new h,p.globalEventEmitter){["onAuthInit","onAuthSuccess","onAuthFailure","onLogout","onSwitchAccount","onSignedMessage","onEmbeddedWalletCreated","onEmbeddedWalletRecovered","onAuthFlowOpen","onAuthFlowClose","onAuthFlowCancel"].forEach(e=>{this.eventEmitter.on(e,(...t)=>{p.globalEventEmitter?.emit(e,...t)})})}else p.globalEventEmitter=this.eventEmitter;this.iPasskeyHandler=e.overrides?.passkeyHandler??new f.PasskeyHandler({rpId:this.configuration.passkeyRpId,rpName:this.configuration.passkeyRpName}),d.InternalSentry.init({configuration:this.configuration}),this.initializeSynchronously(),this.initPromise=Promise.resolve()}static getEventEmitter(){return p.globalEventEmitter||(p.globalEventEmitter=new h),p.globalEventEmitter}async waitForInitialization(){await this.initPromise,await this.ensureAsyncInitialized()}async getAccessToken(){return await this.ensureInitialized(),this.openfortInternal.getAccessToken()}async validateAndRefreshToken(e){return await this.ensureInitialized(),await this.openfortInternal.validateAndRefreshToken(e)}get backendApiClients(){return new e.BackendApiClients({basePath:this.configuration.backendUrl,accessToken:this.configuration.baseConfiguration.publishableKey,nativeAppIdentifier:this.configuration.nativeAppIdentifier,storage:this.storage,onLogout:()=>{this.eventEmitter.emit("onLogout")}})}get authManager(){if(!this.iAuthManager)throw new u.RequestError("AuthManager not initialized");return this.iAuthManager}get passkeyHandler(){return this.iPasskeyHandler}static async isStorageAccessible(e){try{const t=s.StorageKeys.TEST,i="openfort_storage_test";e.save(t,i);const n=await e.get(t);return e.remove(t),n===i}catch(e){return!1}}async initializeAsync(){if(!await p.isStorageAccessible(this.storage))throw new u.OpenfortError("Storage is not accessible",c.OPENFORT_ERROR_CODES.INVALID_CONFIGURATION);this.authManager.setBackendApiClients(this.backendApiClients,this.configuration.baseConfiguration.publishableKey)}async ensureAsyncInitialized(){this.asyncInitPromise||(this.asyncInitPromise=this.initializeAsync()),await this.asyncInitPromise}async ensureInitialized(){await this.initPromise,await this.ensureAsyncInitialized()}}exports.Openfort=p;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("../errors/openfortError.cjs");const s={USER_CANCELLED:"passkey_user_cancelled",CREATION_FAILED:"passkey_creation_failed",ASSERTION_FAILED:"passkey_assertion_failed",PRF_NOT_SUPPORTED:"passkey_prf_not_supported",INVALID_SEED:"passkey_invalid_seed"};class r extends e.OpenfortError{constructor(e="User cancelled passkey operation"){super(s.USER_CANCELLED,e),this.name="PasskeyUserCancelledError",Object.setPrototypeOf(this,r.prototype)}}class t extends e.OpenfortError{cause;constructor(e="Failed to create passkey",r){super(s.CREATION_FAILED,e),this.name="PasskeyCreationFailedError",this.cause=r,Object.setPrototypeOf(this,t.prototype)}}class o extends e.OpenfortError{constructor(e="PRF extension not supported on this device"){super(s.PRF_NOT_SUPPORTED,e),this.name="PasskeyPRFNotSupportedError",Object.setPrototypeOf(this,o.prototype)}}class a extends e.OpenfortError{cause;constructor(e="Failed to get passkey assertion",r){super(s.ASSERTION_FAILED,e),this.name="PasskeyAssertionFailedError",this.cause=r,Object.setPrototypeOf(this,a.prototype)}}class p extends e.OpenfortError{constructor(e="Passkey seed cannot be empty"){super(s.INVALID_SEED,e),this.name="PasskeySeedInvalidError",Object.setPrototypeOf(this,p.prototype)}}exports.PASSKEY_ERROR_CODES=s,exports.PasskeyAssertionFailedError=a,exports.PasskeyCreationFailedError=t,exports.PasskeyPRFNotSupportedError=o,exports.PasskeySeedInvalidError=p,exports.PasskeyUserCancelledError=r;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("human-id"),r=require("./errors.cjs"),t=require("./utils.cjs");exports.PasskeyHandler=class{validByteLengths=[16,24,32];rpId;rpName;timeoutMs;derivedKeyLengthBytes;constructor({rpId:e,rpName:r,timeoutMs:t,derivedKeyLengthBytes:s}={}){if(this.rpId=e,this.rpName=r,this.timeoutMs=t??6e4,this.derivedKeyLengthBytes=s??32,!this.validByteLengths.includes(this.derivedKeyLengthBytes))throw new Error(`Invalid key byte length ${this.derivedKeyLengthBytes}`)}static randomPasskeyName(){return e.humanId({capitalize:!0,separator:" "})}getChallengeBytes(){return crypto.getRandomValues(new Uint8Array(32))}async deriveKeyFromAssertion(e){const t=e.getClientExtensionResults();if(!t)throw new r.PasskeyPRFNotSupportedError("Passkey fetch failed: no client extension results");const s=t.prf;if(!s||!s.results)throw new r.PasskeyPRFNotSupportedError("PRF extension not supported or missing results");const a=s.results.first,n=await crypto.subtle.importKey("raw",a,{name:"AES-CBC",length:this.derivedKeyLengthBytes},!0,["encrypt","decrypt"]);return crypto.subtle.exportKey("raw",n)}async createPasskey({id:e,displayName:s,seed:a}){if(!a||0===a.trim().length)throw new r.PasskeySeedInvalidError;const n={challenge:this.getChallengeBytes(),rp:{id:this.rpId,name:this.rpName},user:{id:(new TextEncoder).encode(e),name:e,displayName:s},pubKeyCredParams:[{type:"public-key",alg:-7},{type:"public-key",alg:-257}],authenticatorSelection:{residentKey:"required",userVerification:"required"},extensions:{prf:{eval:{first:(new TextEncoder).encode(a)}}},timeout:this.timeoutMs,attestation:"direct"};let i,o;try{i=await navigator.credentials.create({publicKey:n})}catch(e){if(e instanceof Error&&"NotAllowedError"===e.name)throw new r.PasskeyUserCancelledError;throw new r.PasskeyCreationFailedError(e instanceof Error?e.message:"Unknown error",e instanceof Error?e:void 0)}if(!i)throw new r.PasskeyUserCancelledError;try{o=await this.deriveKeyFromAssertion(i)}catch(e){throw e instanceof r.PasskeyPRFNotSupportedError&&console.warn(`[Openfort] Passkey created but PRF extension failed. A passkey credential may exist on the device that cannot be used for wallet recovery. Credential ID: ${t.arrayBufferToBase64URL(i.rawId)}`),e}return{id:t.arrayBufferToBase64URL(i.rawId),displayName:s,key:t.arrayBufferToBase64URL(o)}}async deriveAndExportKey({id:e,seed:s}){if(!s||0===s.trim().length)throw new r.PasskeySeedInvalidError;let a;try{a=await navigator.credentials.get({publicKey:{challenge:this.getChallengeBytes(),rpId:this.rpId,allowCredentials:[{id:t.base64ToArrayBuffer(e),type:"public-key"}],userVerification:"required",extensions:{prf:{eval:{first:(new TextEncoder).encode(s)}}}}})}catch(e){if(e instanceof Error&&"NotAllowedError"===e.name)throw new r.PasskeyUserCancelledError;throw new r.PasskeyAssertionFailedError(e instanceof Error?e.message:"Unknown error",e instanceof Error?e:void 0)}if(!a)throw new r.PasskeyUserCancelledError;const n=await this.deriveKeyFromAssertion(a);return t.arrayBufferToBase64URL(n)}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";exports.arrayBufferToBase64URL=function(r){const e=r instanceof Uint8Array?r:new Uint8Array(r);let t="";for(const r of e)t+=String.fromCharCode(r);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")},exports.base64ToArrayBuffer=function(r){const e=atob(r),t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t.buffer};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var r=require("./core/openfort.cjs"),e=require("./api/auth.cjs"),o=require("./api/embeddedWallet.cjs"),t=require("./api/proxy.cjs"),
|
|
1
|
+
"use strict";var r=require("./core/openfort.cjs"),e=require("./api/auth.cjs"),o=require("./api/embeddedWallet.cjs"),t=require("./api/proxy.cjs"),s=require("./api/user.cjs"),n=require("./core/errors/authErrorCodes.cjs"),i=require("./core/errors/openfortError.cjs"),p=require("./core/passkey/errors.cjs"),u=require("./core/passkey/handler.cjs"),a=require("./core/passkey/utils.cjs"),E=require("./core/config/config.cjs"),c=require("./core/openfortInternal.cjs"),d=require("./utils/authorization.cjs"),y=require("./wallets/iframeManager.cjs"),f=require("./types/types.cjs"),x=require("./utils/crypto.cjs");const P=r.Openfort.getEventEmitter();exports.Openfort=r.Openfort,exports.AuthApi=e.AuthApi,exports.EmbeddedWalletApi=o.EmbeddedWalletApi,exports.ProxyApi=t.ProxyApi,exports.UserApi=s.UserApi,exports.OPENFORT_AUTH_ERROR_CODES=n.OPENFORT_AUTH_ERROR_CODES,exports.OPENFORT_ERROR_CODES=n.OPENFORT_ERROR_CODES,exports.AuthenticationError=i.AuthenticationError,exports.AuthorizationError=i.AuthorizationError,exports.ConfigurationError=i.ConfigurationError,exports.OAuthError=i.OAuthError,exports.OTPError=i.OTPError,exports.OpenfortError=i.OpenfortError,exports.RecoveryError=i.RecoveryError,exports.RequestError=i.RequestError,exports.SessionError=i.SessionError,exports.SignerError=i.SignerError,exports.UserError=i.UserError,exports.PASSKEY_ERROR_CODES=p.PASSKEY_ERROR_CODES,exports.PasskeyAssertionFailedError=p.PasskeyAssertionFailedError,exports.PasskeyCreationFailedError=p.PasskeyCreationFailedError,exports.PasskeyPRFNotSupportedError=p.PasskeyPRFNotSupportedError,exports.PasskeySeedInvalidError=p.PasskeySeedInvalidError,exports.PasskeyUserCancelledError=p.PasskeyUserCancelledError,exports.PasskeyHandler=u.PasskeyHandler,exports.arrayBufferToBase64URL=a.arrayBufferToBase64URL,exports.base64ToArrayBuffer=a.base64ToArrayBuffer,exports.OpenfortConfiguration=E.OpenfortConfiguration,exports.SDKConfiguration=E.SDKConfiguration,exports.ShieldConfiguration=E.ShieldConfiguration,exports.OpenfortInternal=c.OpenfortInternal,exports.prepareAndSignAuthorization=d.prepareAndSignAuthorization,exports.serializeSignedAuthorization=d.serializeSignedAuthorization,exports.signAuthorization=d.signAuthorization,exports.MissingProjectEntropyError=y.MissingProjectEntropyError,exports.MissingRecoveryPasswordError=y.MissingRecoveryPasswordError,exports.NotConfiguredError=y.NotConfiguredError,exports.OTPRequiredError=y.OTPRequiredError,exports.WrongPasskeyError=y.WrongPasskeyError,exports.WrongRecoveryPasswordError=y.WrongRecoveryPasswordError,Object.defineProperty(exports,"AccountTypeEnum",{enumerable:!0,get:function(){return f.AccountTypeEnum}}),Object.defineProperty(exports,"AuthActionRequiredActions",{enumerable:!0,get:function(){return f.AuthActionRequiredActions}}),Object.defineProperty(exports,"AuthType",{enumerable:!0,get:function(){return f.AuthType}}),Object.defineProperty(exports,"BasicAuthProvider",{enumerable:!0,get:function(){return f.BasicAuthProvider}}),Object.defineProperty(exports,"ChainTypeEnum",{enumerable:!0,get:function(){return f.ChainTypeEnum}}),Object.defineProperty(exports,"EmbeddedState",{enumerable:!0,get:function(){return f.EmbeddedState}}),Object.defineProperty(exports,"OAuthProvider",{enumerable:!0,get:function(){return f.OAuthProvider}}),Object.defineProperty(exports,"OpenfortEvents",{enumerable:!0,get:function(){return f.OpenfortEvents}}),Object.defineProperty(exports,"RecoveryMethod",{enumerable:!0,get:function(){return f.RecoveryMethod}}),Object.defineProperty(exports,"ThirdPartyOAuthProvider",{enumerable:!0,get:function(){return f.ThirdPartyAuthProvider}}),Object.defineProperty(exports,"TokenType",{enumerable:!0,get:function(){return f.TokenType}}),exports.cryptoDigest=x.cryptoDigest,exports.openfortEvents=P;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";exports.PACKAGE="@openfort/openfort-js",exports.VERSION="1.1.
|
|
1
|
+
"use strict";exports.PACKAGE="@openfort/openfort-js",exports.VERSION="1.1.6";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("../core/configuration/authentication.cjs"),t=require("../core/
|
|
1
|
+
"use strict";var e=require("../core/configuration/authentication.cjs"),t=require("../core/errors/authErrorCodes.cjs"),a=require("../core/errors/openfortError.cjs"),r=require("../core/errors/withApiError.cjs"),o=require("../core/passkey/handler.cjs"),n=require("../core/config/config.cjs"),s=require("../core/configuration/account.cjs"),i=require("../storage/istorage.cjs"),c=require("../types/types.cjs");exports.EmbeddedSigner=class{iframeManager;storage;backendApiClients;passkeyHandler;eventEmitter;constructor(e,t,a,r,o){this.iframeManager=e,this.storage=t,this.backendApiClients=a,this.passkeyHandler=r,this.eventEmitter=o}async createPasskey(e){const t=await this.passkeyHandler.createPasskey({id:o.PasskeyHandler.randomPasskeyName(),displayName:n.SDKConfiguration.getInstance()?.passkeyDisplayName??"Openfort - Embedded Wallet",seed:e});return{id:t.id,key:t.key}}async configure(o){const i=await e.Authentication.fromStorage(this.storage);if(!i)throw new a.SessionError(t.OPENFORT_AUTH_ERROR_CODES.NOT_LOGGED_IN,"No access token found");const d=n.SDKConfiguration.getInstance();if(!d)throw new a.ConfigurationError("Configuration not found");const y=await s.Account.fromStorage(this.storage);let p;if(y){const e={account:y.id,...o.entropy&&{entropy:{...o.entropy.recoveryPassword&&{recoveryPassword:o.entropy.recoveryPassword},...o.entropy.encryptionSession&&{encryptionSession:o.entropy.encryptionSession},..."passkey"===y.recoveryMethod&&{passkey:{id:y.recoveryMethodDetails?.passkeyId,env:y.recoveryMethodDetails?.passkeyEnv,key:await o.getPasskeyKeyFn(y.recoveryMethodDetails?.passkeyId??"")}}}}},t=await this.iframeManager.recover(e);p=t.account}else{const e=await this.backendApiClients.accountsV2Api.getAccountsV2({accountType:o.accountType,chainType:o.chainType},{headers:i.thirdPartyProvider?{authorization:`Bearer ${d.baseConfiguration.publishableKey}`,"x-player-token":i.token,"x-auth-provider":i.thirdPartyProvider,"x-token-type":i.thirdPartyTokenType}:{authorization:`Bearer ${i.token}`,"x-project-key":d.baseConfiguration.publishableKey}});if(0===e.data.data.length){const e=o.entropy?.passkey?await this.createPasskey(i.userId):void 0,t={accountType:o.accountType,chainType:o.chainType,chainId:o.chainId,...o.entropy&&{entropy:{...o.entropy.recoveryPassword&&{recoveryPassword:o.entropy.recoveryPassword},...o.entropy.encryptionSession&&{encryptionSession:o.entropy.encryptionSession},...o.entropy.passkey&&{passkey:e}}}},a=await this.iframeManager.create(t);p=a.account}else{const t=e.data.data,a=t.find(e=>e.chainId===o.chainId),r=a||t[0],n={account:r.id,...o.entropy&&{entropy:{...o.entropy.recoveryPassword&&{recoveryPassword:o.entropy.recoveryPassword},...o.entropy.encryptionSession&&{encryptionSession:o.entropy.encryptionSession},..."passkey"===r.recoveryMethod&&{passkey:{id:r.recoveryMethodDetails?.passkeyId,env:r.recoveryMethodDetails?.passkeyEnv,key:await o.getPasskeyKeyFn(r.recoveryMethodDetails?.passkeyId??"")}}}}},s=await this.iframeManager.recover(n);if(p=s.account,!a){const e=await this.iframeManager.switchChain(o.chainId);p=e.account}}}return r.withApiError(async()=>{const e=await this.backendApiClients.accountsV2Api.getAccountV2({id:p},{headers:i.thirdPartyProvider?{authorization:`Bearer ${d.baseConfiguration.publishableKey}`,"x-player-token":i.token,"x-auth-provider":i.thirdPartyProvider,"x-token-type":i.thirdPartyTokenType}:{authorization:`Bearer ${i.token}`,"x-project-key":d.baseConfiguration.publishableKey}}),t=new s.Account({chainType:e.data.chainType,id:e.data.id,address:e.data.address,ownerAddress:e.data.ownerAddress,accountType:e.data.accountType,createdAt:e.data.createdAt,implementationAddress:e.data.smartAccount?.implementationAddress,implementationType:e.data.smartAccount?.implementationType,chainId:e.data.chainId,salt:e.data.smartAccount?.salt,factoryAddress:e.data.smartAccount?.factoryAddress,recoveryMethod:s.Account.parseRecoveryMethod(e.data.recoveryMethod),recoveryMethodDetails:e.data.recoveryMethodDetails});return t.save(this.storage),this.eventEmitter.emit(c.OpenfortEvents.ON_SWITCH_ACCOUNT,e.data.address),t},{context:"configure"})}async sign(e,t,a,r){const o=await this.iframeManager.sign(e,t,a,r);return this.eventEmitter.emit(c.OpenfortEvents.ON_SIGNED_MESSAGE,{message:e,signature:o}),o}async export(){return await this.iframeManager.export()}async switchChain({chainId:e}){const t=await s.Account.fromStorage(this.storage);if(t?.accountType===c.AccountTypeEnum.EOA)new s.Account({...t,chainId:e}).save(this.storage);else{const a=await this.iframeManager.switchChain(e);new s.Account({...t,id:a.account,chainId:e}).save(this.storage)}}async create(o){const i=await this.iframeManager.create(o),d=await e.Authentication.fromStorage(this.storage);if(!d)throw new a.SessionError(t.OPENFORT_AUTH_ERROR_CODES.NOT_LOGGED_IN,"No access token found");const y=n.SDKConfiguration.getInstance();if(!y)throw new a.ConfigurationError("Configuration not found");return r.withApiError(async()=>{const e=await this.backendApiClients.accountsV2Api.getAccountV2({id:i.account},{headers:d.thirdPartyProvider?{authorization:`Bearer ${y.baseConfiguration.publishableKey}`,"x-player-token":d.token,"x-auth-provider":d.thirdPartyProvider,"x-token-type":d.thirdPartyTokenType}:{authorization:`Bearer ${d.token}`,"x-project-key":y.baseConfiguration.publishableKey}}),t=new s.Account({chainType:e.data.chainType,id:e.data.id,address:e.data.address,ownerAddress:e.data.ownerAddress,accountType:e.data.accountType,createdAt:e.data.createdAt,implementationType:e.data.smartAccount?.implementationType,chainId:e.data.chainId,implementationAddress:e.data.smartAccount?.implementationAddress,salt:e.data.smartAccount?.salt,factoryAddress:e.data.smartAccount?.factoryAddress,recoveryMethod:s.Account.parseRecoveryMethod(e.data.recoveryMethod),recoveryMethodDetails:e.data.recoveryMethodDetails});return t.save(this.storage),this.eventEmitter.emit(c.OpenfortEvents.ON_SWITCH_ACCOUNT,e.data.address),t},{context:"create"})}async recover(o){const i=await this.iframeManager.recover(o),d=await e.Authentication.fromStorage(this.storage);if(!d)throw new a.SessionError(t.OPENFORT_AUTH_ERROR_CODES.NOT_LOGGED_IN,"No access token found");const y=n.SDKConfiguration.getInstance();if(!y)throw new a.ConfigurationError("Configuration not found");return r.withApiError(async()=>{const e=await this.backendApiClients.accountsV2Api.getAccountV2({id:i.account},{headers:d.thirdPartyProvider?{authorization:`Bearer ${y.baseConfiguration.publishableKey}`,"x-player-token":d.token,"x-auth-provider":d.thirdPartyProvider,"x-token-type":d.thirdPartyTokenType}:{authorization:`Bearer ${d.token}`,"x-project-key":y.baseConfiguration.publishableKey}}),t=new s.Account({chainType:e.data.chainType,id:e.data.id,address:e.data.address,ownerAddress:e.data.ownerAddress,accountType:e.data.accountType,createdAt:e.data.createdAt,implementationAddress:e.data.smartAccount?.implementationAddress,implementationType:e.data.smartAccount?.implementationType,chainId:e.data.chainId,salt:e.data.smartAccount?.salt,factoryAddress:e.data.smartAccount?.factoryAddress,recoveryMethod:s.Account.parseRecoveryMethod(e.data.recoveryMethod),recoveryMethodDetails:e.data.recoveryMethodDetails});return t.save(this.storage),this.eventEmitter.emit(c.OpenfortEvents.ON_SWITCH_ACCOUNT,e.data.address),t},{context:"recover"})}async setRecoveryMethod({recoveryMethod:e,recoveryPassword:t,encryptionSession:a,passkeyInfo:r}){await this.iframeManager.setRecoveryMethod(e,t,a,r?.passkeyKey,r?.passkeyId)}async disconnect(){await this.iframeManager.disconnect(),this.storage.remove(i.StorageKeys.ACCOUNT)}};
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PasskeyDetails } from 'wallets/types';
|
|
2
|
-
import {
|
|
1
|
+
import { PasskeyDetails as PasskeyDetails$1 } from 'wallets/types';
|
|
2
|
+
import { IPasskeyHandler as IPasskeyHandler$1 } from 'core/passkey';
|
|
3
3
|
import { User as User$2, ThirdPartyOAuthProvider as ThirdPartyOAuthProvider$1 } from 'types';
|
|
4
4
|
import { Account } from 'core/configuration/account';
|
|
5
5
|
import { Hex } from 'wallets/evm/types';
|
|
@@ -368,6 +368,7 @@ interface TransitionalOptions {
|
|
|
368
368
|
silentJSONParsing?: boolean;
|
|
369
369
|
forcedJSONParsing?: boolean;
|
|
370
370
|
clarifyTimeoutError?: boolean;
|
|
371
|
+
legacyInterceptorReqResOrdering?: boolean;
|
|
371
372
|
}
|
|
372
373
|
|
|
373
374
|
interface GenericAbortSignal {
|
|
@@ -11923,7 +11924,7 @@ type EmbeddedAccountCreateParams = {
|
|
|
11923
11924
|
};
|
|
11924
11925
|
type PasskeyInfo = {
|
|
11925
11926
|
passkeyId: string;
|
|
11926
|
-
passkeyKey?:
|
|
11927
|
+
passkeyKey?: string;
|
|
11927
11928
|
};
|
|
11928
11929
|
type RecoveryParams = {
|
|
11929
11930
|
recoveryMethod: RecoveryMethod.AUTOMATIC;
|
|
@@ -11938,7 +11939,7 @@ type RecoveryParams = {
|
|
|
11938
11939
|
type EntropyResponse = {
|
|
11939
11940
|
recoveryPassword?: string;
|
|
11940
11941
|
encryptionSession?: string;
|
|
11941
|
-
passkey?: PasskeyDetails;
|
|
11942
|
+
passkey?: PasskeyDetails$1;
|
|
11942
11943
|
};
|
|
11943
11944
|
declare enum SortOrdering {
|
|
11944
11945
|
ASC = "asc",
|
|
@@ -12153,7 +12154,7 @@ declare class EmbeddedWalletApi {
|
|
|
12153
12154
|
private provider;
|
|
12154
12155
|
private messagePoster;
|
|
12155
12156
|
private messenger;
|
|
12156
|
-
constructor(storage: IStorage, validateAndRefreshToken: () => Promise<void>, ensureInitialized: () => Promise<void>, eventEmitter: TypedEventEmitter<OpenfortEventMap>, passkeyHandler:
|
|
12157
|
+
constructor(storage: IStorage, validateAndRefreshToken: () => Promise<void>, ensureInitialized: () => Promise<void>, eventEmitter: TypedEventEmitter<OpenfortEventMap>, passkeyHandler: IPasskeyHandler$1);
|
|
12157
12158
|
private get backendApiClients();
|
|
12158
12159
|
private getIframeManager;
|
|
12159
12160
|
private createIframeManager;
|
|
@@ -12218,6 +12219,7 @@ interface SDKOverrides {
|
|
|
12218
12219
|
digest?: (algorithm: string, data: BufferSource) => Promise<ArrayBuffer>;
|
|
12219
12220
|
};
|
|
12220
12221
|
storage?: IStorage;
|
|
12222
|
+
passkeyHandler?: IPasskeyHandler$1;
|
|
12221
12223
|
}
|
|
12222
12224
|
interface ThirdPartyAuthConfiguration {
|
|
12223
12225
|
provider: ThirdPartyOAuthProvider$1;
|
|
@@ -12238,13 +12240,35 @@ declare class ShieldConfiguration {
|
|
|
12238
12240
|
*/
|
|
12239
12241
|
readonly shieldEncryptionKey?: string;
|
|
12240
12242
|
readonly debug?: boolean;
|
|
12243
|
+
/**
|
|
12244
|
+
* The relying party identifier for WebAuthn passkey operations.
|
|
12245
|
+
* This is typically the domain name (e.g. "example.com") and determines which
|
|
12246
|
+
* passkeys are available during authentication — only passkeys created under this
|
|
12247
|
+
* RP ID will be offered by the browser. Must match the domain the app is hosted on.
|
|
12248
|
+
*/
|
|
12241
12249
|
readonly passkeyRpId?: string;
|
|
12250
|
+
/**
|
|
12251
|
+
* The relying party display name shown in the browser's passkey creation dialog
|
|
12252
|
+
* as the service requesting the passkey (e.g. "My App" or "Acme Corp").
|
|
12253
|
+
* This identifies your application to the user during the WebAuthn ceremony.
|
|
12254
|
+
*/
|
|
12242
12255
|
readonly passkeyRpName?: string;
|
|
12256
|
+
/**
|
|
12257
|
+
* The display name shown next to the passkey credential in the browser's passkey dialog
|
|
12258
|
+
* (e.g. "My Wallet" or "Trading Account"). This helps users identify the specific
|
|
12259
|
+
* credential when they have multiple passkeys for the same service.
|
|
12260
|
+
* Defaults to "Openfort - Embedded Wallet" if not provided.
|
|
12261
|
+
*/
|
|
12262
|
+
readonly passkeyDisplayName?: string;
|
|
12243
12263
|
constructor(options: {
|
|
12244
12264
|
shieldPublishableKey: string;
|
|
12245
12265
|
shieldDebug?: boolean;
|
|
12266
|
+
/** The relying party identifier (domain) for WebAuthn passkey operations. */
|
|
12246
12267
|
passkeyRpId?: string;
|
|
12268
|
+
/** The relying party display name shown as the service name in passkey dialogs. */
|
|
12247
12269
|
passkeyRpName?: string;
|
|
12270
|
+
/** The credential display name shown next to the passkey in browser dialogs. Defaults to "Openfort - Embedded Wallet". */
|
|
12271
|
+
passkeyDisplayName?: string;
|
|
12248
12272
|
});
|
|
12249
12273
|
}
|
|
12250
12274
|
type OpenfortSDKConfiguration = {
|
|
@@ -12264,6 +12288,7 @@ declare class SDKConfiguration {
|
|
|
12264
12288
|
readonly storage?: IStorage;
|
|
12265
12289
|
readonly passkeyRpId?: string;
|
|
12266
12290
|
readonly passkeyRpName?: string;
|
|
12291
|
+
readonly passkeyDisplayName?: string;
|
|
12267
12292
|
readonly nativeAppIdentifier?: string;
|
|
12268
12293
|
readonly debug?: boolean;
|
|
12269
12294
|
static instance: SDKConfiguration | null;
|
|
@@ -13067,76 +13092,175 @@ declare class ProxyApi {
|
|
|
13067
13092
|
sendSignatureSessionRequest(sessionId: string, signature: string, optimistic?: boolean): Promise<SessionResponse>;
|
|
13068
13093
|
}
|
|
13069
13094
|
|
|
13095
|
+
/**
|
|
13096
|
+
* Passkey-specific error types for better error handling and UX.
|
|
13097
|
+
*
|
|
13098
|
+
* These errors allow consumers to distinguish between:
|
|
13099
|
+
* - User cancellation (expected flow)
|
|
13100
|
+
* - PRF not supported (device limitation)
|
|
13101
|
+
* - Invalid seed (configuration error)
|
|
13102
|
+
* - Creation/assertion failures (unexpected errors)
|
|
13103
|
+
*/
|
|
13104
|
+
|
|
13105
|
+
/** Error codes for passkey operations */
|
|
13106
|
+
declare const PASSKEY_ERROR_CODES: {
|
|
13107
|
+
readonly USER_CANCELLED: "passkey_user_cancelled";
|
|
13108
|
+
readonly CREATION_FAILED: "passkey_creation_failed";
|
|
13109
|
+
readonly ASSERTION_FAILED: "passkey_assertion_failed";
|
|
13110
|
+
readonly PRF_NOT_SUPPORTED: "passkey_prf_not_supported";
|
|
13111
|
+
readonly INVALID_SEED: "passkey_invalid_seed";
|
|
13112
|
+
};
|
|
13113
|
+
type PasskeyErrorCode = (typeof PASSKEY_ERROR_CODES)[keyof typeof PASSKEY_ERROR_CODES];
|
|
13114
|
+
/**
|
|
13115
|
+
* Error thrown when user cancels a passkey operation.
|
|
13116
|
+
* This is an expected flow, not a failure.
|
|
13117
|
+
*/
|
|
13118
|
+
declare class PasskeyUserCancelledError extends OpenfortError {
|
|
13119
|
+
constructor(message?: string);
|
|
13120
|
+
}
|
|
13121
|
+
/**
|
|
13122
|
+
* Error thrown when passkey creation fails.
|
|
13123
|
+
*/
|
|
13124
|
+
declare class PasskeyCreationFailedError extends OpenfortError {
|
|
13125
|
+
readonly cause?: Error;
|
|
13126
|
+
constructor(message?: string, cause?: Error);
|
|
13127
|
+
}
|
|
13128
|
+
/**
|
|
13129
|
+
* Error thrown when PRF extension is not supported.
|
|
13130
|
+
* This typically means the device/browser doesn't support the PRF WebAuthn extension.
|
|
13131
|
+
*/
|
|
13132
|
+
declare class PasskeyPRFNotSupportedError extends OpenfortError {
|
|
13133
|
+
constructor(message?: string);
|
|
13134
|
+
}
|
|
13135
|
+
/**
|
|
13136
|
+
* Error thrown when passkey assertion (get) fails.
|
|
13137
|
+
*/
|
|
13138
|
+
declare class PasskeyAssertionFailedError extends OpenfortError {
|
|
13139
|
+
readonly cause?: Error;
|
|
13140
|
+
constructor(message?: string, cause?: Error);
|
|
13141
|
+
}
|
|
13142
|
+
/**
|
|
13143
|
+
* Error thrown when passkey seed is invalid (empty or missing).
|
|
13144
|
+
* The seed is required for PRF key derivation.
|
|
13145
|
+
*/
|
|
13146
|
+
declare class PasskeySeedInvalidError extends OpenfortError {
|
|
13147
|
+
constructor(message?: string);
|
|
13148
|
+
}
|
|
13149
|
+
|
|
13150
|
+
/**
|
|
13151
|
+
* Passkey types and interfaces.
|
|
13152
|
+
*/
|
|
13153
|
+
/**
|
|
13154
|
+
* Configuration for creating a new passkey.
|
|
13155
|
+
*/
|
|
13156
|
+
interface PasskeyCreateConfig {
|
|
13157
|
+
/** Unique identifier for the passkey */
|
|
13158
|
+
id: string;
|
|
13159
|
+
/** Human-readable display name shown in passkey dialogs */
|
|
13160
|
+
displayName: string;
|
|
13161
|
+
/** Seed value used for PRF-based key derivation */
|
|
13162
|
+
seed: string;
|
|
13163
|
+
}
|
|
13164
|
+
/**
|
|
13165
|
+
* Configuration for deriving a key from an existing passkey.
|
|
13166
|
+
*/
|
|
13167
|
+
interface PasskeyDeriveConfig {
|
|
13168
|
+
/** The passkey ID (base64 encoded credential ID) */
|
|
13169
|
+
id: string;
|
|
13170
|
+
/** Seed value used for PRF-based key derivation */
|
|
13171
|
+
seed: string;
|
|
13172
|
+
}
|
|
13173
|
+
/**
|
|
13174
|
+
* Result of passkey creation.
|
|
13175
|
+
*/
|
|
13176
|
+
interface PasskeyDetails {
|
|
13177
|
+
/** The passkey ID (base64 encoded credential ID) */
|
|
13178
|
+
id: string;
|
|
13179
|
+
/** Human-readable display name */
|
|
13180
|
+
displayName?: string;
|
|
13181
|
+
/** Derived key material as base64url string */
|
|
13182
|
+
key?: string;
|
|
13183
|
+
}
|
|
13184
|
+
/**
|
|
13185
|
+
* Strategy interface for passkey handlers.
|
|
13186
|
+
* Implementations: PasskeyHandler (browser), native handlers (React Native)
|
|
13187
|
+
*/
|
|
13188
|
+
interface IPasskeyHandler {
|
|
13189
|
+
/** Creates a new passkey and derives a key using the PRF extension. */
|
|
13190
|
+
createPasskey(config: PasskeyCreateConfig): Promise<PasskeyDetails>;
|
|
13191
|
+
/** Derives and exports key material from an existing passkey as base64url string. */
|
|
13192
|
+
deriveAndExportKey(config: PasskeyDeriveConfig): Promise<string>;
|
|
13193
|
+
}
|
|
13194
|
+
|
|
13070
13195
|
/**
|
|
13071
13196
|
* PasskeyHandler handles operations related to passkeys.
|
|
13072
13197
|
* This class is ONLY suitable for key-derivation related use cases.
|
|
13073
13198
|
* That is, it's not designed (and must NOT be used) for authentication.
|
|
13074
13199
|
*/
|
|
13075
|
-
declare class PasskeyHandler {
|
|
13076
|
-
private readonly
|
|
13200
|
+
declare class PasskeyHandler implements IPasskeyHandler {
|
|
13201
|
+
private readonly validByteLengths;
|
|
13077
13202
|
private readonly rpId?;
|
|
13078
13203
|
private readonly rpName?;
|
|
13079
|
-
private readonly
|
|
13204
|
+
private readonly timeoutMs;
|
|
13080
13205
|
private readonly derivedKeyLengthBytes;
|
|
13081
|
-
private readonly extractableKey;
|
|
13082
13206
|
/**
|
|
13083
13207
|
* Creates a new passkey handler
|
|
13084
13208
|
* The only fixed values from an issuer's point of view are rpId + rpName
|
|
13085
13209
|
* @param rpId The issuer's domain name
|
|
13086
13210
|
* @param rpName The issuer's display name
|
|
13087
|
-
* @param
|
|
13088
|
-
* @param derivedKeyLengthBytes Byte length for target keys
|
|
13089
|
-
* @param extractableKey Whether keys are extractable
|
|
13211
|
+
* @param timeoutMs Timeout (in milliseconds) before a passkey dialog expires
|
|
13212
|
+
* @param derivedKeyLengthBytes Byte length for target keys (16, 24, or 32)
|
|
13090
13213
|
*/
|
|
13091
|
-
constructor({ rpId, rpName,
|
|
13214
|
+
constructor({ rpId, rpName, timeoutMs, derivedKeyLengthBytes }?: PasskeyHandlerConfig);
|
|
13092
13215
|
static randomPasskeyName(): string;
|
|
13093
13216
|
private getChallengeBytes;
|
|
13094
|
-
private
|
|
13217
|
+
private deriveKeyFromAssertion;
|
|
13095
13218
|
/**
|
|
13096
13219
|
* Prompts the user to create a passkey.
|
|
13097
|
-
* @param
|
|
13220
|
+
* @param id User identifier
|
|
13098
13221
|
* @param displayName Display name (ideally it should hint about environment, chain id, etc)
|
|
13222
|
+
* @param seed Seed phrase for PRF key derivation
|
|
13099
13223
|
* @returns PasskeyDetails with passkey details if passkey creation was successful
|
|
13224
|
+
* @throws PasskeySeedInvalidError if seed is empty
|
|
13225
|
+
* @throws PasskeyUserCancelledError if user cancels the operation
|
|
13226
|
+
* @throws PasskeyPRFNotSupportedError if PRF extension fails
|
|
13227
|
+
* @throws PasskeyCreationFailedError for other failures
|
|
13100
13228
|
*/
|
|
13101
|
-
createPasskey({ id, displayName, seed }:
|
|
13102
|
-
private base64ToArrayBuffer;
|
|
13103
|
-
/**
|
|
13104
|
-
* Derives a key using a locally available passkey (for which the user must be able to auth to)
|
|
13105
|
-
* @param id: Internal ID of the passkey
|
|
13106
|
-
* @param seed: Seed phrase to derive passkey ID
|
|
13107
|
-
* @returns CryptoKey object
|
|
13108
|
-
*/
|
|
13109
|
-
deriveKey({ id, seed }: Passkeys.DerivationDetails): Promise<CryptoKey>;
|
|
13229
|
+
createPasskey({ id, displayName, seed }: PasskeyCreateConfig): Promise<PasskeyDetails>;
|
|
13110
13230
|
/**
|
|
13111
13231
|
* Derive and export a key using local passkey
|
|
13112
|
-
* @
|
|
13232
|
+
* @param id Internal ID of the passkey
|
|
13233
|
+
* @param seed Seed phrase to derive passkey ID
|
|
13234
|
+
* @returns base64url encoded derived key
|
|
13235
|
+
* @throws PasskeySeedInvalidError if seed is empty
|
|
13236
|
+
* @throws PasskeyUserCancelledError if user cancels the operation
|
|
13237
|
+
* @throws PasskeyPRFNotSupportedError if PRF extension fails
|
|
13238
|
+
* @throws PasskeyAssertionFailedError for other failures
|
|
13113
13239
|
*/
|
|
13114
|
-
deriveAndExportKey({ id, seed }:
|
|
13240
|
+
deriveAndExportKey({ id, seed }: PasskeyDeriveConfig): Promise<string>;
|
|
13115
13241
|
}
|
|
13116
|
-
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
|
|
13121
|
-
|
|
13122
|
-
|
|
13123
|
-
};
|
|
13124
|
-
type UserConfig = {
|
|
13125
|
-
id: string;
|
|
13126
|
-
displayName: string;
|
|
13127
|
-
seed: string;
|
|
13128
|
-
};
|
|
13129
|
-
type Details = {
|
|
13130
|
-
id: string;
|
|
13131
|
-
displayName?: string;
|
|
13132
|
-
key?: Uint8Array;
|
|
13133
|
-
};
|
|
13134
|
-
type DerivationDetails = {
|
|
13135
|
-
id: string;
|
|
13136
|
-
seed: string;
|
|
13137
|
-
};
|
|
13242
|
+
interface PasskeyHandlerConfig {
|
|
13243
|
+
rpId?: string;
|
|
13244
|
+
rpName?: string;
|
|
13245
|
+
/** Timeout in milliseconds before passkey dialog expires (default: 60000) */
|
|
13246
|
+
timeoutMs?: number;
|
|
13247
|
+
/** Derived key length in bytes: 16, 24, or 32 (default: 32) */
|
|
13248
|
+
derivedKeyLengthBytes?: number;
|
|
13138
13249
|
}
|
|
13139
13250
|
|
|
13251
|
+
/**
|
|
13252
|
+
* Base64/Base64URL encoding utilities for passkey operations.
|
|
13253
|
+
*/
|
|
13254
|
+
/**
|
|
13255
|
+
* Converts ArrayBuffer or Uint8Array to base64url string.
|
|
13256
|
+
* Base64URL uses '-' and '_' instead of '+' and '/', and omits padding '='.
|
|
13257
|
+
*/
|
|
13258
|
+
declare function arrayBufferToBase64URL(buffer: ArrayBuffer | Uint8Array): string;
|
|
13259
|
+
/**
|
|
13260
|
+
* Converts base64 string to ArrayBuffer.
|
|
13261
|
+
*/
|
|
13262
|
+
declare function base64ToArrayBuffer(base64: string): ArrayBuffer;
|
|
13263
|
+
|
|
13140
13264
|
declare class Openfort {
|
|
13141
13265
|
private storage;
|
|
13142
13266
|
private iAuthManager;
|
|
@@ -13183,7 +13307,7 @@ declare class Openfort {
|
|
|
13183
13307
|
validateAndRefreshToken(forceRefresh?: boolean): Promise<void>;
|
|
13184
13308
|
private get backendApiClients();
|
|
13185
13309
|
private get authManager();
|
|
13186
|
-
get passkeyHandler():
|
|
13310
|
+
get passkeyHandler(): IPasskeyHandler;
|
|
13187
13311
|
static isStorageAccessible(storage: IStorage): Promise<boolean>;
|
|
13188
13312
|
/**
|
|
13189
13313
|
* Performs async initialization tasks
|
|
@@ -13228,7 +13352,7 @@ interface SignerConfigureRequest {
|
|
|
13228
13352
|
entropy?: EntropyResponse;
|
|
13229
13353
|
accountType: AccountTypeEnum;
|
|
13230
13354
|
chainType: ChainTypeEnum;
|
|
13231
|
-
getPasskeyKeyFn: (id: string) => Promise<
|
|
13355
|
+
getPasskeyKeyFn: (id: string) => Promise<string>;
|
|
13232
13356
|
}
|
|
13233
13357
|
interface SignerCreateRequest {
|
|
13234
13358
|
accountType: AccountTypeEnum;
|
|
@@ -13555,4 +13679,4 @@ declare function cryptoDigest(algorithm: string, data: BufferSource): Promise<Ar
|
|
|
13555
13679
|
*/
|
|
13556
13680
|
declare const openfortEvents: TypedEventEmitter<OpenfortEventMap>;
|
|
13557
13681
|
|
|
13558
|
-
export { AccountTypeEnum, AuthActionRequiredActions, AuthActionRequiredResponse, AuthApi, AuthInitPayload, AuthResponse, AuthType, AuthenticationError, Authorization, AuthorizationError, BasicAuthProvider, ChainTypeEnum, ConfigurationError, EmbeddedAccount, EmbeddedState, EmbeddedWalletApi, GrantPermissionsParameters, GrantPermissionsReturnType, InitializeOAuthOptions, MissingProjectEntropyError, MissingRecoveryPasswordError, NotConfiguredError, OAuthError, OAuthProvider, OPENFORT_AUTH_ERROR_CODES, OPENFORT_ERROR_CODES, OTPError, OTPRequiredError, Openfort, OpenfortAuthErrorCode, OpenfortConfiguration, OpenfortError, OpenfortErrorCode, OpenfortEventMap, OpenfortEvents, OpenfortInternal, OpenfortSDKConfiguration, Permission, Policy, PrepareAuthorizationParams, Provider, ProxyApi, RecoveryError, RecoveryMethod, RecoveryParams, RequestError, RevokePermissionsRequestParams, SDKConfiguration, SDKOverrides, SessionError, SessionResponse, ShieldAuthOptions, ShieldConfiguration, ShieldOptions, SignAuthorizationParams, SignedAuthorization, SignedMessagePayload, Signer, SignerError, IStorage as Storage, ThirdPartyAuthConfiguration, ThirdPartyAuthProvider as ThirdPartyOAuthProvider, TokenType, TransactionIntentResponse, TypedDataPayload, User, ListAccountsGet200ResponseInner as UserAccount, UserApi, UserError, WrongPasskeyError, WrongRecoveryPasswordError, cryptoDigest, openfortEvents, prepareAndSignAuthorization, serializeSignedAuthorization, signAuthorization };
|
|
13682
|
+
export { AccountTypeEnum, AuthActionRequiredActions, AuthActionRequiredResponse, AuthApi, AuthInitPayload, AuthResponse, AuthType, AuthenticationError, Authorization, AuthorizationError, BasicAuthProvider, ChainTypeEnum, ConfigurationError, EmbeddedAccount, EmbeddedState, EmbeddedWalletApi, GrantPermissionsParameters, GrantPermissionsReturnType, IPasskeyHandler, InitializeOAuthOptions, MissingProjectEntropyError, MissingRecoveryPasswordError, NotConfiguredError, OAuthError, OAuthProvider, OPENFORT_AUTH_ERROR_CODES, OPENFORT_ERROR_CODES, OTPError, OTPRequiredError, Openfort, OpenfortAuthErrorCode, OpenfortConfiguration, OpenfortError, OpenfortErrorCode, OpenfortEventMap, OpenfortEvents, OpenfortInternal, OpenfortSDKConfiguration, PASSKEY_ERROR_CODES, PasskeyAssertionFailedError, PasskeyCreateConfig, PasskeyCreationFailedError, PasskeyDeriveConfig, PasskeyDetails, PasskeyEnv, PasskeyErrorCode, PasskeyHandler, PasskeyPRFNotSupportedError, PasskeySeedInvalidError, PasskeyUserCancelledError, Permission, Policy, PrepareAuthorizationParams, Provider, ProxyApi, RecoveryError, RecoveryMethod, RecoveryMethodDetails, RecoveryParams, RequestError, RevokePermissionsRequestParams, SDKConfiguration, SDKOverrides, SessionError, SessionResponse, ShieldAuthOptions, ShieldConfiguration, ShieldOptions, SignAuthorizationParams, SignedAuthorization, SignedMessagePayload, Signer, SignerError, IStorage as Storage, ThirdPartyAuthConfiguration, ThirdPartyAuthProvider as ThirdPartyOAuthProvider, TokenType, TransactionIntentResponse, TypedDataPayload, User, ListAccountsGet200ResponseInner as UserAccount, UserApi, UserError, WrongPasskeyError, WrongRecoveryPasswordError, arrayBufferToBase64URL, base64ToArrayBuffer, cryptoDigest, openfortEvents, prepareAndSignAuthorization, serializeSignedAuthorization, signAuthorization };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PasskeyDetails } from 'wallets/types';
|
|
2
|
-
import {
|
|
1
|
+
import { PasskeyDetails as PasskeyDetails$1 } from 'wallets/types';
|
|
2
|
+
import { IPasskeyHandler as IPasskeyHandler$1 } from 'core/passkey';
|
|
3
3
|
import { User as User$2, ThirdPartyOAuthProvider as ThirdPartyOAuthProvider$1 } from 'types';
|
|
4
4
|
import { Account } from 'core/configuration/account';
|
|
5
5
|
import { Hex } from 'wallets/evm/types';
|
|
@@ -368,6 +368,7 @@ interface TransitionalOptions {
|
|
|
368
368
|
silentJSONParsing?: boolean;
|
|
369
369
|
forcedJSONParsing?: boolean;
|
|
370
370
|
clarifyTimeoutError?: boolean;
|
|
371
|
+
legacyInterceptorReqResOrdering?: boolean;
|
|
371
372
|
}
|
|
372
373
|
|
|
373
374
|
interface GenericAbortSignal {
|
|
@@ -11923,7 +11924,7 @@ type EmbeddedAccountCreateParams = {
|
|
|
11923
11924
|
};
|
|
11924
11925
|
type PasskeyInfo = {
|
|
11925
11926
|
passkeyId: string;
|
|
11926
|
-
passkeyKey?:
|
|
11927
|
+
passkeyKey?: string;
|
|
11927
11928
|
};
|
|
11928
11929
|
type RecoveryParams = {
|
|
11929
11930
|
recoveryMethod: RecoveryMethod.AUTOMATIC;
|
|
@@ -11938,7 +11939,7 @@ type RecoveryParams = {
|
|
|
11938
11939
|
type EntropyResponse = {
|
|
11939
11940
|
recoveryPassword?: string;
|
|
11940
11941
|
encryptionSession?: string;
|
|
11941
|
-
passkey?: PasskeyDetails;
|
|
11942
|
+
passkey?: PasskeyDetails$1;
|
|
11942
11943
|
};
|
|
11943
11944
|
declare enum SortOrdering {
|
|
11944
11945
|
ASC = "asc",
|
|
@@ -12153,7 +12154,7 @@ declare class EmbeddedWalletApi {
|
|
|
12153
12154
|
private provider;
|
|
12154
12155
|
private messagePoster;
|
|
12155
12156
|
private messenger;
|
|
12156
|
-
constructor(storage: IStorage, validateAndRefreshToken: () => Promise<void>, ensureInitialized: () => Promise<void>, eventEmitter: TypedEventEmitter<OpenfortEventMap>, passkeyHandler:
|
|
12157
|
+
constructor(storage: IStorage, validateAndRefreshToken: () => Promise<void>, ensureInitialized: () => Promise<void>, eventEmitter: TypedEventEmitter<OpenfortEventMap>, passkeyHandler: IPasskeyHandler$1);
|
|
12157
12158
|
private get backendApiClients();
|
|
12158
12159
|
private getIframeManager;
|
|
12159
12160
|
private createIframeManager;
|
|
@@ -12218,6 +12219,7 @@ interface SDKOverrides {
|
|
|
12218
12219
|
digest?: (algorithm: string, data: BufferSource) => Promise<ArrayBuffer>;
|
|
12219
12220
|
};
|
|
12220
12221
|
storage?: IStorage;
|
|
12222
|
+
passkeyHandler?: IPasskeyHandler$1;
|
|
12221
12223
|
}
|
|
12222
12224
|
interface ThirdPartyAuthConfiguration {
|
|
12223
12225
|
provider: ThirdPartyOAuthProvider$1;
|
|
@@ -12238,13 +12240,35 @@ declare class ShieldConfiguration {
|
|
|
12238
12240
|
*/
|
|
12239
12241
|
readonly shieldEncryptionKey?: string;
|
|
12240
12242
|
readonly debug?: boolean;
|
|
12243
|
+
/**
|
|
12244
|
+
* The relying party identifier for WebAuthn passkey operations.
|
|
12245
|
+
* This is typically the domain name (e.g. "example.com") and determines which
|
|
12246
|
+
* passkeys are available during authentication — only passkeys created under this
|
|
12247
|
+
* RP ID will be offered by the browser. Must match the domain the app is hosted on.
|
|
12248
|
+
*/
|
|
12241
12249
|
readonly passkeyRpId?: string;
|
|
12250
|
+
/**
|
|
12251
|
+
* The relying party display name shown in the browser's passkey creation dialog
|
|
12252
|
+
* as the service requesting the passkey (e.g. "My App" or "Acme Corp").
|
|
12253
|
+
* This identifies your application to the user during the WebAuthn ceremony.
|
|
12254
|
+
*/
|
|
12242
12255
|
readonly passkeyRpName?: string;
|
|
12256
|
+
/**
|
|
12257
|
+
* The display name shown next to the passkey credential in the browser's passkey dialog
|
|
12258
|
+
* (e.g. "My Wallet" or "Trading Account"). This helps users identify the specific
|
|
12259
|
+
* credential when they have multiple passkeys for the same service.
|
|
12260
|
+
* Defaults to "Openfort - Embedded Wallet" if not provided.
|
|
12261
|
+
*/
|
|
12262
|
+
readonly passkeyDisplayName?: string;
|
|
12243
12263
|
constructor(options: {
|
|
12244
12264
|
shieldPublishableKey: string;
|
|
12245
12265
|
shieldDebug?: boolean;
|
|
12266
|
+
/** The relying party identifier (domain) for WebAuthn passkey operations. */
|
|
12246
12267
|
passkeyRpId?: string;
|
|
12268
|
+
/** The relying party display name shown as the service name in passkey dialogs. */
|
|
12247
12269
|
passkeyRpName?: string;
|
|
12270
|
+
/** The credential display name shown next to the passkey in browser dialogs. Defaults to "Openfort - Embedded Wallet". */
|
|
12271
|
+
passkeyDisplayName?: string;
|
|
12248
12272
|
});
|
|
12249
12273
|
}
|
|
12250
12274
|
type OpenfortSDKConfiguration = {
|
|
@@ -12264,6 +12288,7 @@ declare class SDKConfiguration {
|
|
|
12264
12288
|
readonly storage?: IStorage;
|
|
12265
12289
|
readonly passkeyRpId?: string;
|
|
12266
12290
|
readonly passkeyRpName?: string;
|
|
12291
|
+
readonly passkeyDisplayName?: string;
|
|
12267
12292
|
readonly nativeAppIdentifier?: string;
|
|
12268
12293
|
readonly debug?: boolean;
|
|
12269
12294
|
static instance: SDKConfiguration | null;
|
|
@@ -13067,76 +13092,175 @@ declare class ProxyApi {
|
|
|
13067
13092
|
sendSignatureSessionRequest(sessionId: string, signature: string, optimistic?: boolean): Promise<SessionResponse>;
|
|
13068
13093
|
}
|
|
13069
13094
|
|
|
13095
|
+
/**
|
|
13096
|
+
* Passkey-specific error types for better error handling and UX.
|
|
13097
|
+
*
|
|
13098
|
+
* These errors allow consumers to distinguish between:
|
|
13099
|
+
* - User cancellation (expected flow)
|
|
13100
|
+
* - PRF not supported (device limitation)
|
|
13101
|
+
* - Invalid seed (configuration error)
|
|
13102
|
+
* - Creation/assertion failures (unexpected errors)
|
|
13103
|
+
*/
|
|
13104
|
+
|
|
13105
|
+
/** Error codes for passkey operations */
|
|
13106
|
+
declare const PASSKEY_ERROR_CODES: {
|
|
13107
|
+
readonly USER_CANCELLED: "passkey_user_cancelled";
|
|
13108
|
+
readonly CREATION_FAILED: "passkey_creation_failed";
|
|
13109
|
+
readonly ASSERTION_FAILED: "passkey_assertion_failed";
|
|
13110
|
+
readonly PRF_NOT_SUPPORTED: "passkey_prf_not_supported";
|
|
13111
|
+
readonly INVALID_SEED: "passkey_invalid_seed";
|
|
13112
|
+
};
|
|
13113
|
+
type PasskeyErrorCode = (typeof PASSKEY_ERROR_CODES)[keyof typeof PASSKEY_ERROR_CODES];
|
|
13114
|
+
/**
|
|
13115
|
+
* Error thrown when user cancels a passkey operation.
|
|
13116
|
+
* This is an expected flow, not a failure.
|
|
13117
|
+
*/
|
|
13118
|
+
declare class PasskeyUserCancelledError extends OpenfortError {
|
|
13119
|
+
constructor(message?: string);
|
|
13120
|
+
}
|
|
13121
|
+
/**
|
|
13122
|
+
* Error thrown when passkey creation fails.
|
|
13123
|
+
*/
|
|
13124
|
+
declare class PasskeyCreationFailedError extends OpenfortError {
|
|
13125
|
+
readonly cause?: Error;
|
|
13126
|
+
constructor(message?: string, cause?: Error);
|
|
13127
|
+
}
|
|
13128
|
+
/**
|
|
13129
|
+
* Error thrown when PRF extension is not supported.
|
|
13130
|
+
* This typically means the device/browser doesn't support the PRF WebAuthn extension.
|
|
13131
|
+
*/
|
|
13132
|
+
declare class PasskeyPRFNotSupportedError extends OpenfortError {
|
|
13133
|
+
constructor(message?: string);
|
|
13134
|
+
}
|
|
13135
|
+
/**
|
|
13136
|
+
* Error thrown when passkey assertion (get) fails.
|
|
13137
|
+
*/
|
|
13138
|
+
declare class PasskeyAssertionFailedError extends OpenfortError {
|
|
13139
|
+
readonly cause?: Error;
|
|
13140
|
+
constructor(message?: string, cause?: Error);
|
|
13141
|
+
}
|
|
13142
|
+
/**
|
|
13143
|
+
* Error thrown when passkey seed is invalid (empty or missing).
|
|
13144
|
+
* The seed is required for PRF key derivation.
|
|
13145
|
+
*/
|
|
13146
|
+
declare class PasskeySeedInvalidError extends OpenfortError {
|
|
13147
|
+
constructor(message?: string);
|
|
13148
|
+
}
|
|
13149
|
+
|
|
13150
|
+
/**
|
|
13151
|
+
* Passkey types and interfaces.
|
|
13152
|
+
*/
|
|
13153
|
+
/**
|
|
13154
|
+
* Configuration for creating a new passkey.
|
|
13155
|
+
*/
|
|
13156
|
+
interface PasskeyCreateConfig {
|
|
13157
|
+
/** Unique identifier for the passkey */
|
|
13158
|
+
id: string;
|
|
13159
|
+
/** Human-readable display name shown in passkey dialogs */
|
|
13160
|
+
displayName: string;
|
|
13161
|
+
/** Seed value used for PRF-based key derivation */
|
|
13162
|
+
seed: string;
|
|
13163
|
+
}
|
|
13164
|
+
/**
|
|
13165
|
+
* Configuration for deriving a key from an existing passkey.
|
|
13166
|
+
*/
|
|
13167
|
+
interface PasskeyDeriveConfig {
|
|
13168
|
+
/** The passkey ID (base64 encoded credential ID) */
|
|
13169
|
+
id: string;
|
|
13170
|
+
/** Seed value used for PRF-based key derivation */
|
|
13171
|
+
seed: string;
|
|
13172
|
+
}
|
|
13173
|
+
/**
|
|
13174
|
+
* Result of passkey creation.
|
|
13175
|
+
*/
|
|
13176
|
+
interface PasskeyDetails {
|
|
13177
|
+
/** The passkey ID (base64 encoded credential ID) */
|
|
13178
|
+
id: string;
|
|
13179
|
+
/** Human-readable display name */
|
|
13180
|
+
displayName?: string;
|
|
13181
|
+
/** Derived key material as base64url string */
|
|
13182
|
+
key?: string;
|
|
13183
|
+
}
|
|
13184
|
+
/**
|
|
13185
|
+
* Strategy interface for passkey handlers.
|
|
13186
|
+
* Implementations: PasskeyHandler (browser), native handlers (React Native)
|
|
13187
|
+
*/
|
|
13188
|
+
interface IPasskeyHandler {
|
|
13189
|
+
/** Creates a new passkey and derives a key using the PRF extension. */
|
|
13190
|
+
createPasskey(config: PasskeyCreateConfig): Promise<PasskeyDetails>;
|
|
13191
|
+
/** Derives and exports key material from an existing passkey as base64url string. */
|
|
13192
|
+
deriveAndExportKey(config: PasskeyDeriveConfig): Promise<string>;
|
|
13193
|
+
}
|
|
13194
|
+
|
|
13070
13195
|
/**
|
|
13071
13196
|
* PasskeyHandler handles operations related to passkeys.
|
|
13072
13197
|
* This class is ONLY suitable for key-derivation related use cases.
|
|
13073
13198
|
* That is, it's not designed (and must NOT be used) for authentication.
|
|
13074
13199
|
*/
|
|
13075
|
-
declare class PasskeyHandler {
|
|
13076
|
-
private readonly
|
|
13200
|
+
declare class PasskeyHandler implements IPasskeyHandler {
|
|
13201
|
+
private readonly validByteLengths;
|
|
13077
13202
|
private readonly rpId?;
|
|
13078
13203
|
private readonly rpName?;
|
|
13079
|
-
private readonly
|
|
13204
|
+
private readonly timeoutMs;
|
|
13080
13205
|
private readonly derivedKeyLengthBytes;
|
|
13081
|
-
private readonly extractableKey;
|
|
13082
13206
|
/**
|
|
13083
13207
|
* Creates a new passkey handler
|
|
13084
13208
|
* The only fixed values from an issuer's point of view are rpId + rpName
|
|
13085
13209
|
* @param rpId The issuer's domain name
|
|
13086
13210
|
* @param rpName The issuer's display name
|
|
13087
|
-
* @param
|
|
13088
|
-
* @param derivedKeyLengthBytes Byte length for target keys
|
|
13089
|
-
* @param extractableKey Whether keys are extractable
|
|
13211
|
+
* @param timeoutMs Timeout (in milliseconds) before a passkey dialog expires
|
|
13212
|
+
* @param derivedKeyLengthBytes Byte length for target keys (16, 24, or 32)
|
|
13090
13213
|
*/
|
|
13091
|
-
constructor({ rpId, rpName,
|
|
13214
|
+
constructor({ rpId, rpName, timeoutMs, derivedKeyLengthBytes }?: PasskeyHandlerConfig);
|
|
13092
13215
|
static randomPasskeyName(): string;
|
|
13093
13216
|
private getChallengeBytes;
|
|
13094
|
-
private
|
|
13217
|
+
private deriveKeyFromAssertion;
|
|
13095
13218
|
/**
|
|
13096
13219
|
* Prompts the user to create a passkey.
|
|
13097
|
-
* @param
|
|
13220
|
+
* @param id User identifier
|
|
13098
13221
|
* @param displayName Display name (ideally it should hint about environment, chain id, etc)
|
|
13222
|
+
* @param seed Seed phrase for PRF key derivation
|
|
13099
13223
|
* @returns PasskeyDetails with passkey details if passkey creation was successful
|
|
13224
|
+
* @throws PasskeySeedInvalidError if seed is empty
|
|
13225
|
+
* @throws PasskeyUserCancelledError if user cancels the operation
|
|
13226
|
+
* @throws PasskeyPRFNotSupportedError if PRF extension fails
|
|
13227
|
+
* @throws PasskeyCreationFailedError for other failures
|
|
13100
13228
|
*/
|
|
13101
|
-
createPasskey({ id, displayName, seed }:
|
|
13102
|
-
private base64ToArrayBuffer;
|
|
13103
|
-
/**
|
|
13104
|
-
* Derives a key using a locally available passkey (for which the user must be able to auth to)
|
|
13105
|
-
* @param id: Internal ID of the passkey
|
|
13106
|
-
* @param seed: Seed phrase to derive passkey ID
|
|
13107
|
-
* @returns CryptoKey object
|
|
13108
|
-
*/
|
|
13109
|
-
deriveKey({ id, seed }: Passkeys.DerivationDetails): Promise<CryptoKey>;
|
|
13229
|
+
createPasskey({ id, displayName, seed }: PasskeyCreateConfig): Promise<PasskeyDetails>;
|
|
13110
13230
|
/**
|
|
13111
13231
|
* Derive and export a key using local passkey
|
|
13112
|
-
* @
|
|
13232
|
+
* @param id Internal ID of the passkey
|
|
13233
|
+
* @param seed Seed phrase to derive passkey ID
|
|
13234
|
+
* @returns base64url encoded derived key
|
|
13235
|
+
* @throws PasskeySeedInvalidError if seed is empty
|
|
13236
|
+
* @throws PasskeyUserCancelledError if user cancels the operation
|
|
13237
|
+
* @throws PasskeyPRFNotSupportedError if PRF extension fails
|
|
13238
|
+
* @throws PasskeyAssertionFailedError for other failures
|
|
13113
13239
|
*/
|
|
13114
|
-
deriveAndExportKey({ id, seed }:
|
|
13240
|
+
deriveAndExportKey({ id, seed }: PasskeyDeriveConfig): Promise<string>;
|
|
13115
13241
|
}
|
|
13116
|
-
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
|
|
13121
|
-
|
|
13122
|
-
|
|
13123
|
-
};
|
|
13124
|
-
type UserConfig = {
|
|
13125
|
-
id: string;
|
|
13126
|
-
displayName: string;
|
|
13127
|
-
seed: string;
|
|
13128
|
-
};
|
|
13129
|
-
type Details = {
|
|
13130
|
-
id: string;
|
|
13131
|
-
displayName?: string;
|
|
13132
|
-
key?: Uint8Array;
|
|
13133
|
-
};
|
|
13134
|
-
type DerivationDetails = {
|
|
13135
|
-
id: string;
|
|
13136
|
-
seed: string;
|
|
13137
|
-
};
|
|
13242
|
+
interface PasskeyHandlerConfig {
|
|
13243
|
+
rpId?: string;
|
|
13244
|
+
rpName?: string;
|
|
13245
|
+
/** Timeout in milliseconds before passkey dialog expires (default: 60000) */
|
|
13246
|
+
timeoutMs?: number;
|
|
13247
|
+
/** Derived key length in bytes: 16, 24, or 32 (default: 32) */
|
|
13248
|
+
derivedKeyLengthBytes?: number;
|
|
13138
13249
|
}
|
|
13139
13250
|
|
|
13251
|
+
/**
|
|
13252
|
+
* Base64/Base64URL encoding utilities for passkey operations.
|
|
13253
|
+
*/
|
|
13254
|
+
/**
|
|
13255
|
+
* Converts ArrayBuffer or Uint8Array to base64url string.
|
|
13256
|
+
* Base64URL uses '-' and '_' instead of '+' and '/', and omits padding '='.
|
|
13257
|
+
*/
|
|
13258
|
+
declare function arrayBufferToBase64URL(buffer: ArrayBuffer | Uint8Array): string;
|
|
13259
|
+
/**
|
|
13260
|
+
* Converts base64 string to ArrayBuffer.
|
|
13261
|
+
*/
|
|
13262
|
+
declare function base64ToArrayBuffer(base64: string): ArrayBuffer;
|
|
13263
|
+
|
|
13140
13264
|
declare class Openfort {
|
|
13141
13265
|
private storage;
|
|
13142
13266
|
private iAuthManager;
|
|
@@ -13183,7 +13307,7 @@ declare class Openfort {
|
|
|
13183
13307
|
validateAndRefreshToken(forceRefresh?: boolean): Promise<void>;
|
|
13184
13308
|
private get backendApiClients();
|
|
13185
13309
|
private get authManager();
|
|
13186
|
-
get passkeyHandler():
|
|
13310
|
+
get passkeyHandler(): IPasskeyHandler;
|
|
13187
13311
|
static isStorageAccessible(storage: IStorage): Promise<boolean>;
|
|
13188
13312
|
/**
|
|
13189
13313
|
* Performs async initialization tasks
|
|
@@ -13228,7 +13352,7 @@ interface SignerConfigureRequest {
|
|
|
13228
13352
|
entropy?: EntropyResponse;
|
|
13229
13353
|
accountType: AccountTypeEnum;
|
|
13230
13354
|
chainType: ChainTypeEnum;
|
|
13231
|
-
getPasskeyKeyFn: (id: string) => Promise<
|
|
13355
|
+
getPasskeyKeyFn: (id: string) => Promise<string>;
|
|
13232
13356
|
}
|
|
13233
13357
|
interface SignerCreateRequest {
|
|
13234
13358
|
accountType: AccountTypeEnum;
|
|
@@ -13555,4 +13679,4 @@ declare function cryptoDigest(algorithm: string, data: BufferSource): Promise<Ar
|
|
|
13555
13679
|
*/
|
|
13556
13680
|
declare const openfortEvents: TypedEventEmitter<OpenfortEventMap>;
|
|
13557
13681
|
|
|
13558
|
-
export { AccountTypeEnum, AuthActionRequiredActions, AuthActionRequiredResponse, AuthApi, AuthInitPayload, AuthResponse, AuthType, AuthenticationError, Authorization, AuthorizationError, BasicAuthProvider, ChainTypeEnum, ConfigurationError, EmbeddedAccount, EmbeddedState, EmbeddedWalletApi, GrantPermissionsParameters, GrantPermissionsReturnType, InitializeOAuthOptions, MissingProjectEntropyError, MissingRecoveryPasswordError, NotConfiguredError, OAuthError, OAuthProvider, OPENFORT_AUTH_ERROR_CODES, OPENFORT_ERROR_CODES, OTPError, OTPRequiredError, Openfort, OpenfortAuthErrorCode, OpenfortConfiguration, OpenfortError, OpenfortErrorCode, OpenfortEventMap, OpenfortEvents, OpenfortInternal, OpenfortSDKConfiguration, Permission, Policy, PrepareAuthorizationParams, Provider, ProxyApi, RecoveryError, RecoveryMethod, RecoveryParams, RequestError, RevokePermissionsRequestParams, SDKConfiguration, SDKOverrides, SessionError, SessionResponse, ShieldAuthOptions, ShieldConfiguration, ShieldOptions, SignAuthorizationParams, SignedAuthorization, SignedMessagePayload, Signer, SignerError, IStorage as Storage, ThirdPartyAuthConfiguration, ThirdPartyAuthProvider as ThirdPartyOAuthProvider, TokenType, TransactionIntentResponse, TypedDataPayload, User, ListAccountsGet200ResponseInner as UserAccount, UserApi, UserError, WrongPasskeyError, WrongRecoveryPasswordError, cryptoDigest, openfortEvents, prepareAndSignAuthorization, serializeSignedAuthorization, signAuthorization };
|
|
13682
|
+
export { AccountTypeEnum, AuthActionRequiredActions, AuthActionRequiredResponse, AuthApi, AuthInitPayload, AuthResponse, AuthType, AuthenticationError, Authorization, AuthorizationError, BasicAuthProvider, ChainTypeEnum, ConfigurationError, EmbeddedAccount, EmbeddedState, EmbeddedWalletApi, GrantPermissionsParameters, GrantPermissionsReturnType, IPasskeyHandler, InitializeOAuthOptions, MissingProjectEntropyError, MissingRecoveryPasswordError, NotConfiguredError, OAuthError, OAuthProvider, OPENFORT_AUTH_ERROR_CODES, OPENFORT_ERROR_CODES, OTPError, OTPRequiredError, Openfort, OpenfortAuthErrorCode, OpenfortConfiguration, OpenfortError, OpenfortErrorCode, OpenfortEventMap, OpenfortEvents, OpenfortInternal, OpenfortSDKConfiguration, PASSKEY_ERROR_CODES, PasskeyAssertionFailedError, PasskeyCreateConfig, PasskeyCreationFailedError, PasskeyDeriveConfig, PasskeyDetails, PasskeyEnv, PasskeyErrorCode, PasskeyHandler, PasskeyPRFNotSupportedError, PasskeySeedInvalidError, PasskeyUserCancelledError, Permission, Policy, PrepareAuthorizationParams, Provider, ProxyApi, RecoveryError, RecoveryMethod, RecoveryMethodDetails, RecoveryParams, RequestError, RevokePermissionsRequestParams, SDKConfiguration, SDKOverrides, SessionError, SessionResponse, ShieldAuthOptions, ShieldConfiguration, ShieldOptions, SignAuthorizationParams, SignedAuthorization, SignedMessagePayload, Signer, SignerError, IStorage as Storage, ThirdPartyAuthConfiguration, ThirdPartyAuthProvider as ThirdPartyOAuthProvider, TokenType, TransactionIntentResponse, TypedDataPayload, User, ListAccountsGet200ResponseInner as UserAccount, UserApi, UserError, WrongPasskeyError, WrongRecoveryPasswordError, arrayBufferToBase64URL, base64ToArrayBuffer, cryptoDigest, openfortEvents, prepareAndSignAuthorization, serializeSignedAuthorization, signAuthorization };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{BackendApiClients as e}from"../../../packages/internal/openapi-clients/dist/index.js";import{PasskeyHandler as t}from"../core/configuration/passkey.js";import{SDKConfiguration as r}from"../core/config/config.js";import{Account as s}from"../core/configuration/account.js";import{Authentication as a}from"../core/configuration/authentication.js";import{OPENFORT_AUTH_ERROR_CODES as i}from"../core/errors/authErrorCodes.js";import{ConfigurationError as n,SessionError as o,SignerError as d}from"../core/errors/openfortError.js";import{withApiError as c}from"../core/errors/withApiError.js";import{OpenfortEvents as h,RecoveryMethod as m,ChainTypeEnum as g,AccountTypeEnum as l,EmbeddedState as y}from"../types/types.js";import{debugLog as p}from"../utils/debug.js";import{EmbeddedSigner as f}from"../wallets/embedded.js";import{EvmProvider as u}from"../wallets/evm/evmProvider.js";import"../wallets/evm/types.js";import{announceProvider as A,openfortProviderInfo as w}from"../wallets/evm/provider/eip6963.js";import{signMessage as v}from"../wallets/evm/walletHelpers.js";import{IframeManager as M}from"../wallets/iframeManager.js";import{ReactNativeMessenger as E}from"../wallets/messaging/ReactNativeMessenger.js";import"../wallets/messaging/browserMessenger/backwardCompatibility.js";import T from"../wallets/messaging/browserMessenger/messengers/WindowMessenger.js";class I{storage;validateAndRefreshToken;ensureInitialized;eventEmitter;passkeyHandler;iframeManager=null;iframeManagerPromise=null;signer=null;signerPromise=null;provider=null;messagePoster=null;messenger=null;constructor(e,t,r,s,a){this.storage=e,this.validateAndRefreshToken=t,this.ensureInitialized=r,this.eventEmitter=s,this.passkeyHandler=a,this.eventEmitter.on(h.ON_LOGOUT,()=>{p("Handling logout event in EmbeddedWalletApi"),this.handleLogout()})}get backendApiClients(){const t=r.getInstance();if(!t)throw new n("Configuration not found");return new e({basePath:t.backendUrl,accessToken:t.baseConfiguration.publishableKey,nativeAppIdentifier:t.nativeAppIdentifier})}async getIframeManager(){if(p("[HANDSHAKE DEBUG] getIframeManager called"),this.iframeManager&&this.iframeManager.hasFailed&&(p("[HANDSHAKE DEBUG] Existing iframeManager has failed, clearing for recreation"),this.messenger&&(this.messenger.destroy(),this.messenger=null),this.iframeManager=null),this.iframeManager)return p("[HANDSHAKE DEBUG] Returning existing iframeManager instance"),this.iframeManager;if(this.iframeManagerPromise)return p("[HANDSHAKE DEBUG] Returning existing iframeManagerPromise"),this.iframeManagerPromise;p("[HANDSHAKE DEBUG] Creating new iframeManager"),this.iframeManagerPromise=this.createIframeManager();try{return p("[HANDSHAKE DEBUG] Awaiting iframeManager creation"),this.iframeManager=await this.iframeManagerPromise,p("[HANDSHAKE DEBUG] IframeManager created successfully"),this.iframeManagerPromise=null,this.iframeManager}catch(e){throw p("[HANDSHAKE DEBUG] Error creating iframeManager:",e),this.iframeManagerPromise=null,this.messenger&&(this.messenger.destroy(),this.messenger=null),this.iframeManager=null,e}}async createIframeManager(){p("[HANDSHAKE DEBUG] createIframeManager starting");const e=r.getInstance();if(!e)throw p("[HANDSHAKE DEBUG] Configuration not found"),new n("Configuration not found");let t;if(p("[HANDSHAKE DEBUG] Configuration found"),this.messagePoster)p("[HANDSHAKE DEBUG] Creating ReactNativeMessenger with messagePoster"),this.messenger&&(p("[HANDSHAKE DEBUG] Destroying old messenger before creating new one"),this.messenger.destroy()),this.messenger=new E(this.messagePoster),p("[HANDSHAKE DEBUG] Created new ReactNativeMessenger instance"),t=this.messenger;else{p("[HANDSHAKE DEBUG] Creating WindowMessenger for browser mode");const r=this.createIframe(e.iframeUrl),s=new URL(e.iframeUrl).origin;t=new T({remoteWindow:r.contentWindow,allowedOrigins:[s]}),p("[HANDSHAKE DEBUG] Created WindowMessenger")}return p("[HANDSHAKE DEBUG] Creating IframeManager instance"),new M(e,this.storage,t)}async ensureSigner(){if(this.iframeManager&&this.iframeManager.hasFailed&&(p("IframeManager has failed, clearing signer for recreation"),this.signer=null),this.signer)return this.signer;if(this.signerPromise)return this.signerPromise;this.signerPromise=this.createSigner();try{return this.signer=await this.signerPromise,this.signer}catch(e){throw this.signerPromise=null,e}finally{this.signerPromise=null}}async createSigner(){const e=await this.getIframeManager();return new f(e,this.storage,this.backendApiClients,this.passkeyHandler,this.eventEmitter)}createIframe(e){if("undefined"==typeof document)throw new n("Document is not available. Please provide a message poster for non-browser environments.");const t=document.getElementById("openfort-iframe");t&&t.remove();const r=document.createElement("iframe");return r.style.display="none",r.id="openfort-iframe",r.src=e,document.body.appendChild(r),r}async getPasskeyKey(e){const t=await a.fromStorage(this.storage);return await this.passkeyHandler.deriveAndExportKey({id:e,seed:t?.userId??""})}async getEntropy(e){switch(e.recoveryMethod){case m.PASSWORD:return{recoveryPassword:e.password};case m.AUTOMATIC:return{encryptionSession:e.encryptionSession};case m.PASSKEY:return{passkey:e.passkeyInfo?{id:e.passkeyInfo.passkeyId,key:e.passkeyInfo.passkeyKey||await this.getPasskeyKey(e.passkeyInfo.passkeyId)}:{}};default:throw new n("Invalid recovery method")}}async configure(e){await this.validateAndRefreshToken();const t=e.recoveryParams??{recoveryMethod:m.AUTOMATIC},[r,a]=await Promise.all([this.ensureSigner(),this.getEntropy(t)]),i={chainId:e.chainId,entropy:a,accountType:e.accountType??l.SMART_ACCOUNT,chainType:e.chainType??g.EVM,getPasskeyKeyFn:async e=>this.getPasskeyKey(e)},n=await r.configure(i);return{id:n.id,chainId:n.chainId,address:n.address,ownerAddress:n.ownerAddress,chainType:n.chainType,accountType:n.accountType,implementationType:n.implementationType,factoryAddress:n.factoryAddress,salt:n.salt,createdAt:n.createdAt,implementationAddress:n.implementationAddress,recoveryMethod:s.parseRecoveryMethod(n.recoveryMethod),recoveryMethodDetails:n.recoveryMethodDetails}}async create(e){await this.validateAndRefreshToken();const r=e.recoveryParams??{recoveryMethod:m.AUTOMATIC},n=await a.fromStorage(this.storage);if(!n)throw new o(i.NOT_LOGGED_IN,"missing authentication");if(r.recoveryMethod===m.PASSKEY){const e=await this.passkeyHandler.createPasskey({id:t.randomPasskeyName(),displayName:"Openfort - Embedded Wallet",seed:n?.userId});r.passkeyInfo={passkeyId:e.id,passkeyKey:e.key}}const[d,c]=await Promise.all([this.ensureSigner(),this.getEntropy(r)]),g=await d.create({accountType:e.accountType,chainType:e.chainType,chainId:e.chainId,entropy:c}),l={id:g.id,chainId:g.chainId,address:g.address,ownerAddress:g.ownerAddress,chainType:g.chainType,accountType:g.accountType,implementationType:g.implementationType,factoryAddress:g.factoryAddress,salt:g.salt,createdAt:g.createdAt,implementationAddress:g.implementationAddress,recoveryMethod:s.parseRecoveryMethod(g.recoveryMethod),recoveryMethodDetails:g.recoveryMethodDetails};return this.eventEmitter.emit(h.ON_EMBEDDED_WALLET_CREATED,l),l}async recover(e){await this.validateAndRefreshToken();const t=e.recoveryParams??{recoveryMethod:m.AUTOMATIC};if(t.recoveryMethod===m.PASSKEY){if(!t.passkeyInfo?.passkeyId)throw new n("Passkey ID must be provided for passkey recovery");t.passkeyInfo={passkeyId:t.passkeyInfo.passkeyId}}const[r,a]=await Promise.all([this.ensureSigner(),this.getEntropy(t)]),i=await r.recover({account:e.account,entropy:a}),o={id:i.id,chainId:i.chainId,implementationAddress:i.implementationAddress,factoryAddress:i.factoryAddress,salt:i.salt,address:i.address,ownerAddress:i.ownerAddress,chainType:i.chainType,accountType:i.accountType,implementationType:i.implementationType,createdAt:i.createdAt,recoveryMethod:s.parseRecoveryMethod(i.recoveryMethod),recoveryMethodDetails:i.recoveryMethodDetails};return this.eventEmitter.emit(h.ON_EMBEDDED_WALLET_RECOVERED,o),o}async signMessage(e,t){await this.validateAndRefreshToken();const r=await this.ensureSigner(),{hashMessage:a=!0,arrayifyMessage:i=!1}=t||{},n=await s.fromStorage(this.storage);return await r.sign(e,i,a,n?.chainType)}async signTypedData(e,t,r){await this.validateAndRefreshToken();const a=await this.ensureSigner(),n=await s.fromStorage(this.storage);if(!n)throw new d(i.MISSING_SIGNER,"No account found");const o={...t};delete o.EIP712Domain;const{_TypedDataEncoder:c}=await import("@ethersproject/hash"),h=c.hash(e,o,r);return await v({hash:h,implementationType:n.implementationType||n.type,chainId:Number(n.chainId),signer:a,address:n.address,ownerAddress:n.ownerAddress,factoryAddress:n.factoryAddress,salt:n.salt})}async exportPrivateKey(){await this.validateAndRefreshToken();const e=await this.ensureSigner();return await e.export()}async setRecoveryMethod(e,r){await this.validateAndRefreshToken();const d=await this.ensureSigner(),c=await a.fromStorage(this.storage);if(!c)throw new o(i.NOT_LOGGED_IN,"missing authentication");let h,g,l,y;if(e.recoveryMethod===m.PASSKEY){const e=await s.fromStorage(this.storage);if(!e)throw new n("missing account");const t=e?.recoveryMethodDetails?.passkeyId;if(!t)throw new n("missing passkey id for account");l={passkeyId:t,passkeyKey:await this.passkeyHandler.deriveAndExportKey({id:t,seed:c.userId})}}else if(r.recoveryMethod===m.PASSKEY){const e=await this.passkeyHandler.createPasskey({id:t.randomPasskeyName(),displayName:"Openfort - Embedded Wallet",seed:c.userId});l={passkeyId:e.id,passkeyKey:e.key},y={passkeyId:e.id}}if(e.recoveryMethod===m.PASSWORD?h=e.password:r.recoveryMethod===m.PASSWORD&&(h=r.password),e.recoveryMethod===m.AUTOMATIC?g=e.encryptionSession:r.recoveryMethod===m.AUTOMATIC&&(g=r.encryptionSession),!h&&!g)throw new n("Password or encryption session is not provided");await d.setRecoveryMethod({recoveryMethod:r.recoveryMethod,recoveryPassword:h,encryptionSession:g,passkeyInfo:l});const p=await s.fromStorage(this.storage);p&&new s({...p,recoveryMethod:r.recoveryMethod,recoveryMethodDetails:y}).save(this.storage)}async get(){await this.validateAndRefreshToken();const e=await s.fromStorage(this.storage);if(!e)throw new d(i.MISSING_SIGNER,"No signer configured");if(!await a.fromStorage(this.storage))throw new o(i.NOT_LOGGED_IN,"No access token found");return{id:e.id,chainId:e.chainId,address:e.address,ownerAddress:e.ownerAddress,factoryAddress:e.factoryAddress,salt:e.salt,chainType:e.chainType,accountType:e.accountType,implementationAddress:e.implementationAddress,implementationType:e.implementationType,createdAt:e.createdAt,recoveryMethod:s.parseRecoveryMethod(e.recoveryMethod),recoveryMethodDetails:e.recoveryMethodDetails}}async list(e){await this.validateAndRefreshToken();const t={accountType:l.SMART_ACCOUNT,...e},d=r.getInstance();if(!d)throw new n("Configuration not found");const h=await a.fromStorage(this.storage);if(!h)throw new o(i.NOT_LOGGED_IN,"No access token found");return await this.validateAndRefreshToken(),c(async()=>(await this.backendApiClients.accountsV2Api.getAccountsV2(t,{headers:h.thirdPartyProvider?{authorization:`Bearer ${d.baseConfiguration.publishableKey}`,"x-player-token":h.token,"x-auth-provider":h.thirdPartyProvider,"x-token-type":h.thirdPartyTokenType}:{authorization:`Bearer ${h.token}`,"x-project-key":d.baseConfiguration.publishableKey}})).data.data.map(e=>({chainType:e.chainType,id:e.id,address:e.address,active:e.smartAccount?.active,ownerAddress:e.ownerAddress,factoryAddress:e.smartAccount?.factoryAddress,salt:e.smartAccount?.salt,accountType:e.accountType,implementationAddress:e.smartAccount?.implementationAddress,createdAt:e.createdAt,implementationType:e.smartAccount?.implementationType,chainId:e.chainId,recoveryMethod:s.parseRecoveryMethod(e.recoveryMethod),recoveryMethodDetails:e.recoveryMethodDetails})),{context:"list"})}async getEmbeddedState(){try{if(!await a.fromStorage(this.storage))return y.UNAUTHENTICATED;return await s.fromStorage(this.storage)?y.READY:y.EMBEDDED_SIGNER_NOT_CONFIGURED}catch(e){return p("Failed to get embedded state:",e),y.UNAUTHENTICATED}}async getEthereumProvider(e){await this.ensureInitialized();const t={announceProvider:!0,...e},r=await a.fromStorage(this.storage),i=await s.fromStorage(this.storage);return this.provider?this.provider&&t.policy&&this.provider.updatePolicy(t.policy):(this.provider=new u({storage:this.storage,openfortEventEmitter:this.eventEmitter,ensureSigner:this.ensureSigner.bind(this),account:i||void 0,authentication:r||void 0,backendApiClients:this.backendApiClients,policyId:t.policy,validateAndRefreshSession:this.validateAndRefreshToken.bind(this),chains:t.chains}),t.announceProvider&&A({info:{...w,...t.providerInfo},provider:this.provider})),this.provider}async ping(e){try{e>0&&await new Promise(t=>{setTimeout(t,e)});const t=await this.getIframeManager();if(!t.isLoaded())return!1;const r=await a.fromStorage(this.storage);if(r)try{return await t.getCurrentDevice(r.userId),!0}catch(e){return!1}return t.isLoaded()}catch(e){return p("Ping failed:",e),!1}}getURL(){const e=r.getInstance();if(!e)throw new n("Configuration not found");return e.iframeUrl}async setMessagePoster(e){if(!e||"function"!=typeof e.postMessage)throw new n("Invalid message poster");this.messagePoster=e,this.messenger&&this.messenger.destroy(),this.iframeManager&&this.iframeManager.destroy(),this.signer=null,this.signerPromise=null,this.iframeManager=null,this.iframeManagerPromise=null,this.messenger=null}async handleLogout(){if("undefined"==typeof document&&!this.messagePoster)return p("Skipping signer disconnect: no messagePoster available in non-browser environment"),this.provider=null,this.messenger=null,this.iframeManager=null,this.iframeManagerPromise=null,this.signer=null,void(this.signerPromise=null);const e=await this.ensureSigner();await e.disconnect(),this.provider=null,this.messenger=null,this.iframeManager=null,this.iframeManagerPromise=null,this.signer=null,this.signerPromise=null}async onMessage(e){if(!e||"object"!=typeof e)return void p("Invalid message received:",e);p("[HANDSHAKE DEBUG] EmbeddedWalletApi onMessage:",e);const t="penpal"===e.namespace&&"SYN"===e.type||e.penpal&&"string"==typeof e.penpal;if(t&&this.messenger&&this.messagePoster)return p("[HANDSHAKE DEBUG] Passing message directly to existing ReactNativeMessenger"),void this.messenger.handleMessage(e);const r=await this.getIframeManager();p(`[HANDSHAKE DEBUG] IframeManager obtained, isLoaded: ${r.isLoaded()}`),t&&!r.isLoaded()&&p("[HANDSHAKE DEBUG] Received penpal message before connection initialized, setting up connection..."),p("[HANDSHAKE DEBUG] Calling iframeManager.onMessage"),await r.onMessage(e),p("[HANDSHAKE DEBUG] iframeManager.onMessage completed")}isReady(){return this.iframeManager?.isLoaded()||!1}}export{I as EmbeddedWalletApi};
|
|
1
|
+
import{BackendApiClients as e}from"../../../packages/internal/openapi-clients/dist/index.js";import{ConfigurationError as r,AuthenticationError as t,SessionError as s,SignerError as a}from"../core/errors/openfortError.js";import{PasskeyHandler as i}from"../core/passkey/handler.js";import{SDKConfiguration as n}from"../core/config/config.js";import{Account as o}from"../core/configuration/account.js";import{Authentication as d}from"../core/configuration/authentication.js";import{OPENFORT_AUTH_ERROR_CODES as c}from"../core/errors/authErrorCodes.js";import{withApiError as h}from"../core/errors/withApiError.js";import{OpenfortEvents as m,RecoveryMethod as g,ChainTypeEnum as y,AccountTypeEnum as l,EmbeddedState as p}from"../types/types.js";import{debugLog as f}from"../utils/debug.js";import{EmbeddedSigner as u}from"../wallets/embedded.js";import{EvmProvider as w}from"../wallets/evm/evmProvider.js";import"../wallets/evm/types.js";import{announceProvider as A,openfortProviderInfo as v}from"../wallets/evm/provider/eip6963.js";import{signMessage as M}from"../wallets/evm/walletHelpers.js";import{IframeManager as E}from"../wallets/iframeManager.js";import{ReactNativeMessenger as I}from"../wallets/messaging/ReactNativeMessenger.js";import"../wallets/messaging/browserMessenger/backwardCompatibility.js";import D from"../wallets/messaging/browserMessenger/messengers/WindowMessenger.js";class T{storage;validateAndRefreshToken;ensureInitialized;eventEmitter;passkeyHandler;iframeManager=null;iframeManagerPromise=null;signer=null;signerPromise=null;provider=null;messagePoster=null;messenger=null;constructor(e,r,t,s,a){this.storage=e,this.validateAndRefreshToken=r,this.ensureInitialized=t,this.eventEmitter=s,this.passkeyHandler=a,this.eventEmitter.on(m.ON_LOGOUT,()=>{f("Handling logout event in EmbeddedWalletApi"),this.handleLogout()})}get backendApiClients(){const t=n.getInstance();if(!t)throw new r("Configuration not found");return new e({basePath:t.backendUrl,accessToken:t.baseConfiguration.publishableKey,nativeAppIdentifier:t.nativeAppIdentifier})}async getIframeManager(){if(f("[HANDSHAKE DEBUG] getIframeManager called"),this.iframeManager&&this.iframeManager.hasFailed&&(f("[HANDSHAKE DEBUG] Existing iframeManager has failed, clearing for recreation"),this.messenger&&(this.messenger.destroy(),this.messenger=null),this.iframeManager=null),this.iframeManager)return f("[HANDSHAKE DEBUG] Returning existing iframeManager instance"),this.iframeManager;if(this.iframeManagerPromise)return f("[HANDSHAKE DEBUG] Returning existing iframeManagerPromise"),this.iframeManagerPromise;f("[HANDSHAKE DEBUG] Creating new iframeManager"),this.iframeManagerPromise=this.createIframeManager();try{return f("[HANDSHAKE DEBUG] Awaiting iframeManager creation"),this.iframeManager=await this.iframeManagerPromise,f("[HANDSHAKE DEBUG] IframeManager created successfully"),this.iframeManagerPromise=null,this.iframeManager}catch(e){throw f("[HANDSHAKE DEBUG] Error creating iframeManager:",e),this.iframeManagerPromise=null,this.messenger&&(this.messenger.destroy(),this.messenger=null),this.iframeManager=null,e}}async createIframeManager(){f("[HANDSHAKE DEBUG] createIframeManager starting");const e=n.getInstance();if(!e)throw f("[HANDSHAKE DEBUG] Configuration not found"),new r("Configuration not found");let t;if(f("[HANDSHAKE DEBUG] Configuration found"),this.messagePoster)f("[HANDSHAKE DEBUG] Creating ReactNativeMessenger with messagePoster"),this.messenger&&(f("[HANDSHAKE DEBUG] Destroying old messenger before creating new one"),this.messenger.destroy()),this.messenger=new I(this.messagePoster),f("[HANDSHAKE DEBUG] Created new ReactNativeMessenger instance"),t=this.messenger;else{f("[HANDSHAKE DEBUG] Creating WindowMessenger for browser mode");const r=this.createIframe(e.iframeUrl),s=new URL(e.iframeUrl).origin;t=new D({remoteWindow:r.contentWindow,allowedOrigins:[s]}),f("[HANDSHAKE DEBUG] Created WindowMessenger")}return f("[HANDSHAKE DEBUG] Creating IframeManager instance"),new E(e,this.storage,t)}async ensureSigner(){if(this.iframeManager&&this.iframeManager.hasFailed&&(f("IframeManager has failed, clearing signer for recreation"),this.signer=null),this.signer)return this.signer;if(this.signerPromise)return this.signerPromise;this.signerPromise=this.createSigner();try{return this.signer=await this.signerPromise,this.signer}catch(e){throw this.signerPromise=null,e}finally{this.signerPromise=null}}async createSigner(){const e=await this.getIframeManager();await e.initialize();return new u(e,this.storage,this.backendApiClients,this.passkeyHandler,this.eventEmitter)}createIframe(e){if("undefined"==typeof document)throw new r("Document is not available. Please provide a message poster for non-browser environments.");const t=document.getElementById("openfort-iframe");t&&t.remove();const s=document.createElement("iframe");return s.style.display="none",s.id="openfort-iframe",s.src=e,document.body.appendChild(s),s}async getPasskeyKey(e){const r=await d.fromStorage(this.storage);if(!r?.userId)throw new t("auth","User is required for passkey key derivation. Logout and login again.",401);return this.passkeyHandler.deriveAndExportKey({id:e,seed:r.userId})}async getEntropy(e){switch(e.recoveryMethod){case g.PASSWORD:return{recoveryPassword:e.password};case g.AUTOMATIC:return{encryptionSession:e.encryptionSession};case g.PASSKEY:return{passkey:e.passkeyInfo?{id:e.passkeyInfo.passkeyId,key:e.passkeyInfo.passkeyKey||await this.getPasskeyKey(e.passkeyInfo.passkeyId)}:{}};default:throw new r("Invalid recovery method")}}async configure(e){await this.validateAndRefreshToken();const r=e.recoveryParams??{recoveryMethod:g.AUTOMATIC},[t,s]=await Promise.all([this.ensureSigner(),this.getEntropy(r)]),a={chainId:e.chainId,entropy:s,accountType:e.accountType??l.SMART_ACCOUNT,chainType:e.chainType??y.EVM,getPasskeyKeyFn:async e=>this.getPasskeyKey(e)},i=await t.configure(a);return{id:i.id,chainId:i.chainId,address:i.address,ownerAddress:i.ownerAddress,chainType:i.chainType,accountType:i.accountType,implementationType:i.implementationType,factoryAddress:i.factoryAddress,salt:i.salt,createdAt:i.createdAt,implementationAddress:i.implementationAddress,recoveryMethod:o.parseRecoveryMethod(i.recoveryMethod),recoveryMethodDetails:i.recoveryMethodDetails}}async create(e){await this.validateAndRefreshToken();const t=e.recoveryParams??{recoveryMethod:g.AUTOMATIC},a=await d.fromStorage(this.storage);if(!a)throw new s(c.NOT_LOGGED_IN,"missing authentication");if(t.recoveryMethod===g.PASSKEY){if(!a.userId)throw new r("User ID is required for passkey creation");const e=await this.passkeyHandler.createPasskey({id:i.randomPasskeyName(),displayName:n.getInstance()?.passkeyDisplayName??"Openfort - Embedded Wallet",seed:a.userId});if(!e.key)throw new r("Passkey creation failed: no key material returned");t.passkeyInfo={passkeyId:e.id,passkeyKey:e.key}}const[h,y]=await Promise.all([this.ensureSigner(),this.getEntropy(t)]),l=await h.create({accountType:e.accountType,chainType:e.chainType,chainId:e.chainId,entropy:y}),p={id:l.id,chainId:l.chainId,address:l.address,ownerAddress:l.ownerAddress,chainType:l.chainType,accountType:l.accountType,implementationType:l.implementationType,factoryAddress:l.factoryAddress,salt:l.salt,createdAt:l.createdAt,implementationAddress:l.implementationAddress,recoveryMethod:o.parseRecoveryMethod(l.recoveryMethod),recoveryMethodDetails:l.recoveryMethodDetails};return this.eventEmitter.emit(m.ON_EMBEDDED_WALLET_CREATED,p),p}async recover(e){await this.validateAndRefreshToken();const t=e.recoveryParams??{recoveryMethod:g.AUTOMATIC};if(t.recoveryMethod===g.PASSKEY){if(!t.passkeyInfo?.passkeyId)throw new r("Passkey ID must be provided for passkey recovery");t.passkeyInfo={passkeyId:t.passkeyInfo.passkeyId}}const[s,a]=await Promise.all([this.ensureSigner(),this.getEntropy(t)]),i=await s.recover({account:e.account,entropy:a}),n={id:i.id,chainId:i.chainId,implementationAddress:i.implementationAddress,factoryAddress:i.factoryAddress,salt:i.salt,address:i.address,ownerAddress:i.ownerAddress,chainType:i.chainType,accountType:i.accountType,implementationType:i.implementationType,createdAt:i.createdAt,recoveryMethod:o.parseRecoveryMethod(i.recoveryMethod),recoveryMethodDetails:i.recoveryMethodDetails};return this.eventEmitter.emit(m.ON_EMBEDDED_WALLET_RECOVERED,n),n}async signMessage(e,r){await this.validateAndRefreshToken();const t=await this.ensureSigner(),{hashMessage:s=!0,arrayifyMessage:a=!1}=r||{},i=await o.fromStorage(this.storage);return await t.sign(e,a,s,i?.chainType)}async signTypedData(e,r,t){await this.validateAndRefreshToken();const s=await this.ensureSigner(),i=await o.fromStorage(this.storage);if(!i)throw new a(c.MISSING_SIGNER,"No account found");const n={...r};delete n.EIP712Domain;const{_TypedDataEncoder:d}=await import("@ethersproject/hash"),h=d.hash(e,n,t);return await M({hash:h,implementationType:i.implementationType||i.type,chainId:Number(i.chainId),signer:s,address:i.address,ownerAddress:i.ownerAddress,factoryAddress:i.factoryAddress,salt:i.salt})}async exportPrivateKey(){await this.validateAndRefreshToken();const e=await this.ensureSigner();return await e.export()}async setRecoveryMethod(e,t){await this.validateAndRefreshToken();const a=await this.ensureSigner(),h=await d.fromStorage(this.storage);if(!h)throw new s(c.NOT_LOGGED_IN,"missing authentication");let m,y,l,p;if(e.recoveryMethod===g.PASSKEY){const e=await o.fromStorage(this.storage);if(!e)throw new r("missing account");const t=e?.recoveryMethodDetails?.passkeyId;if(!t)throw new r("missing passkey id for account");if(!h.userId)throw new r("User ID is required for passkey key derivation");l={passkeyId:t,passkeyKey:await this.passkeyHandler.deriveAndExportKey({id:t,seed:h.userId})}}else if(t.recoveryMethod===g.PASSKEY){if(!h.userId)throw new r("User ID is required for passkey creation");const e=await this.passkeyHandler.createPasskey({id:i.randomPasskeyName(),displayName:n.getInstance()?.passkeyDisplayName??"Openfort - Embedded Wallet",seed:h.userId});if(!e.key)throw new r("Passkey creation failed: no key material returned");l={passkeyId:e.id,passkeyKey:e.key},p={passkeyId:e.id}}if(e.recoveryMethod===g.PASSWORD?m=e.password:t.recoveryMethod===g.PASSWORD&&(m=t.password),e.recoveryMethod===g.AUTOMATIC?y=e.encryptionSession:t.recoveryMethod===g.AUTOMATIC&&(y=t.encryptionSession),!m&&!y)throw new r("Password or encryption session is not provided");await a.setRecoveryMethod({recoveryMethod:t.recoveryMethod,recoveryPassword:m,encryptionSession:y,passkeyInfo:l});const f=await o.fromStorage(this.storage);f&&new o({...f,recoveryMethod:t.recoveryMethod,recoveryMethodDetails:p}).save(this.storage)}async get(){await this.validateAndRefreshToken();const e=await o.fromStorage(this.storage);if(!e)throw new a(c.MISSING_SIGNER,"No signer configured");if(!await d.fromStorage(this.storage))throw new s(c.NOT_LOGGED_IN,"No access token found");return{id:e.id,chainId:e.chainId,address:e.address,ownerAddress:e.ownerAddress,factoryAddress:e.factoryAddress,salt:e.salt,chainType:e.chainType,accountType:e.accountType,implementationAddress:e.implementationAddress,implementationType:e.implementationType,createdAt:e.createdAt,recoveryMethod:o.parseRecoveryMethod(e.recoveryMethod),recoveryMethodDetails:e.recoveryMethodDetails}}async list(e){await this.validateAndRefreshToken();const t={accountType:l.SMART_ACCOUNT,...e},a=n.getInstance();if(!a)throw new r("Configuration not found");const i=await d.fromStorage(this.storage);if(!i)throw new s(c.NOT_LOGGED_IN,"No access token found");return await this.validateAndRefreshToken(),h(async()=>(await this.backendApiClients.accountsV2Api.getAccountsV2(t,{headers:i.thirdPartyProvider?{authorization:`Bearer ${a.baseConfiguration.publishableKey}`,"x-player-token":i.token,"x-auth-provider":i.thirdPartyProvider,"x-token-type":i.thirdPartyTokenType}:{authorization:`Bearer ${i.token}`,"x-project-key":a.baseConfiguration.publishableKey}})).data.data.map(e=>({chainType:e.chainType,id:e.id,address:e.address,active:e.smartAccount?.active,ownerAddress:e.ownerAddress,factoryAddress:e.smartAccount?.factoryAddress,salt:e.smartAccount?.salt,accountType:e.accountType,implementationAddress:e.smartAccount?.implementationAddress,createdAt:e.createdAt,implementationType:e.smartAccount?.implementationType,chainId:e.chainId,recoveryMethod:o.parseRecoveryMethod(e.recoveryMethod),recoveryMethodDetails:e.recoveryMethodDetails})),{context:"list"})}async getEmbeddedState(){try{if(!await d.fromStorage(this.storage))return p.UNAUTHENTICATED;return await o.fromStorage(this.storage)?p.READY:p.EMBEDDED_SIGNER_NOT_CONFIGURED}catch(e){return f("Failed to get embedded state:",e),p.UNAUTHENTICATED}}async getEthereumProvider(e){await this.ensureInitialized();const r={announceProvider:!0,...e},t=await d.fromStorage(this.storage),s=await o.fromStorage(this.storage);return this.provider?this.provider&&r.policy&&this.provider.updatePolicy(r.policy):(this.provider=new w({storage:this.storage,openfortEventEmitter:this.eventEmitter,ensureSigner:this.ensureSigner.bind(this),account:s||void 0,authentication:t||void 0,backendApiClients:this.backendApiClients,policyId:r.policy,validateAndRefreshSession:this.validateAndRefreshToken.bind(this),chains:r.chains}),r.announceProvider&&A({info:{...v,...r.providerInfo},provider:this.provider})),this.provider}async ping(e){try{e>0&&await new Promise(r=>{setTimeout(r,e)});const r=await this.getIframeManager();if(!r.isLoaded())return!1;const t=await d.fromStorage(this.storage);if(t)try{return await r.getCurrentDevice(t.userId),!0}catch(e){return!1}return r.isLoaded()}catch(e){return f("Ping failed:",e),!1}}getURL(){const e=n.getInstance();if(!e)throw new r("Configuration not found");return e.iframeUrl}async setMessagePoster(e){if(!e||"function"!=typeof e.postMessage)throw new r("Invalid message poster");this.messagePoster=e,this.messenger&&this.messenger.destroy(),this.iframeManager&&this.iframeManager.destroy(),this.signer=null,this.signerPromise=null,this.iframeManager=null,this.iframeManagerPromise=null,this.messenger=null}async handleLogout(){if("undefined"==typeof document&&!this.messagePoster)return f("Skipping signer disconnect: no messagePoster available in non-browser environment"),this.provider=null,this.messenger=null,this.iframeManager=null,this.iframeManagerPromise=null,this.signer=null,void(this.signerPromise=null);const e=await this.ensureSigner();await e.disconnect(),this.provider=null,this.messenger=null,this.iframeManager=null,this.iframeManagerPromise=null,this.signer=null,this.signerPromise=null}async onMessage(e){if(!e||"object"!=typeof e)return void f("Invalid message received:",e);f("[HANDSHAKE DEBUG] EmbeddedWalletApi onMessage:",e);const r="penpal"===e.namespace&&"SYN"===e.type||e.penpal&&"string"==typeof e.penpal;if(r&&this.messenger&&this.messagePoster)return f("[HANDSHAKE DEBUG] Passing message directly to existing ReactNativeMessenger"),void this.messenger.handleMessage(e);const t=await this.getIframeManager();f(`[HANDSHAKE DEBUG] IframeManager obtained, isLoaded: ${t.isLoaded()}`),r&&!t.isLoaded()&&f("[HANDSHAKE DEBUG] Received penpal message before connection initialized, setting up connection..."),f("[HANDSHAKE DEBUG] Calling iframeManager.onMessage"),await t.onMessage(e),f("[HANDSHAKE DEBUG] iframeManager.onMessage completed")}isReady(){return this.iframeManager?.isLoaded()||!1}}export{T as EmbeddedWalletApi};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{setCryptoDigestOverride as e}from"../../utils/crypto.js";class
|
|
1
|
+
import{setCryptoDigestOverride as e}from"../../utils/crypto.js";class s{publishableKey;nativeAppIdentifier;constructor(e){this.publishableKey=e.publishableKey,this.nativeAppIdentifier=e.nativeAppIdentifier}}class i{shieldPublishableKey;shieldEncryptionKey;debug=!1;passkeyRpId;passkeyRpName;passkeyDisplayName;constructor(e){this.shieldPublishableKey=e.shieldPublishableKey,this.debug=e.shieldDebug||!1,this.passkeyRpId=e.passkeyRpId,this.passkeyRpName=e.passkeyRpName,this.passkeyDisplayName=e.passkeyDisplayName}}class t{baseConfiguration;shieldConfiguration;thirdPartyAuth;shieldUrl;iframeUrl;backendUrl;storage;passkeyRpId;passkeyRpName;passkeyDisplayName;nativeAppIdentifier;debug;static instance=null;constructor({baseConfiguration:s,shieldConfiguration:i,overrides:a,thirdPartyAuth:p,debug:r}){this.shieldConfiguration=i,this.baseConfiguration=s,this.backendUrl=a?.backendUrl||"https://api.openfort.io",this.iframeUrl=a?.iframeUrl||"https://embed.openfort.io",this.iframeUrl=`${this.iframeUrl}/iframe/${this.baseConfiguration.publishableKey}`,this.debug=r,i?.debug&&(this.iframeUrl=`${this.iframeUrl}?debug=true`),this.shieldUrl=a?.shieldUrl||"https://shield.openfort.io",this.storage=a?.storage,this.thirdPartyAuth=p,this.passkeyRpId=i?.passkeyRpId,this.passkeyRpName=i?.passkeyRpName,this.passkeyDisplayName=i?.passkeyDisplayName,this.nativeAppIdentifier=s.nativeAppIdentifier,a?.crypto?.digest&&e(a.crypto.digest),t.instance=this}static getInstance(){return t.instance}}export{s as OpenfortConfiguration,t as SDKConfiguration,i as ShieldConfiguration};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{BackendApiClients as t}from"../../../packages/internal/openapi-clients/dist/index.js";import{AuthApi as e}from"../api/auth.js";import{EmbeddedWalletApi as i}from"../api/embeddedWallet.js";import{ProxyApi as n}from"../api/proxy.js";import{UserApi as
|
|
1
|
+
import{BackendApiClients as t}from"../../../packages/internal/openapi-clients/dist/index.js";import{AuthApi as e}from"../api/auth.js";import{EmbeddedWalletApi as i}from"../api/embeddedWallet.js";import{ProxyApi as n}from"../api/proxy.js";import{UserApi as s}from"../api/user.js";import{AuthManager as a}from"../auth/authManager.js";import{StorageKeys as r}from"../storage/istorage.js";import{LazyStorage as o}from"../storage/lazyStorage.js";import h from"../utils/typedEventEmitter.js";import{SDKConfiguration as l}from"./config/config.js";import{OPENFORT_AUTH_ERROR_CODES as c,OPENFORT_ERROR_CODES as d}from"./errors/authErrorCodes.js";import{ConfigurationError as u,SignerError as g,RequestError as m,OpenfortError as f}from"./errors/openfortError.js";import{InternalSentry as p}from"./errors/sentry.js";import{OpenfortInternal as I}from"./openfortInternal.js";import{PasskeyHandler as w}from"./passkey/handler.js";class y{storage;iAuthManager=null;openfortInternal;initPromise;asyncInitPromise=null;authInstance;embeddedWalletInstance;userInstance;proxyInstance;configuration;eventEmitter;iPasskeyHandler;static globalEventEmitter=null;get auth(){if(!this.authInstance)throw new u("Openfort SDK not initialized. Please await waitForInitialization() before accessing auth.");return this.authInstance}get embeddedWallet(){if(!this.embeddedWalletInstance)throw new u("Openfort SDK not initialized. Please await waitForInitialization() before accessing embeddedWallet.");return this.embeddedWalletInstance}get user(){if(!this.userInstance)throw new u("Openfort SDK not initialized. Please await waitForInitialization() before accessing user.");return this.userInstance}get proxy(){if(!this.proxyInstance)throw new u("Openfort SDK not initialized. Please await waitForInitialization() before accessing proxy.");return this.proxyInstance}initializeSynchronously(){try{this.iAuthManager=new a,this.openfortInternal=new I(this.storage,this.authManager,this.eventEmitter),this.authInstance=new e(this.storage,this.authManager,this.validateAndRefreshToken.bind(this),this.ensureInitialized.bind(this),this.eventEmitter),this.embeddedWalletInstance=new i(this.storage,this.validateAndRefreshToken.bind(this),this.ensureInitialized.bind(this),this.eventEmitter,this.passkeyHandler),this.userInstance=new s(this.storage,this.authManager,this.validateAndRefreshToken.bind(this)),this.proxyInstance=new n(this.storage,this.backendApiClients,this.validateAndRefreshToken.bind(this),this.ensureInitialized.bind(this),async()=>{if(!this.embeddedWalletInstance)throw new g(c.MISSING_SIGNER,"Embedded wallet not initialized");const t=this.embeddedWalletInstance;return e=>t.signMessage(e,{hashMessage:!0,arrayifyMessage:!0})})}catch(t){throw new u("Openfort SDK synchronous initialization failed")}}constructor(t){if(this.configuration=new l(t),this.storage=new o(this.configuration.baseConfiguration.publishableKey,this.configuration.storage),this.eventEmitter=new h,y.globalEventEmitter){["onAuthInit","onAuthSuccess","onAuthFailure","onLogout","onSwitchAccount","onSignedMessage","onEmbeddedWalletCreated","onEmbeddedWalletRecovered","onAuthFlowOpen","onAuthFlowClose","onAuthFlowCancel"].forEach(t=>{this.eventEmitter.on(t,(...e)=>{y.globalEventEmitter?.emit(t,...e)})})}else y.globalEventEmitter=this.eventEmitter;this.iPasskeyHandler=t.overrides?.passkeyHandler??new w({rpId:this.configuration.passkeyRpId,rpName:this.configuration.passkeyRpName}),p.init({configuration:this.configuration}),this.initializeSynchronously(),this.initPromise=Promise.resolve()}static getEventEmitter(){return y.globalEventEmitter||(y.globalEventEmitter=new h),y.globalEventEmitter}async waitForInitialization(){await this.initPromise,await this.ensureAsyncInitialized()}async getAccessToken(){return await this.ensureInitialized(),this.openfortInternal.getAccessToken()}async validateAndRefreshToken(t){return await this.ensureInitialized(),await this.openfortInternal.validateAndRefreshToken(t)}get backendApiClients(){return new t({basePath:this.configuration.backendUrl,accessToken:this.configuration.baseConfiguration.publishableKey,nativeAppIdentifier:this.configuration.nativeAppIdentifier,storage:this.storage,onLogout:()=>{this.eventEmitter.emit("onLogout")}})}get authManager(){if(!this.iAuthManager)throw new m("AuthManager not initialized");return this.iAuthManager}get passkeyHandler(){return this.iPasskeyHandler}static async isStorageAccessible(t){try{const e=r.TEST,i="openfort_storage_test";t.save(e,i);const n=await t.get(e);return t.remove(e),n===i}catch(t){return!1}}async initializeAsync(){if(!await y.isStorageAccessible(this.storage))throw new f("Storage is not accessible",d.INVALID_CONFIGURATION);this.authManager.setBackendApiClients(this.backendApiClients,this.configuration.baseConfiguration.publishableKey)}async ensureAsyncInitialized(){this.asyncInitPromise||(this.asyncInitPromise=this.initializeAsync()),await this.asyncInitPromise}async ensureInitialized(){await this.initPromise,await this.ensureAsyncInitialized()}}export{y as Openfort};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{OpenfortError as e}from"../errors/openfortError.js";const s={USER_CANCELLED:"passkey_user_cancelled",CREATION_FAILED:"passkey_creation_failed",ASSERTION_FAILED:"passkey_assertion_failed",PRF_NOT_SUPPORTED:"passkey_prf_not_supported",INVALID_SEED:"passkey_invalid_seed"};class t extends e{constructor(e="User cancelled passkey operation"){super(s.USER_CANCELLED,e),this.name="PasskeyUserCancelledError",Object.setPrototypeOf(this,t.prototype)}}class r extends e{cause;constructor(e="Failed to create passkey",t){super(s.CREATION_FAILED,e),this.name="PasskeyCreationFailedError",this.cause=t,Object.setPrototypeOf(this,r.prototype)}}class o extends e{constructor(e="PRF extension not supported on this device"){super(s.PRF_NOT_SUPPORTED,e),this.name="PasskeyPRFNotSupportedError",Object.setPrototypeOf(this,o.prototype)}}class a extends e{cause;constructor(e="Failed to get passkey assertion",t){super(s.ASSERTION_FAILED,e),this.name="PasskeyAssertionFailedError",this.cause=t,Object.setPrototypeOf(this,a.prototype)}}class p extends e{constructor(e="Passkey seed cannot be empty"){super(s.INVALID_SEED,e),this.name="PasskeySeedInvalidError",Object.setPrototypeOf(this,p.prototype)}}export{s as PASSKEY_ERROR_CODES,a as PasskeyAssertionFailedError,r as PasskeyCreationFailedError,o as PasskeyPRFNotSupportedError,p as PasskeySeedInvalidError,t as PasskeyUserCancelledError};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{humanId as e}from"human-id";import{PasskeyPRFNotSupportedError as t,PasskeySeedInvalidError as r,PasskeyUserCancelledError as i,PasskeyCreationFailedError as n,PasskeyAssertionFailedError as s}from"./errors.js";import{arrayBufferToBase64URL as o,base64ToArrayBuffer as a}from"./utils.js";class d{validByteLengths=[16,24,32];rpId;rpName;timeoutMs;derivedKeyLengthBytes;constructor({rpId:e,rpName:t,timeoutMs:r,derivedKeyLengthBytes:i}={}){if(this.rpId=e,this.rpName=t,this.timeoutMs=r??6e4,this.derivedKeyLengthBytes=i??32,!this.validByteLengths.includes(this.derivedKeyLengthBytes))throw new Error(`Invalid key byte length ${this.derivedKeyLengthBytes}`)}static randomPasskeyName(){return e({capitalize:!0,separator:" "})}getChallengeBytes(){return crypto.getRandomValues(new Uint8Array(32))}async deriveKeyFromAssertion(e){const r=e.getClientExtensionResults();if(!r)throw new t("Passkey fetch failed: no client extension results");const i=r.prf;if(!i||!i.results)throw new t("PRF extension not supported or missing results");const n=i.results.first,s=await crypto.subtle.importKey("raw",n,{name:"AES-CBC",length:this.derivedKeyLengthBytes},!0,["encrypt","decrypt"]);return crypto.subtle.exportKey("raw",s)}async createPasskey({id:e,displayName:s,seed:a}){if(!a||0===a.trim().length)throw new r;const d={challenge:this.getChallengeBytes(),rp:{id:this.rpId,name:this.rpName},user:{id:(new TextEncoder).encode(e),name:e,displayName:s},pubKeyCredParams:[{type:"public-key",alg:-7},{type:"public-key",alg:-257}],authenticatorSelection:{residentKey:"required",userVerification:"required"},extensions:{prf:{eval:{first:(new TextEncoder).encode(a)}}},timeout:this.timeoutMs,attestation:"direct"};let c,l;try{c=await navigator.credentials.create({publicKey:d})}catch(e){if(e instanceof Error&&"NotAllowedError"===e.name)throw new i;throw new n(e instanceof Error?e.message:"Unknown error",e instanceof Error?e:void 0)}if(!c)throw new i;try{l=await this.deriveKeyFromAssertion(c)}catch(e){throw e instanceof t&&console.warn(`[Openfort] Passkey created but PRF extension failed. A passkey credential may exist on the device that cannot be used for wallet recovery. Credential ID: ${o(c.rawId)}`),e}return{id:o(c.rawId),displayName:s,key:o(l)}}async deriveAndExportKey({id:e,seed:t}){if(!t||0===t.trim().length)throw new r;let n;try{n=await navigator.credentials.get({publicKey:{challenge:this.getChallengeBytes(),rpId:this.rpId,allowCredentials:[{id:a(e),type:"public-key"}],userVerification:"required",extensions:{prf:{eval:{first:(new TextEncoder).encode(t)}}}}})}catch(e){if(e instanceof Error&&"NotAllowedError"===e.name)throw new i;throw new s(e instanceof Error?e.message:"Unknown error",e instanceof Error?e:void 0)}if(!n)throw new i;const d=await this.deriveKeyFromAssertion(n);return o(d)}}export{d as PasskeyHandler};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function r(r){const t=r instanceof Uint8Array?r:new Uint8Array(r);let e="";for(const r of t)e+=String.fromCharCode(r);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function t(r){const t=atob(r),e=new Uint8Array(t.length);for(let r=0;r<t.length;r++)e[r]=t.charCodeAt(r);return e.buffer}export{r as arrayBufferToBase64URL,t as base64ToArrayBuffer};
|
package/dist/sdk/src/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Openfort as r}from"./core/openfort.js";export{AuthApi}from"./api/auth.js";export{EmbeddedWalletApi}from"./api/embeddedWallet.js";export{ProxyApi}from"./api/proxy.js";export{UserApi}from"./api/user.js";export{OPENFORT_AUTH_ERROR_CODES,OPENFORT_ERROR_CODES}from"./core/errors/authErrorCodes.js";export{AuthenticationError,AuthorizationError,ConfigurationError,OAuthError,OTPError,OpenfortError,RecoveryError,RequestError,SessionError,SignerError,UserError}from"./core/errors/openfortError.js";export{OpenfortConfiguration,SDKConfiguration,ShieldConfiguration}from"./core/config/config.js";export{OpenfortInternal}from"./core/openfortInternal.js";export{prepareAndSignAuthorization,serializeSignedAuthorization,signAuthorization}from"./utils/authorization.js";export{MissingProjectEntropyError,MissingRecoveryPasswordError,NotConfiguredError,OTPRequiredError,WrongPasskeyError,WrongRecoveryPasswordError}from"./wallets/iframeManager.js";export{AccountTypeEnum,AuthActionRequiredActions,AuthType,BasicAuthProvider,ChainTypeEnum,EmbeddedState,OAuthProvider,OpenfortEvents,RecoveryMethod,ThirdPartyAuthProvider as ThirdPartyOAuthProvider,TokenType}from"./types/types.js";export{cryptoDigest}from"./utils/crypto.js";const o=r.getEventEmitter();export{r as Openfort,o as openfortEvents};
|
|
1
|
+
import{Openfort as r}from"./core/openfort.js";export{AuthApi}from"./api/auth.js";export{EmbeddedWalletApi}from"./api/embeddedWallet.js";export{ProxyApi}from"./api/proxy.js";export{UserApi}from"./api/user.js";export{OPENFORT_AUTH_ERROR_CODES,OPENFORT_ERROR_CODES}from"./core/errors/authErrorCodes.js";export{AuthenticationError,AuthorizationError,ConfigurationError,OAuthError,OTPError,OpenfortError,RecoveryError,RequestError,SessionError,SignerError,UserError}from"./core/errors/openfortError.js";export{PASSKEY_ERROR_CODES,PasskeyAssertionFailedError,PasskeyCreationFailedError,PasskeyPRFNotSupportedError,PasskeySeedInvalidError,PasskeyUserCancelledError}from"./core/passkey/errors.js";export{PasskeyHandler}from"./core/passkey/handler.js";export{arrayBufferToBase64URL,base64ToArrayBuffer}from"./core/passkey/utils.js";export{OpenfortConfiguration,SDKConfiguration,ShieldConfiguration}from"./core/config/config.js";export{OpenfortInternal}from"./core/openfortInternal.js";export{prepareAndSignAuthorization,serializeSignedAuthorization,signAuthorization}from"./utils/authorization.js";export{MissingProjectEntropyError,MissingRecoveryPasswordError,NotConfiguredError,OTPRequiredError,WrongPasskeyError,WrongRecoveryPasswordError}from"./wallets/iframeManager.js";export{AccountTypeEnum,AuthActionRequiredActions,AuthType,BasicAuthProvider,ChainTypeEnum,EmbeddedState,OAuthProvider,OpenfortEvents,RecoveryMethod,ThirdPartyAuthProvider as ThirdPartyOAuthProvider,TokenType}from"./types/types.js";export{cryptoDigest}from"./utils/crypto.js";const o=r.getEventEmitter();export{r as Openfort,o as openfortEvents};
|
package/dist/sdk/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const o="1.1.
|
|
1
|
+
const o="1.1.6",t="@openfort/openfort-js";export{t as PACKAGE,o as VERSION};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Authentication as e}from"../core/configuration/authentication.js";import{
|
|
1
|
+
import{Authentication as e}from"../core/configuration/authentication.js";import{OPENFORT_AUTH_ERROR_CODES as t}from"../core/errors/authErrorCodes.js";import{SessionError as a,ConfigurationError as r}from"../core/errors/openfortError.js";import{withApiError as o}from"../core/errors/withApiError.js";import{PasskeyHandler as s}from"../core/passkey/handler.js";import{SDKConfiguration as n}from"../core/config/config.js";import{Account as i}from"../core/configuration/account.js";import{StorageKeys as c}from"../storage/istorage.js";import{OpenfortEvents as d,AccountTypeEnum as y}from"../types/types.js";class p{iframeManager;storage;backendApiClients;passkeyHandler;eventEmitter;constructor(e,t,a,r,o){this.iframeManager=e,this.storage=t,this.backendApiClients=a,this.passkeyHandler=r,this.eventEmitter=o}async createPasskey(e){const t=await this.passkeyHandler.createPasskey({id:s.randomPasskeyName(),displayName:n.getInstance()?.passkeyDisplayName??"Openfort - Embedded Wallet",seed:e});return{id:t.id,key:t.key}}async configure(s){const c=await e.fromStorage(this.storage);if(!c)throw new a(t.NOT_LOGGED_IN,"No access token found");const y=n.getInstance();if(!y)throw new r("Configuration not found");const p=await i.fromStorage(this.storage);let h;if(p){const e={account:p.id,...s.entropy&&{entropy:{...s.entropy.recoveryPassword&&{recoveryPassword:s.entropy.recoveryPassword},...s.entropy.encryptionSession&&{encryptionSession:s.entropy.encryptionSession},..."passkey"===p.recoveryMethod&&{passkey:{id:p.recoveryMethodDetails?.passkeyId,env:p.recoveryMethodDetails?.passkeyEnv,key:await s.getPasskeyKeyFn(p.recoveryMethodDetails?.passkeyId??"")}}}}},t=await this.iframeManager.recover(e);h=t.account}else{const e=await this.backendApiClients.accountsV2Api.getAccountsV2({accountType:s.accountType,chainType:s.chainType},{headers:c.thirdPartyProvider?{authorization:`Bearer ${y.baseConfiguration.publishableKey}`,"x-player-token":c.token,"x-auth-provider":c.thirdPartyProvider,"x-token-type":c.thirdPartyTokenType}:{authorization:`Bearer ${c.token}`,"x-project-key":y.baseConfiguration.publishableKey}});if(0===e.data.data.length){const e=s.entropy?.passkey?await this.createPasskey(c.userId):void 0,t={accountType:s.accountType,chainType:s.chainType,chainId:s.chainId,...s.entropy&&{entropy:{...s.entropy.recoveryPassword&&{recoveryPassword:s.entropy.recoveryPassword},...s.entropy.encryptionSession&&{encryptionSession:s.entropy.encryptionSession},...s.entropy.passkey&&{passkey:e}}}},a=await this.iframeManager.create(t);h=a.account}else{const t=e.data.data,a=t.find(e=>e.chainId===s.chainId),r=a||t[0],o={account:r.id,...s.entropy&&{entropy:{...s.entropy.recoveryPassword&&{recoveryPassword:s.entropy.recoveryPassword},...s.entropy.encryptionSession&&{encryptionSession:s.entropy.encryptionSession},..."passkey"===r.recoveryMethod&&{passkey:{id:r.recoveryMethodDetails?.passkeyId,env:r.recoveryMethodDetails?.passkeyEnv,key:await s.getPasskeyKeyFn(r.recoveryMethodDetails?.passkeyId??"")}}}}},n=await this.iframeManager.recover(o);if(h=n.account,!a){const e=await this.iframeManager.switchChain(s.chainId);h=e.account}}}return o(async()=>{const e=await this.backendApiClients.accountsV2Api.getAccountV2({id:h},{headers:c.thirdPartyProvider?{authorization:`Bearer ${y.baseConfiguration.publishableKey}`,"x-player-token":c.token,"x-auth-provider":c.thirdPartyProvider,"x-token-type":c.thirdPartyTokenType}:{authorization:`Bearer ${c.token}`,"x-project-key":y.baseConfiguration.publishableKey}}),t=new i({chainType:e.data.chainType,id:e.data.id,address:e.data.address,ownerAddress:e.data.ownerAddress,accountType:e.data.accountType,createdAt:e.data.createdAt,implementationAddress:e.data.smartAccount?.implementationAddress,implementationType:e.data.smartAccount?.implementationType,chainId:e.data.chainId,salt:e.data.smartAccount?.salt,factoryAddress:e.data.smartAccount?.factoryAddress,recoveryMethod:i.parseRecoveryMethod(e.data.recoveryMethod),recoveryMethodDetails:e.data.recoveryMethodDetails});return t.save(this.storage),this.eventEmitter.emit(d.ON_SWITCH_ACCOUNT,e.data.address),t},{context:"configure"})}async sign(e,t,a,r){const o=await this.iframeManager.sign(e,t,a,r);return this.eventEmitter.emit(d.ON_SIGNED_MESSAGE,{message:e,signature:o}),o}async export(){return await this.iframeManager.export()}async switchChain({chainId:e}){const t=await i.fromStorage(this.storage);if(t?.accountType===y.EOA)new i({...t,chainId:e}).save(this.storage);else{const a=await this.iframeManager.switchChain(e);new i({...t,id:a.account,chainId:e}).save(this.storage)}}async create(s){const c=await this.iframeManager.create(s),y=await e.fromStorage(this.storage);if(!y)throw new a(t.NOT_LOGGED_IN,"No access token found");const p=n.getInstance();if(!p)throw new r("Configuration not found");return o(async()=>{const e=await this.backendApiClients.accountsV2Api.getAccountV2({id:c.account},{headers:y.thirdPartyProvider?{authorization:`Bearer ${p.baseConfiguration.publishableKey}`,"x-player-token":y.token,"x-auth-provider":y.thirdPartyProvider,"x-token-type":y.thirdPartyTokenType}:{authorization:`Bearer ${y.token}`,"x-project-key":p.baseConfiguration.publishableKey}}),t=new i({chainType:e.data.chainType,id:e.data.id,address:e.data.address,ownerAddress:e.data.ownerAddress,accountType:e.data.accountType,createdAt:e.data.createdAt,implementationType:e.data.smartAccount?.implementationType,chainId:e.data.chainId,implementationAddress:e.data.smartAccount?.implementationAddress,salt:e.data.smartAccount?.salt,factoryAddress:e.data.smartAccount?.factoryAddress,recoveryMethod:i.parseRecoveryMethod(e.data.recoveryMethod),recoveryMethodDetails:e.data.recoveryMethodDetails});return t.save(this.storage),this.eventEmitter.emit(d.ON_SWITCH_ACCOUNT,e.data.address),t},{context:"create"})}async recover(s){const c=await this.iframeManager.recover(s),y=await e.fromStorage(this.storage);if(!y)throw new a(t.NOT_LOGGED_IN,"No access token found");const p=n.getInstance();if(!p)throw new r("Configuration not found");return o(async()=>{const e=await this.backendApiClients.accountsV2Api.getAccountV2({id:c.account},{headers:y.thirdPartyProvider?{authorization:`Bearer ${p.baseConfiguration.publishableKey}`,"x-player-token":y.token,"x-auth-provider":y.thirdPartyProvider,"x-token-type":y.thirdPartyTokenType}:{authorization:`Bearer ${y.token}`,"x-project-key":p.baseConfiguration.publishableKey}}),t=new i({chainType:e.data.chainType,id:e.data.id,address:e.data.address,ownerAddress:e.data.ownerAddress,accountType:e.data.accountType,createdAt:e.data.createdAt,implementationAddress:e.data.smartAccount?.implementationAddress,implementationType:e.data.smartAccount?.implementationType,chainId:e.data.chainId,salt:e.data.smartAccount?.salt,factoryAddress:e.data.smartAccount?.factoryAddress,recoveryMethod:i.parseRecoveryMethod(e.data.recoveryMethod),recoveryMethodDetails:e.data.recoveryMethodDetails});return t.save(this.storage),this.eventEmitter.emit(d.ON_SWITCH_ACCOUNT,e.data.address),t},{context:"recover"})}async setRecoveryMethod({recoveryMethod:e,recoveryPassword:t,encryptionSession:a,passkeyInfo:r}){await this.iframeManager.setRecoveryMethod(e,t,a,r?.passkeyKey,r?.passkeyId)}async disconnect(){await this.iframeManager.disconnect(),this.storage.remove(c.ACCOUNT)}}export{p as EmbeddedSigner};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfort/openfort-js",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6",
|
|
4
4
|
"author": "Openfort (https://www.openfort.io)",
|
|
5
5
|
"bugs": "https://github.com/openfort-xyz/openfort-js/issues",
|
|
6
6
|
"repository": "openfort-xyz/openfort-js.git",
|
|
@@ -54,9 +54,7 @@
|
|
|
54
54
|
"@rollup/plugin-typescript": "^11.1.0",
|
|
55
55
|
"@vitest/coverage-v8": "^2.1.8",
|
|
56
56
|
"jsdom": "^25.0.1",
|
|
57
|
-
"@types/jest": "^29.4.3",
|
|
58
57
|
"@types/node": "^22.7.5",
|
|
59
|
-
"jest": "^29.4.3",
|
|
60
58
|
"rollup": "^4.0.0",
|
|
61
59
|
"rollup-plugin-dts": "^5.3.0",
|
|
62
60
|
"rollup-plugin-visualizer": "^5.14.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var e=require("human-id");exports.PasskeyHandler=class{iValidByteLengths=[16,24,32];rpId;rpName;timeoutMillis;derivedKeyLengthBytes;extractableKey;constructor({rpId:e,rpName:t,timeoutMillis:r,derivedKeyLengthBytes:i,extractableKey:s}){if(this.rpId=e,this.rpName=t,this.timeoutMillis=r??6e4,this.derivedKeyLengthBytes=i??32,this.extractableKey=s??!0,!this.iValidByteLengths.includes(this.derivedKeyLengthBytes))throw new Error(`Invalid key byte length ${this.derivedKeyLengthBytes}`)}static randomPasskeyName(){return e.humanId({capitalize:!0,separator:" "})}getChallengeBytes(){return crypto.getRandomValues(new Uint8Array(32))}async deriveFromAssertion(e){const t=e.getClientExtensionResults();if(!t)throw new Error("Passkey fetch failed");const r=t.prf;if(!r||!r.results)throw new Error("PRF extension not supported or missing results");const i=r.results.first;return await crypto.subtle.importKey("raw",i,{name:"AES-CBC",length:this.derivedKeyLengthBytes},this.extractableKey,["encrypt","decrypt"])}async createPasskey({id:e,displayName:t,seed:r}){const i={challenge:this.getChallengeBytes(),rp:{id:this.rpId,name:this.rpName},user:{id:(new TextEncoder).encode(e),name:e,displayName:t},pubKeyCredParams:[{type:"public-key",alg:-7},{type:"public-key",alg:-257}],authenticatorSelection:{residentKey:"required",userVerification:"required"},extensions:{prf:{eval:{first:(new TextEncoder).encode(r)}}},timeout:this.timeoutMillis,attestation:"direct"},s=await navigator.credentials.create({publicKey:i});if(s){return{id:btoa(String.fromCharCode(...new Uint8Array(s.rawId))),displayName:t,key:new Uint8Array(await crypto.subtle.exportKey("raw",await this.deriveFromAssertion(s)))}}throw new Error("could not create passkey")}base64ToArrayBuffer(e){const t=atob(e),r=new Uint8Array(t.length);for(let e=0;e<t.length;e++)r[e]=t.charCodeAt(e);return r.buffer}async deriveKey({id:e,seed:t}){const r=e,i=await navigator.credentials.get({publicKey:{challenge:this.getChallengeBytes(),rpId:this.rpId,allowCredentials:[{id:this.base64ToArrayBuffer(r),type:"public-key"}],userVerification:"required",extensions:{prf:{eval:{first:(new TextEncoder).encode(t)}}}}});return this.deriveFromAssertion(i)}async deriveAndExportKey({id:e,seed:t}){if(!this.extractableKey)throw new Error("Derived keys cannot be exported if extractableKey is not set to true");const r=await this.deriveKey({id:e,seed:t});return new Uint8Array(await crypto.subtle.exportKey("raw",r))}};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{humanId as e}from"human-id";class t{iValidByteLengths=[16,24,32];rpId;rpName;timeoutMillis;derivedKeyLengthBytes;extractableKey;constructor({rpId:e,rpName:t,timeoutMillis:r,derivedKeyLengthBytes:i,extractableKey:s}){if(this.rpId=e,this.rpName=t,this.timeoutMillis=r??6e4,this.derivedKeyLengthBytes=i??32,this.extractableKey=s??!0,!this.iValidByteLengths.includes(this.derivedKeyLengthBytes))throw new Error(`Invalid key byte length ${this.derivedKeyLengthBytes}`)}static randomPasskeyName(){return e({capitalize:!0,separator:" "})}getChallengeBytes(){return crypto.getRandomValues(new Uint8Array(32))}async deriveFromAssertion(e){const t=e.getClientExtensionResults();if(!t)throw new Error("Passkey fetch failed");const r=t.prf;if(!r||!r.results)throw new Error("PRF extension not supported or missing results");const i=r.results.first;return await crypto.subtle.importKey("raw",i,{name:"AES-CBC",length:this.derivedKeyLengthBytes},this.extractableKey,["encrypt","decrypt"])}async createPasskey({id:e,displayName:t,seed:r}){const i={challenge:this.getChallengeBytes(),rp:{id:this.rpId,name:this.rpName},user:{id:(new TextEncoder).encode(e),name:e,displayName:t},pubKeyCredParams:[{type:"public-key",alg:-7},{type:"public-key",alg:-257}],authenticatorSelection:{residentKey:"required",userVerification:"required"},extensions:{prf:{eval:{first:(new TextEncoder).encode(r)}}},timeout:this.timeoutMillis,attestation:"direct"},s=await navigator.credentials.create({publicKey:i});if(s){return{id:btoa(String.fromCharCode(...new Uint8Array(s.rawId))),displayName:t,key:new Uint8Array(await crypto.subtle.exportKey("raw",await this.deriveFromAssertion(s)))}}throw new Error("could not create passkey")}base64ToArrayBuffer(e){const t=atob(e),r=new Uint8Array(t.length);for(let e=0;e<t.length;e++)r[e]=t.charCodeAt(e);return r.buffer}async deriveKey({id:e,seed:t}){const r=e,i=await navigator.credentials.get({publicKey:{challenge:this.getChallengeBytes(),rpId:this.rpId,allowCredentials:[{id:this.base64ToArrayBuffer(r),type:"public-key"}],userVerification:"required",extensions:{prf:{eval:{first:(new TextEncoder).encode(t)}}}}});return this.deriveFromAssertion(i)}async deriveAndExportKey({id:e,seed:t}){if(!this.extractableKey)throw new Error("Derived keys cannot be exported if extractableKey is not set to true");const r=await this.deriveKey({id:e,seed:t});return new Uint8Array(await crypto.subtle.exportKey("raw",r))}}export{t as PasskeyHandler};
|