@emblemvault/auth-sdk 2.3.0 → 2.3.2

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.
@@ -14,6 +14,8 @@ export declare class EmblemAuthSDK {
14
14
  private readonly events;
15
15
  private _cachedVaultInfo;
16
16
  private readonly storageKey;
17
+ private readonly visitorIdKey;
18
+ private _visitorId;
17
19
  constructor(config: EmblemAuthConfig);
18
20
  /**
19
21
  * Authenticate with a wallet signature (programmatic/headless auth)
@@ -28,6 +30,11 @@ export declare class EmblemAuthSDK {
28
30
  * Get the current session
29
31
  */
30
32
  getSession(): AuthSession | null;
33
+ /**
34
+ * Get the visitor ID from the last authentication
35
+ * This is the VaultFP fingerprint ID captured during auth
36
+ */
37
+ getVisitorId(): string | null;
31
38
  /**
32
39
  * Refresh the current session
33
40
  * Supports two modes:
@@ -152,5 +159,7 @@ export declare class EmblemAuthSDK {
152
159
  private safeJson;
153
160
  private loadPersistedSession;
154
161
  private persistSession;
162
+ private loadPersistedVisitorId;
163
+ private persistVisitorId;
155
164
  }
156
165
  //# sourceMappingURL=EmblemAuthSDK.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EmblemAuthSDK.d.ts","sourceRoot":"","sources":["../src/EmblemAuthSDK.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EmblemAuthSDK.d.ts","sourceRoot":"","sources":["../src/EmblemAuthSDK.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).EmblemAuth={})}(this,function(t){"use strict";class e{constructor(t={}){this.session=null,this.timer=null,this.events={},this.onRefresh=t.onRefresh,this.refreshSkewMs=t.refreshSkewMs??6e4}setSession(t){this.session=t,this.schedule(),this.emit("session",t)}getSession(){return this.session}clear(){this.session=null,this.cancel(),this.emit("session",null)}on(t,e){this.events[t]||(this.events[t]=[]),this.events[t].push(e)}off(t,e){const s=this.events[t];if(s){const t=s.indexOf(e);-1!==t&&s.splice(t,1)}}destroy(){this.cancel(),this.session=null,Object.keys(this.events).forEach(t=>{delete this.events[t]})}emit(t,e){const s=this.events[t];if(s)for(const t of s)try{t(e)}catch(t){}}cancel(){this.timer&&(clearTimeout(this.timer),this.timer=null)}schedule(){this.cancel();const t=this.session;if(!t?.expiresAt)return;const e=Date.now(),s=t.expiresAt-e;if(s<=0)return void this.emit("sessionExpired",t);const i=Math.max(0,s-this.refreshSkewMs);this.emit("sessionWillRefresh",{inMs:i,ttl:s}),this.timer=setTimeout(async()=>{if(this.onRefresh)try{const e=await this.onRefresh(t);e?.expiresAt&&e.authToken?(this.setSession(e),this.emit("sessionRefreshed",e)):Date.now()>=t.expiresAt&&this.emit("sessionExpired",t)}catch(e){Date.now()>=t.expiresAt&&this.emit("sessionExpired",t)}else Date.now()>=t.expiresAt&&this.emit("sessionExpired",t)},i)}}class s{constructor(t){if(this.session=null,this.pendingNonce=null,this.overlayEl=null,this._iframeEl=null,this.overlayCleanup=null,this.events={},this._cachedVaultInfo=null,!t?.appId)throw new Error("appId is required");if(this.config={...t,authUrl:t.authUrl??"https://auth.emblemvault.ai",apiUrl:t.apiUrl??"https://api.emblemvault.ai",persistSession:t.persistSession??!0},this.storageKey=`emblem_session_${t.appId}`,this.messageHandler=this.onMessage.bind(this),window.addEventListener("message",this.messageHandler),this.sessionMgr=new e({onRefresh:async t=>{try{return await this.refreshSession()||t}catch{return t}}}),this.sessionMgr.on("sessionExpired",t=>this.emit("sessionExpired",t)),this.sessionMgr.on("sessionRefreshed",t=>this.emit("sessionRefreshed",t)),this.sessionMgr.on("sessionWillRefresh",t=>this.emit("sessionWillRefresh",t)),this.config.persistSession){const t=this.loadPersistedSession();t&&this.hydrateSession(t)}}async authenticateWallet(t){const{network:e,message:s,signature:i,publicKey:n,address:r}=t;if(!this.config.apiUrl)throw new Error("apiUrl is required for authenticateWallet");if(!e||!s||!i)throw new Error("network, message, signature are required");const a=`${this.config.apiUrl.replace(/\/$/,"")}/api/auth/wallet/verify-external`,o=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:this.config.appId,network:e,message:s,signature:i,publicKey:n,address:r})});if(!o.ok){const t=await this.safeJson(o),e=new Error(t?.error||`wallet_verify_${o.status}`);throw e.status=o.status,e.payload=t,e}const c=await o.json(),l=c?.session;return l&&(this.session=l,this.persistSession(l),this.sessionMgr.setSession(l),this.config.onSuccess?.(l),this.emit("session",l)),l}async openAuthModal(){const t=window.location.origin;let e=null,s=null;try{e=await this.getAuthInit({origin:t})}catch(t){s=t}const i=e?.nonce||this.randomId();this.pendingNonce=i;let n=this.resolveModalUrl({nonce:i,origin:t,state:e?.state});if("origin_not_allowed"===s?.payload?.error)try{const e=new URL("/connect",this.config.authUrl);e.searchParams.set("error","origin_not_allowed"),e.searchParams.set("appId",this.config.appId),e.searchParams.set("origin",t),n=e.toString()}catch{}const r=this.config.modalMode||"auto";let a=!1;if("iframe"===r||"auto"===r)try{a=this.openIframeModal(n)}catch(t){}if(!a){const t=this.popupFeatures();if(!window.open(n,"emblem-auth",t)){const t=new Error("Popup blocked. Please allow popups for this site.");this.emitError(t)}}}getSession(){return this.session}async refreshSession(){try{if(!this.session)return null;const t=this.tryGetOriginFromConfig();if(!t)return this.session;const e=`${t}/api/auth/refresh`,s=Boolean(this.session.refreshToken),i=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s?{refreshToken:this.session.refreshToken}:{}),credentials:"include"});if(!i.ok)return this.session;const n=await i.json(),r=n?.session;return r&&(this.session=r,this.persistSession(r),this.sessionMgr.setSession(r),this.emit("session",r)),this.session}catch{return this.session}}async getVaultInfo(){if(this._cachedVaultInfo)return this._cachedVaultInfo;const t=this.getSession();if(!t?.authToken)throw new Error("No session");if(!this.config.apiUrl)throw new Error("apiUrl is required");const e=this.config.apiUrl.replace(/\/$/,""),s=await fetch(`${e}/vault/info`,{method:"POST",headers:{Authorization:`Bearer ${t.authToken}`,"Content-Type":"application/json"},body:"{}"});if(!s.ok)throw new Error("Failed to fetch vault info");const i=await s.json();return this._cachedVaultInfo=i,i}async getVaultApiKey(){if(!this.config.apiUrl)throw new Error("apiUrl is required");const t=this.getSession();if(!t?.authToken)throw new Error("No active session");const e=this.config.apiUrl.replace(/\/$/,""),s=t.authToken,i=t.user?.vaultId;let n=null;try{const t=await fetch(`${e}/vault/info-complete`,{method:"POST",headers:{Authorization:`Bearer ${s}`}});if(t.ok){const e=await t.json();n=e?.raw?.pkp?.api_key_hash||e?.raw?.pkp?.apiKeyHash||null}}catch{}if(!n)try{const s=t.appId,r=t.user?.identifier||"",a=s?`${s}:${r}`:r;if(a){const t=await fetch(`${e}/api/vaults/${encodeURIComponent(a)}`);if(t.ok){const e=await t.json(),s=Array.isArray(e)?e.find(t=>String(t.tokenId||t.token_id)===String(i))||e[0]:null;n=s?.api_key_hash||s?.apiKeyHash||null}}}catch{}if(!n){const t=await fetch(`${e}/api/vaults/${encodeURIComponent(i)}/api-key`,{method:"POST",headers:{Authorization:`Bearer ${s}`}});if(!t.ok)throw new Error(`gen_key_${t.status}`);const n=await t.json(),r=n?.apiKey||n?.key||null;if(!r)throw new Error("missing_apiKey");return r}const r=await fetch(`${e}/decrypt`,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify({tokenId:i,dataToEncryptHash:n})});if(!r.ok)throw new Error(`decrypt_${r.status}`);const a=await r.json(),o=a?.decryptedString||null;if(!o)throw new Error("missing_decrypted");return o}hydrateSession(t){t?.authToken&&(this.session=t,this.persistSession(t),this._cachedVaultInfo=null,this.sessionMgr.setSession(t),this.emit("session",t))}logout(){this.session=null,this.persistSession(null),this._cachedVaultInfo=null,this.sessionMgr.clear(),this.emit("session",null)}on(t,e){this.events[t]||(this.events[t]=[]),this.events[t].push(e)}off(t,e){const s=this.events[t];if(s){const t=s.indexOf(e);-1!==t&&s.splice(t,1)}}async getSignerContext(){const t=this.getSession();if(!t?.authToken)throw new Error("No active session. Call openAuthModal() or authenticateWallet() first.");const e=await this.getVaultInfo();return{config:{baseUrl:this.config.apiUrl,getJwt:()=>this.getSession()?.authToken},vaultInfo:{vaultId:e.vaultId,evmAddress:e.evmAddress||"0x",address:e.solanaAddress||e.address||"",tokenId:e.tokenId,created_by:e.created_by}}}async toViemAccount(){const{toViemAccount:t}=await Promise.resolve().then(function(){return l}),{config:e,vaultInfo:s}=await this.getSignerContext();return t(e,s)}async toEthersWallet(t){const{toEthersWallet:e}=await Promise.resolve().then(function(){return u}),{config:s,vaultInfo:i}=await this.getSignerContext();return e(s,t,i)}async toWeb3Adapter(){const{toWeb3Adapter:t}=await Promise.resolve().then(function(){return w}),{config:e,vaultInfo:s}=await this.getSignerContext();return t(e,s)}async toSolanaWeb3Signer(){const{toSolanaWeb3Signer:t}=await Promise.resolve().then(function(){return m}),{config:e,vaultInfo:s}=await this.getSignerContext();return t(e,s)}async toSolanaKitSigner(){const{toSolanaKitSigner:t}=await Promise.resolve().then(function(){return m}),{config:e,vaultInfo:s}=await this.getSignerContext();return t(e,s)}destroy(){window.removeEventListener("message",this.messageHandler),this.sessionMgr.destroy(),this.closeOverlay(),Object.keys(this.events).forEach(t=>{delete this.events[t]})}resolveModalUrl(t){const e=`${this.config.authUrl.replace(/\/$/,"")}/connect`,s=new URL(e,window.location.href);return s.searchParams.set("appId",this.config.appId),s.searchParams.set("origin",t.origin),s.searchParams.set("nonce",t.nonce),t.state&&s.searchParams.set("state",t.state),s.toString()}onMessage(t){try{if(!new Set([window.location.origin,this.tryGetOriginFromConfig()].filter(Boolean)).has(t.origin))return;const e=t.data;if("emblem-auth-cancelled"===e?.type){if(!this.pendingNonce||e.nonce!==this.pendingNonce)return;return this.pendingNonce=null,this.closeOverlay(),this.config.onCancel&&this.config.onCancel(),void this.emit("cancelled",void 0)}if("emblem-auth-success"!==e?.type)return;if(!this.pendingNonce||e.nonce!==this.pendingNonce)return;this.pendingNonce=null;const s=e.session;this.session=s,this.persistSession(s),this.sessionMgr.setSession(s),s&&this.config.onSuccess&&this.config.onSuccess(s),this.emit("session",s),this.closeOverlay()}catch(t){this.emitError(t)}}emit(t,e){const s=this.events[t];if(s)for(const t of s)try{t(e)}catch(t){}}emitError(t){this.config.onError?.(t),this.emit("authError",t)}popupFeatures(){const t=Math.max(0,(window.outerHeight-600)/2);return`popup=yes,width=420,height=600,left=${Math.max(0,(window.outerWidth-420)/2)},top=${t}`}randomId(){const t=new Uint8Array(16);if(window.crypto?.getRandomValues)window.crypto.getRandomValues(t);else for(let e=0;e<t.length;e++)t[e]=Math.floor(256*Math.random());return Array.from(t,t=>t.toString(16).padStart(2,"0")).join("")}tryGetOriginFromConfig(){try{if(!this.config.authUrl)return null;return new URL(this.config.authUrl,window.location.href).origin}catch{return null}}async getAuthInit(t){const e=await fetch(`${this.config.authUrl.replace(/\/$/,"")}/api/auth/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:this.config.appId,origin:t.origin})}),s=await e.json().catch(()=>null);if(!e.ok){const t=new Error(`init ${e.status}`);throw t.status=e.status,t.payload=s||{},t}return s}openIframeModal(t){this.overlayEl&&this.closeOverlay();const e=document.createElement("div");e.setAttribute("data-emblem-overlay",""),e.style.position="fixed",e.style.inset="0",e.style.background="rgba(0,0,0,0.5)",e.style.zIndex="999999",e.style.display="flex",e.style.alignItems="center",e.style.justifyContent="center";const s=document.createElement("div");s.style.width="min(420px, 95vw)",s.style.height="min(600px, 90vh)",s.style.background="#12161b",s.style.border="1px solid #222b35",s.style.borderRadius="12px",s.style.boxShadow="0 12px 48px rgba(0,0,0,0.7)",s.style.overflow="hidden",s.style.position="relative";const i=document.createElement("button");i.textContent="×",i.setAttribute("aria-label","Close"),i.style.position="absolute",i.style.top="6px",i.style.right="8px",i.style.zIndex="2",i.style.background="transparent",i.style.color="#e6eef8",i.style.border="none",i.style.fontSize="20px",i.style.cursor="pointer",i.onclick=()=>this.cancelAuth();const n=document.createElement("iframe");n.src=t,n.style.width="100%",n.style.height="100%",n.style.border="0",n.referrerPolicy="no-referrer",n.allow="clipboard-read; clipboard-write;",s.appendChild(i),s.appendChild(n),e.appendChild(s),document.body.appendChild(e);const r=t=>{"Escape"===t.key&&this.cancelAuth()};return document.addEventListener("keydown",r,{capture:!0}),this.overlayEl=e,this._iframeEl=n,this.overlayCleanup=()=>{document.removeEventListener("keydown",r,{capture:!0})},!0}closeOverlay(){try{this.overlayCleanup?.()}catch{}this.overlayCleanup=null,this.overlayEl?.parentNode&&this.overlayEl.parentNode.removeChild(this.overlayEl),this.overlayEl=null,this._iframeEl=null}cancelAuth(){this.pendingNonce=null,this.closeOverlay(),this.config.onCancel&&this.config.onCancel(),this.emit("cancelled",void 0)}async safeJson(t){try{return await t.json()}catch{return null}}loadPersistedSession(){try{if("undefined"==typeof localStorage)return null;const t=localStorage.getItem(this.storageKey);if(!t)return null;const e=JSON.parse(t);return e?.authToken&&e?.expiresAt?Date.now()>=e.expiresAt?(localStorage.removeItem(this.storageKey),null):e:null}catch{return null}}persistSession(t){try{if("undefined"==typeof localStorage)return;t&&this.config.persistSession?localStorage.setItem(this.storageKey,JSON.stringify(t)):localStorage.removeItem(this.storageKey)}catch{}}}async function i(t,e,s){const i=s.baseUrl??"https://api.emblemvault.ai",n=await async function(t){if("function"==typeof t.getAuthHeaders){const e=await t.getAuthHeaders();if(e&&"object"==typeof e)return e}const e=t.jwt??("function"==typeof t.getJwt?await t.getJwt():void 0)??t.sdk?.getSession()?.authToken??void 0;if(e)return{Authorization:`Bearer ${e}`};if(t.apiKey)return{"x-api-key":t.apiKey};throw new Error("No authentication available: provide jwt, getJwt(), getAuthHeaders(), sdk, or apiKey")}(s),r=await fetch(`${i}${t}`,{method:"POST",headers:{"content-type":"application/json",...n},body:JSON.stringify(e,(t,e)=>"bigint"==typeof e?e.toString():e)});if(!r.ok){const t=await r.text().catch(()=>"");throw new Error(function(t,e){let s=`Emblem signer error ${t}`;return t>=500?s+=": Internal server error":401===t||403===t?s+=": Authentication failed":404===t?s+=": Resource not found":405===t?s+=": Method not allowed":e&&(s+=`: ${e.substring(0,200)}`),s}(r.status,t))}return r.json()}function n(t,e){const s=Number(t);if(!Number.isSafeInteger(s))throw new Error(`${e} value ${t} exceeds safe integer range (max: ${Number.MAX_SAFE_INTEGER})`);return s}function r(t){return"bigint"==typeof t?"0x"+t.toString(16):t}function a(t){const e={...t};return void 0!==e.value&&(e.value=r(e.value)),void 0!==e.gas&&(e.gasLimit=r(e.gas),delete e.gas),void 0!==e.gasLimit&&(e.gasLimit=r(e.gasLimit)),void 0!==e.gasPrice&&(e.gasPrice=r(e.gasPrice)),void 0!==e.maxFeePerGas&&(e.maxFeePerGas=r(e.maxFeePerGas)),void 0!==e.maxPriorityFeePerGas&&(e.maxPriorityFeePerGas=r(e.maxPriorityFeePerGas)),void 0!==e.nonce&&(e.nonce=n(e.nonce,"nonce")),void 0!==e.chainId&&(e.chainId=n(e.chainId,"chainId")),void 0===e.maxFeePerGas&&void 0===e.maxPriorityFeePerGas||(void 0===e.gasPrice&&void 0!==e.maxFeePerGas&&(e.gasPrice=e.maxFeePerGas),delete e.maxFeePerGas,delete e.maxPriorityFeePerGas),delete e.type,delete e.accessList,delete e.account,delete e.chain,delete e.from,e}function o(t){let e="0x";for(let s=0;s<t.length;s++)e+=t[s].toString(16).padStart(2,"0");return e}async function c(t){const e=await i("/vault/info",{},t);if(!e||!e.vaultId||!e.evmAddress)throw new Error("Invalid vault info response: missing required fields");if(!String(e.evmAddress).startsWith("0x"))throw new Error("Invalid evmAddress format in response");return{vaultId:e.vaultId,tokenId:e.vaultId,address:e.address||"",evmAddress:e.evmAddress,created_by:e.created_by}}var l=Object.freeze({__proto__:null,toViemAccount:async function(t,e){const s=e??await c(t),{evmAddress:n,vaultId:r}=s,{toAccount:l}=await import("viem/accounts");return l({address:n,async signMessage({message:e}){let s,n=!1;if("string"==typeof e)s=e,n=!1;else if(e&&void 0!==e.raw){const t=e.raw;s="string"==typeof t?t:o(t),n=!0}else if(e instanceof Uint8Array)s=o(e),n=!1;else{if("string"!=typeof(a=e)||!/^0x[0-9a-fA-F]*$/.test(a))throw new Error(`Unsupported message type: ${typeof e}. Expected string, Uint8Array, or hex string.`);s=e,n=!1}var a;return(await i("/sign-eth-message",{vaultId:r,message:s,raw:n},t)).signature},async signTypedData(e){const{domain:s,types:n,message:a}=e;return(await i("/sign-typed-message",{vaultId:r,domain:s,types:n,message:a},t)).signature},async signTransaction(e,s){const n=a(e);return(await i("/sign-eth-tx",{vaultId:r,transaction:n},t)).signedTransaction}})}});var h,d,u=Object.freeze({__proto__:null,toEthersWallet:async function(t,e,s){let n;try{const t="ethers";n=await import(t)}catch{throw new Error("ethers is required for toEthersWallet(). Install it with: npm install ethers")}const{AbstractSigner:r,resolveAddress:l}=n,h=s??await c(t);class d extends r{constructor(t,e,s){super(e??null),this._address=null,this._vaultId=null,this._chainId=1,this._config=t,s?.address&&(this._address=s.address),s?.vaultId&&(this._vaultId=s.vaultId),s?.chainId&&(this._chainId=s.chainId)}async initialize(){return this._initPromise||(this._initPromise=c(this._config).then(t=>{this._address=t.evmAddress,this._vaultId=t.vaultId}).catch(t=>{throw this._initPromise=void 0,t})),this._initPromise}async getAddress(){return this._address||await this.initialize(),this._address}getVaultId(){if(!this._vaultId)throw new Error("Wallet not initialized. Call initialize() first.");return this._vaultId}setChainId(t){this._chainId=t}getChainId(){return this._chainId}connect(t){if(!t)throw new Error("Provider cannot be null");return new d(this._config,t,{address:this._address??void 0,vaultId:this._vaultId??void 0,chainId:this._chainId})}async signMessage(t){this._vaultId||await this.initialize();const e="string"==typeof t?t:o(t);return(await i("/sign-eth-message",{vaultId:this._vaultId,message:e},this._config)).signature}async signTypedData(t,e,s){this._vaultId||await this.initialize();const n={...e};n&&n.EIP712Domain&&delete n.EIP712Domain;return(await i("/sign-typed-message",{vaultId:this._vaultId,domain:t,types:n,message:s},this._config)).signature}async _signTypedData(t,e,s){return this.signTypedData(t,e,s)}async signTransaction(t){this._vaultId||await this.initialize();const e=t.from,s=await this.getAddress();if(e&&e.toLowerCase()!==s.toLowerCase())throw new Error("transaction from does not match signer address");const n=this.provider?{...await this.populateTransaction(t)}:{...t};if(n.from&&delete n.from,!("to"in n)||!n.to)throw new Error("Transaction must have a 'to' address");if(void 0===n.nonce||null===n.nonce)throw new Error("Transaction must have a nonce");const r=a(n);return(await i("/sign-eth-tx",{vaultId:this._vaultId,transaction:r,options:{chainId:this._chainId}},this._config)).signedTransaction}async sendTransaction(t){if(!this.provider)throw new Error("Provider required to send transaction");const e=await this.signTransaction(t);return await this.provider.broadcastTransaction(e)}async populateTransaction(t){const e={...t};if(!this.provider)throw new Error("Provider required to populate transaction");const s=e.from?await l(e.from,this.provider):await this.getAddress();let i;if(e.chainId)i=BigInt(e.chainId),this._chainId=Number(e.chainId);else{const t=await this.provider.getNetwork();i=t.chainId,this._chainId=Number(t.chainId)}const n=null!=e.nonce?Number(e.nonce):await this.provider.getTransactionCount(s,"pending"),r=e.to?await l(e.to,this.provider):null,a=e.value?BigInt(e.value.toString()):0n;let o;if(e.gasLimit)o=BigInt(e.gasLimit.toString());else try{o=await this.provider.estimateGas({...e,from:s})}catch{o=21000n}let c=null;if(e.gasPrice||2===e.type)e.gasPrice&&(c=BigInt(e.gasPrice.toString()));else{c=(await this.provider.getFeeData()).gasPrice??null}const h={from:s,to:r,value:a,nonce:n,gasLimit:o,data:e.data,chainId:i,type:e.type||void 0};return null!==c&&(h.gasPrice=c),e.maxFeePerGas&&(h.maxFeePerGas=BigInt(e.maxFeePerGas.toString())),e.maxPriorityFeePerGas&&(h.maxPriorityFeePerGas=BigInt(e.maxPriorityFeePerGas.toString())),h}async signAndBroadcast(t,e=!1){if(!this.provider)throw new Error("Provider required to send transaction");const s=await this.signTransaction(t),i=(await this.provider.broadcastTransaction(s)).hash;return e&&await this.provider.waitForTransaction(i),i}}return new d(t,e,{address:h.evmAddress,vaultId:h.vaultId})}});function f(t,e,s,i){if("a"===s&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!i:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===s?i:"a"===s?i.call(t):i?i.value:e.get(t)}function g(t,e,s,i,n){if("m"===i)throw new TypeError("Private method is not writable");if("a"===i&&!n)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!n:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===i?n.call(t,s):n?n.value=s:e.set(t,s),s}"function"==typeof SuppressedError&&SuppressedError;class p{constructor(t,e,s){h.set(this,void 0),d.set(this,void 0),this.address=t,g(this,h,e,"f"),g(this,d,s,"f")}async signMessage(t){const e="string"==typeof t?t:o(t);return(await i("/sign-eth-message",{vaultId:f(this,h,"f"),message:e},f(this,d,"f"))).signature}async signTypedData(t,e,s){return(await i("/sign-typed-message",{vaultId:f(this,h,"f"),domain:t,types:e,message:s},f(this,d,"f"))).signature}async signTransaction(t){const e=a(t);return{rawTransaction:(await i("/sign-eth-tx",{vaultId:f(this,h,"f"),transaction:e},f(this,d,"f"))).signedTransaction}}}h=new WeakMap,d=new WeakMap;var w=Object.freeze({__proto__:null,EmblemWeb3Adapter:p,toWeb3Adapter:async function(t,e){const s=e??await c(t);return new p(s.evmAddress,s.vaultId,t)}});class y{constructor(t,e){this.publicKey=e.address,this.config=t,this.vaultId=e.vaultId}async signMessage(t){const e="string"==typeof t?(new TextEncoder).encode(t):t,s=btoa(String.fromCharCode(...e)),n=await i("/sign-solana-message",{vaultId:this.vaultId,message:s},this.config);try{const t="undefined"!=typeof window?window:void 0;if(t?.bs58)return t.bs58.decode(n.signature);return Uint8Array.from(atob(n.signature),t=>t.charCodeAt(0))}catch(t){if(n.signature.startsWith("0x")){const t=n.signature.slice(2),e=new Uint8Array(t.length/2);for(let s=0;s<t.length;s+=2)e[s/2]=parseInt(t.substr(s,2),16);return e}throw new Error(`Unable to decode signature format: ${t}`)}}async signTransaction(t){const e=this.serializeTransaction(t),s=await i("/sign-solana-transaction",{vaultId:this.vaultId,transactionToSign:e,broadcast:!1,versionedTransaction:!0},this.config),n=s.serializedSignedTransaction||s.signedTransaction;if(!n)throw new Error("No signed transaction data received from server");return this.deserializeTransaction(n)}serializeTransaction(t){if(t&&"object"==typeof t){if(t.serialize){const e=t.serialize();return btoa(String.fromCharCode(...e))}if(t.instructions||t.recentBlockhash)throw new Error("Cannot serialize unsigned transaction objects. Please use VersionedTransaction.")}return t}deserializeTransaction(t){if("object"==typeof t&&t&&t.serializedSignedTransaction&&(t=t.serializedSignedTransaction),"string"==typeof t)try{const e=atob(t);return new Uint8Array(e.split("").map(t=>t.charCodeAt(0)))}catch(t){throw new Error(`Unable to deserialize transaction response: ${t}`)}return t}getVaultId(){return this.vaultId}async signAllTransactions(t){const e=[];for(const s of t)e.push(await this.signTransaction(s));return e}canSign(t){return t===this.publicKey}async signAndBroadcast(t,e=!0){const s=this.serializeTransaction(t),n=await i("/sign-solana-transaction",{vaultId:this.vaultId,transactionToSign:s,broadcast:e,versionedTransaction:!0},this.config);if(e){if(!n.transactionSignature)throw new Error("No transaction signature received from broadcast");return n.transactionSignature}if(!n.serializedSignedTransaction)throw new Error("No signed transaction data received from server");return n.serializedSignedTransaction}}var m=Object.freeze({__proto__:null,EmblemSolanaSigner:y,toSolanaWeb3Signer:async function(t,e){const s=e??await c(t);return new y(t,s)},toSolanaKitSigner:async function(t,e){const s=e??await c(t);return new y(t,s)}});t.EmblemAuthSDK=s,t.SessionManager=e,t.default=s,Object.defineProperty(t,"__esModule",{value:!0})});
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).EmblemAuth={})}(this,function(t){"use strict";class e{constructor(t={}){this.session=null,this.timer=null,this.events={},this.onRefresh=t.onRefresh,this.refreshSkewMs=t.refreshSkewMs??6e4}setSession(t){this.session=t,this.schedule(),this.emit("session",t)}getSession(){return this.session}clear(){this.session=null,this.cancel(),this.emit("session",null)}on(t,e){this.events[t]||(this.events[t]=[]),this.events[t].push(e)}off(t,e){const s=this.events[t];if(s){const t=s.indexOf(e);-1!==t&&s.splice(t,1)}}destroy(){this.cancel(),this.session=null,Object.keys(this.events).forEach(t=>{delete this.events[t]})}emit(t,e){const s=this.events[t];if(s)for(const t of s)try{t(e)}catch(t){}}cancel(){this.timer&&(clearTimeout(this.timer),this.timer=null)}schedule(){this.cancel();const t=this.session;if(!t?.expiresAt)return;const e=Date.now(),s=t.expiresAt-e;if(s<=0)return void this.emit("sessionExpired",t);const i=Math.max(0,s-this.refreshSkewMs);this.emit("sessionWillRefresh",{inMs:i,ttl:s}),this.timer=setTimeout(async()=>{if(this.onRefresh)try{const e=await this.onRefresh(t);e?.expiresAt&&e.authToken?(this.setSession(e),this.emit("sessionRefreshed",e)):Date.now()>=t.expiresAt&&this.emit("sessionExpired",t)}catch(e){Date.now()>=t.expiresAt&&this.emit("sessionExpired",t)}else Date.now()>=t.expiresAt&&this.emit("sessionExpired",t)},i)}}class s{constructor(t){if(this.session=null,this.pendingNonce=null,this.overlayEl=null,this._iframeEl=null,this.overlayCleanup=null,this.events={},this._cachedVaultInfo=null,this._visitorId=null,!t?.appId)throw new Error("appId is required");if(this.config={...t,authUrl:t.authUrl??"https://auth.emblemvault.ai",apiUrl:t.apiUrl??"https://api.emblemvault.ai",persistSession:t.persistSession??!0},this.storageKey=`emblem_session_${t.appId}`,this.visitorIdKey=`emblem_visitorId_${t.appId}`,this.messageHandler=this.onMessage.bind(this),window.addEventListener("message",this.messageHandler),this.sessionMgr=new e({onRefresh:async t=>{try{return await this.refreshSession()||t}catch{return t}}}),this.sessionMgr.on("sessionExpired",t=>this.emit("sessionExpired",t)),this.sessionMgr.on("sessionRefreshed",t=>this.emit("sessionRefreshed",t)),this.sessionMgr.on("sessionWillRefresh",t=>this.emit("sessionWillRefresh",t)),this.config.persistSession){const t=this.loadPersistedSession();t&&this.hydrateSession(t),this._visitorId=this.loadPersistedVisitorId()}}async authenticateWallet(t){const{network:e,message:s,signature:i,publicKey:n,address:r}=t;if(!this.config.apiUrl)throw new Error("apiUrl is required for authenticateWallet");if(!e||!s||!i)throw new Error("network, message, signature are required");const a=`${this.config.apiUrl.replace(/\/$/,"")}/api/auth/wallet/verify-external`,o=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:this.config.appId,network:e,message:s,signature:i,publicKey:n,address:r})});if(!o.ok){const t=await this.safeJson(o),e=new Error(t?.error||`wallet_verify_${o.status}`);throw e.status=o.status,e.payload=t,e}const c=await o.json(),l=c?.session;return l&&(this.session=l,this.persistSession(l),this.sessionMgr.setSession(l),this.config.onSuccess?.(l),this.emit("session",l)),l}async openAuthModal(){const t=window.location.origin;let e=null,s=null;try{e=await this.getAuthInit({origin:t})}catch(t){s=t}const i=e?.nonce||this.randomId();this.pendingNonce=i;let n=this.resolveModalUrl({nonce:i,origin:t,state:e?.state});if("origin_not_allowed"===s?.payload?.error)try{const e=new URL("/connect",this.config.authUrl);e.searchParams.set("error","origin_not_allowed"),e.searchParams.set("appId",this.config.appId),e.searchParams.set("origin",t),n=e.toString()}catch{}const r=this.config.modalMode||"auto";let a=!1;if("iframe"===r||"auto"===r)try{a=this.openIframeModal(n)}catch(t){}if(!a){const t=this.popupFeatures();if(!window.open(n,"emblem-auth",t)){const t=new Error("Popup blocked. Please allow popups for this site.");this.emitError(t)}}}getSession(){return this.session}getVisitorId(){return this._visitorId}async refreshSession(){try{if(!this.session)return null;const t=this.tryGetOriginFromConfig();if(!t)return this.session;const e=`${t}/api/auth/refresh`,s=Boolean(this.session.refreshToken),i=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s?{refreshToken:this.session.refreshToken}:{}),credentials:"include"});if(!i.ok)return this.session;const n=await i.json(),r=n?.session;return r&&(this.session=r,this.persistSession(r),this.sessionMgr.setSession(r),this.emit("session",r)),this.session}catch{return this.session}}async getVaultInfo(){if(this._cachedVaultInfo)return this._cachedVaultInfo;const t=this.getSession();if(!t?.authToken)throw new Error("No session");if(!this.config.apiUrl)throw new Error("apiUrl is required");const e=this.config.apiUrl.replace(/\/$/,""),s=await fetch(`${e}/vault/info`,{method:"POST",headers:{Authorization:`Bearer ${t.authToken}`,"Content-Type":"application/json"},body:"{}"});if(!s.ok)throw new Error("Failed to fetch vault info");const i=await s.json();return this._cachedVaultInfo=i,i}async getVaultApiKey(){if(!this.config.apiUrl)throw new Error("apiUrl is required");const t=this.getSession();if(!t?.authToken)throw new Error("No active session");const e=this.config.apiUrl.replace(/\/$/,""),s=t.authToken,i=t.user?.vaultId;let n=null;try{const t=await fetch(`${e}/vault/info-complete`,{method:"POST",headers:{Authorization:`Bearer ${s}`}});if(t.ok){const e=await t.json();n=e?.raw?.pkp?.api_key_hash||e?.raw?.pkp?.apiKeyHash||null}}catch{}if(!n)try{const s=t.appId,r=t.user?.identifier||"",a=s?`${s}:${r}`:r;if(a){const t=await fetch(`${e}/api/vaults/${encodeURIComponent(a)}`);if(t.ok){const e=await t.json(),s=Array.isArray(e)?e.find(t=>String(t.tokenId||t.token_id)===String(i))||e[0]:null;n=s?.api_key_hash||s?.apiKeyHash||null}}}catch{}if(!n){const t=await fetch(`${e}/api/vaults/${encodeURIComponent(i)}/api-key`,{method:"POST",headers:{Authorization:`Bearer ${s}`}});if(!t.ok)throw new Error(`gen_key_${t.status}`);const n=await t.json(),r=n?.apiKey||n?.key||null;if(!r)throw new Error("missing_apiKey");return r}const r=await fetch(`${e}/decrypt`,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify({tokenId:i,dataToEncryptHash:n})});if(!r.ok)throw new Error(`decrypt_${r.status}`);const a=await r.json(),o=a?.decryptedString||null;if(!o)throw new Error("missing_decrypted");return o}hydrateSession(t){t?.authToken&&(this.session=t,this.persistSession(t),this._cachedVaultInfo=null,this.sessionMgr.setSession(t),this.emit("session",t))}logout(){this.session=null,this.persistSession(null),this._visitorId=null,this.persistVisitorId(null),this._cachedVaultInfo=null,this.sessionMgr.clear(),this.emit("session",null)}on(t,e){this.events[t]||(this.events[t]=[]),this.events[t].push(e)}off(t,e){const s=this.events[t];if(s){const t=s.indexOf(e);-1!==t&&s.splice(t,1)}}async getSignerContext(){const t=this.getSession();if(!t?.authToken)throw new Error("No active session. Call openAuthModal() or authenticateWallet() first.");const e=await this.getVaultInfo();return{config:{baseUrl:this.config.apiUrl,getJwt:()=>this.getSession()?.authToken},vaultInfo:{vaultId:e.vaultId,evmAddress:e.evmAddress||"0x",address:e.solanaAddress||e.address||"",tokenId:e.tokenId,created_by:e.created_by}}}async toViemAccount(){const{toViemAccount:t}=await Promise.resolve().then(function(){return l}),{config:e,vaultInfo:s}=await this.getSignerContext();return t(e,s)}async toEthersWallet(t){const{toEthersWallet:e}=await Promise.resolve().then(function(){return u}),{config:s,vaultInfo:i}=await this.getSignerContext();return e(s,t,i)}async toWeb3Adapter(){const{toWeb3Adapter:t}=await Promise.resolve().then(function(){return y}),{config:e,vaultInfo:s}=await this.getSignerContext();return t(e,s)}async toSolanaWeb3Signer(){const{toSolanaWeb3Signer:t}=await Promise.resolve().then(function(){return m}),{config:e,vaultInfo:s}=await this.getSignerContext();return t(e,s)}async toSolanaKitSigner(){const{toSolanaKitSigner:t}=await Promise.resolve().then(function(){return m}),{config:e,vaultInfo:s}=await this.getSignerContext();return t(e,s)}destroy(){window.removeEventListener("message",this.messageHandler),this.sessionMgr.destroy(),this.closeOverlay(),Object.keys(this.events).forEach(t=>{delete this.events[t]})}resolveModalUrl(t){const e=`${this.config.authUrl.replace(/\/$/,"")}/connect`,s=new URL(e,window.location.href);return s.searchParams.set("appId",this.config.appId),s.searchParams.set("origin",t.origin),s.searchParams.set("nonce",t.nonce),t.state&&s.searchParams.set("state",t.state),s.toString()}onMessage(t){try{if(!new Set([window.location.origin,this.tryGetOriginFromConfig()].filter(Boolean)).has(t.origin))return;const e=t.data;if("emblem-auth-cancelled"===e?.type){if(!this.pendingNonce||e.nonce!==this.pendingNonce)return;return this.pendingNonce=null,this.closeOverlay(),this.config.onCancel&&this.config.onCancel(),void this.emit("cancelled",void 0)}if("emblem-auth-success"!==e?.type)return;if(!this.pendingNonce||e.nonce!==this.pendingNonce)return;this.pendingNonce=null;const s=e.session;this.session=s,this.persistSession(s),this.sessionMgr.setSession(s),e.visitorId&&(this._visitorId=e.visitorId,this.persistVisitorId(e.visitorId)),s&&this.config.onSuccess&&this.config.onSuccess(s),this.emit("session",s),this.closeOverlay()}catch(t){this.emitError(t)}}emit(t,e){const s=this.events[t];if(s)for(const t of s)try{t(e)}catch(t){}}emitError(t){this.config.onError?.(t),this.emit("authError",t)}popupFeatures(){const t=Math.max(0,(window.outerHeight-600)/2);return`popup=yes,width=420,height=600,left=${Math.max(0,(window.outerWidth-420)/2)},top=${t}`}randomId(){const t=new Uint8Array(16);if(window.crypto?.getRandomValues)window.crypto.getRandomValues(t);else for(let e=0;e<t.length;e++)t[e]=Math.floor(256*Math.random());return Array.from(t,t=>t.toString(16).padStart(2,"0")).join("")}tryGetOriginFromConfig(){try{if(!this.config.authUrl)return null;return new URL(this.config.authUrl,window.location.href).origin}catch{return null}}async getAuthInit(t){const e=await fetch(`${this.config.authUrl.replace(/\/$/,"")}/api/auth/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:this.config.appId,origin:t.origin})}),s=await e.json().catch(()=>null);if(!e.ok){const t=new Error(`init ${e.status}`);throw t.status=e.status,t.payload=s||{},t}return s}openIframeModal(t){this.overlayEl&&this.closeOverlay();const e=document.createElement("div");e.setAttribute("data-emblem-overlay",""),e.style.position="fixed",e.style.inset="0",e.style.background="rgba(0,0,0,0.5)",e.style.zIndex="999999",e.style.display="flex",e.style.alignItems="center",e.style.justifyContent="center";const s=document.createElement("div");s.style.width="min(420px, 95vw)",s.style.height="min(600px, 90vh)",s.style.background="#12161b",s.style.border="1px solid #222b35",s.style.borderRadius="12px",s.style.boxShadow="0 12px 48px rgba(0,0,0,0.7)",s.style.overflow="hidden",s.style.position="relative";const i=document.createElement("button");i.textContent="×",i.setAttribute("aria-label","Close"),i.style.position="absolute",i.style.top="6px",i.style.right="8px",i.style.zIndex="2",i.style.background="transparent",i.style.color="#e6eef8",i.style.border="none",i.style.fontSize="20px",i.style.cursor="pointer",i.onclick=()=>this.cancelAuth();const n=document.createElement("iframe");n.src=t,n.style.width="100%",n.style.height="100%",n.style.border="0",n.referrerPolicy="no-referrer",n.allow="clipboard-read; clipboard-write;",s.appendChild(i),s.appendChild(n),e.appendChild(s),document.body.appendChild(e);const r=t=>{"Escape"===t.key&&this.cancelAuth()};return document.addEventListener("keydown",r,{capture:!0}),this.overlayEl=e,this._iframeEl=n,this.overlayCleanup=()=>{document.removeEventListener("keydown",r,{capture:!0})},!0}closeOverlay(){try{this.overlayCleanup?.()}catch{}this.overlayCleanup=null,this.overlayEl?.parentNode&&this.overlayEl.parentNode.removeChild(this.overlayEl),this.overlayEl=null,this._iframeEl=null}cancelAuth(){this.pendingNonce=null,this.closeOverlay(),this.config.onCancel&&this.config.onCancel(),this.emit("cancelled",void 0)}async safeJson(t){try{return await t.json()}catch{return null}}loadPersistedSession(){try{if("undefined"==typeof localStorage)return null;const t=localStorage.getItem(this.storageKey);if(!t)return null;const e=JSON.parse(t);return e?.authToken&&e?.expiresAt?Date.now()>=e.expiresAt?(localStorage.removeItem(this.storageKey),null):e:null}catch{return null}}persistSession(t){try{if("undefined"==typeof localStorage)return;t&&this.config.persistSession?localStorage.setItem(this.storageKey,JSON.stringify(t)):localStorage.removeItem(this.storageKey)}catch{}}loadPersistedVisitorId(){try{return"undefined"==typeof localStorage?null:localStorage.getItem(this.visitorIdKey)}catch{return null}}persistVisitorId(t){try{if("undefined"==typeof localStorage)return;t&&this.config.persistSession?localStorage.setItem(this.visitorIdKey,t):localStorage.removeItem(this.visitorIdKey)}catch{}}}async function i(t,e,s){const i=s.baseUrl??"https://api.emblemvault.ai",n=await async function(t){if("function"==typeof t.getAuthHeaders){const e=await t.getAuthHeaders();if(e&&"object"==typeof e)return e}const e=t.jwt??("function"==typeof t.getJwt?await t.getJwt():void 0)??t.sdk?.getSession()?.authToken??void 0;if(e)return{Authorization:`Bearer ${e}`};if(t.apiKey)return{"x-api-key":t.apiKey};throw new Error("No authentication available: provide jwt, getJwt(), getAuthHeaders(), sdk, or apiKey")}(s),r=await fetch(`${i}${t}`,{method:"POST",headers:{"content-type":"application/json",...n},body:JSON.stringify(e,(t,e)=>"bigint"==typeof e?e.toString():e)});if(!r.ok){const t=await r.text().catch(()=>"");throw new Error(function(t,e){let s=`Emblem signer error ${t}`;return t>=500?s+=": Internal server error":401===t||403===t?s+=": Authentication failed":404===t?s+=": Resource not found":405===t?s+=": Method not allowed":e&&(s+=`: ${e.substring(0,200)}`),s}(r.status,t))}return r.json()}function n(t,e){const s=Number(t);if(!Number.isSafeInteger(s))throw new Error(`${e} value ${t} exceeds safe integer range (max: ${Number.MAX_SAFE_INTEGER})`);return s}function r(t){return"bigint"==typeof t?"0x"+t.toString(16):t}function a(t){const e={...t};return void 0!==e.value&&(e.value=r(e.value)),void 0!==e.gas&&(e.gasLimit=r(e.gas),delete e.gas),void 0!==e.gasLimit&&(e.gasLimit=r(e.gasLimit)),void 0!==e.gasPrice&&(e.gasPrice=r(e.gasPrice)),void 0!==e.maxFeePerGas&&(e.maxFeePerGas=r(e.maxFeePerGas)),void 0!==e.maxPriorityFeePerGas&&(e.maxPriorityFeePerGas=r(e.maxPriorityFeePerGas)),void 0!==e.nonce&&(e.nonce=n(e.nonce,"nonce")),void 0!==e.chainId&&(e.chainId=n(e.chainId,"chainId")),void 0===e.maxFeePerGas&&void 0===e.maxPriorityFeePerGas||(void 0===e.gasPrice&&void 0!==e.maxFeePerGas&&(e.gasPrice=e.maxFeePerGas),delete e.maxFeePerGas,delete e.maxPriorityFeePerGas),delete e.type,delete e.accessList,delete e.account,delete e.chain,delete e.from,e}function o(t){let e="0x";for(let s=0;s<t.length;s++)e+=t[s].toString(16).padStart(2,"0");return e}async function c(t){const e=await i("/vault/info",{},t);if(!e||!e.vaultId||!e.evmAddress)throw new Error("Invalid vault info response: missing required fields");if(!String(e.evmAddress).startsWith("0x"))throw new Error("Invalid evmAddress format in response");return{vaultId:e.vaultId,tokenId:e.vaultId,address:e.address||"",evmAddress:e.evmAddress,created_by:e.created_by}}var l=Object.freeze({__proto__:null,toViemAccount:async function(t,e){const s=e??await c(t),{evmAddress:n,vaultId:r}=s,{toAccount:l}=await import("viem/accounts");return l({address:n,async signMessage({message:e}){let s,n=!1;if("string"==typeof e)s=e,n=!1;else if(e&&void 0!==e.raw){const t=e.raw;s="string"==typeof t?t:o(t),n=!0}else if(e instanceof Uint8Array)s=o(e),n=!1;else{if("string"!=typeof(a=e)||!/^0x[0-9a-fA-F]*$/.test(a))throw new Error(`Unsupported message type: ${typeof e}. Expected string, Uint8Array, or hex string.`);s=e,n=!1}var a;return(await i("/sign-eth-message",{vaultId:r,message:s,raw:n},t)).signature},async signTypedData(e){const{domain:s,types:n,message:a}=e;return(await i("/sign-typed-message",{vaultId:r,domain:s,types:n,message:a},t)).signature},async signTransaction(e,s){const n=a(e);return(await i("/sign-eth-tx",{vaultId:r,transaction:n},t)).signedTransaction}})}});var h,d,u=Object.freeze({__proto__:null,toEthersWallet:async function(t,e,s){let n;try{const t="ethers";n=await import(t)}catch{throw new Error("ethers is required for toEthersWallet(). Install it with: npm install ethers")}const{AbstractSigner:r,resolveAddress:l}=n,h=s??await c(t);class d extends r{constructor(t,e,s){super(e??null),this._address=null,this._vaultId=null,this._chainId=1,this._config=t,s?.address&&(this._address=s.address),s?.vaultId&&(this._vaultId=s.vaultId),s?.chainId&&(this._chainId=s.chainId)}async initialize(){return this._initPromise||(this._initPromise=c(this._config).then(t=>{this._address=t.evmAddress,this._vaultId=t.vaultId}).catch(t=>{throw this._initPromise=void 0,t})),this._initPromise}async getAddress(){return this._address||await this.initialize(),this._address}getVaultId(){if(!this._vaultId)throw new Error("Wallet not initialized. Call initialize() first.");return this._vaultId}setChainId(t){this._chainId=t}getChainId(){return this._chainId}connect(t){if(!t)throw new Error("Provider cannot be null");return new d(this._config,t,{address:this._address??void 0,vaultId:this._vaultId??void 0,chainId:this._chainId})}async signMessage(t){this._vaultId||await this.initialize();const e="string"==typeof t?t:o(t);return(await i("/sign-eth-message",{vaultId:this._vaultId,message:e},this._config)).signature}async signTypedData(t,e,s){this._vaultId||await this.initialize();const n={...e};n&&n.EIP712Domain&&delete n.EIP712Domain;return(await i("/sign-typed-message",{vaultId:this._vaultId,domain:t,types:n,message:s},this._config)).signature}async _signTypedData(t,e,s){return this.signTypedData(t,e,s)}async signTransaction(t){this._vaultId||await this.initialize();const e=t.from,s=await this.getAddress();if(e&&e.toLowerCase()!==s.toLowerCase())throw new Error("transaction from does not match signer address");const n=this.provider?{...await this.populateTransaction(t)}:{...t};if(n.from&&delete n.from,!("to"in n)||!n.to)throw new Error("Transaction must have a 'to' address");if(void 0===n.nonce||null===n.nonce)throw new Error("Transaction must have a nonce");const r=a(n);return(await i("/sign-eth-tx",{vaultId:this._vaultId,transaction:r,options:{chainId:this._chainId}},this._config)).signedTransaction}async sendTransaction(t){if(!this.provider)throw new Error("Provider required to send transaction");const e=await this.signTransaction(t);return await this.provider.broadcastTransaction(e)}async populateTransaction(t){const e={...t};if(!this.provider)throw new Error("Provider required to populate transaction");const s=e.from?await l(e.from,this.provider):await this.getAddress();let i;if(e.chainId)i=BigInt(e.chainId),this._chainId=Number(e.chainId);else{const t=await this.provider.getNetwork();i=t.chainId,this._chainId=Number(t.chainId)}const n=null!=e.nonce?Number(e.nonce):await this.provider.getTransactionCount(s,"pending"),r=e.to?await l(e.to,this.provider):null,a=e.value?BigInt(e.value.toString()):0n;let o;if(e.gasLimit)o=BigInt(e.gasLimit.toString());else try{o=await this.provider.estimateGas({...e,from:s})}catch{o=21000n}let c=null;if(e.gasPrice||2===e.type)e.gasPrice&&(c=BigInt(e.gasPrice.toString()));else{c=(await this.provider.getFeeData()).gasPrice??null}const h={from:s,to:r,value:a,nonce:n,gasLimit:o,data:e.data,chainId:i,type:e.type||void 0};return null!==c&&(h.gasPrice=c),e.maxFeePerGas&&(h.maxFeePerGas=BigInt(e.maxFeePerGas.toString())),e.maxPriorityFeePerGas&&(h.maxPriorityFeePerGas=BigInt(e.maxPriorityFeePerGas.toString())),h}async signAndBroadcast(t,e=!1){if(!this.provider)throw new Error("Provider required to send transaction");const s=await this.signTransaction(t),i=(await this.provider.broadcastTransaction(s)).hash;return e&&await this.provider.waitForTransaction(i),i}}return new d(t,e,{address:h.evmAddress,vaultId:h.vaultId})}});function f(t,e,s,i){if("a"===s&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!i:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===s?i:"a"===s?i.call(t):i?i.value:e.get(t)}function g(t,e,s,i,n){if("m"===i)throw new TypeError("Private method is not writable");if("a"===i&&!n)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!n:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===i?n.call(t,s):n?n.value=s:e.set(t,s),s}"function"==typeof SuppressedError&&SuppressedError;class p{constructor(t,e,s){h.set(this,void 0),d.set(this,void 0),this.address=t,g(this,h,e,"f"),g(this,d,s,"f")}async signMessage(t){const e="string"==typeof t?t:o(t);return(await i("/sign-eth-message",{vaultId:f(this,h,"f"),message:e},f(this,d,"f"))).signature}async signTypedData(t,e,s){return(await i("/sign-typed-message",{vaultId:f(this,h,"f"),domain:t,types:e,message:s},f(this,d,"f"))).signature}async signTransaction(t){const e=a(t);return{rawTransaction:(await i("/sign-eth-tx",{vaultId:f(this,h,"f"),transaction:e},f(this,d,"f"))).signedTransaction}}}h=new WeakMap,d=new WeakMap;var y=Object.freeze({__proto__:null,EmblemWeb3Adapter:p,toWeb3Adapter:async function(t,e){const s=e??await c(t);return new p(s.evmAddress,s.vaultId,t)}});class w{constructor(t,e){this.publicKey=e.address,this.config=t,this.vaultId=e.vaultId}async signMessage(t){const e="string"==typeof t?(new TextEncoder).encode(t):t,s=btoa(String.fromCharCode(...e)),n=await i("/sign-solana-message",{vaultId:this.vaultId,message:s},this.config);try{const t="undefined"!=typeof window?window:void 0;if(t?.bs58)return t.bs58.decode(n.signature);return Uint8Array.from(atob(n.signature),t=>t.charCodeAt(0))}catch(t){if(n.signature.startsWith("0x")){const t=n.signature.slice(2),e=new Uint8Array(t.length/2);for(let s=0;s<t.length;s+=2)e[s/2]=parseInt(t.substr(s,2),16);return e}throw new Error(`Unable to decode signature format: ${t}`)}}async signTransaction(t){const e=this.serializeTransaction(t),s=await i("/sign-solana-transaction",{vaultId:this.vaultId,transactionToSign:e,broadcast:!1,versionedTransaction:!0},this.config),n=s.serializedSignedTransaction||s.signedTransaction;if(!n)throw new Error("No signed transaction data received from server");return this.deserializeTransaction(n)}serializeTransaction(t){if(t&&"object"==typeof t){if(t.serialize){const e=t.serialize();return btoa(String.fromCharCode(...e))}if(t.instructions||t.recentBlockhash)throw new Error("Cannot serialize unsigned transaction objects. Please use VersionedTransaction.")}return t}deserializeTransaction(t){if("object"==typeof t&&t&&t.serializedSignedTransaction&&(t=t.serializedSignedTransaction),"string"==typeof t)try{const e=atob(t);return new Uint8Array(e.split("").map(t=>t.charCodeAt(0)))}catch(t){throw new Error(`Unable to deserialize transaction response: ${t}`)}return t}getVaultId(){return this.vaultId}async signAllTransactions(t){const e=[];for(const s of t)e.push(await this.signTransaction(s));return e}canSign(t){return t===this.publicKey}async signAndBroadcast(t,e=!0){const s=this.serializeTransaction(t),n=await i("/sign-solana-transaction",{vaultId:this.vaultId,transactionToSign:s,broadcast:e,versionedTransaction:!0},this.config);if(e){if(!n.transactionSignature)throw new Error("No transaction signature received from broadcast");return n.transactionSignature}if(!n.serializedSignedTransaction)throw new Error("No signed transaction data received from server");return n.serializedSignedTransaction}}var m=Object.freeze({__proto__:null,EmblemSolanaSigner:w,toSolanaWeb3Signer:async function(t,e){const s=e??await c(t);return new w(t,s)},toSolanaKitSigner:async function(t,e){const s=e??await c(t);return new w(t,s)}});t.EmblemAuthSDK=s,t.SessionManager=e,t.default=s,Object.defineProperty(t,"__esModule",{value:!0})});
2
2
  //# sourceMappingURL=emblem-auth.min.js.map