@getpara/core-sdk 1.4.2 → 1.4.4-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -1,2 +1,3722 @@
1
- var Qe=Object.defineProperty;var Ze=(i,e)=>{for(var t in e)Qe(i,t,{get:e[t],enumerable:!0})};import{Buffer as ye}from"buffer";import{AuthMethod as fe,PublicKeyStatus as Xe,PublicKeyType as qe,WalletType as f,WalletScheme as E,OAuthMethod as kt,extractWalletRef as Kt,PasswordStatus as Dt,extractAuthInfo as Gt}from"@getpara/user-management-client";import Bt from"node-forge";import gt from"base64url";import y from"node-forge";function u(i,e,t){typeof window<"u"&&window.dispatchEvent&&window.dispatchEvent(new CustomEvent(i,{detail:{data:e,...t&&{error:new Error(t)}}}))}import{toBech32 as et}from"@cosmjs/encoding";import{sha256 as tt}from"@noble/hashes/sha256";import{ripemd160 as rt}from"@noble/hashes/ripemd160";import st from"elliptic";import it from"libphonenumber-js";var nt=new st.ec("secp256k1");function Xt(i){return i.substring(0,2)==="0x"&&(i=i.substring(2)),Buffer.from(i,"hex").toString("base64")}function qt(i){return{r:`0x${i.slice(2,66)}`,s:`0x${i.slice(66,130)}`,v:BigInt(i.slice(130,132))}}function zt(i){return i.startsWith("0x")&&(i=i.slice(2)),new Uint8Array(Buffer.from(i,"hex"))}function Qt(i){return i.startsWith("0x")&&(i=i.slice(2)),`${parseInt(i,16)}`}function Zt(i){return`0x${parseInt(i).toString(16)}`}function at(i){switch(i.length){case 33:return i;case 65:return Uint8Array.from(nt.keyFromPublic(i).getPublic(!0,"array"));default:throw new Error("Invalid pubkey length")}}function ot(i){if(i.length!==33)throw new Error(`Invalid Secp256k1 pubkey length (compressed): ${i.length}`);return rt(tt(i))}function Ee(i,e){let t=new Uint8Array(Buffer.from(i.startsWith("0x")?i.slice(2):i,"hex")),r=at(t);return et(e,ot(r))}function se(i,e,{prefix:t=e==="COSMOS"?"cosmos":void 0}={}){let r=(e==="COSMOS"?t.length:e==="SOLANA"?0:2)+4;return`${i.slice(0,r)}...${i.slice(-4)}`}function j(i){return it(i)?.formatInternational().replace(/[^\d+]/g,"")}function we(i,e){return j(`${i[0]!=="+"?"+":""}${i}${e}`)}function ie(i){let e=[];return Object.keys(i).forEach(t=>{let r=i[t];Object.keys(r).forEach(s=>{let n=r[s];Object.keys(n).forEach(a=>{let o=n[a];e.push([t,s,a,o])})})}),e}function lt(i,{walletType:e,allowed:t}={}){return[...new Set(ie(i).filter(([r,s])=>(!e||r===e)&&(!t||t.includes(s))).map(([r,s])=>s))]}function ct(i,{walletType:e,network:t,allowed:r}={}){return[...new Set(ie(i).filter(([s,n,a])=>(!e||s===e)&&(!t||n===t)&&(!Array.isArray(r)||r.includes(a))).map(([,,s])=>s))]}async function rr(i,e,t){let r=Date.now();for(;Date.now()-r<e;){if(await i())return!0;await new Promise(s=>setTimeout(s,t))}return!1}var pt=(a=>(a.DEV="DEV",a.SANDBOX="SANDBOX",a.BETA="BETA",a.PROD="PROD",a.DEVELOPMENT="BETA",a.PRODUCTION="PROD",a))(pt||{}),dt=(r=>(r.BUY="BUY",r.RECEIVE="RECEIVE",r.WITHDRAW="WITHDRAW",r))(dt||{});var Ie=(t=>(t.EMAIL="EMAIL",t.PHONE="PHONE",t))(Ie||{});var Pe=(s=>(s.ACH="ACH",s.DEBIT="Debit",s.CREDIT="Credit",s.APPLE_PAY="Apple Pay",s))(Pe||{});var ne=(a=>(a.SIGN_TRANSACTION_REVIEW="SIGN_TRANSACTION_REVIEW",a.SIGN_MESSAGE_REVIEW="SIGN_MESSAGE_REVIEW",a.LOGIN_PASSKEY="LOGIN_PASSKEY",a.CREATE_PASSKEY="CREATE_PASSKEY",a.OAUTH="OAUTH",a.ON_RAMP_TRANSACTION="ON_RAMP_TRANSACTION",a))(ne||{});var Ae=(n=>(n.INITIATED="INITIATED",n.READY="READY",n.EXPIRED="EXPIRED",n.FINISHED="FINISHED",n.CANCELLED="CANCELLED",n))(Ae||{});var I="para",d=(p=>(p.LOGIN_EVENT=`${I}Login`,p.ACCOUNT_CREATION_EVENT=`${I}AccountCreation`,p.ACCOUNT_SETUP_EVENT=`${I}AccountSetup`,p.LOGOUT_EVENT=`${I}Logout`,p.SIGN_MESSAGE_EVENT=`${I}SignMessage`,p.SIGN_TRANSACTION_EVENT=`${I}SignTransaction`,p.EXTERNAL_WALLET_CHANGE_EVENT=`${I}ExternalWalletChange`,p.WALLETS_CHANGE_EVENT=`${I}WalletsChange`,p.WALLET_CREATED=`${I}WalletCreated`,p.PREGEN_WALLET_CLAIMED=`${I}PregenWalletClaimed`,p))(d||{});function Te(i,e){if(e)return"localhost";switch(i){case"DEV":return"localhost";case"SANDBOX":return"app.sandbox.usecapsule.com";case"BETA":return"app.beta.usecapsule.com";case"PROD":return"app.usecapsule.com";default:throw new Error(`env: ${i} not supported`)}}function T({env:i,isE2E:e},t,r){if(e)return r?"https://app.sandbox.usecapsule.com":"http://localhost:3003";let s=Te(i);return i==="DEV"?t?"http://127.0.0.1:3003":`http://${s}:3003`:`https://${s}`}function ut(i){switch(i){case"DEV":return"localhost";case"SANDBOX":return"connect.sandbox.getpara.com";case"BETA":return"connect.beta.getpara.com";case"PROD":return"connect.getpara.com";default:throw new Error(`env: ${i} not supported`)}}function We({env:i},e){let t=ut(i);return i==="DEV"?e?"http://127.0.0.1:3008":`http://${t}:3008`:`https://${t}`}function Q({base:i,path:e,params:t={}}){let r=new URL(e,i);return Object.entries(t).forEach(([s,n])=>{n&&n!=="undefined"&&n!=="null"&&r.searchParams.set(s,n.toString())}),r.toString()}import{WalletScheme as v,WalletType as P}from"@getpara/user-management-client";var w={[v.DKLS]:{[P.EVM]:!0,[P.COSMOS]:!0},[v.CGGMP]:{[P.EVM]:!0,[P.COSMOS]:!0},[v.ED25519]:{[P.SOLANA]:!0}};function Ce(i,e,t){if(!i||!e)return!1;switch(t){case"EMAIL":return i.toLowerCase()===e.toLowerCase();case"PHONE":return j(i)===j(e);case"CUSTOM_ID":return i===e;default:return i.replace(/^@/g,"").toLowerCase()===e.replace(/^@/g,"").toLowerCase()}}function ae(i,e){return i.some(t=>!!w[e.scheme][t])}function oe(i){return Object.keys(w).filter(e=>e===v.CGGMP?!1:(Array.isArray(i)?i:Object.keys(i)).some(t=>w[e][t]))}function ht(i){return[...new Set(i.reduce((e,t)=>[...e,...Object.keys(w[t]).filter(r=>w[t][r])],[]))]}function le(i){return ht(oe((Array.isArray(i)?i:[i]).map(e=>P[e])))}function _(i){return{...i,scheme:i.scheme,type:i.type,pregenIdentifierType:i.pregenIdentifierType}}function U(i){return["USER","PREGEN"].includes(i.type)&&(i.isPregen=i.type==="PREGEN",i.type=i.scheme===v.ED25519?P.SOLANA:P.EVM),i.scheme&&!i.type&&(i.type=i.scheme===v.ED25519?P.SOLANA:P.EVM),i}var mt=y.pki.rsa,ce="RSA-OAEP",Re="794241bc819a125a7b78ea313decc0bc",Z=new Uint8Array([23,66,157,146,179,158,117,120,184,73,123,81]);function Oe(i){let e=y.md.sha256.create();return e.update(i),e.digest().toHex()}function N(i){let e=y.pki.publicKeyToRSAPublicKeyPem(i.publicKey);return Buffer.from(e,"utf-8").toString("hex")}function yt(i){let e=xe(i);return y.pki.publicKeyFromPem(e)}function xe(i){return Buffer.from(i,"hex").toString("utf-8")}function pe(i){let e=y.pki.privateKeyToPem(i.privateKey);return Buffer.from(e,"utf-8").toString("hex")}function Le(i){let e=Buffer.from(i,"hex").toString("utf-8");return y.pki.privateKeyFromPem(e)}async function ft(i,e){let t=pe(i),r=await window.crypto.subtle.importKey("raw",Buffer.from(e,"base64"),{name:"AES-GCM",length:256},!0,["encrypt","decrypt"]),s=new TextEncoder().encode(t),n=await window.crypto.subtle.encrypt({name:"AES-GCM",iv:Z},r,s);return Buffer.from(n).toString("base64")}async function be(i,e){let t=await crypto.subtle.importKey("raw",Buffer.from(e,"base64"),{name:"AES-GCM",length:256},!0,["encrypt","decrypt"]),r=await crypto.subtle.decrypt({name:"AES-GCM",iv:Z},t,Buffer.from(i,"base64")),s=new TextDecoder().decode(r);return Le(s)}async function J(i,e){let t=y.random.createInstance();e&&(t.seedFileSync=s=>e,t.seedFile=(s,n)=>{n(null,e)});let r={bits:2048,e:65537,prng:t};if(!i.disableWorkers){r.workLoad=100,r.workers=e?1:-1;let s=await fetch(`${T(i)}/static/js/prime.worker.min.js`),n=new Blob([await s.text()],{type:"application/javascript"});r.workerScript=URL.createObjectURL(n)}return new Promise((s,n)=>mt.generateKeyPair(r,(a,o)=>{a&&n(a),s(o)}))}async function St(i,e){let t=gt.encode(e),r=await J(i,t);return N(r)}function Et(i){let e=y.random.getBytesSync(16),t=y.cipher.createCipher("AES-CBC",e);t.start({iv:Re}),t.update(y.util.createBuffer(i)),t.finish();let r=t.output.toHex();return{key:e,encryptedMessageHex:r}}function ve(i,e){let t=y.cipher.createDecipher("AES-CBC",i);return t.start({iv:Re}),t.update(y.util.createBuffer(y.util.hexToBytes(e))),t.finish(),t.output.toString()}function wt(i,e,t){let r=Buffer.from(t,"hex").toString("utf-8"),s=i.privateKey.decrypt(r,ce);return ve(s,e)}function Y(i,e,t){let r=Buffer.from(t,"hex").toString("utf-8"),s=i.decrypt(r,ce);return ve(s,e)}async function It(i,{seedValue:e,encryptedMessageHex:t,encryptedKeyHex:r}){let s=await J(i,e);return Y(s.privateKey,t,r)}async function Pt(i,e,t){return Promise.all(t.map(async r=>({walletId:r.walletId,walletScheme:r.walletScheme,partnerId:r.partnerId,signer:await It(i,{seedValue:e,encryptedMessageHex:r.encryptedShare,encryptedKeyHex:r.encryptedKey}),protocolId:r.protocolId})))}async function At(i,e,t){let r;try{r=await be(t,i)}catch{}try{r=await _e(t,i)}catch{}if(!r)throw new Error("Could not decrypt private key");return e.map(s=>({walletId:s.walletId,walletScheme:s.walletScheme,partnerId:s.partnerId,signer:Y(r,s.encryptedShare,s.encryptedKey),protocolId:s.protocolId}))}function ee(i,e){let{key:t,encryptedMessageHex:r}=Et(e),s=xe(i),a=y.pki.publicKeyFromPem(s).encrypt(t,ce),o=Buffer.from(a,"utf-8").toString("hex");return{encryptedMessageHex:r,encryptedKeyHex:o}}function Tt(i){let e=Wt(),t=e+i,r=Oe(t);return{salt:e,hash:r}}function Wt(i=16){return y.util.bytesToHex(y.random.getBytesSync(i))}async function Ct(i){let e=Buffer.from(i,"hex");return await window.crypto.subtle.importKey("raw",e,{name:"AES-GCM",length:256},!0,["encrypt","decrypt"])}async function Rt(i,e){let t=await Ct(e),r=pe(i),s=new TextEncoder().encode(r),n=await window.crypto.subtle.encrypt({name:"AES-GCM",iv:Z},t,s);return Buffer.from(n).toString("base64")}async function _e(i,e){let t=await crypto.subtle.importKey("raw",Buffer.from(e,"hex"),{name:"AES-GCM",length:256},!0,["encrypt","decrypt"]),r=await crypto.subtle.decrypt({name:"AES-GCM",iv:Z},t,Buffer.from(i,"base64")),s=new TextDecoder().decode(r);return Le(s)}import Ot from"@getpara/user-management-client";function Ue(i){switch(i){case"DEV":return"http://localhost:8080/";case"SANDBOX":return"https://api.sandbox.usecapsule.com/";case"BETA":return"https://api.beta.usecapsule.com/";case"PROD":return"https://api.usecapsule.com/";default:throw new Error(`unsupported env: ${i}`)}}function Ne(i){switch(i){case"DEV":return"http://localhost:8080/";case"SANDBOX":return"https://api.sandbox.getpara.com/";case"BETA":return"https://api.beta.getpara.com/";case"PROD":return"https://api.getpara.com/";default:throw new Error(`unsupported env: ${i}`)}}function Ir(i,e){let t=e?"ws":"http";switch(i){case"DEV":return`${t}://localhost:3000`;case"SANDBOX":return`${t}s://mpc-network.sandbox.getpara.com`;case"BETA":return`${t}s://mpc-network.beta.getpara.com`;case"PROD":return`${t}s://mpc-network.prod.getpara.com`;default:throw new Error(`unsupported env: ${i}`)}}function de({env:i,version:e,apiKey:t,partnerId:r,useFetchAdapter:s=!1,retrieveSessionCookie:n,persistSessionCookie:a}){return new Ot({userManagementHost:Ne(i),version:["DEV","SANDBOX"].includes(i)?"dev":e,apiKey:t,partnerId:r,opts:{useFetchAdapter:s},retrieveSessionCookie:n,persistSessionCookie:a})}var he={};Ze(he,{initClient:()=>ue});import xt from"axios";function ue(i,e){let t=xt.create({baseURL:i});return e&&(t.defaults.adapter=function(r){return fetch(r.baseURL+r.url,{method:r.method,headers:r.headers,body:r.data,credentials:r.withCredentials?"include":void 0}).then(s=>s.text().then(n=>({data:n,status:s.status,statusText:s.statusText,headers:s.headers,config:r,request:fetch}))).catch(function(s){throw s})}),t}import{EncryptorType as Fe,KeyShareType as Me}from"@getpara/user-management-client";import{EncryptorType as Ge,KeyShareType as Be}from"@getpara/user-management-client";import{Encrypt as ke,Decrypt as Lt}from"@celo/utils/lib/ecies.js";import*as Ke from"ethereumjs-util";import*as De from"node-forge";var k=class i{constructor(e,t,r){this.walletId=e,this.keyshare=t,this.address=r,this.backupDecryptionKey=Buffer.from(De.random.getBytesSync(32),"binary").toString("hex")}static buildFrom(e){try{let t=JSON.parse(e);return Object.assign(new i("","",""),t)}catch{let r=new i("","","");return r.backupDecryptionKey=e.split("|")[0],r}}getPublicEncryptionKey(){return Buffer.from(Ke.privateToPublic(Buffer.from(this.backupDecryptionKey,"hex")))}getPublicEncryptionKeyHex(){return this.getPublicEncryptionKey().toString("hex")}encryptForSelf(e){try{let t=this.getPublicEncryptionKey();return ke(t,Buffer.from(e,"ucs2")).toString("base64")}catch{throw Error("Error encrypting backup")}}static encryptWithPublicKey(e,t){try{return ke(e,Buffer.from(t,"ucs2")).toString("base64")}catch{throw Error("Error encrypting backup")}}decrypt(e){try{let t=Buffer.from(e,"base64"),r=Lt(Buffer.from(this.backupDecryptionKey,"hex"),t);return Buffer.from(r.buffer).toString("ucs2")}catch{throw Error("Error decrypting backup")}}};async function te({ctx:i,userId:e,walletId:t,otherEncryptedShares:r=[],userSigner:s,ignoreRedistributingBackupEncryptedShare:n=!1,emailProps:a={},forceRefresh:o=!1}){if(n)return await i.client.uploadUserKeyShares(e,r.map(S=>({walletId:t,...S}))),"";let l,c,{recoveryPublicKeys:p}=await i.client.getRecoveryPublicKeys(e);if(o||!p?.length){c=new k(t,"","");let{recoveryPublicKeys:S}=await i.client.persistRecoveryPublicKeys(e,[c.getPublicEncryptionKeyHex()]),h=c.encryptForSelf(s);l=[{walletId:t,encryptedShare:h,type:Be.USER,encryptor:Ge.RECOVERY,recoveryPublicKeyId:S[0].id}]}else l=p.map(S=>{let{id:h,publicKey:g}=S,A=k.encryptWithPublicKey(Buffer.from(g,"hex"),s);return{walletId:t,encryptedShare:A,type:Be.USER,encryptor:Ge.RECOVERY,recoveryPublicKeyId:h}});return await i.client.uploadUserKeyShares(e,[...r.map(S=>({walletId:t,...S})),...n?[]:l]),await i.client.distributeParaShare({userId:e,walletId:t,useDKLS:i.useDKLS,...a}),c?JSON.stringify(c):""}async function K({ctx:i,userId:e,walletId:t,userShare:r,ignoreRedistributingBackupEncryptedShare:s=!1,emailProps:n={},partnerId:a,protocolId:o}){let c=(await i.client.getSessionPublicKeys(e)).data.keys.map(g=>{if(!g.publicKey)return;let{encryptedMessageHex:A,encryptedKeyHex:b}=ee(g.sigDerivedPublicKey,r);return{encryptedShare:A,encryptedKey:b,type:Me.USER,encryptor:Fe.BIOMETRICS,biometricPublicKey:g.sigDerivedPublicKey,partnerId:a,protocolId:o}}).filter(Boolean),S=(await i.client.getPasswords({userId:e})).map(g=>{if(g.status==="PENDING")return;let{encryptedMessageHex:A,encryptedKeyHex:b}=ee(g.sigDerivedPublicKey,r);return{encryptedShare:A,encryptedKey:b,type:Me.USER,encryptor:Fe.PASSWORD,passwordId:g.id,partnerId:a,protocolId:o}}).filter(Boolean),h=[...c,...S];return await te({ctx:i,userId:e,walletId:t,otherEncryptedShares:h,userSigner:r,ignoreRedistributingBackupEncryptedShare:s,emailProps:n})}import{Encrypt as bt,Decrypt as vt}from"@celo/utils/lib/ecies.js";import{Buffer as D}from"buffer";import*as Ve from"ethereumjs-util";import{randomBytes as _t}from"crypto";async function $e(i,e){let t,r;for(;;)try{t=_t(32).toString("hex"),r=Ve.privateToPublic(D.from(t,"hex"));break}catch{continue}let s=D.from(r),n=bt(s,D.from(i,"ucs2")).toString("base64"),{data:{id:a}}=await e.tempTrasmissionInit(n);return encodeURIComponent(a+"|"+t)}async function Ut(i,e){let[t,r]=decodeURIComponent(i).split("|"),n=(await e.tempTrasmission(t)).data.message,a=D.from(n,"base64");return D.from(vt(D.from(r,"hex"),a).buffer).toString("ucs2")}var re=class extends Error{constructor(e){super("transaction review error"),this.name="TransactionReviewError",this.transactionReviewUrl=e}},X=class extends Error{constructor(){super("transaction review has been denied by the user"),this.name="TransactionReviewDenied"}},q=class extends Error{constructor(e,t){super("transaction review has timed out"),this.name="TransactionReviewTimeout",this.transactionReviewUrl=e,this.pendingTransactionId=t}};var He='1.4.1',m="@CAPSULE/",G=`${m}e-mail`,B=`${m}phone`,F=`${m}countryCode`,je=`${m}farcasterUsername`,M=`${m}telegramUserId`,V=`${m}userId`,O=`${m}ed25519Wallets`,W=`${m}wallets`,$=`${m}externalWallets`,x=`${m}currentWalletIds`,H=`${m}currentExternalWalletAddresses`,R=`${m}sessionCookie`,L=`${m}loginEncryptionKeyPair`,C=2e3,ge=1e3;function Ye(i){i.url.includes(window.location.origin)&&(i.key===H&&this.updateCurrentExternalWalletAddressesFromStorage(),i.key===$&&this.updateExternalWalletsFromStorage(),i.key===L&&this.updateLoginEncryptionKeyPairFromStorage(),i.key===R&&this.updateSessionCookieFromStorage(),i.key===x&&this.updateWalletIdsFromStorage(),(i.key===W||i.key===O)&&this.updateWalletsFromStorage(),i.key===G&&this.updateEmailFromStorage(),i.key===F&&this.updateCountryCodeFromStorage(),i.key===B&&this.updatePhoneFromStorage(),i.key===V&&this.updateUserIdFromStorage(),i.key===M&&this.updateTelegramUserIdFromStorage())}function me(){typeof window<"u"&&window.addEventListener&&window.location&&(window.removeEventListener("storage",Ye.bind(this)),window.addEventListener("storage",Ye.bind(this)))}typeof global<"u"?global.Buffer=global.Buffer||ye:typeof window<"u"?(window.Buffer=window.Buffer||ye,window.global=window.global||window):(self.Buffer=self.Buffer||ye,self.global=self.global||self);var{pki:ze,jsbn:Ft}=Bt,z=class i{constructor(e,t,r){this.isAwaitingAccountCreation=!1;this.isAwaitingLogin=!1;this.isAwaitingFarcaster=!1;this.isAwaitingOAuth=!1;this.currentWalletIds={};this.#e=void 0;this.#t=void 0;this.localStorageGetItem=e=>this.platformUtils.localStorage.get(e);this.localStorageSetItem=(e,t)=>this.platformUtils.localStorage.set(e,t);this.sessionStorageGetItem=e=>this.platformUtils.sessionStorage.get(e);this.sessionStorageSetItem=(e,t)=>this.platformUtils.sessionStorage.set(e,t);this.sessionStorageRemoveItem=e=>this.platformUtils.sessionStorage.removeItem(e);this.retrieveSessionCookie=()=>this.sessionCookie;this.clearStorage=async(e="all")=>{let t=e==="all";(t||e==="local")&&this.platformUtils.localStorage.clear(m),(t||e==="session")&&this.platformUtils.sessionStorage.clear(m),(t||e==="secure")&&this.platformUtils.secureStorage&&this.platformUtils.secureStorage.clear(m)};this.initializeFromStorage=()=>{this.updateEmailFromStorage(),this.updateCountryCodeFromStorage(),this.updatePhoneFromStorage(),this.updateUserIdFromStorage(),this.updateTelegramUserIdFromStorage(),this.updateWalletsFromStorage(),this.updateWalletIdsFromStorage(),this.updateSessionCookieFromStorage(),this.updateLoginEncryptionKeyPairFromStorage(),this.updateExternalWalletsFromStorage(),this.updateCurrentExternalWalletAddressesFromStorage()};this.updateTelegramUserIdFromStorage=()=>{this.telegramUserId=this.localStorageGetItem(M)||void 0};this.updateUserIdFromStorage=()=>{this.userId=this.localStorageGetItem(V)||void 0};this.updatePhoneFromStorage=()=>{this.phone=this.localStorageGetItem(B)||void 0};this.updateCountryCodeFromStorage=()=>{this.countryCode=this.localStorageGetItem(F)||void 0};this.updateEmailFromStorage=()=>{this.email=this.localStorageGetItem(G)||void 0};this.updateWalletsFromStorage=async()=>{let e=this.localStorageGetItem(x)??void 0,t=[void 0,null,"undefined"].includes(e)?{}:(()=>{let l=JSON.parse(e);return Array.isArray(l)?Object.keys(f).reduce((c,p)=>{let S=Object.values(this.wallets).find(h=>l.includes(h.id)&&w[h.scheme][p]);return{...c,...S&&!c[p]?{[p]:[S.id]}:{}}},{}):l})();this.setCurrentWalletIds(t);let r=this.platformUtils.secureStorage?this.platformUtils.secureStorage.get(W):this.localStorageGetItem(W),s=JSON.parse(r||"{}"),n=this.platformUtils.secureStorage?this.platformUtils.secureStorage.get(O):this.localStorageGetItem(O),a=JSON.parse(n||"{}"),o={...Object.keys(s).reduce((l,c)=>({...l,[c]:U(s[c])}),{}),...Object.keys(a).reduce((l,c)=>({...l,...l[c]?{}:{[c]:U(a[c])}}),{})};this.setWallets(o)};this.updateWalletIdsFromStorage=()=>{let e=this.localStorageGetItem(x)??void 0,t=[void 0,null,"undefined"].includes(e)?{}:(()=>{let r=JSON.parse(e);return Array.isArray(r)?Object.keys(f).reduce((s,n)=>{let a=Object.values(this.wallets).find(o=>r.includes(o.id)&&w[o.scheme][n]);return{...s,...a&&!s[n]?{[n]:[a.id]}:{}}},{}):r})();this.setCurrentWalletIds(t),Object.values(this.wallets).filter(r=>this.isWalletOwned(r)).length>0&&this.currentWalletIdsArray.length===0&&this.findWalletId(void 0,{forbidPregen:!0})};this.updateSessionCookieFromStorage=()=>{this.sessionCookie=this.localStorageGetItem(R)||this.sessionStorageGetItem(R)||void 0};this.updateLoginEncryptionKeyPairFromStorage=()=>{let e=this.sessionStorageGetItem(L);e&&e!=="undefined"&&(this.loginEncryptionKeyPair=this.convertEncryptionKeyPair(JSON.parse(e)))};this.updateExternalWalletsFromStorage=()=>{let e=this.localStorageGetItem($),t=JSON.parse(e||"{}");this.setExternalWallets(t)};this.updateCurrentExternalWalletAddressesFromStorage=()=>{let e=this.localStorageGetItem(H)||void 0;this.currentExternalWalletAddresses=e?JSON.parse(e):void 0};this.createWalletPerMissingType=this.createWalletPerType;r||(r={}),this.emailPrimaryColor=r.emailPrimaryColor,this.emailTheme=r.emailTheme,this.homepageUrl=r.homepageUrl,this.supportUrl=r.supportUrl,this.xUrl=r.xUrl,this.githubUrl=r.githubUrl,this.linkedinUrl=r.linkedinUrl,this.portalBackgroundColor=r.portalBackgroundColor,this.portalPrimaryButtonColor=r.portalPrimaryButtonColor,this.portalTextColor=r.portalTextColor,this.portalPrimaryButtonTextColor=r.portalPrimaryButtonTextColor,this.portalTheme=r.portalTheme,this.platformUtils=this.getPlatformUtils(),this.disableProviderModal=this.platformUtils.disableProviderModal,r.useStorageOverrides&&(this.localStorageGetItem=r.localStorageGetItemOverride,this.localStorageSetItem=r.localStorageSetItemOverride,this.sessionStorageGetItem=r.sessionStorageGetItemOverride,this.sessionStorageSetItem=r.sessionStorageSetItemOverride,this.sessionStorageRemoveItem=r.sessionStorageRemoveItemOverride,this.clearStorage=r.clearStorageOverride),r.useSessionStorage&&(this.localStorageGetItem=this.sessionStorageGetItem,this.localStorageSetItem=this.sessionStorageSetItem),this.persistSessionCookie=s=>{this.sessionCookie=s,(r.useSessionStorage?this.sessionStorageSetItem:this.localStorageSetItem)(R,s)},this.ctx={env:e,apiKey:t,client:de({env:e,version:i.version,apiKey:t,partnerId:this.isPortal(e)?r.portalPartnerId:void 0,useFetchAdapter:!!r.disableWorkers,retrieveSessionCookie:this.retrieveSessionCookie,persistSessionCookie:this.persistSessionCookie}),disableWorkers:r.disableWorkers,offloadMPCComputationURL:r.offloadMPCComputationURL,useLocalFiles:r.useLocalFiles,useDKLS:r.useDKLSForCreation||!r.offloadMPCComputationURL,disableWebSockets:!!r.disableWebSockets,wasmOverride:r.wasmOverride,cosmosPrefix:this.cosmosPrefix},r.offloadMPCComputationURL&&(this.ctx.mpcComputationClient=ue(r.offloadMPCComputationURL,r.disableWorkers));try{this.#e=r.supportedWalletTypes?(()=>{if(Object.values(r.supportedWalletTypes).every(s=>!!s&&typeof s=="object"&&s.optional))throw new Error("at least one wallet type must be non-optional");if(!Object.keys(r.supportedWalletTypes).every(s=>Object.values(f).includes(s)))throw new Error("unsupported wallet type");return this.#t=r.supportedWalletTypes,Object.entries(r.supportedWalletTypes).reduce((s,[n,a])=>a?(n===f.COSMOS&&typeof a=="object"&&a.prefix&&(this.cosmosPrefix=a.prefix),[...s,{type:n,optional:a===!0?!1:a.optional??!1}]):s,[])})():void 0}catch{this.#e=void 0}!this.platformUtils.isSyncStorage||r.useStorageOverrides||(this.initializeFromStorage(),me.bind(this)())}static{this.version=He}get isEmail(){return!!this.email&&!this.phone&&!this.countryCode&&!this.farcasterUsername&&!this.telegramUserId}get isPhone(){return!!this.phone&&!!this.countryCode&&!this.email&&!this.farcasterUsername&&!this.telegramUserId}get isFarcaster(){return!!this.farcasterUsername&&!this.email&&!this.phone&&!this.countryCode&&!this.telegramUserId}get isTelegram(){return!!this.telegramUserId&&!this.email&&!this.phone&&!this.countryCode&&!this.farcasterUsername}get currentWalletIdsArray(){return this.supportedWalletTypes.reduce((e,{type:t})=>[...e,...(this.currentWalletIds[t]??[]).map(r=>[r,t])],[])}get currentWalletIdsUnique(){return[...new Set(Object.values(this.currentWalletIds).flat())]}get pregenIds(){return{...Object.values(this.wallets).filter(e=>!this.userId||this.isPregenWalletClaimable(e)).reduce((e,t)=>(e[t.pregenIdentifierType]??[]).includes(t.pregenIdentifier)?e:{...e,[t.pregenIdentifierType]:[...new Set([...e[t.pregenIdentifierType]??[],t.pregenIdentifier])]},{})}}get isMultiWallet(){return this.currentWalletIdsArray.length>1}#e;#t;get supportedWalletTypes(){return this.#e??[]}get isWalletTypeEnabled(){return this.supportedWalletTypes.reduce((e,{type:t})=>({...e,[t]:!0}),{})}convertBigInt(e){let t=new Ft.BigInteger(null);return t.data=e.data,t.s=e.s,t.t=e.t,t}convertEncryptionKeyPair(e){return{privateKey:ze.setRsaPrivateKey(this.convertBigInt(e.privateKey.n),this.convertBigInt(e.privateKey.e),this.convertBigInt(e.privateKey.d),this.convertBigInt(e.privateKey.p),this.convertBigInt(e.privateKey.q),this.convertBigInt(e.privateKey.dP),this.convertBigInt(e.privateKey.dQ),this.convertBigInt(e.privateKey.qInv)),publicKey:ze.setRsaPublicKey(this.convertBigInt(e.publicKey.n),this.convertBigInt(e.publicKey.e))}}isPortal(e){return typeof window>"u"?!1:!!window.location?.host&&T(e?{env:e}:this.ctx).includes(window.location.host)}isParaConnect(){return typeof window>"u"?!1:!!window.location?.host&&We(this.ctx).includes(window.location.host)}requireApiKey(){if(!this.ctx.apiKey)throw new Error(`in order to create a wallet or user with Para, you
2
- must provide an API key to the Para instance`)}isWalletSupported(e){return!this.#e||ae(this.supportedWalletTypes.map(({type:t})=>t)??[],e)}isWalletOwned(e){return this.isWalletSupported(e)&&!e.pregenIdentifier&&!e.pregenIdentifierType&&!!this.userId&&e.userId===this.userId}isPregenWalletUnclaimed(e){return this.isWalletSupported(e)&&(!e.userId||e.isPregen&&!!e.pregenIdentifier&&!!e.pregenIdentifierType)}isPregenWalletClaimable(e){return this.isWalletSupported(e)&&this.isPregenWalletUnclaimed(e)&&(!["EMAIL","PHONE","TELEGRAM"].includes(e.pregenIdentifierType)||Ce(e.pregenIdentifierType==="EMAIL"?this.email:e.pregenIdentifierType==="TELEGRAM"?this.telegramUserId:this.getPhoneNumber(),e.pregenIdentifier,e.pregenIdentifierType))}isWalletUsable(e,{type:t,scheme:r,forbidPregen:s=!1}={},n=!1){let a;if(!this.wallets[e])a=`wallet with id ${e} does not exist`;else{let o=this.wallets[e],[l,c]=[this.isPregenWalletUnclaimed(o),this.isWalletOwned(o)];s&&l?a=`pre-generated wallet with id ${o.id} cannot be selected`:!c&&!l?a=`wallet with id ${o.id} is not owned by the current user`:this.isWalletSupported(o)?t&&(!le(t).includes(o.type)||c&&!t.some(p=>this.currentWalletIds?.[p]?.includes(e)))?a=`wallet with id ${o.id} and type ${o.type} cannot be selected`:r&&!r.includes(o.scheme)&&(a=`wallet with id ${o.id} and scheme ${o.scheme} cannot be selected`):a=`wallet with id ${o.id} and type ${o.type} is not supported, supported types are: ${this.supportedWalletTypes.map(({type:p})=>p).join(", ")}`}if(a){if(n)throw new Error(a);return!1}return!0}getDisplayAddress(e,t={}){if(this.externalWallets[e]){let n=this.externalWallets[e];return t.truncate?se(n.address,n.type,{prefix:this.cosmosPrefix}):n.address}let r=this.findWallet(e,t.addressType);if(!r)return;let s;switch(r.type){case f.COSMOS:s=Ee(r.publicKey,this.cosmosPrefix??"cosmos");break;default:s=r.address;break}return t.truncate?se(s,r.type,{prefix:this.cosmosPrefix}):s}getIdenticonHash(e,t){if(this.externalWallets[e]){let s=this.externalWallets[e];return`${s.id}-${s.address}-${s.type}`}let r=this.findWallet(e,t);return r?`${r.id}-${r.address}-${r.type}`:void 0}getWallets(){return this.wallets}getAddress(e){return e?this.wallets[e].address:Object.values(this.wallets)?.[0]?.address}async constructPortalUrl(e,t={}){let r=e==="onRamp"?T(this.ctx):await this.getPortalURL(t.partnerId),s;switch(e){case"createPassword":{s=`/web/users/${this.userId}/passwords/${t.pathId}`;break}case"createAuth":{s=`/web/users/${this.userId}/biometrics/${t.pathId}`;break}case"loginPassword":{s="/web/passwords/login";break}case"loginAuth":{s="/web/biometrics/login";break}case"txReview":{s=`/web/users/${this.userId}/transaction-review/${t.pathId}`;break}case"onRamp":{s=`/web/users/${this.userId}/on-ramp-transaction/${t.pathId}`;break}default:throw new Error(`invalid URL type ${e}`)}let[n,a,o]=[["createAuth","createPassword"].includes(e),["loginAuth","loginPassword"].includes(e),e==="onRamp"],l=t.partnerId?(await this.ctx.client.getPartner(t.partnerId)).data?.partner:void 0,c={apiKey:this.ctx.apiKey,partnerId:t.partnerId,portalFont:t.theme?.font||l?.font||this.portalTheme?.font,portalBorderRadius:t.theme?.borderRadius||this.portalTheme?.borderRadius,portalThemeMode:t.theme?.mode||l?.themeMode||this.portalTheme?.mode,portalAccentColor:t.theme?.accentColor||l?.accentColor||this.portalTheme?.accentColor,portalForegroundColor:t.theme?.foregroundColor||l?.foregroundColor||this.portalTheme?.foregroundColor,portalBackgroundColor:t.theme?.backgroundColor||l?.backgroundColor||this.portalBackgroundColor||this.portalTheme?.backgroundColor,portalPrimaryButtonColor:this.portalPrimaryButtonColor,portalTextColor:this.portalTextColor,portalPrimaryButtonTextColor:this.portalPrimaryButtonTextColor,isForNewDevice:t.isForNewDevice?t.isForNewDevice.toString():void 0,supportedWalletTypes:this.#t?JSON.stringify(this.#t):void 0,...n||a?{...t.authType==="email"?{email:this.email}:{},...t.authType==="phone"?{phone:this.phone,countryCode:this.countryCode}:{},...t.authType==="farcaster"?{farcasterUsername:this.farcasterUsername}:{},...t.authType==="telegram"?{telegramUserId:this.telegramUserId}:{}}:{},...a||o?{sessionId:t.sessionId}:{},...a?{encryptionKey:t.loginEncryptionPublicKey,newDeviceSessionLookupId:t.newDeviceSessionId,newDeviceEncryptionKey:t.newDeviceEncryptionKey,pregenIds:JSON.stringify(this.pregenIds),displayName:t.displayName,pfpUrl:t.pfpUrl}:{},...t.params||{}};return Q({base:r,path:s,params:c})}async touchSession(e=!1){let t=await this.ctx.client.touchSession(e);return this.setSupportedWalletTypes(t.data.supportedWalletTypes,t.data.cosmosPrefix),t}setSupportedWalletTypes(e,t){e&&!this.#e&&(this.#e=e,Object.keys(this.currentWalletIds).forEach(r=>{this.#e?.some(({type:s})=>s===r)||delete this.currentWalletIds[r]})),t&&!this.cosmosPrefix&&(this.cosmosPrefix=t)}getVerificationEmailProps(){return{brandColor:this.emailPrimaryColor,theme:this.emailTheme,supportUrl:this.supportUrl,homepageUrl:this.homepageUrl,xUrl:this.xUrl,githubUrl:this.githubUrl,linkedinUrl:this.linkedinUrl}}getBackupKitEmailProps(){return{brandColor:this.emailPrimaryColor,theme:this.emailTheme,homepageUrl:this.homepageUrl,xUrl:this.xUrl,linkedinUrl:this.linkedinUrl,githubUrl:this.githubUrl,supportUrl:this.supportUrl}}async init(){this.email=await this.localStorageGetItem(G)||void 0,this.countryCode=await this.localStorageGetItem(F)||void 0,this.phone=await this.localStorageGetItem(B)||void 0,this.userId=await this.localStorageGetItem(V)||void 0,this.telegramUserId=await this.localStorageGetItem(M)||void 0;let e=this.platformUtils.secureStorage?await this.platformUtils.secureStorage.get(W):await this.localStorageGetItem(W),t=JSON.parse(e||"{}"),r=this.platformUtils.secureStorage?await this.platformUtils.secureStorage.get(O):await this.localStorageGetItem(O),s=JSON.parse(r||"{}"),n={...Object.keys(t).reduce((h,g)=>({...h,[g]:U(t[g])}),{}),...Object.keys(s).reduce((h,g)=>({...h,...h[g]?{}:{[g]:U(s[g])}}),{})};await this.setWallets(n);let a=await this.localStorageGetItem(x)??void 0,o=[void 0,null,"undefined","null"].includes(a)?{}:(()=>{let h=JSON.parse(a);return Array.isArray(h)?Object.keys(f).reduce((g,A)=>{let b=Object.values(this.wallets).find(Se=>h.includes(Se.id)&&w[Se.scheme][A]);return{...g,...b&&!g[A]?{[A]:[b.id]}:{}}},{}):h})();await this.setCurrentWalletIds(o),this.sessionCookie=await this.localStorageGetItem(R)||await this.sessionStorageGetItem(R)||void 0,Object.values(this.wallets).filter(h=>this.isWalletOwned(h)).length>0&&this.currentWalletIdsArray.length===0&&this.findWalletId(void 0,{forbidPregen:!0});let l=await this.sessionStorageGetItem(L);l&&l!=="undefined"&&(this.loginEncryptionKeyPair=this.convertEncryptionKeyPair(JSON.parse(l)));let c=await this.localStorageGetItem($),p=JSON.parse(c||"{}");await this.setExternalWallets(p);let S=await this.localStorageGetItem(H)||void 0;this.currentExternalWalletAddresses=S?JSON.parse(S):void 0,me.bind(this)(),await this.touchSession()}async setEmail(e){this.email=e,await this.localStorageSetItem(G,e)}async setTelegramUserId(e){this.telegramUserId=e,await this.localStorageSetItem(M,e)}async setPhoneNumber(e,t){this.phone=e,this.countryCode=t,await this.localStorageSetItem(B,e),await this.localStorageSetItem(F,t)}async setFarcasterUsername(e){this.farcasterUsername=e,await this.localStorageSetItem(je,e)}async setExternalWallet({address:e,type:t,provider:r,addressBech32:s}){this.externalWallets={[e]:{id:e,address:s??e,type:t,name:r,isExternal:!0,signer:""}},this.currentExternalWalletAddresses=[e],this.setCurrentExternalWalletAddresses(this.currentExternalWalletAddresses),this.setExternalWallets(this.externalWallets),u(d.EXTERNAL_WALLET_CHANGE_EVENT,null)}async setUserId(e){this.userId=e,await this.localStorageSetItem(V,e)}async setWallets(e){if(this.wallets=e,this.platformUtils.secureStorage){await this.platformUtils.secureStorage.set(W,JSON.stringify(e));return}await this.localStorageSetItem(W,JSON.stringify(e))}async setExternalWallets(e){this.externalWallets=e,await this.localStorageSetItem($,JSON.stringify(e))}async setCurrentExternalWalletAddresses(e){this.currentExternalWalletAddresses=e,await this.localStorageSetItem(H,JSON.stringify(e))}async setLoginEncryptionKeyPair(e){e||(e=await J(this.ctx)),this.loginEncryptionKeyPair=e,await this.sessionStorageSetItem(L,JSON.stringify(e))}async deleteLoginEncryptionKeyPair(){this.loginEncryptionKeyPair=void 0,await this.sessionStorageRemoveItem(L)}getUserId(){return this.userId}getEmail(){return this.email}getPhone(){return{phone:this.phone,countryCode:this.countryCode}}getPhoneNumber(){if(!(!this.phone||!this.countryCode))return we(this.countryCode,this.phone)}getFarcasterUsername(){return this.farcasterUsername}async setCurrentWalletIds(e,{needsWallet:t=!1,sessionLookupId:r,newDeviceSessionLookupId:s}={}){this.currentWalletIds=e,await this.localStorageSetItem(x,JSON.stringify(this.currentWalletIds)),r&&await this.ctx.client.setCurrentWalletIds(this.getUserId(),this.currentWalletIds,t,r,s),u(d.WALLETS_CHANGE_EVENT,null)}findWalletId(e,t={}){if(e)this.assertIsValidWalletId(e,t);else{for(let r of[...this.currentWalletIdsUnique,...Object.keys(this.wallets)])if(this.isWalletUsable(r,t)){e=r;break}if(!e)throw new Error("no valid wallet id found")}return e}findWalletByAddress(e,t){if(this.externalWallets[e])return this.externalWallets[e];let r;if(Object.entries(this.currentWalletIds).forEach(([s,n])=>{let a=Object.keys(this.wallets).filter(o=>this.wallets[o].type===s&&this.isPregenWalletClaimable(this.wallets[o]));[...n,...a].forEach(o=>{e.toLowerCase()===this.getDisplayAddress(o,{addressType:s}).toLowerCase()&&(r=this.wallets[o])})}),!r)throw new Error(`wallet with address ${e} not found`);return this.assertIsValidWalletId(r.id,t),r}findWallet(e,t,r={}){if(!e&&Object.keys(this.externalWallets).length>0)return Object.values(this.externalWallets)[0];if(this.externalWallets[e])return this.externalWallets[e];try{let s=this.findWalletId(e,r);if(s&&this.wallets[s]){let{signer:n,...a}=this.wallets[s],o=t??this.currentWalletIdsArray.find(([l])=>l===s)?.[1]??a.type;return{...a,type:f[o]}}}catch{return}}get availableWallets(){return[...this.currentWalletIdsArray.map(([e,t])=>[e,t,!1]).map(([e,t])=>{let r=this.findWallet(e,t);return r?{id:r.id,type:t,address:this.getDisplayAddress(e,{addressType:t}),name:r.name}:null}).filter(e=>e!==null),...Object.values(this.externalWallets??{})]}getWalletsByType(e){return Object.values(this.wallets).filter(t=>this.isWalletUsable(t.id,{type:[e]}))}assertIsValidWalletId(e,t={}){this.isWalletUsable(e,t,!0)}async assertIsValidWalletType(e,t){if(this.#e||await this.touchSession(),!e||!Object.values(f).includes(e)||!(t??this.supportedWalletTypes.map(({type:r})=>r)).includes(e))throw new Error(`wallet type ${e} is not supported`);return e}async getMissingTypes(){return this.#e||await this.touchSession(),this.supportedWalletTypes.filter(({type:e,optional:t})=>!t&&Object.values(this.wallets).every(r=>!this.isWalletOwned(r)||!w[r.scheme][e])).map(({type:e})=>e)}async getTypesToCreate(e){return this.#e||await this.touchSession(),oe(e??await this.getMissingTypes()).map(t=>{switch(t){case E.ED25519:return f.SOLANA;default:return this.supportedWalletTypes.some(({type:r,optional:s})=>r===f.COSMOS&&!s)?f.COSMOS:f.EVM}})}async getPartnerURL(e){return(await this.ctx.client.getPartner(e)).data.partner.portalUrl}async getPortalURL(e){return e&&await this.getPartnerURL(e)||T(this.ctx)}async getWebAuthURLForCreate({webAuthId:e,...t}){return this.constructPortalUrl("createAuth",{...t,pathId:e})}async getPasswordURLForCreate({passwordId:e,...t}){return this.constructPortalUrl("createPassword",{...t,pathId:e})}getShortUrl(e){return Q({base:T(this.ctx),path:`/short/${e}`})}async shortenLoginLink(e){let t=await $e(e,this.ctx.client);return this.getShortUrl(t)}async getWebAuthURLForLogin(e){return this.constructPortalUrl("loginAuth",e)}async getPasswordURLForLogin(e){return this.constructPortalUrl("loginPassword",e)}async getWebAuthURLForLoginForPhone(e){return this.constructPortalUrl("loginAuth",{authType:"phone",...e})}async getPrivateKey(e){let t=Object.values(this.wallets),r=e?this.wallets[e]:t?.[0];if(!r)throw new Error("wallet not found");if(r.scheme!==E.DKLS)throw new Error("invalid wallet scheme");return await this.platformUtils.getPrivateKey(this.ctx,this.userId,r.id,r.signer,this.retrieveSessionCookie())}async fetchWallets(){return(await(this.isPortal()||this.isParaConnect()?this.ctx.client.getAllWallets(this.userId):this.ctx.client.getWallets(this.userId,!0))).data.wallets.filter(t=>!!t.address&&(this.isParaConnect()||!this.isParaConnect()&&this.isWalletSupported(_(t))))}async populateWalletAddresses(){(await this.ctx.client.getWallets(this.userId,!0)).data.wallets.forEach(r=>{this.wallets[r.id]&&(this.wallets[r.id]={..._(r),...this.wallets[r.id]})}),await this.setWallets(this.wallets)}async populatePregenWalletAddresses(){(await this.getPregenWallets()).forEach(t=>{this.wallets[t.id]&&(this.wallets[t.id]={..._(t),...this.wallets[t.id]})}),await this.setWallets(this.wallets)}async checkIfUserExists({email:e}){return(await this.ctx.client.checkUserExists({email:e})).data.exists}async checkIfUserExistsByPhone({phone:e,countryCode:t}){return(await this.ctx.client.checkUserExists({phone:e,countryCode:t})).data.exists}async createUser({email:e}){this.requireApiKey(),await this.setEmail(e);let{userId:t}=await this.ctx.client.createUser({email:this.email,...this.getVerificationEmailProps()});await this.setUserId(t)}async createUserByPhone({phone:e,countryCode:t}){this.requireApiKey(),await this.setPhoneNumber(e,t);let{userId:r}=await this.ctx.client.createUser({phone:this.phone,countryCode:this.countryCode});await this.setUserId(r)}async externalWalletLogin(e){this.requireApiKey();let t=await this.ctx.client.externalWalletLogin({externalAddress:e.address,type:e.type,externalWalletProvider:e.provider,shouldTrackUser:e.shouldTrackUser});return await this.setExternalWallet(e),await this.setUserId(t.userId),t}isUsingExternalWallet(){return!!Object.keys(this.externalWallets).length}async verifyEmail({verificationCode:e}){return await this.ctx.client.verifyEmail(this.userId,{verificationCode:e}),this.getSetUpBiometricsURL()}async verifyExternalWallet({address:e,signedMessage:t,cosmosPublicKeyHex:r,cosmosSigner:s}){return await this.ctx.client.verifyExternalWallet(this.userId,{address:e,signedMessage:t,cosmosPublicKeyHex:r,cosmosSigner:s}),this.getSetUpBiometricsURL()}async verifyPhone({verificationCode:e}){return await this.ctx.client.verifyPhone(this.userId,{verificationCode:e}),this.getSetUpBiometricsURLForPhone()}async verifyTelegram(e){let t=await this.ctx.client.verifyTelegram(e);return t.isValid&&(await this.setUserId(t.userId),await this.setTelegramUserId(t.telegramUserId),await this.touchSession(!0),this.loginEncryptionKeyPair||await this.setLoginEncryptionKeyPair()),t}async verify2FA({email:e,verificationCode:t}){let r=await this.ctx.client.verify2FA(e,t);return{initiatedAt:r.data.initiatedAt,status:r.data.status,userId:r.data.userId,wallets:r.data.wallets}}async verify2FAForPhone({phone:e,countryCode:t,verificationCode:r}){let s=await this.ctx.client.verify2FAForPhone(e,t,r);return{initiatedAt:s.data.initiatedAt,status:s.data.status,userId:s.data.userId,wallets:s.data.wallets}}async setup2FA(){return{uri:(await this.ctx.client.setup2FA(this.userId)).data.uri}}async enable2FA({verificationCode:e}){await this.ctx.client.enable2FA(this.userId,e)}async check2FAStatus(){return this.userId?{isSetup:(await this.ctx.client.check2FAStatus(this.userId)).data.isSetup}:{isSetup:!1}}async resendVerificationCode(){await this.ctx.client.resendVerificationCode({userId:this.userId,...this.getVerificationEmailProps()})}async resendVerificationCodeByPhone(){await this.ctx.client.resendVerificationCodeByPhone({userId:this.userId})}async getSetUpBiometricsURL({authType:e="email",isForNewDevice:t=!1}={}){let r=await this.ctx.client.addSessionPublicKey(this.userId,{status:Xe.PENDING,type:qe.WEB});return this.getWebAuthURLForCreate({authType:e,isForNewDevice:t,webAuthId:r.data.id,partnerId:r.data.partnerId})}async getSetUpBiometricsURLForPhone({isForNewDevice:e=!1}={}){let t=await this.ctx.client.addSessionPublicKey(this.userId,{status:Xe.PENDING,type:qe.WEB});return this.getWebAuthURLForCreate({authType:"phone",isForNewDevice:e,webAuthId:t.data.id,partnerId:t.data.partnerId})}async getSetupPasswordURL({authType:e="email",isForNewDevice:t=!1,theme:r}={}){let s=await this.ctx.client.addSessionPasswordPublicKey(this.userId,{status:Dt.PENDING});return this.getPasswordURLForCreate({authType:e,isForNewDevice:t,passwordId:s.data.id,partnerId:s.data.partnerId,theme:r})}async isSessionActive(){return this.isUsingExternalWallet()?!0:!!(await this.touchSession()).data.isAuthenticated}async isFullyLoggedIn(){return this.isUsingExternalWallet()?!0:await this.isSessionActive()&&this.currentWalletIdsArray.length>0&&this.currentWalletIdsArray.reduce((t,[r])=>t&&!!this.wallets[r],!0)}async supportedAuthMethods(e){let{supportedAuthMethods:t}=await this.ctx.client.getSupportedAuthMethods(e),r=new Set;for(let s of t)switch(s){case"PASSWORD":r.add(fe.PASSWORD);break;case"BIOMETRIC":r.add(fe.PASSKEY);break}return r}async getUserBiometricLocationHints(){if(!this.email&&!this.phone&&!this.farcasterUsername&&!this.telegramUserId)throw new Error("one of email, phone or farcaster username are required to get biometric location hints");return await this.ctx.client.getBiometricLocationHints({email:this.email,phone:this.phone,countryCode:this.countryCode,farcasterUsername:this.farcasterUsername,telegramUserId:this.telegramUserId})}async setAuth(e){let t=Gt(e);if(t){switch(t.authType){case"email":await this.setEmail(t.identifier);break;case"phone":await this.setPhoneNumber(t.auth.phone,t.auth.countryCode);break;case"farcaster":await this.setFarcasterUsername(t.identifier);break;case"telegram":await this.setTelegramUserId(t.identifier);break}return t}}async initiateUserLogin({useShortUrl:e=!1,...t}){let r=await this.setAuth(t);if(!r)return;let s=await this.touchSession(!0);this.loginEncryptionKeyPair||await this.setLoginEncryptionKeyPair();let n=await this.getWebAuthURLForLogin({authType:r.authType,sessionId:s.data.sessionId,partnerId:s.data.partnerId,loginEncryptionPublicKey:N(this.loginEncryptionKeyPair)});return e?this.shortenLoginLink(n):n}async initiateUserLoginV2(e){let t=await this.setAuth(e);if(t)return await this.touchSession(!0),this.loginEncryptionKeyPair||await this.setLoginEncryptionKeyPair(),await this.supportedAuthMethods(t.auth)}async initiateUserLoginForPhone({useShortUrl:e=!1,...t}){await this.setAuth(t);let r=await this.touchSession(!0);this.loginEncryptionKeyPair||await this.setLoginEncryptionKeyPair();let s=await this.getWebAuthURLForLoginForPhone({sessionId:r.data.sessionId,loginEncryptionPublicKey:N(this.loginEncryptionKeyPair),partnerId:r.data.partnerId});return e?this.shortenLoginLink(s):s}async waitForAccountCreation({popupWindow:e}={}){for(await this.touchSession(),this.currentExternalWalletAddresses=void 0,this.externalWallets={},this.isAwaitingAccountCreation=!0;this.isAwaitingAccountCreation;)try{if(await new Promise(t=>setTimeout(t,C)),await this.isSessionActive())return this.isAwaitingAccountCreation=!1,u(d.ACCOUNT_CREATION_EVENT,!0),!0;if(e?.closed)return this.isAwaitingAccountCreation=!1,!1}catch(t){console.error(t)}return!1}async waitForPasskeyAndCreateWallet({popupWindow:e}={}){await this.waitForAccountCreation({popupWindow:e});let t=await this.getPregenWallets(),r,s={};t.length>0&&(r=await this.claimPregenWallets(),s=this.supportedWalletTypes.reduce((o,{type:l})=>({...o,[l]:[t.find(c=>!!w[c.scheme][l])?.id]}),{}));let n=await this.createWalletPerType();r=r??n.recoverySecret,s={...s,...n.walletIds};let a={walletIds:s,recoverySecret:r};return u(d.ACCOUNT_SETUP_EVENT,a),a}async getFarcasterConnectURL(){await this.logout(),await this.touchSession(!0);let{data:{connect_uri:e}}=await this.ctx.client.initializeFarcasterLogin();return e}async waitForFarcasterStatus(){for(this.isAwaitingFarcaster=!0;this.isAwaitingFarcaster;)try{await new Promise(t=>setTimeout(t,C));let e=await this.ctx.client.getFarcasterAuthStatus();if(e.data.state==="completed"){let{userId:t,userExists:r,username:s,pfpUrl:n}=e.data;return await this.setUserId(t),await this.setFarcasterUsername(s),{userExists:r,username:s,pfpUrl:n}}}catch(e){console.error(e),this.isAwaitingFarcaster=!1}}async getOAuthURL({method:e,deeplinkUrl:t}){await this.logout();let r=await this.touchSession(!0);return Q({base:e===kt.TELEGRAM?T(this.ctx,!0):Ue(this.ctx.env),path:`/auth/${e.toLowerCase()}`,params:{apiKey:this.ctx.apiKey,sessionLookupId:r.data.sessionLookupId,deeplinkUrl:t}})}async waitForOAuth({popupWindow:e}={}){for(this.isAwaitingOAuth=!0;this.isAwaitingOAuth;)try{if(e?.closed)return{isError:!0,userExists:!1};if(await new Promise(t=>setTimeout(t,C)),this.isAwaitingOAuth){let t=await this.touchSession();if(t.data.userId){let{userId:r,email:s}=t.data;this.loginEncryptionKeyPair||await this.setLoginEncryptionKeyPair(),await this.setUserId(r),await this.setEmail(s);let n=await this.checkIfUserExists({email:s});return this.isAwaitingOAuth=!1,{userExists:n,email:s}}}}catch(t){console.error(t)}return{userExists:!1}}async waitForLoginAndSetup({popupWindow:e,skipSessionRefresh:t=!1}={}){for(this.currentExternalWalletAddresses=void 0,this.externalWallets={},this.isAwaitingLogin=!0;this.isAwaitingLogin;)try{if(await new Promise(l=>setTimeout(l,C)),!await this.isSessionActive()){if(e?.closed){let l={isComplete:!1,isError:!0};return u(d.LOGIN_EVENT,l,"failed to setup user"),l}continue}let s=await this.userSetupAfterLogin(),n=s.data.needsWallet??!1;if(!n&&this.currentWalletIdsArray.length===0)if(e?.closed){let l={isComplete:!1,isError:!0};return u(d.LOGIN_EVENT,l,"failed to setup user"),l}else continue;let a=await this.fetchWallets(),o=await this.getTransmissionKeyShares();if(o.data.temporaryShares.length===a.length){await this.setupAfterLogin({temporaryShares:o.data.temporaryShares,skipSessionRefresh:t}),await this.claimPregenWallets();let l={isComplete:!0,needsWallet:n||Object.values(this.wallets).length===0,partnerId:s.data.partnerId};return u(d.LOGIN_EVENT,l),l}}catch(s){console.error(s)}let r={isComplete:!1};return u(d.LOGIN_EVENT,r,"exitted login without setting up user"),r}async refreshSession({shouldOpenPopup:e=!1}={}){let t=await this.touchSession(!0);this.loginEncryptionKeyPair||await this.setLoginEncryptionKeyPair();let r=await this.getWebAuthURLForLogin({sessionId:t.data.sessionId,loginEncryptionPublicKey:N(this.loginEncryptionKeyPair)});return e&&this.platformUtils.openPopup(r),r}async userSetupAfterLogin(){let e=await this.touchSession();return await this.setUserId(e.data.userId),e.data.currentWalletIds&&e.data.currentWalletIds!==this.currentWalletIds&&await this.setCurrentWalletIds(e.data.currentWalletIds,{sessionLookupId:this.isPortal()?e.data.sessionLookupId:void 0}),e}async getTransmissionKeyShares({isForNewDevice:e=!1}={}){let t=await this.touchSession(),r=e?`${t.data.sessionLookupId}-new-device`:t.data.sessionLookupId;return this.ctx.client.getTransmissionKeyshares(this.userId,r)}async setupAfterLogin({temporaryShares:e,skipSessionRefresh:t=!1}={}){e||(e=(await this.getTransmissionKeyShares()).data.temporaryShares),e.forEach(r=>{let s=Y(this.loginEncryptionKeyPair.privateKey,r.encryptedShare,r.encryptedKey);this.wallets[r.walletId]={id:r.walletId,signer:s}}),await this.deleteLoginEncryptionKeyPair(),await this.populateWalletAddresses(),await this.touchSession(!t)}async distributeNewWalletShare({walletId:e,userShare:t,skipBiometricShareCreation:r=!1,forceRefresh:s=!1}){let n=t;return n||(n=this.wallets[e].signer),r?await te({ctx:this.ctx,userId:this.userId,walletId:e,userSigner:n,emailProps:this.getBackupKitEmailProps(),forceRefresh:s}):await K({ctx:this.ctx,userId:this.userId,walletId:e,userShare:n,emailProps:this.getBackupKitEmailProps()})}async waitForWalletAddress(e){let t=0;for(;;)try{if(t===10)break;++t;let s=(await this.ctx.client.getWallets(this.userId)).data.wallets.find(n=>n.id===e);if(s&&s.address)return;await new Promise(n=>setTimeout(n,ge))}catch(r){console.error(r)}throw new Error("timed out waiting for wallet address")}async waitForPregenWalletAddress(e){let t=0;for(;;)try{if(t===10)break;++t;let s=(await this.getPregenWallets()).find(n=>n.id===e);if(s&&s.address)return;await new Promise(n=>setTimeout(n,ge))}catch(r){console.error(r)}throw new Error("timed out waiting for wallet address")}async createWalletPerType({skipDistribute:e=!1,types:t}={}){let r=[],s={},n;for(let a of await this.getTypesToCreate(t)){let[o,l]=await this.createWallet({type:a,skipDistribute:e});r.push(o),le(a).filter(c=>!!this.isWalletTypeEnabled[c]).forEach(c=>{s[c]=[o.id]}),l&&(n=l)}return{wallets:r,walletIds:s,recoverySecret:n}}async refreshShare({walletId:e,share:t,oldPartnerId:r,newPartnerId:s,keyShareProtocolId:n,redistributeBackupEncryptedShares:a}){let{signer:o,protocolId:l}=await this.platformUtils.refresh(this.ctx,this.retrieveSessionCookie(),this.userId,e,t,r,s,n),c=await K({ctx:this.ctx,userId:this.userId,walletId:e,userShare:o,ignoreRedistributingBackupEncryptedShare:!a,emailProps:this.getBackupKitEmailProps(),partnerId:s,protocolId:l});return{signer:o,recoverySecret:c,protocolId:l}}async createWallet({type:e,skipDistribute:t=!1}={}){this.requireApiKey();let r=await this.assertIsValidWalletType(e??this.supportedWalletTypes.find(({optional:p})=>!p)?.type),s,n,a;switch(r){case f.SOLANA:{a=await this.platformUtils.ed25519Keygen(this.ctx,this.userId,this.retrieveSessionCookie(),this.getBackupKitEmailProps());break}default:{a=await this.platformUtils.keygen(this.ctx,this.userId,r,null,this.retrieveSessionCookie(),this.getBackupKitEmailProps());break}}let o=a.walletId;s=a.signer,this.wallets[o]={id:o,signer:s,scheme:r===f.SOLANA?E.ED25519:E.DKLS,type:r},n=this.wallets[o],await this.waitForWalletAddress(n.id),await this.populateWalletAddresses();let l=null;t||(l=await K({ctx:this.ctx,userId:this.userId,walletId:n.id,userShare:s,emailProps:this.getBackupKitEmailProps()})),await this.setCurrentWalletIds({...this.currentWalletIds,[r]:[...this.currentWalletIds[r]??[],o]});let c={...n};return delete c.signer,u(d.WALLET_CREATED,{wallet:c,recoverySecret:l}),[n,l]}async createPregenWallet(e){let{type:t=this.supportedWalletTypes.find(({optional:c})=>!c)?.type,pregenIdentifier:r,pregenIdentifierType:s="EMAIL"}=e;this.requireApiKey();let n=await this.assertIsValidWalletType(t??this.supportedWalletTypes.find(({optional:c})=>!c)?.type),a;switch(n){case f.SOLANA:a=await this.platformUtils.ed25519PreKeygen(this.ctx,r,s,this.retrieveSessionCookie());break;default:a=await this.platformUtils.preKeygen(this.ctx,void 0,r,s,n,null,this.retrieveSessionCookie());break}let{signer:o,walletId:l}=a;return this.wallets[l]={id:l,signer:o,scheme:n===f.SOLANA?E.ED25519:E.DKLS,type:n,isPregen:!0,pregenIdentifier:r,pregenIdentifierType:s},await this.waitForPregenWalletAddress(l),await this.populatePregenWalletAddresses(),this.wallets[l]}async createPregenWalletPerType({types:e,pregenIdentifier:t,pregenIdentifierType:r="EMAIL"}){let s=[];for(let n of await this.getTypesToCreate(e)){let a=await this.createPregenWallet({type:n,pregenIdentifier:t,pregenIdentifierType:r});s.push(a)}return s}async claimPregenWallets({pregenIdentifier:e,pregenIdentifierType:t=e?"EMAIL":void 0}={}){this.requireApiKey();let r=e&&t?await this.getPregenWallets({pregenIdentifier:e,pregenIdentifierType:t}):await this.getPregenWallets();if(r.length===0)return;let s,{walletIds:n}=await this.ctx.client.claimPregenWallets({userId:this.userId,walletIds:r.map(a=>a.id)});for(let a of n){let o=this.wallets[a],l;if(o.scheme===E.ED25519){let p=await K({ctx:this.ctx,userId:this.userId,walletId:o.id,userShare:this.wallets[o.id].signer,emailProps:this.getBackupKitEmailProps(),partnerId:o.partnerId});p.length>0&&(s=p)}else l=await this.refreshShare({walletId:o.id,share:this.wallets[o.id].signer,oldPartnerId:o.partnerId,newPartnerId:o.partnerId,redistributeBackupEncryptedShares:!0}),l.recoverySecret&&(s=l.recoverySecret);this.wallets[o.id]={...this.wallets[o.id],signer:l?.signer??o.signer,userId:this.userId,pregenIdentifier:void 0,pregenIdentifierType:void 0};let c={...this.wallets[o.id]};delete c.signer,u(d.PREGEN_WALLET_CLAIMED,{wallet:c,recoverySecret:s})}return await this.setWallets(this.wallets),s}async updatePregenWalletIdentifier({walletId:e,newPregenIdentifier:t,newPregenIdentifierType:r}){this.requireApiKey(),await this.ctx.client.updatePregenWallet(e,{pregenIdentifier:t,pregenIdentifierType:r}),this.wallets[e]&&(this.wallets[e]={...this.wallets[e],pregenIdentifier:t,pregenIdentifierType:r},await this.setWallets(this.wallets))}async hasPregenWallet({pregenIdentifier:e,pregenIdentifierType:t}){return this.requireApiKey(),!!(await this.getPregenWallets({pregenIdentifier:e,pregenIdentifierType:t})).find(n=>n.pregenIdentifier===e&&n.pregenIdentifierType===t)}async getPregenWallets({pregenIdentifier:e,pregenIdentifierType:t=e?"EMAIL":void 0}={}){return this.requireApiKey(),(await this.ctx.client.getPregenWallets(e&&t?{[t]:[e]}:this.pregenIds,this.isPortal(),this.userId)).wallets.filter(s=>this.isWalletSupported(_(s)))}encodeWalletBase64(e){let t=JSON.stringify(e);return Buffer.from(t).toString("base64")}getUserShare(){return Object.values(this.wallets).length===0?null:Object.values(this.wallets).map(e=>this.encodeWalletBase64(e)).join("-")}async setUserShare(e){if(!e)return;let t=e.split("-");for(let r of t){let s=Buffer.from(r,"base64").toString(),n=U(JSON.parse(s));this.wallets[n.id]=n,await this.setWallets(this.wallets)}}async getTransactionReviewUrl(e,t){let r=await this.touchSession();return this.constructPortalUrl("txReview",{partnerId:r.data.partnerId,pathId:e,params:{email:this.email,timeoutMs:t?.toString()}})}async getOnRampTransactionUrl({purchaseId:e,providerKey:t,...r}){let s=await this.touchSession(),[n,a]=Kt(r);return this.constructPortalUrl("onRamp",{partnerId:s.data.partnerId,pathId:e,sessionId:s.data.sessionId,params:{[n]:a,providerKey:t,currentWalletIds:JSON.stringify(this.currentWalletIds)}})}async signMessage({walletId:e,messageBase64:t,timeoutMs:r=3e4,cosmosSignDocBase64:s}){this.assertIsValidWalletId(e);let n=this.wallets[e],a=this.userId;n.partnerId&&!n.userId&&(a=n.partnerId);let o=await this.signMessageInner({wallet:n,signerId:a,messageBase64:t,cosmosSignDocBase64:s}),l=Date.now();if(o.pendingTransactionId)this.platformUtils.openPopup(await this.getTransactionReviewUrl(o.pendingTransactionId,r),{type:s?"SIGN_TRANSACTION_REVIEW":"SIGN_MESSAGE_REVIEW"});else return u(d.SIGN_MESSAGE_EVENT,o),o;for(await new Promise(c=>setTimeout(c,C));!(Date.now()-l>r);){try{await this.ctx.client.getPendingTransaction(this.userId,o.pendingTransactionId)}catch{let p=new X;throw u(d.SIGN_MESSAGE_EVENT,o,p.message),p}if(o=await this.signMessageInner({wallet:n,signerId:a,messageBase64:t,cosmosSignDocBase64:s}),o.pendingTransactionId)await new Promise(c=>setTimeout(c,C));else break}if(o.pendingTransactionId){let c=new q(await this.getTransactionReviewUrl(o.pendingTransactionId),o.pendingTransactionId);throw u(d.SIGN_MESSAGE_EVENT,o,c.message),c}return u(d.SIGN_MESSAGE_EVENT,o),o}async signMessageInner({wallet:e,signerId:t,messageBase64:r,cosmosSignDocBase64:s}){let n;switch(e.scheme){case E.ED25519:n=await this.platformUtils.ed25519Sign(this.ctx,t,e.id,e.signer,r,this.retrieveSessionCookie());break;default:n=await this.platformUtils.signMessage(this.ctx,t,e.id,e.signer,r,this.retrieveSessionCookie(),e.scheme===E.DKLS,s);break}return n}async signTransaction({walletId:e,rlpEncodedTxBase64:t,chainId:r,timeoutMs:s=3e4}){this.assertIsValidWalletId(e);let n=this.wallets[e],a=this.userId;n.partnerId&&!n.userId&&(a=n.partnerId);let o=await this.platformUtils.signTransaction(this.ctx,a,e,this.wallets[e].signer,t,r,this.retrieveSessionCookie(),n.scheme===E.DKLS),l=Date.now();if(o.pendingTransactionId)this.platformUtils.openPopup(await this.getTransactionReviewUrl(o.pendingTransactionId,s),{type:"SIGN_TRANSACTION_REVIEW"});else return u(d.SIGN_TRANSACTION_EVENT,o),o;for(await new Promise(c=>setTimeout(c,C));!(Date.now()-l>s);){try{await this.ctx.client.getPendingTransaction(this.userId,o.pendingTransactionId)}catch{let p=new X;throw u(d.SIGN_TRANSACTION_EVENT,o,p.message),p}if(o=await this.platformUtils.signTransaction(this.ctx,a,e,this.wallets[e].signer,t,r,this.retrieveSessionCookie(),n.scheme===E.DKLS),o.pendingTransactionId)await new Promise(c=>setTimeout(c,C));else break}if(o.pendingTransactionId){let c=new q(await this.getTransactionReviewUrl(o.pendingTransactionId),o.pendingTransactionId);throw u(d.SIGN_TRANSACTION_EVENT,o,c.message),c}return u(d.SIGN_TRANSACTION_EVENT,o),o}async sendTransaction({walletId:e,rlpEncodedTxBase64:t,chainId:r}){this.assertIsValidWalletId(e);let s=this.wallets[e],n=await this.platformUtils.sendTransaction(this.ctx,this.userId,e,this.wallets[e].signer,t,r,this.retrieveSessionCookie(),s.scheme===E.DKLS);if(n.pendingTransactionId)throw this.platformUtils.openPopup(await this.getTransactionReviewUrl(n.pendingTransactionId),{type:"SIGN_TRANSACTION_REVIEW"}),new re(await this.getTransactionReviewUrl(n.pendingTransactionId));return n}isProviderModalDisabled(){return!!this.disableProviderModal}async initiateOnRampTransaction(e){let{params:t,shouldOpenPopup:r,...s}=e,n=await this.ctx.client.createOnRampPurchase({userId:this.userId,params:{...t,address:s.externalWalletAddress??this.getDisplayAddress(s.walletId,{addressType:t.walletType})},...s}),a=await this.getOnRampTransactionUrl({purchaseId:n.id,providerKey:n.providerKey,...s});return r&&this.platformUtils.openPopup(a,{type:"ON_RAMP_TRANSACTION"}),{onRampPurchase:n,portalUrl:a}}async keepSessionAlive(){try{return await this.ctx.client.keepSessionAlive(this.userId),!0}catch{return!1}}exportSession(){let e={email:this.email,userId:this.userId,wallets:this.wallets,currentWalletIds:this.currentWalletIds,sessionCookie:this.sessionCookie,phone:this.phone,countryCode:this.countryCode,telegramUserId:this.telegramUserId,farcasterUsername:this.farcasterUsername,externalWallets:this.externalWallets};return Buffer.from(JSON.stringify(e)).toString("base64")}async importSession(e){let t=Buffer.from(e,"base64").toString("utf8"),r=JSON.parse(t);await this.setEmail(r.email),await this.setTelegramUserId(r.telegramUserId),await this.setFarcasterUsername(r.farcasterUsername),await this.setUserId(r.userId),await this.setWallets(r.wallets),await this.setExternalWallets(r.externalWallets||{});for(let s of Object.keys(this.wallets))this.wallets[s].userId||(this.wallets[s].userId=this.userId);if(Object.keys(r.currentWalletIds).length!==0)await this.setCurrentWalletIds(r.currentWalletIds);else{let s={};for(let n of Object.keys(r.wallets))s[r.wallets[n].type]=[...s[r.wallets[n].type]??[],n];await this.setCurrentWalletIds(s)}this.persistSessionCookie(r.sessionCookie),await this.setPhoneNumber(r.phone,r.countryCode)}exitAccountCreation(){this.isAwaitingAccountCreation=!1}exitLogin(){this.isAwaitingLogin=!1}exitFarcaster(){this.isAwaitingFarcaster=!1}exitOAuth(){this.isAwaitingOAuth=!1}exitLoops(){this.exitAccountCreation(),this.exitLogin(),this.exitFarcaster(),this.exitOAuth()}async getVerificationToken(){let{data:e}=await this.touchSession();return e.sessionLookupId}async logout({clearPregenWallets:e=!1}={}){await this.ctx.client.logout(),await this.clearStorage(),e?this.wallets={}:(Object.entries(this.wallets).forEach(([t,r])=>{r.pregenIdentifier||delete this.wallets[t]}),await this.setWallets(this.wallets)),this.currentWalletIds={},this.currentExternalWalletAddresses=void 0,this.externalWallets={},this.loginEncryptionKeyPair=void 0,this.email=void 0,this.telegramUserId=void 0,this.phone=void 0,this.countryCode=void 0,this.userId=void 0,this.sessionCookie=void 0,u(d.LOGOUT_EVENT,null)}async getSupportedCreateAuthMethods(){let t=(await this.touchSession()).data.partnerId,r=await this.ctx.client.getPartner(t),s=new Set;for(let n of r.data.partner.supportedAuthMethods)s.add(fe[n]);return s}toString(){let e=Object.keys(this.wallets).reduce((r,s)=>({...r,[s]:{...this.wallets[s],signer:this.wallets[s].signer?"[REDACTED]":void 0}}),{}),t={supportedWalletTypes:this.supportedWalletTypes,cosmosPrefix:this.cosmosPrefix,email:this.email,phone:this.phone,countryCode:this.countryCode,telegramUserId:this.telegramUserId,farcasterUsername:this.farcasterUsername,userId:this.userId,pregenIds:this.pregenIds,currentWalletIds:this.currentWalletIds,wallets:e,loginEncryptionKeyPair:this.loginEncryptionKeyPair?"[REDACTED]":void 0,ctx:{apiKey:this.ctx.apiKey,disableWorkers:this.ctx.disableWorkers,disableWebSockets:this.ctx.disableWebSockets,env:this.ctx.env,offloadMPCComputationURL:this.ctx.offloadMPCComputationURL,useLocalFiles:this.ctx.useLocalFiles,useDKLS:this.ctx.useDKLS,cosmosPrefix:this.ctx.cosmosPrefix}};return`Para ${JSON.stringify(t,null,2)}`}};import{AuthMethod as $s,EmailTheme as Hs,Network as js,WalletType as Js,WalletScheme as Ys,OnRampAsset as Xs,OnRampPurchaseType as qs,OnRampProvider as zs,OnRampPurchaseStatus as Qs,OAuthMethod as Zs,NON_ED25519 as ei,PREGEN_IDENTIFIER_TYPES as ti}from"@getpara/user-management-client";var Bs=z.version,Fs=z;export{$s as AuthMethod,Hs as EmailTheme,dt as EnabledFlow,pt as Environment,k as KeyContainer,ei as NON_ED25519,js as Network,Zs as OAuthMethod,Xs as OnRampAsset,Pe as OnRampMethod,zs as OnRampProvider,Qs as OnRampPurchaseStatus,qs as OnRampPurchaseType,ti as PREGEN_IDENTIFIER_TYPES,d as ParaEvent,ne as PopupType,Ie as PregenIdentifierType,Ae as RecoveryStatus,m as STORAGE_PREFIX,X as TransactionReviewDenied,re as TransactionReviewError,q as TransactionReviewTimeout,Ys as WalletScheme,Js as WalletType,Zt as decimalToHex,be as decryptPrivateKey,At as decryptPrivateKeyAndDecryptShare,_e as decryptPrivateKeyWithPassword,wt as decryptWithKeyPair,Y as decryptWithPrivateKey,Fs as default,K as distributeNewShare,pe as encodePrivateKeyToPemHex,ft as encryptPrivateKey,Rt as encryptPrivateKeyWithPassword,ee as encryptWithDerivedPublicKey,_ as entityToWallet,J as getAsymmetricKeyPair,Ir as getBaseMPCNetworkUrl,Ue as getBaseOAuthUrl,Ne as getBaseUrl,Ee as getCosmosAddress,Pt as getDerivedPrivateKeyAndDecrypt,ct as getOnRampAssets,lt as getOnRampNetworks,T as getPortalBaseURL,Te as getPortalDomain,St as getPublicKeyFromSignature,N as getPublicKeyHex,Oe as getSHA256HashHex,Tt as hashPasswordWithSalt,Xt as hexStringToBase64,Qt as hexToDecimal,qt as hexToSignature,zt as hexToUint8Array,de as initClient,ae as isWalletSupported,he as mpcComputationClient,we as normalizePhoneNumber,Bs as paraVersion,yt as publicKeyFromHex,j as stringToPhoneNumber,ie as toAssetInfoArray,Ut as transmissionUtilsRetrieve,se as truncateAddress,rr as waitUntilTrue};
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // src/ParaCore.ts
8
+ import { Buffer as NodeBuffer } from "buffer";
9
+ import {
10
+ AuthMethod,
11
+ PublicKeyStatus,
12
+ PublicKeyType,
13
+ WalletType as WalletType2,
14
+ WalletScheme as WalletScheme2,
15
+ OAuthMethod,
16
+ extractWalletRef,
17
+ PasswordStatus,
18
+ extractAuthInfo
19
+ } from "@getpara/user-management-client";
20
+ import forge3 from "node-forge";
21
+
22
+ // src/cryptography/utils.ts
23
+ import base64url from "base64url";
24
+ import forge from "node-forge";
25
+
26
+ // src/utils/events.ts
27
+ function dispatchEvent(type, data, error) {
28
+ typeof window !== "undefined" && !!window.dispatchEvent && window.dispatchEvent(
29
+ new CustomEvent(type, { detail: { data, ...error && { error: new Error(error) } } })
30
+ );
31
+ }
32
+
33
+ // src/utils/formatting.ts
34
+ import { toBech32 } from "@cosmjs/encoding";
35
+ import { sha256 } from "@noble/hashes/sha256";
36
+ import { ripemd160 } from "@noble/hashes/ripemd160";
37
+ import elliptic from "elliptic";
38
+ import parsePhoneNumberFromString from "libphonenumber-js";
39
+ var secp256k1 = new elliptic.ec("secp256k1");
40
+ function hexStringToBase64(hexString) {
41
+ if (hexString.substring(0, 2) === "0x") {
42
+ hexString = hexString.substring(2);
43
+ }
44
+ return Buffer.from(hexString, "hex").toString("base64");
45
+ }
46
+ function hexToSignature(hexSig) {
47
+ return {
48
+ r: `0x${hexSig.slice(2, 66)}`,
49
+ s: `0x${hexSig.slice(66, 130)}`,
50
+ v: BigInt(hexSig.slice(130, 132))
51
+ };
52
+ }
53
+ function hexToUint8Array(hex) {
54
+ if (hex.startsWith("0x")) {
55
+ hex = hex.slice(2);
56
+ }
57
+ return new Uint8Array(Buffer.from(hex, "hex"));
58
+ }
59
+ function hexToDecimal(hex) {
60
+ if (hex.startsWith("0x")) {
61
+ hex = hex.slice(2);
62
+ }
63
+ return `${parseInt(hex, 16)}`;
64
+ }
65
+ function decimalToHex(decimal) {
66
+ return `0x${parseInt(decimal).toString(16)}`;
67
+ }
68
+ function compressPubkey(pubkey) {
69
+ switch (pubkey.length) {
70
+ case 33:
71
+ return pubkey;
72
+ case 65:
73
+ return Uint8Array.from(secp256k1.keyFromPublic(pubkey).getPublic(true, "array"));
74
+ default:
75
+ throw new Error("Invalid pubkey length");
76
+ }
77
+ }
78
+ function rawSecp256k1PubkeyToRawAddress(pubkeyData) {
79
+ if (pubkeyData.length !== 33) {
80
+ throw new Error(`Invalid Secp256k1 pubkey length (compressed): ${pubkeyData.length}`);
81
+ }
82
+ return ripemd160(sha256(pubkeyData));
83
+ }
84
+ function getCosmosAddress(publicKey, prefix) {
85
+ const uncompressedPublicKey = new Uint8Array(
86
+ Buffer.from(publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey, "hex")
87
+ );
88
+ const compressedPublicKey = compressPubkey(uncompressedPublicKey);
89
+ return toBech32(prefix, rawSecp256k1PubkeyToRawAddress(compressedPublicKey));
90
+ }
91
+ function truncateAddress(str, addressType, { prefix = addressType === "COSMOS" ? "cosmos" : void 0 } = {}) {
92
+ const headLength = (addressType === "COSMOS" ? prefix.length : addressType === "SOLANA" ? 0 : 2) + 4;
93
+ return `${str.slice(0, headLength)}...${str.slice(-4)}`;
94
+ }
95
+ function stringToPhoneNumber(str) {
96
+ return parsePhoneNumberFromString(str)?.formatInternational().replace(/[^\d+]/g, "");
97
+ }
98
+ function normalizePhoneNumber(countryCode, number) {
99
+ return stringToPhoneNumber(`${countryCode[0] !== "+" ? "+" : ""}${countryCode}${number}`);
100
+ }
101
+
102
+ // src/utils/onRamps.ts
103
+ function toAssetInfoArray(data) {
104
+ const result = [];
105
+ Object.keys(data).forEach((walletType) => {
106
+ const networks = data[walletType];
107
+ Object.keys(networks).forEach((network) => {
108
+ const assets = networks[network];
109
+ Object.keys(assets).forEach((asset) => {
110
+ const providerInfo = assets[asset];
111
+ result.push([walletType, network, asset, providerInfo]);
112
+ });
113
+ });
114
+ });
115
+ return result;
116
+ }
117
+ function getOnRampNetworks(data, { walletType, allowed } = {}) {
118
+ return [
119
+ ...new Set(
120
+ toAssetInfoArray(data).filter(([type, network]) => (!walletType || type === walletType) && (!allowed || allowed.includes(network))).map(([_, network]) => network)
121
+ )
122
+ ];
123
+ }
124
+ function getOnRampAssets(data, {
125
+ walletType,
126
+ network,
127
+ allowed
128
+ } = {}) {
129
+ return [
130
+ ...new Set(
131
+ toAssetInfoArray(data).filter(
132
+ ([t, n, a]) => (!walletType || t === walletType) && (!network || n === network) && (!Array.isArray(allowed) || allowed.includes(a))
133
+ ).map(([, , asset]) => asset)
134
+ )
135
+ ];
136
+ }
137
+
138
+ // src/utils/polling.ts
139
+ async function waitUntilTrue(condition, timeoutMs, intervalMs) {
140
+ const start = Date.now();
141
+ while (Date.now() - start < timeoutMs) {
142
+ if (await condition()) {
143
+ return true;
144
+ }
145
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
146
+ }
147
+ return false;
148
+ }
149
+
150
+ // src/types/config.ts
151
+ var Environment = /* @__PURE__ */ ((Environment3) => {
152
+ Environment3["DEV"] = "DEV";
153
+ Environment3["SANDBOX"] = "SANDBOX";
154
+ Environment3["BETA"] = "BETA";
155
+ Environment3["PROD"] = "PROD";
156
+ Environment3["DEVELOPMENT"] = "BETA";
157
+ Environment3["PRODUCTION"] = "PROD";
158
+ return Environment3;
159
+ })(Environment || {});
160
+ var EnabledFlow = /* @__PURE__ */ ((EnabledFlow2) => {
161
+ EnabledFlow2["BUY"] = "BUY";
162
+ EnabledFlow2["RECEIVE"] = "RECEIVE";
163
+ EnabledFlow2["WITHDRAW"] = "WITHDRAW";
164
+ return EnabledFlow2;
165
+ })(EnabledFlow || {});
166
+
167
+ // src/types/wallet.ts
168
+ var PregenIdentifierType = /* @__PURE__ */ ((PregenIdentifierType2) => {
169
+ PregenIdentifierType2["EMAIL"] = "EMAIL";
170
+ PregenIdentifierType2["PHONE"] = "PHONE";
171
+ return PregenIdentifierType2;
172
+ })(PregenIdentifierType || {});
173
+
174
+ // src/types/onRamps.ts
175
+ var OnRampMethod = /* @__PURE__ */ ((OnRampMethod2) => {
176
+ OnRampMethod2["ACH"] = "ACH";
177
+ OnRampMethod2["DEBIT"] = "Debit";
178
+ OnRampMethod2["CREDIT"] = "Credit";
179
+ OnRampMethod2["APPLE_PAY"] = "Apple Pay";
180
+ return OnRampMethod2;
181
+ })(OnRampMethod || {});
182
+
183
+ // src/types/popup.ts
184
+ var PopupType = /* @__PURE__ */ ((PopupType2) => {
185
+ PopupType2["SIGN_TRANSACTION_REVIEW"] = "SIGN_TRANSACTION_REVIEW";
186
+ PopupType2["SIGN_MESSAGE_REVIEW"] = "SIGN_MESSAGE_REVIEW";
187
+ PopupType2["LOGIN_PASSKEY"] = "LOGIN_PASSKEY";
188
+ PopupType2["CREATE_PASSKEY"] = "CREATE_PASSKEY";
189
+ PopupType2["OAUTH"] = "OAUTH";
190
+ PopupType2["ON_RAMP_TRANSACTION"] = "ON_RAMP_TRANSACTION";
191
+ return PopupType2;
192
+ })(PopupType || {});
193
+
194
+ // src/types/recovery.ts
195
+ var RecoveryStatus = /* @__PURE__ */ ((RecoveryStatus3) => {
196
+ RecoveryStatus3["INITIATED"] = "INITIATED";
197
+ RecoveryStatus3["READY"] = "READY";
198
+ RecoveryStatus3["EXPIRED"] = "EXPIRED";
199
+ RecoveryStatus3["FINISHED"] = "FINISHED";
200
+ RecoveryStatus3["CANCELLED"] = "CANCELLED";
201
+ return RecoveryStatus3;
202
+ })(RecoveryStatus || {});
203
+
204
+ // src/types/events.ts
205
+ var EVENT_PREFIX = "para";
206
+ var ParaEvent = ((ParaEvent2) => {
207
+ ParaEvent2["LOGIN_EVENT"] = `${EVENT_PREFIX}Login`;
208
+ ParaEvent2["ACCOUNT_CREATION_EVENT"] = `${EVENT_PREFIX}AccountCreation`;
209
+ ParaEvent2["ACCOUNT_SETUP_EVENT"] = `${EVENT_PREFIX}AccountSetup`;
210
+ ParaEvent2["LOGOUT_EVENT"] = `${EVENT_PREFIX}Logout`;
211
+ ParaEvent2["SIGN_MESSAGE_EVENT"] = `${EVENT_PREFIX}SignMessage`;
212
+ ParaEvent2["SIGN_TRANSACTION_EVENT"] = `${EVENT_PREFIX}SignTransaction`;
213
+ ParaEvent2["EXTERNAL_WALLET_CHANGE_EVENT"] = `${EVENT_PREFIX}ExternalWalletChange`;
214
+ ParaEvent2["WALLETS_CHANGE_EVENT"] = `${EVENT_PREFIX}WalletsChange`;
215
+ ParaEvent2["WALLET_CREATED"] = `${EVENT_PREFIX}WalletCreated`;
216
+ ParaEvent2["PREGEN_WALLET_CLAIMED"] = `${EVENT_PREFIX}PregenWalletClaimed`;
217
+ return ParaEvent2;
218
+ })(ParaEvent || {});
219
+
220
+ // src/utils/url.ts
221
+ function getPortalDomain(env, isE2E) {
222
+ if (isE2E) {
223
+ return `localhost`;
224
+ }
225
+ switch (env) {
226
+ case "DEV" /* DEV */:
227
+ return "localhost";
228
+ case "SANDBOX" /* SANDBOX */:
229
+ return "app.sandbox.usecapsule.com";
230
+ case "BETA" /* BETA */:
231
+ return "app.beta.usecapsule.com";
232
+ case "PROD" /* PROD */:
233
+ return "app.usecapsule.com";
234
+ default:
235
+ throw new Error(`env: ${env} not supported`);
236
+ }
237
+ }
238
+ function getPortalBaseURL({ env, isE2E }, useLocalIp, isForWasm) {
239
+ if (isE2E) {
240
+ if (isForWasm) {
241
+ return `https://app.sandbox.usecapsule.com`;
242
+ }
243
+ return `http://localhost:3003`;
244
+ }
245
+ const domain = getPortalDomain(env);
246
+ if (env === "DEV" /* DEV */) {
247
+ if (useLocalIp) {
248
+ return `http://127.0.0.1:3003`;
249
+ }
250
+ return `http://${domain}:3003`;
251
+ }
252
+ return `https://${domain}`;
253
+ }
254
+ function getParaConnectDomain(env) {
255
+ switch (env) {
256
+ case "DEV" /* DEV */:
257
+ return "localhost";
258
+ case "SANDBOX" /* SANDBOX */:
259
+ return "connect.sandbox.getpara.com";
260
+ case "BETA" /* BETA */:
261
+ return "connect.beta.getpara.com";
262
+ case "PROD" /* PROD */:
263
+ return "connect.getpara.com";
264
+ default:
265
+ throw new Error(`env: ${env} not supported`);
266
+ }
267
+ }
268
+ function getParaConnectBaseUrl({ env }, useLocalIp) {
269
+ const domain = getParaConnectDomain(env);
270
+ if (env === "DEV" /* DEV */) {
271
+ if (useLocalIp) {
272
+ return `http://127.0.0.1:3008`;
273
+ }
274
+ return `http://${domain}:3008`;
275
+ }
276
+ return `https://${domain}`;
277
+ }
278
+ function constructUrl({
279
+ base,
280
+ path,
281
+ params = {}
282
+ }) {
283
+ const url = new URL(path, base);
284
+ Object.entries(params).forEach(([key, value]) => {
285
+ if (!!value && value !== "undefined" && value !== "null") url.searchParams.set(key, value.toString());
286
+ });
287
+ return url.toString();
288
+ }
289
+
290
+ // src/utils/wallet.ts
291
+ import { WalletScheme, WalletType } from "@getpara/user-management-client";
292
+ var WalletSchemeTypeMap = {
293
+ [WalletScheme.DKLS]: {
294
+ [WalletType.EVM]: true,
295
+ [WalletType.COSMOS]: true
296
+ },
297
+ [WalletScheme.CGGMP]: {
298
+ [WalletType.EVM]: true,
299
+ [WalletType.COSMOS]: true
300
+ },
301
+ [WalletScheme.ED25519]: {
302
+ [WalletType.SOLANA]: true
303
+ }
304
+ };
305
+ function isPregenIdentifierMatch(a, b, type) {
306
+ if (!a || !b) {
307
+ return false;
308
+ }
309
+ switch (type) {
310
+ case "EMAIL":
311
+ return a.toLowerCase() === b.toLowerCase();
312
+ case "PHONE":
313
+ return stringToPhoneNumber(a) === stringToPhoneNumber(b);
314
+ case "CUSTOM_ID":
315
+ return a === b;
316
+ default:
317
+ return a.replace(/^@/g, "").toLowerCase() === b.replace(/^@/g, "").toLowerCase();
318
+ }
319
+ }
320
+ function isWalletSupported(types, wallet) {
321
+ return types.some((walletType) => !!WalletSchemeTypeMap[wallet.scheme][walletType]);
322
+ }
323
+ function getSchemes(types) {
324
+ return Object.keys(WalletSchemeTypeMap).filter((scheme) => {
325
+ if (scheme === WalletScheme.CGGMP) {
326
+ return false;
327
+ }
328
+ return (Array.isArray(types) ? types : Object.keys(types)).some((type) => WalletSchemeTypeMap[scheme][type]);
329
+ });
330
+ }
331
+ function getWalletTypes(schemes) {
332
+ return [
333
+ ...new Set(
334
+ schemes.reduce((acc, scheme) => {
335
+ return [...acc, ...Object.keys(WalletSchemeTypeMap[scheme]).filter((type) => WalletSchemeTypeMap[scheme][type])];
336
+ }, [])
337
+ )
338
+ ];
339
+ }
340
+ function getEquivalentTypes(types) {
341
+ return getWalletTypes(getSchemes((Array.isArray(types) ? types : [types]).map((t) => WalletType[t])));
342
+ }
343
+ function entityToWallet(w) {
344
+ return {
345
+ ...w,
346
+ scheme: w.scheme,
347
+ type: w.type,
348
+ pregenIdentifierType: w.pregenIdentifierType
349
+ };
350
+ }
351
+ function migrateWallet(obj) {
352
+ if (["USER", "PREGEN"].includes(obj.type)) {
353
+ obj.isPregen = obj.type === "PREGEN";
354
+ obj.type = obj.scheme === WalletScheme.ED25519 ? WalletType.SOLANA : WalletType.EVM;
355
+ }
356
+ if (!!obj.scheme && !obj.type) {
357
+ obj.type = obj.scheme === WalletScheme.ED25519 ? WalletType.SOLANA : WalletType.EVM;
358
+ }
359
+ return obj;
360
+ }
361
+
362
+ // src/cryptography/utils.ts
363
+ var rsa = forge.pki.rsa;
364
+ var RSA_ENCRYPTION_SCHEME = "RSA-OAEP";
365
+ var CONSTANT_IV = "794241bc819a125a7b78ea313decc0bc";
366
+ var CONSTANT_IV_AES = new Uint8Array([23, 66, 157, 146, 179, 158, 117, 120, 184, 73, 123, 81]);
367
+ function getSHA256HashHex(str) {
368
+ const md = forge.md.sha256.create();
369
+ md.update(str);
370
+ return md.digest().toHex();
371
+ }
372
+ function getPublicKeyHex(keyPair) {
373
+ const pem = forge.pki.publicKeyToRSAPublicKeyPem(keyPair.publicKey);
374
+ return Buffer.from(pem, "utf-8").toString("hex");
375
+ }
376
+ function publicKeyFromHex(publicKeyHex) {
377
+ const pem = publicKeyHexToPem(publicKeyHex);
378
+ return forge.pki.publicKeyFromPem(pem);
379
+ }
380
+ function publicKeyHexToPem(publicKeyHex) {
381
+ return Buffer.from(publicKeyHex, "hex").toString("utf-8");
382
+ }
383
+ function encodePrivateKeyToPemHex(keyPair) {
384
+ const pem = forge.pki.privateKeyToPem(keyPair.privateKey);
385
+ return Buffer.from(pem, "utf-8").toString("hex");
386
+ }
387
+ function decodePrivateKeyPemHex(privateKeyPemHex) {
388
+ const pem = Buffer.from(privateKeyPemHex, "hex").toString("utf-8");
389
+ return forge.pki.privateKeyFromPem(pem);
390
+ }
391
+ async function encryptPrivateKey(keyPair, key) {
392
+ const privateKeyPemHex = encodePrivateKeyToPemHex(keyPair);
393
+ const cryptoKey = await window.crypto.subtle.importKey(
394
+ "raw",
395
+ Buffer.from(key, "base64"),
396
+ {
397
+ name: "AES-GCM",
398
+ length: 256
399
+ },
400
+ true,
401
+ ["encrypt", "decrypt"]
402
+ );
403
+ const encodedPlaintext = new TextEncoder().encode(privateKeyPemHex);
404
+ const ciphertext = await window.crypto.subtle.encrypt(
405
+ { name: "AES-GCM", iv: CONSTANT_IV_AES },
406
+ cryptoKey,
407
+ encodedPlaintext
408
+ );
409
+ return Buffer.from(ciphertext).toString("base64");
410
+ }
411
+ async function decryptPrivateKey(encryptedPrivateKeyPemHex, key) {
412
+ const secretKey = await crypto.subtle.importKey(
413
+ "raw",
414
+ Buffer.from(key, "base64"),
415
+ {
416
+ name: "AES-GCM",
417
+ length: 256
418
+ },
419
+ true,
420
+ ["encrypt", "decrypt"]
421
+ );
422
+ const cleartext = await crypto.subtle.decrypt(
423
+ { name: "AES-GCM", iv: CONSTANT_IV_AES },
424
+ secretKey,
425
+ Buffer.from(encryptedPrivateKeyPemHex, "base64")
426
+ );
427
+ const privateKeyPemHex = new TextDecoder().decode(cleartext);
428
+ const privateKey = decodePrivateKeyPemHex(privateKeyPemHex);
429
+ return privateKey;
430
+ }
431
+ async function getAsymmetricKeyPair(ctx, seedValue) {
432
+ const prng = forge.random.createInstance();
433
+ if (seedValue) {
434
+ prng.seedFileSync = (_n) => seedValue;
435
+ prng.seedFile = (_n, cb) => {
436
+ cb(null, seedValue);
437
+ };
438
+ }
439
+ const options = {
440
+ bits: 2048,
441
+ e: 65537,
442
+ prng
443
+ };
444
+ if (!ctx.disableWorkers) {
445
+ options.workLoad = 100;
446
+ options.workers = seedValue ? 1 : -1;
447
+ const workerRes = await fetch(`${getPortalBaseURL(ctx)}/static/js/prime.worker.min.js`);
448
+ const workerBlob = new Blob([await workerRes.text()], { type: "application/javascript" });
449
+ options.workerScript = URL.createObjectURL(workerBlob);
450
+ }
451
+ return new Promise(
452
+ (resolve, reject) => rsa.generateKeyPair(options, (err, keypair) => {
453
+ if (err) {
454
+ reject(err);
455
+ }
456
+ resolve(keypair);
457
+ })
458
+ );
459
+ }
460
+ async function getPublicKeyFromSignature(ctx, userHandle) {
461
+ const encodedUserHandle = base64url.encode(userHandle);
462
+ const keyPair = await getAsymmetricKeyPair(ctx, encodedUserHandle);
463
+ return getPublicKeyHex(keyPair);
464
+ }
465
+ function symmetricKeyEncryptMessage(message) {
466
+ const key = forge.random.getBytesSync(16);
467
+ const cipher = forge.cipher.createCipher("AES-CBC", key);
468
+ cipher.start({ iv: CONSTANT_IV });
469
+ cipher.update(forge.util.createBuffer(message));
470
+ cipher.finish();
471
+ const encryptedMessageHex = cipher.output.toHex();
472
+ return { key, encryptedMessageHex };
473
+ }
474
+ function decipherEncryptedMessageHex(key, encryptedMessageHex) {
475
+ const decipher = forge.cipher.createDecipher("AES-CBC", key);
476
+ decipher.start({ iv: CONSTANT_IV });
477
+ decipher.update(forge.util.createBuffer(forge.util.hexToBytes(encryptedMessageHex)));
478
+ decipher.finish();
479
+ return decipher.output.toString();
480
+ }
481
+ function decryptWithKeyPair(keyPair, encryptedMessageHex, encryptedKeyHex) {
482
+ const encryptedKey = Buffer.from(encryptedKeyHex, "hex").toString("utf-8");
483
+ const key = keyPair.privateKey.decrypt(encryptedKey, RSA_ENCRYPTION_SCHEME);
484
+ return decipherEncryptedMessageHex(key, encryptedMessageHex);
485
+ }
486
+ function decryptWithPrivateKey(privateKey, encryptedMessageHex, encryptedKeyHex) {
487
+ const encryptedKey = Buffer.from(encryptedKeyHex, "hex").toString("utf-8");
488
+ const key = privateKey.decrypt(encryptedKey, RSA_ENCRYPTION_SCHEME);
489
+ return decipherEncryptedMessageHex(key, encryptedMessageHex);
490
+ }
491
+ async function decryptWithDerivedPrivateKey(ctx, {
492
+ seedValue,
493
+ encryptedMessageHex,
494
+ encryptedKeyHex
495
+ }) {
496
+ const keyPair = await getAsymmetricKeyPair(ctx, seedValue);
497
+ return decryptWithPrivateKey(keyPair.privateKey, encryptedMessageHex, encryptedKeyHex);
498
+ }
499
+ async function getDerivedPrivateKeyAndDecrypt(ctx, seedValue, encryptedShares) {
500
+ return Promise.all(
501
+ encryptedShares.map(async (share) => ({
502
+ walletId: share.walletId,
503
+ walletScheme: share.walletScheme,
504
+ partnerId: share.partnerId,
505
+ signer: await decryptWithDerivedPrivateKey(ctx, {
506
+ seedValue,
507
+ encryptedMessageHex: share.encryptedShare,
508
+ encryptedKeyHex: share.encryptedKey
509
+ }),
510
+ protocolId: share.protocolId
511
+ }))
512
+ );
513
+ }
514
+ async function decryptPrivateKeyAndDecryptShare(encryptionKey, encryptedShares, encryptedPrivateKey) {
515
+ let privateKey;
516
+ try {
517
+ privateKey = await decryptPrivateKey(encryptedPrivateKey, encryptionKey);
518
+ } catch (e) {
519
+ }
520
+ try {
521
+ privateKey = await decryptPrivateKeyWithPassword(encryptedPrivateKey, encryptionKey);
522
+ } catch (e) {
523
+ }
524
+ if (!privateKey) {
525
+ throw new Error("Could not decrypt private key");
526
+ }
527
+ return encryptedShares.map((share) => ({
528
+ walletId: share.walletId,
529
+ walletScheme: share.walletScheme,
530
+ partnerId: share.partnerId,
531
+ signer: decryptWithPrivateKey(privateKey, share.encryptedShare, share.encryptedKey),
532
+ protocolId: share.protocolId
533
+ }));
534
+ }
535
+ function encryptWithDerivedPublicKey(publicKeyHex, message) {
536
+ const { key, encryptedMessageHex } = symmetricKeyEncryptMessage(message);
537
+ const publicKeyPem = publicKeyHexToPem(publicKeyHex);
538
+ const publicKey = forge.pki.publicKeyFromPem(publicKeyPem);
539
+ const encryptedKey = publicKey.encrypt(key, RSA_ENCRYPTION_SCHEME);
540
+ const encryptedKeyHex = Buffer.from(encryptedKey, "utf-8").toString("hex");
541
+ return { encryptedMessageHex, encryptedKeyHex };
542
+ }
543
+ function hashPasswordWithSalt(password) {
544
+ const salt = generateSalt();
545
+ const saltedPassword = salt + password;
546
+ const hash = getSHA256HashHex(saltedPassword);
547
+ return { salt, hash };
548
+ }
549
+ function generateSalt(length = 16) {
550
+ return forge.util.bytesToHex(forge.random.getBytesSync(length));
551
+ }
552
+ async function deriveCryptoKeyFromPassword(hashedPassword) {
553
+ const keyBuffer = Buffer.from(hashedPassword, "hex");
554
+ return await window.crypto.subtle.importKey(
555
+ "raw",
556
+ keyBuffer,
557
+ {
558
+ name: "AES-GCM",
559
+ length: 256
560
+ },
561
+ true,
562
+ ["encrypt", "decrypt"]
563
+ );
564
+ }
565
+ async function encryptPrivateKeyWithPassword(keyPair, hashedPassword) {
566
+ const cryptoKey = await deriveCryptoKeyFromPassword(hashedPassword);
567
+ const privateKeyPemHex = encodePrivateKeyToPemHex(keyPair);
568
+ const encodedPlaintext = new TextEncoder().encode(privateKeyPemHex);
569
+ const ciphertext = await window.crypto.subtle.encrypt(
570
+ { name: "AES-GCM", iv: CONSTANT_IV_AES },
571
+ cryptoKey,
572
+ encodedPlaintext
573
+ );
574
+ return Buffer.from(ciphertext).toString("base64");
575
+ }
576
+ async function decryptPrivateKeyWithPassword(encryptedPrivateKeyPemHex, hashedPassword) {
577
+ const secretKey = await crypto.subtle.importKey(
578
+ "raw",
579
+ Buffer.from(hashedPassword, "hex"),
580
+ {
581
+ name: "AES-GCM",
582
+ length: 256
583
+ },
584
+ true,
585
+ ["encrypt", "decrypt"]
586
+ );
587
+ const cleartext = await crypto.subtle.decrypt(
588
+ { name: "AES-GCM", iv: CONSTANT_IV_AES },
589
+ secretKey,
590
+ Buffer.from(encryptedPrivateKeyPemHex, "base64")
591
+ );
592
+ const privateKeyPemHex = new TextDecoder().decode(cleartext);
593
+ const privateKey = decodePrivateKeyPemHex(privateKeyPemHex);
594
+ return privateKey;
595
+ }
596
+
597
+ // src/external/userManagementClient.ts
598
+ import Client from "@getpara/user-management-client";
599
+ function getBaseOAuthUrl(env) {
600
+ switch (env) {
601
+ case "DEV" /* DEV */:
602
+ return "http://localhost:8080/";
603
+ case "SANDBOX" /* SANDBOX */:
604
+ return "https://api.sandbox.usecapsule.com/";
605
+ case "BETA" /* BETA */:
606
+ return "https://api.beta.usecapsule.com/";
607
+ case "PROD" /* PROD */:
608
+ return "https://api.usecapsule.com/";
609
+ default:
610
+ throw new Error(`unsupported env: ${env}`);
611
+ }
612
+ }
613
+ function getBaseUrl(env) {
614
+ switch (env) {
615
+ case "DEV" /* DEV */:
616
+ return "http://localhost:8080/";
617
+ case "SANDBOX" /* SANDBOX */:
618
+ return "https://api.sandbox.getpara.com/";
619
+ case "BETA" /* BETA */:
620
+ return "https://api.beta.getpara.com/";
621
+ case "PROD" /* PROD */:
622
+ return "https://api.getpara.com/";
623
+ default:
624
+ throw new Error(`unsupported env: ${env}`);
625
+ }
626
+ }
627
+ function getBaseMPCNetworkUrl(env, useWebsocket) {
628
+ const prefix = useWebsocket ? "ws" : "http";
629
+ switch (env) {
630
+ case "DEV" /* DEV */:
631
+ return `${prefix}://localhost:3000`;
632
+ case "SANDBOX" /* SANDBOX */:
633
+ return `${prefix}s://mpc-network.sandbox.getpara.com`;
634
+ case "BETA" /* BETA */:
635
+ return `${prefix}s://mpc-network.beta.getpara.com`;
636
+ case "PROD" /* PROD */:
637
+ return `${prefix}s://mpc-network.prod.getpara.com`;
638
+ default:
639
+ throw new Error(`unsupported env: ${env}`);
640
+ }
641
+ }
642
+ function initClient({
643
+ env,
644
+ version,
645
+ apiKey,
646
+ partnerId,
647
+ useFetchAdapter = false,
648
+ retrieveSessionCookie,
649
+ persistSessionCookie
650
+ }) {
651
+ return new Client({
652
+ userManagementHost: getBaseUrl(env),
653
+ version: ["DEV" /* DEV */, "SANDBOX" /* SANDBOX */].includes(env) ? "dev" : version,
654
+ apiKey,
655
+ partnerId,
656
+ opts: { useFetchAdapter },
657
+ retrieveSessionCookie,
658
+ persistSessionCookie
659
+ });
660
+ }
661
+
662
+ // src/external/mpcComputationClient.ts
663
+ var mpcComputationClient_exports = {};
664
+ __export(mpcComputationClient_exports, {
665
+ initClient: () => initClient2
666
+ });
667
+ import axios from "axios";
668
+ function initClient2(baseURL, useAdapter) {
669
+ const client = axios.create({ baseURL });
670
+ if (useAdapter) {
671
+ client.defaults.adapter = function(config) {
672
+ return fetch(config.baseURL + config.url, {
673
+ method: config.method,
674
+ headers: config.headers,
675
+ body: config.data,
676
+ credentials: config.withCredentials ? "include" : void 0
677
+ }).then(
678
+ (response) => response.text().then((text) => ({
679
+ data: text,
680
+ status: response.status,
681
+ statusText: response.statusText,
682
+ headers: response.headers,
683
+ config,
684
+ request: fetch
685
+ }))
686
+ ).catch(function(reason) {
687
+ throw reason;
688
+ });
689
+ };
690
+ }
691
+ return client;
692
+ }
693
+
694
+ // src/shares/shareDistribution.ts
695
+ import { EncryptorType as EncryptorType2, KeyShareType as KeyShareType2 } from "@getpara/user-management-client";
696
+
697
+ // src/shares/recovery.ts
698
+ import { EncryptorType, KeyShareType } from "@getpara/user-management-client";
699
+
700
+ // src/shares/KeyContainer.ts
701
+ import { Encrypt as ECIESEncrypt, Decrypt as ECIESDecrypt } from "@celo/utils/lib/ecies.js";
702
+ import * as eutil from "ethereumjs-util";
703
+ import * as forge2 from "node-forge";
704
+ var KeyContainer = class _KeyContainer {
705
+ constructor(walletId, keyshare, address) {
706
+ this.walletId = walletId;
707
+ this.keyshare = keyshare;
708
+ this.address = address;
709
+ this.backupDecryptionKey = Buffer.from(forge2.random.getBytesSync(32), "binary").toString("hex");
710
+ }
711
+ static buildFrom(serializedContainer) {
712
+ try {
713
+ const parsedObject = JSON.parse(serializedContainer);
714
+ return Object.assign(new _KeyContainer("", "", ""), parsedObject);
715
+ } catch (e) {
716
+ const container = new _KeyContainer("", "", "");
717
+ container.backupDecryptionKey = serializedContainer.split("|")[0];
718
+ return container;
719
+ }
720
+ }
721
+ getPublicEncryptionKey() {
722
+ return Buffer.from(eutil.privateToPublic(Buffer.from(this.backupDecryptionKey, "hex")));
723
+ }
724
+ getPublicEncryptionKeyHex() {
725
+ return this.getPublicEncryptionKey().toString("hex");
726
+ }
727
+ encryptForSelf(backup) {
728
+ try {
729
+ const pubkey = this.getPublicEncryptionKey();
730
+ const data = ECIESEncrypt(pubkey, Buffer.from(backup, "ucs2")).toString("base64");
731
+ return data;
732
+ } catch (error) {
733
+ throw Error("Error encrypting backup");
734
+ }
735
+ }
736
+ static encryptWithPublicKey(publicKey, backup) {
737
+ try {
738
+ const data = ECIESEncrypt(publicKey, Buffer.from(backup, "ucs2")).toString("base64");
739
+ return data;
740
+ } catch (error) {
741
+ throw Error("Error encrypting backup");
742
+ }
743
+ }
744
+ decrypt(encryptedBackup) {
745
+ try {
746
+ const buf = Buffer.from(encryptedBackup, "base64");
747
+ const data = ECIESDecrypt(Buffer.from(this.backupDecryptionKey, "hex"), buf);
748
+ return Buffer.from(data.buffer).toString("ucs2");
749
+ } catch (error) {
750
+ throw Error("Error decrypting backup");
751
+ }
752
+ }
753
+ };
754
+
755
+ // src/shares/recovery.ts
756
+ async function sendRecoveryForShare({
757
+ ctx,
758
+ userId,
759
+ walletId,
760
+ otherEncryptedShares = [],
761
+ userSigner,
762
+ ignoreRedistributingBackupEncryptedShare = false,
763
+ emailProps = {},
764
+ forceRefresh = false
765
+ }) {
766
+ if (ignoreRedistributingBackupEncryptedShare) {
767
+ await ctx.client.uploadUserKeyShares(
768
+ userId,
769
+ otherEncryptedShares.map((share) => ({
770
+ walletId,
771
+ ...share
772
+ }))
773
+ );
774
+ return "";
775
+ }
776
+ let userBackupKeyShareOptsArr;
777
+ let recoveryPrivateKeyContainer;
778
+ const { recoveryPublicKeys } = await ctx.client.getRecoveryPublicKeys(userId);
779
+ if (forceRefresh || !recoveryPublicKeys?.length) {
780
+ recoveryPrivateKeyContainer = new KeyContainer(walletId, "", "");
781
+ const { recoveryPublicKeys: recoveryPublicKeys2 } = await ctx.client.persistRecoveryPublicKeys(userId, [
782
+ recoveryPrivateKeyContainer.getPublicEncryptionKeyHex()
783
+ ]);
784
+ const encryptedUserBackup = recoveryPrivateKeyContainer.encryptForSelf(userSigner);
785
+ userBackupKeyShareOptsArr = [
786
+ {
787
+ walletId,
788
+ encryptedShare: encryptedUserBackup,
789
+ type: KeyShareType.USER,
790
+ encryptor: EncryptorType.RECOVERY,
791
+ recoveryPublicKeyId: recoveryPublicKeys2[0].id
792
+ }
793
+ ];
794
+ } else {
795
+ userBackupKeyShareOptsArr = recoveryPublicKeys.map((recoveryPublicKey) => {
796
+ const { id: recoveryPublicKeyId, publicKey } = recoveryPublicKey;
797
+ const encryptedUserBackup = KeyContainer.encryptWithPublicKey(Buffer.from(publicKey, "hex"), userSigner);
798
+ return {
799
+ walletId,
800
+ encryptedShare: encryptedUserBackup,
801
+ type: KeyShareType.USER,
802
+ encryptor: EncryptorType.RECOVERY,
803
+ recoveryPublicKeyId
804
+ };
805
+ });
806
+ }
807
+ await ctx.client.uploadUserKeyShares(userId, [
808
+ ...otherEncryptedShares.map((share) => ({
809
+ walletId,
810
+ ...share
811
+ })),
812
+ ...ignoreRedistributingBackupEncryptedShare ? [] : userBackupKeyShareOptsArr
813
+ ]);
814
+ await ctx.client.distributeParaShare({
815
+ userId,
816
+ walletId,
817
+ useDKLS: ctx.useDKLS,
818
+ ...emailProps
819
+ });
820
+ return recoveryPrivateKeyContainer ? JSON.stringify(recoveryPrivateKeyContainer) : "";
821
+ }
822
+
823
+ // src/shares/shareDistribution.ts
824
+ async function distributeNewShare({
825
+ ctx,
826
+ userId,
827
+ walletId,
828
+ userShare,
829
+ ignoreRedistributingBackupEncryptedShare = false,
830
+ emailProps = {},
831
+ partnerId,
832
+ protocolId
833
+ }) {
834
+ const publicKeysRes = await ctx.client.getSessionPublicKeys(userId);
835
+ const biometricEncryptedShares = publicKeysRes.data.keys.map((key) => {
836
+ if (!key.publicKey) {
837
+ return;
838
+ }
839
+ const { encryptedMessageHex, encryptedKeyHex } = encryptWithDerivedPublicKey(key.sigDerivedPublicKey, userShare);
840
+ return {
841
+ encryptedShare: encryptedMessageHex,
842
+ encryptedKey: encryptedKeyHex,
843
+ type: KeyShareType2.USER,
844
+ encryptor: EncryptorType2.BIOMETRICS,
845
+ biometricPublicKey: key.sigDerivedPublicKey,
846
+ partnerId,
847
+ protocolId
848
+ };
849
+ }).filter(Boolean);
850
+ const passwords = await ctx.client.getPasswords({ userId });
851
+ const passwordEncryptedShares = passwords.map((password) => {
852
+ if (password.status === "PENDING") {
853
+ return;
854
+ }
855
+ const { encryptedMessageHex, encryptedKeyHex } = encryptWithDerivedPublicKey(password.sigDerivedPublicKey, userShare);
856
+ return {
857
+ encryptedShare: encryptedMessageHex,
858
+ encryptedKey: encryptedKeyHex,
859
+ type: KeyShareType2.USER,
860
+ encryptor: EncryptorType2.PASSWORD,
861
+ passwordId: password.id,
862
+ partnerId,
863
+ protocolId
864
+ };
865
+ }).filter(Boolean);
866
+ const allEncryptedShares = [...biometricEncryptedShares, ...passwordEncryptedShares];
867
+ return await sendRecoveryForShare({
868
+ ctx,
869
+ userId,
870
+ walletId,
871
+ otherEncryptedShares: allEncryptedShares,
872
+ userSigner: userShare,
873
+ ignoreRedistributingBackupEncryptedShare,
874
+ emailProps
875
+ });
876
+ }
877
+
878
+ // src/transmission/transmissionUtils.ts
879
+ import { Encrypt as ECIESEncrypt2, Decrypt as ECIESDecrypt2 } from "@celo/utils/lib/ecies.js";
880
+ import { Buffer as Buffer2 } from "buffer";
881
+ import * as eutil2 from "ethereumjs-util";
882
+ import { randomBytes } from "crypto";
883
+ async function upload(message, userManagementClient) {
884
+ let secret;
885
+ let publicKeyUint8Array;
886
+ while (true) {
887
+ try {
888
+ secret = randomBytes(32).toString("hex");
889
+ publicKeyUint8Array = eutil2.privateToPublic(Buffer2.from(secret, "hex"));
890
+ break;
891
+ } catch (e) {
892
+ continue;
893
+ }
894
+ }
895
+ const pubkey = Buffer2.from(publicKeyUint8Array);
896
+ const data = ECIESEncrypt2(pubkey, Buffer2.from(message, "ucs2")).toString("base64");
897
+ const {
898
+ data: { id }
899
+ } = await userManagementClient.tempTrasmissionInit(data);
900
+ return encodeURIComponent(id + "|" + secret);
901
+ }
902
+ async function retrieve(uriEncodedMessage, userManagementClient) {
903
+ const [id, secret] = decodeURIComponent(uriEncodedMessage).split("|");
904
+ const response = await userManagementClient.tempTrasmission(id);
905
+ const data = response.data.message;
906
+ const buf = Buffer2.from(data, "base64");
907
+ const res = Buffer2.from(ECIESDecrypt2(Buffer2.from(secret, "hex"), buf).buffer).toString("ucs2");
908
+ return res;
909
+ }
910
+
911
+ // src/errors.ts
912
+ var TransactionReviewError = class extends Error {
913
+ constructor(transactionReviewUrl) {
914
+ super("transaction review error");
915
+ this.name = "TransactionReviewError";
916
+ this.transactionReviewUrl = transactionReviewUrl;
917
+ }
918
+ };
919
+ var TransactionReviewDenied = class extends Error {
920
+ constructor() {
921
+ super("transaction review has been denied by the user");
922
+ this.name = "TransactionReviewDenied";
923
+ }
924
+ };
925
+ var TransactionReviewTimeout = class extends Error {
926
+ constructor(transactionReviewUrl, pendingTransactionId) {
927
+ super("transaction review has timed out");
928
+ this.name = "TransactionReviewTimeout";
929
+ this.transactionReviewUrl = transactionReviewUrl;
930
+ this.pendingTransactionId = pendingTransactionId;
931
+ }
932
+ };
933
+
934
+ // src/constants.ts
935
+ var PARA_CORE_VERSION = '1.4.4-dev.0';
936
+ var PREFIX = "@CAPSULE/";
937
+ var LOCAL_STORAGE_EMAIL = `${PREFIX}e-mail`;
938
+ var LOCAL_STORAGE_PHONE = `${PREFIX}phone`;
939
+ var LOCAL_STORAGE_COUNTRY_CODE = `${PREFIX}countryCode`;
940
+ var LOCAL_STORAGE_FARCASTER_USERNAME = `${PREFIX}farcasterUsername`;
941
+ var LOCAL_STORAGE_TELEGRAM_USER_ID = `${PREFIX}telegramUserId`;
942
+ var LOCAL_STORAGE_USER_ID = `${PREFIX}userId`;
943
+ var LOCAL_STORAGE_ED25519_WALLETS = `${PREFIX}ed25519Wallets`;
944
+ var LOCAL_STORAGE_WALLETS = `${PREFIX}wallets`;
945
+ var LOCAL_STORAGE_EXTERNAL_WALLETS = `${PREFIX}externalWallets`;
946
+ var LOCAL_STORAGE_CURRENT_WALLET_IDS = `${PREFIX}currentWalletIds`;
947
+ var LOCAL_STORAGE_CURRENT_EXTERNAL_WALLET_ADDRESSES = `${PREFIX}currentExternalWalletAddresses`;
948
+ var LOCAL_STORAGE_SESSION_COOKIE = `${PREFIX}sessionCookie`;
949
+ var SESSION_STORAGE_LOGIN_ENCRYPTION_KEY_PAIR = `${PREFIX}loginEncryptionKeyPair`;
950
+ var POLLING_INTERVAL_MS = 2e3;
951
+ var SHORT_POLLING_INTERVAL_MS = 1e3;
952
+
953
+ // src/utils/listeners.ts
954
+ function storageListener(e) {
955
+ if (!e.url.includes(window.location.origin)) {
956
+ return;
957
+ }
958
+ if (e.key === LOCAL_STORAGE_CURRENT_EXTERNAL_WALLET_ADDRESSES) {
959
+ this.updateCurrentExternalWalletAddressesFromStorage();
960
+ }
961
+ if (e.key === LOCAL_STORAGE_EXTERNAL_WALLETS) {
962
+ this.updateExternalWalletsFromStorage();
963
+ }
964
+ if (e.key === SESSION_STORAGE_LOGIN_ENCRYPTION_KEY_PAIR) {
965
+ this.updateLoginEncryptionKeyPairFromStorage();
966
+ }
967
+ if (e.key === LOCAL_STORAGE_SESSION_COOKIE) {
968
+ this.updateSessionCookieFromStorage();
969
+ }
970
+ if (e.key === LOCAL_STORAGE_CURRENT_WALLET_IDS) {
971
+ this.updateWalletIdsFromStorage();
972
+ }
973
+ if (e.key === LOCAL_STORAGE_WALLETS || e.key === LOCAL_STORAGE_ED25519_WALLETS) {
974
+ this.updateWalletsFromStorage();
975
+ }
976
+ if (e.key === LOCAL_STORAGE_EMAIL) {
977
+ this.updateEmailFromStorage();
978
+ }
979
+ if (e.key === LOCAL_STORAGE_COUNTRY_CODE) {
980
+ this.updateCountryCodeFromStorage();
981
+ }
982
+ if (e.key === LOCAL_STORAGE_PHONE) {
983
+ this.updatePhoneFromStorage();
984
+ }
985
+ if (e.key === LOCAL_STORAGE_USER_ID) {
986
+ this.updateUserIdFromStorage();
987
+ }
988
+ if (e.key === LOCAL_STORAGE_TELEGRAM_USER_ID) {
989
+ this.updateTelegramUserIdFromStorage();
990
+ }
991
+ }
992
+ function setupListeners() {
993
+ if (typeof window !== "undefined" && window.addEventListener && window.location) {
994
+ window.removeEventListener("storage", storageListener.bind(this));
995
+ window.addEventListener("storage", storageListener.bind(this));
996
+ }
997
+ }
998
+
999
+ // src/ParaCore.ts
1000
+ if (typeof global !== "undefined") {
1001
+ global.Buffer = global.Buffer || NodeBuffer;
1002
+ } else if (typeof window !== "undefined") {
1003
+ window.Buffer = window.Buffer || NodeBuffer;
1004
+ window.global = window.global || window;
1005
+ } else {
1006
+ self.Buffer = self.Buffer || NodeBuffer;
1007
+ self.global = self.global || self;
1008
+ }
1009
+ var { pki, jsbn } = forge3;
1010
+ var ParaCore = class _ParaCore {
1011
+ /**
1012
+ * Constructs a new `ParaCore` instance.
1013
+ * @param env - `Environment` to use.
1014
+ * @param apiKey - API key to use.
1015
+ * @param opts - Additional constructor options; see `ConstructorOpts`.
1016
+ * @returns - A new ParaCore instance.
1017
+ */
1018
+ constructor(env, apiKey, opts) {
1019
+ this.isAwaitingAccountCreation = false;
1020
+ this.isAwaitingLogin = false;
1021
+ this.isAwaitingFarcaster = false;
1022
+ this.isAwaitingOAuth = false;
1023
+ /**
1024
+ * The IDs of the currently active wallets, for each supported wallet type. Any signer integrations will default to the first viable wallet ID in this dictionary.
1025
+ */
1026
+ this.currentWalletIds = {};
1027
+ this.#supportedWalletTypes = void 0;
1028
+ this.#supportedWalletTypesOpt = void 0;
1029
+ this.localStorageGetItem = (key) => {
1030
+ return this.platformUtils.localStorage.get(key);
1031
+ };
1032
+ this.localStorageSetItem = (key, value) => {
1033
+ return this.platformUtils.localStorage.set(key, value);
1034
+ };
1035
+ this.sessionStorageGetItem = (key) => {
1036
+ return this.platformUtils.sessionStorage.get(key);
1037
+ };
1038
+ this.sessionStorageSetItem = (key, value) => {
1039
+ return this.platformUtils.sessionStorage.set(key, value);
1040
+ };
1041
+ this.sessionStorageRemoveItem = (key) => {
1042
+ return this.platformUtils.sessionStorage.removeItem(key);
1043
+ };
1044
+ this.retrieveSessionCookie = () => {
1045
+ return this.sessionCookie;
1046
+ };
1047
+ /**
1048
+ * Remove all local storage and prefixed session storage.
1049
+ * @param {'local' | 'session' | 'secure' | 'all'} type - Type of storage to clear. Defaults to 'all'.
1050
+ */
1051
+ this.clearStorage = async (type = "all") => {
1052
+ const isAll = type === "all";
1053
+ (isAll || type === "local") && this.platformUtils.localStorage.clear(PREFIX);
1054
+ (isAll || type === "session") && this.platformUtils.sessionStorage.clear(PREFIX);
1055
+ if ((isAll || type === "secure") && this.platformUtils.secureStorage) {
1056
+ this.platformUtils.secureStorage.clear(PREFIX);
1057
+ }
1058
+ };
1059
+ this.initializeFromStorage = () => {
1060
+ this.updateEmailFromStorage();
1061
+ this.updateCountryCodeFromStorage();
1062
+ this.updatePhoneFromStorage();
1063
+ this.updateUserIdFromStorage();
1064
+ this.updateTelegramUserIdFromStorage();
1065
+ this.updateWalletsFromStorage();
1066
+ this.updateWalletIdsFromStorage();
1067
+ this.updateSessionCookieFromStorage();
1068
+ this.updateLoginEncryptionKeyPairFromStorage();
1069
+ this.updateExternalWalletsFromStorage();
1070
+ this.updateCurrentExternalWalletAddressesFromStorage();
1071
+ };
1072
+ this.updateTelegramUserIdFromStorage = () => {
1073
+ this.telegramUserId = this.localStorageGetItem(LOCAL_STORAGE_TELEGRAM_USER_ID) || void 0;
1074
+ };
1075
+ this.updateUserIdFromStorage = () => {
1076
+ this.userId = this.localStorageGetItem(LOCAL_STORAGE_USER_ID) || void 0;
1077
+ };
1078
+ this.updatePhoneFromStorage = () => {
1079
+ this.phone = this.localStorageGetItem(LOCAL_STORAGE_PHONE) || void 0;
1080
+ };
1081
+ this.updateCountryCodeFromStorage = () => {
1082
+ this.countryCode = this.localStorageGetItem(LOCAL_STORAGE_COUNTRY_CODE) || void 0;
1083
+ };
1084
+ this.updateEmailFromStorage = () => {
1085
+ this.email = this.localStorageGetItem(LOCAL_STORAGE_EMAIL) || void 0;
1086
+ };
1087
+ this.updateWalletsFromStorage = async () => {
1088
+ const _currentWalletIds = this.localStorageGetItem(LOCAL_STORAGE_CURRENT_WALLET_IDS) ?? void 0;
1089
+ const currentWalletIds = [void 0, null, "undefined"].includes(_currentWalletIds) ? {} : (() => {
1090
+ const fromJson = JSON.parse(_currentWalletIds);
1091
+ return Array.isArray(fromJson) ? Object.keys(WalletType2).reduce((acc, type) => {
1092
+ const wallet = Object.values(this.wallets).find(
1093
+ (w) => fromJson.includes(w.id) && WalletSchemeTypeMap[w.scheme][type]
1094
+ );
1095
+ return {
1096
+ ...acc,
1097
+ ...wallet && !acc[type] ? { [type]: [wallet.id] } : {}
1098
+ };
1099
+ }, {}) : fromJson;
1100
+ })();
1101
+ this.setCurrentWalletIds(currentWalletIds);
1102
+ const stringWallets = this.platformUtils.secureStorage ? this.platformUtils.secureStorage.get(LOCAL_STORAGE_WALLETS) : this.localStorageGetItem(LOCAL_STORAGE_WALLETS);
1103
+ const _wallets = JSON.parse(stringWallets || "{}");
1104
+ const stringEd25519Wallets = this.platformUtils.secureStorage ? this.platformUtils.secureStorage.get(LOCAL_STORAGE_ED25519_WALLETS) : this.localStorageGetItem(LOCAL_STORAGE_ED25519_WALLETS);
1105
+ const _ed25519Wallets = JSON.parse(stringEd25519Wallets || "{}");
1106
+ const wallets = {
1107
+ ...Object.keys(_wallets).reduce((res, key) => {
1108
+ return {
1109
+ ...res,
1110
+ [key]: migrateWallet(_wallets[key])
1111
+ };
1112
+ }, {}),
1113
+ ...Object.keys(_ed25519Wallets).reduce((res, key) => {
1114
+ return {
1115
+ ...res,
1116
+ ...!res[key] ? { [key]: migrateWallet(_ed25519Wallets[key]) } : {}
1117
+ };
1118
+ }, {})
1119
+ };
1120
+ this.setWallets(wallets);
1121
+ };
1122
+ this.updateWalletIdsFromStorage = () => {
1123
+ const _currentWalletIds = this.localStorageGetItem(LOCAL_STORAGE_CURRENT_WALLET_IDS) ?? void 0;
1124
+ const currentWalletIds = [void 0, null, "undefined"].includes(_currentWalletIds) ? {} : (() => {
1125
+ const fromJson = JSON.parse(_currentWalletIds);
1126
+ return Array.isArray(fromJson) ? Object.keys(WalletType2).reduce((acc, type) => {
1127
+ const wallet = Object.values(this.wallets).find(
1128
+ (w) => fromJson.includes(w.id) && WalletSchemeTypeMap[w.scheme][type]
1129
+ );
1130
+ return {
1131
+ ...acc,
1132
+ ...wallet && !acc[type] ? { [type]: [wallet.id] } : {}
1133
+ };
1134
+ }, {}) : fromJson;
1135
+ })();
1136
+ this.setCurrentWalletIds(currentWalletIds);
1137
+ if (Object.values(this.wallets).filter((w) => this.isWalletOwned(w)).length > 0 && this.currentWalletIdsArray.length === 0) {
1138
+ this.findWalletId(void 0, { forbidPregen: true });
1139
+ }
1140
+ };
1141
+ this.updateSessionCookieFromStorage = () => {
1142
+ this.sessionCookie = this.localStorageGetItem(LOCAL_STORAGE_SESSION_COOKIE) || this.sessionStorageGetItem(LOCAL_STORAGE_SESSION_COOKIE) || void 0;
1143
+ };
1144
+ this.updateLoginEncryptionKeyPairFromStorage = () => {
1145
+ const loginEncryptionKey = this.sessionStorageGetItem(SESSION_STORAGE_LOGIN_ENCRYPTION_KEY_PAIR);
1146
+ if (loginEncryptionKey && loginEncryptionKey !== "undefined") {
1147
+ this.loginEncryptionKeyPair = this.convertEncryptionKeyPair(JSON.parse(loginEncryptionKey));
1148
+ }
1149
+ };
1150
+ this.updateExternalWalletsFromStorage = () => {
1151
+ const stringExternalWallets = this.localStorageGetItem(LOCAL_STORAGE_EXTERNAL_WALLETS);
1152
+ const _externalWallets = JSON.parse(stringExternalWallets || "{}");
1153
+ this.setExternalWallets(_externalWallets);
1154
+ };
1155
+ this.updateCurrentExternalWalletAddressesFromStorage = () => {
1156
+ const _currentExternalWalletAddresses = this.localStorageGetItem(LOCAL_STORAGE_CURRENT_EXTERNAL_WALLET_ADDRESSES) || void 0;
1157
+ this.currentExternalWalletAddresses = _currentExternalWalletAddresses ? JSON.parse(_currentExternalWalletAddresses) : void 0;
1158
+ };
1159
+ /**
1160
+ * Creates several new wallets with the desired types. If no types are provided, this method
1161
+ * will create one for each of the non-optional types specified in the instance's `supportedWalletTypes`
1162
+ * object that are not already present. This is automatically called upon account creation to ensure that
1163
+ * the user has a wallet of each required type.
1164
+ *
1165
+ * @deprecated alias for `createWalletPerType`
1166
+ **/
1167
+ this.createWalletPerMissingType = this.createWalletPerType;
1168
+ if (!opts) opts = {};
1169
+ this.emailPrimaryColor = opts.emailPrimaryColor;
1170
+ this.emailTheme = opts.emailTheme;
1171
+ this.homepageUrl = opts.homepageUrl;
1172
+ this.supportUrl = opts.supportUrl;
1173
+ this.xUrl = opts.xUrl;
1174
+ this.githubUrl = opts.githubUrl;
1175
+ this.linkedinUrl = opts.linkedinUrl;
1176
+ this.portalBackgroundColor = opts.portalBackgroundColor;
1177
+ this.portalPrimaryButtonColor = opts.portalPrimaryButtonColor;
1178
+ this.portalTextColor = opts.portalTextColor;
1179
+ this.portalPrimaryButtonTextColor = opts.portalPrimaryButtonTextColor;
1180
+ this.portalTheme = opts.portalTheme;
1181
+ this.platformUtils = this.getPlatformUtils();
1182
+ this.disableProviderModal = this.platformUtils.disableProviderModal;
1183
+ if (opts.useStorageOverrides) {
1184
+ this.localStorageGetItem = opts.localStorageGetItemOverride;
1185
+ this.localStorageSetItem = opts.localStorageSetItemOverride;
1186
+ this.sessionStorageGetItem = opts.sessionStorageGetItemOverride;
1187
+ this.sessionStorageSetItem = opts.sessionStorageSetItemOverride;
1188
+ this.sessionStorageRemoveItem = opts.sessionStorageRemoveItemOverride;
1189
+ this.clearStorage = opts.clearStorageOverride;
1190
+ }
1191
+ if (opts.useSessionStorage) {
1192
+ this.localStorageGetItem = this.sessionStorageGetItem;
1193
+ this.localStorageSetItem = this.sessionStorageSetItem;
1194
+ }
1195
+ this.persistSessionCookie = (cookie) => {
1196
+ this.sessionCookie = cookie;
1197
+ (opts.useSessionStorage ? this.sessionStorageSetItem : this.localStorageSetItem)(
1198
+ LOCAL_STORAGE_SESSION_COOKIE,
1199
+ cookie
1200
+ );
1201
+ };
1202
+ this.ctx = {
1203
+ env,
1204
+ apiKey,
1205
+ client: initClient({
1206
+ env,
1207
+ version: _ParaCore.version,
1208
+ apiKey,
1209
+ partnerId: this.isPortal(env) ? opts.portalPartnerId : void 0,
1210
+ useFetchAdapter: !!opts.disableWorkers,
1211
+ retrieveSessionCookie: this.retrieveSessionCookie,
1212
+ persistSessionCookie: this.persistSessionCookie
1213
+ }),
1214
+ disableWorkers: opts.disableWorkers,
1215
+ offloadMPCComputationURL: opts.offloadMPCComputationURL,
1216
+ useLocalFiles: opts.useLocalFiles,
1217
+ useDKLS: opts.useDKLSForCreation || !opts.offloadMPCComputationURL,
1218
+ disableWebSockets: !!opts.disableWebSockets,
1219
+ wasmOverride: opts.wasmOverride,
1220
+ cosmosPrefix: this.cosmosPrefix
1221
+ };
1222
+ if (opts.offloadMPCComputationURL) {
1223
+ this.ctx.mpcComputationClient = initClient2(opts.offloadMPCComputationURL, opts.disableWorkers);
1224
+ }
1225
+ try {
1226
+ this.#supportedWalletTypes = opts.supportedWalletTypes ? (() => {
1227
+ if (Object.values(opts.supportedWalletTypes).every(
1228
+ (config) => !!config && typeof config === "object" && config.optional
1229
+ )) {
1230
+ throw new Error("at least one wallet type must be non-optional");
1231
+ }
1232
+ if (!Object.keys(opts.supportedWalletTypes).every((type) => Object.values(WalletType2).includes(type))) {
1233
+ throw new Error("unsupported wallet type");
1234
+ }
1235
+ this.#supportedWalletTypesOpt = opts.supportedWalletTypes;
1236
+ return Object.entries(opts.supportedWalletTypes).reduce((acc, [key, value]) => {
1237
+ if (!value) {
1238
+ return acc;
1239
+ }
1240
+ if (key === WalletType2.COSMOS && typeof value === "object" && !!value.prefix) {
1241
+ this.cosmosPrefix = value.prefix;
1242
+ }
1243
+ return [...acc, { type: key, optional: value === true ? false : value.optional ?? false }];
1244
+ }, []);
1245
+ })() : void 0;
1246
+ } catch (e) {
1247
+ this.#supportedWalletTypes = void 0;
1248
+ }
1249
+ if (!this.platformUtils.isSyncStorage || opts.useStorageOverrides) {
1250
+ return;
1251
+ }
1252
+ this.initializeFromStorage();
1253
+ setupListeners.bind(this)();
1254
+ }
1255
+ static {
1256
+ this.version = PARA_CORE_VERSION;
1257
+ }
1258
+ get isEmail() {
1259
+ return !!this.email && !this.phone && !this.countryCode && !this.farcasterUsername && !this.telegramUserId;
1260
+ }
1261
+ get isPhone() {
1262
+ return !!this.phone && !!this.countryCode && !this.email && !this.farcasterUsername && !this.telegramUserId;
1263
+ }
1264
+ get isFarcaster() {
1265
+ return !!this.farcasterUsername && !this.email && !this.phone && !this.countryCode && !this.telegramUserId;
1266
+ }
1267
+ get isTelegram() {
1268
+ return !!this.telegramUserId && !this.email && !this.phone && !this.countryCode && !this.farcasterUsername;
1269
+ }
1270
+ get currentWalletIdsArray() {
1271
+ return this.supportedWalletTypes.reduce((acc, { type }) => {
1272
+ return [
1273
+ ...acc,
1274
+ ...(this.currentWalletIds[type] ?? []).map((id) => {
1275
+ return [id, type];
1276
+ })
1277
+ ];
1278
+ }, []);
1279
+ }
1280
+ get currentWalletIdsUnique() {
1281
+ return [...new Set(Object.values(this.currentWalletIds).flat())];
1282
+ }
1283
+ /**
1284
+ * A map of pre-generated wallet identifiers that can be claimed in the current instance.
1285
+ */
1286
+ get pregenIds() {
1287
+ return {
1288
+ ...Object.values(this.wallets).filter((wallet) => !this.userId || this.isPregenWalletClaimable(wallet)).reduce((acc, wallet) => {
1289
+ if ((acc[wallet.pregenIdentifierType] ?? []).includes(wallet.pregenIdentifier)) {
1290
+ return acc;
1291
+ }
1292
+ return {
1293
+ ...acc,
1294
+ [wallet.pregenIdentifierType]: [
1295
+ .../* @__PURE__ */ new Set([...acc[wallet.pregenIdentifierType] ?? [], wallet.pregenIdentifier])
1296
+ ]
1297
+ };
1298
+ }, {})
1299
+ };
1300
+ }
1301
+ /**
1302
+ * Whether the instance has multiple wallets connected.
1303
+ */
1304
+ get isMultiWallet() {
1305
+ return this.currentWalletIdsArray.length > 1;
1306
+ }
1307
+ #supportedWalletTypes;
1308
+ #supportedWalletTypesOpt;
1309
+ get supportedWalletTypes() {
1310
+ return this.#supportedWalletTypes ?? [];
1311
+ }
1312
+ get isWalletTypeEnabled() {
1313
+ return this.supportedWalletTypes.reduce((acc, { type }) => {
1314
+ return { ...acc, [type]: true };
1315
+ }, {});
1316
+ }
1317
+ convertBigInt(bigInt) {
1318
+ const convertedBigInt = new jsbn.BigInteger(null);
1319
+ convertedBigInt.data = bigInt.data;
1320
+ convertedBigInt.s = bigInt.s;
1321
+ convertedBigInt.t = bigInt.t;
1322
+ return convertedBigInt;
1323
+ }
1324
+ convertEncryptionKeyPair(jsonKeyPair) {
1325
+ return {
1326
+ privateKey: pki.setRsaPrivateKey(
1327
+ this.convertBigInt(jsonKeyPair.privateKey.n),
1328
+ this.convertBigInt(jsonKeyPair.privateKey.e),
1329
+ this.convertBigInt(jsonKeyPair.privateKey.d),
1330
+ this.convertBigInt(jsonKeyPair.privateKey.p),
1331
+ this.convertBigInt(jsonKeyPair.privateKey.q),
1332
+ this.convertBigInt(jsonKeyPair.privateKey.dP),
1333
+ this.convertBigInt(jsonKeyPair.privateKey.dQ),
1334
+ this.convertBigInt(jsonKeyPair.privateKey.qInv)
1335
+ ),
1336
+ publicKey: pki.setRsaPublicKey(
1337
+ this.convertBigInt(jsonKeyPair.publicKey.n),
1338
+ this.convertBigInt(jsonKeyPair.publicKey.e)
1339
+ )
1340
+ };
1341
+ }
1342
+ isPortal(envOverride) {
1343
+ if (typeof window === "undefined") return false;
1344
+ return !!window.location?.host && getPortalBaseURL(envOverride ? { env: envOverride } : this.ctx).includes(window.location.host);
1345
+ }
1346
+ isParaConnect() {
1347
+ if (typeof window === "undefined") return false;
1348
+ return !!window.location?.host && getParaConnectBaseUrl(this.ctx).includes(window.location.host);
1349
+ }
1350
+ requireApiKey() {
1351
+ if (!this.ctx.apiKey) {
1352
+ throw new Error(
1353
+ `in order to create a wallet or user with Para, you
1354
+ must provide an API key to the Para instance`
1355
+ );
1356
+ }
1357
+ }
1358
+ isWalletSupported(wallet) {
1359
+ return !this.#supportedWalletTypes || isWalletSupported(this.supportedWalletTypes.map(({ type }) => type) ?? [], wallet);
1360
+ }
1361
+ isWalletOwned(wallet) {
1362
+ return this.isWalletSupported(wallet) && !wallet.pregenIdentifier && !wallet.pregenIdentifierType && !!this.userId && wallet.userId === this.userId;
1363
+ }
1364
+ isPregenWalletUnclaimed(wallet) {
1365
+ return this.isWalletSupported(wallet) && (!wallet.userId || wallet.isPregen && !!wallet.pregenIdentifier && !!wallet.pregenIdentifierType);
1366
+ }
1367
+ isPregenWalletClaimable(wallet) {
1368
+ return this.isWalletSupported(wallet) && this.isPregenWalletUnclaimed(wallet) && (!["EMAIL", "PHONE", "TELEGRAM"].includes(wallet.pregenIdentifierType) || isPregenIdentifierMatch(
1369
+ wallet.pregenIdentifierType === "EMAIL" ? this.email : wallet.pregenIdentifierType === "TELEGRAM" ? this.telegramUserId : this.getPhoneNumber(),
1370
+ wallet.pregenIdentifier,
1371
+ wallet.pregenIdentifierType
1372
+ ));
1373
+ }
1374
+ isWalletUsable(walletId, { type: types, scheme: schemes, forbidPregen = false } = {}, throwError = false) {
1375
+ let error;
1376
+ if (!this.wallets[walletId]) {
1377
+ error = `wallet with id ${walletId} does not exist`;
1378
+ } else {
1379
+ const wallet = this.wallets[walletId];
1380
+ const [isUnclaimed, isOwned] = [this.isPregenWalletUnclaimed(wallet), this.isWalletOwned(wallet)];
1381
+ if (forbidPregen && isUnclaimed) {
1382
+ error = `pre-generated wallet with id ${wallet.id} cannot be selected`;
1383
+ } else if (!isOwned && !isUnclaimed) {
1384
+ error = `wallet with id ${wallet.id} is not owned by the current user`;
1385
+ } else if (!this.isWalletSupported(wallet)) {
1386
+ error = `wallet with id ${wallet.id} and type ${wallet.type} is not supported, supported types are: ${this.supportedWalletTypes.map(({ type }) => type).join(", ")}`;
1387
+ } else if (types && (!getEquivalentTypes(types).includes(wallet.type) || isOwned && !types.some((type) => this.currentWalletIds?.[type]?.includes(walletId)))) {
1388
+ error = `wallet with id ${wallet.id} and type ${wallet.type} cannot be selected`;
1389
+ } else if (schemes && !schemes.includes(wallet.scheme)) {
1390
+ error = `wallet with id ${wallet.id} and scheme ${wallet.scheme} cannot be selected`;
1391
+ }
1392
+ }
1393
+ if (error) {
1394
+ if (throwError) {
1395
+ throw new Error(error);
1396
+ }
1397
+ return false;
1398
+ }
1399
+ return true;
1400
+ }
1401
+ /**
1402
+ * Returns the formatted address for the desired wallet ID, depending on your app settings.
1403
+ * @param {string} walletId the ID of the wallet address to display.
1404
+ * @param {object} options additional options for formatting the address.
1405
+ * @param {boolean} options.truncate whether to truncate the address.
1406
+ * @param {WalletType} options.addressType the type of address to display.
1407
+ * @returns the formatted address
1408
+ */
1409
+ getDisplayAddress(walletId, options = {}) {
1410
+ if (this.externalWallets[walletId]) {
1411
+ const wallet2 = this.externalWallets[walletId];
1412
+ return options.truncate ? truncateAddress(wallet2.address, wallet2.type, { prefix: this.cosmosPrefix }) : wallet2.address;
1413
+ }
1414
+ const wallet = this.findWallet(walletId, options.addressType);
1415
+ if (!wallet) {
1416
+ return void 0;
1417
+ }
1418
+ let str;
1419
+ switch (wallet.type) {
1420
+ case WalletType2.COSMOS:
1421
+ str = getCosmosAddress(wallet.publicKey, this.cosmosPrefix ?? "cosmos");
1422
+ break;
1423
+ default:
1424
+ str = wallet.address;
1425
+ break;
1426
+ }
1427
+ return options.truncate ? truncateAddress(str, wallet.type, { prefix: this.cosmosPrefix }) : str;
1428
+ }
1429
+ /**
1430
+ * Returns a unique hash for a wallet suitable for use as an identicon seed.
1431
+ * @param {string} walletId the ID of the wallet.
1432
+ * @param {boolean} options.addressType used to format the hash for another wallet type.
1433
+ * @returns the identicon hash string
1434
+ */
1435
+ getIdenticonHash(walletId, overrideType) {
1436
+ if (this.externalWallets[walletId]) {
1437
+ const wallet2 = this.externalWallets[walletId];
1438
+ return `${wallet2.id}-${wallet2.address}-${wallet2.type}`;
1439
+ }
1440
+ const wallet = this.findWallet(walletId, overrideType);
1441
+ return wallet ? `${wallet.id}-${wallet.address}-${wallet.type}` : void 0;
1442
+ }
1443
+ getWallets() {
1444
+ return this.wallets;
1445
+ }
1446
+ getAddress(walletId) {
1447
+ return walletId ? this.wallets[walletId].address : Object.values(this.wallets)?.[0]?.address;
1448
+ }
1449
+ async constructPortalUrl(type, opts = {}) {
1450
+ const base = type === "onRamp" ? getPortalBaseURL(this.ctx) : await this.getPortalURL(opts.partnerId);
1451
+ let path;
1452
+ switch (type) {
1453
+ case "createPassword": {
1454
+ path = `/web/users/${this.userId}/passwords/${opts.pathId}`;
1455
+ break;
1456
+ }
1457
+ case "createAuth": {
1458
+ path = `/web/users/${this.userId}/biometrics/${opts.pathId}`;
1459
+ break;
1460
+ }
1461
+ case "loginPassword": {
1462
+ path = "/web/passwords/login";
1463
+ break;
1464
+ }
1465
+ case "loginAuth": {
1466
+ path = "/web/biometrics/login";
1467
+ break;
1468
+ }
1469
+ case "txReview": {
1470
+ path = `/web/users/${this.userId}/transaction-review/${opts.pathId}`;
1471
+ break;
1472
+ }
1473
+ case "onRamp": {
1474
+ path = `/web/users/${this.userId}/on-ramp-transaction/${opts.pathId}`;
1475
+ break;
1476
+ }
1477
+ default: {
1478
+ throw new Error(`invalid URL type ${type}`);
1479
+ }
1480
+ }
1481
+ const [isCreate, isLogin, isOnRamp] = [
1482
+ ["createAuth", "createPassword"].includes(type),
1483
+ ["loginAuth", "loginPassword"].includes(type),
1484
+ type === "onRamp"
1485
+ ];
1486
+ const partner = opts.partnerId ? (await this.ctx.client.getPartner(opts.partnerId)).data?.partner : void 0;
1487
+ const params = {
1488
+ apiKey: this.ctx.apiKey,
1489
+ partnerId: opts.partnerId,
1490
+ portalFont: opts.theme?.font || partner?.font || this.portalTheme?.font,
1491
+ portalBorderRadius: opts.theme?.borderRadius || this.portalTheme?.borderRadius,
1492
+ portalThemeMode: opts.theme?.mode || partner?.themeMode || this.portalTheme?.mode,
1493
+ portalAccentColor: opts.theme?.accentColor || partner?.accentColor || this.portalTheme?.accentColor,
1494
+ portalForegroundColor: opts.theme?.foregroundColor || partner?.foregroundColor || this.portalTheme?.foregroundColor,
1495
+ portalBackgroundColor: opts.theme?.backgroundColor || partner?.backgroundColor || this.portalBackgroundColor || this.portalTheme?.backgroundColor,
1496
+ portalPrimaryButtonColor: this.portalPrimaryButtonColor,
1497
+ portalTextColor: this.portalTextColor,
1498
+ portalPrimaryButtonTextColor: this.portalPrimaryButtonTextColor,
1499
+ isForNewDevice: opts.isForNewDevice ? opts.isForNewDevice.toString() : void 0,
1500
+ supportedWalletTypes: this.#supportedWalletTypesOpt ? JSON.stringify(this.#supportedWalletTypesOpt) : void 0,
1501
+ ...isCreate || isLogin ? {
1502
+ ...opts.authType === "email" ? { email: this.email } : {},
1503
+ ...opts.authType === "phone" ? { phone: this.phone, countryCode: this.countryCode } : {},
1504
+ ...opts.authType === "farcaster" ? { farcasterUsername: this.farcasterUsername } : {},
1505
+ ...opts.authType === "telegram" ? { telegramUserId: this.telegramUserId } : {}
1506
+ } : {},
1507
+ ...isLogin || isOnRamp ? { sessionId: opts.sessionId } : {},
1508
+ ...isLogin ? {
1509
+ encryptionKey: opts.loginEncryptionPublicKey,
1510
+ newDeviceSessionLookupId: opts.newDeviceSessionId,
1511
+ newDeviceEncryptionKey: opts.newDeviceEncryptionKey,
1512
+ pregenIds: JSON.stringify(this.pregenIds),
1513
+ displayName: opts.displayName,
1514
+ pfpUrl: opts.pfpUrl
1515
+ } : {},
1516
+ ...opts.params || {}
1517
+ };
1518
+ return constructUrl({ base, path, params });
1519
+ }
1520
+ async touchSession(regenerate = false) {
1521
+ const res = await this.ctx.client.touchSession(regenerate);
1522
+ this.setSupportedWalletTypes(res.data.supportedWalletTypes, res.data.cosmosPrefix);
1523
+ return res;
1524
+ }
1525
+ setSupportedWalletTypes(supportedWalletTypes, cosmosPrefix) {
1526
+ if (supportedWalletTypes && !this.#supportedWalletTypes) {
1527
+ this.#supportedWalletTypes = supportedWalletTypes;
1528
+ Object.keys(this.currentWalletIds).forEach((type) => {
1529
+ if (!this.#supportedWalletTypes?.some(({ type: supportedType }) => supportedType === type)) {
1530
+ delete this.currentWalletIds[type];
1531
+ }
1532
+ });
1533
+ }
1534
+ if (cosmosPrefix && !this.cosmosPrefix) {
1535
+ this.cosmosPrefix = cosmosPrefix;
1536
+ }
1537
+ }
1538
+ getVerificationEmailProps() {
1539
+ return {
1540
+ brandColor: this.emailPrimaryColor,
1541
+ theme: this.emailTheme,
1542
+ supportUrl: this.supportUrl,
1543
+ homepageUrl: this.homepageUrl,
1544
+ xUrl: this.xUrl,
1545
+ githubUrl: this.githubUrl,
1546
+ linkedinUrl: this.linkedinUrl
1547
+ };
1548
+ }
1549
+ getBackupKitEmailProps() {
1550
+ return {
1551
+ brandColor: this.emailPrimaryColor,
1552
+ theme: this.emailTheme,
1553
+ homepageUrl: this.homepageUrl,
1554
+ xUrl: this.xUrl,
1555
+ linkedinUrl: this.linkedinUrl,
1556
+ githubUrl: this.githubUrl,
1557
+ supportUrl: this.supportUrl
1558
+ };
1559
+ }
1560
+ /**
1561
+ * Initialize storage relating to a `ParaCore` instance.
1562
+ *
1563
+ * Init only needs to be called for storage that is async.
1564
+ */
1565
+ async init() {
1566
+ this.email = await this.localStorageGetItem(LOCAL_STORAGE_EMAIL) || void 0;
1567
+ this.countryCode = await this.localStorageGetItem(LOCAL_STORAGE_COUNTRY_CODE) || void 0;
1568
+ this.phone = await this.localStorageGetItem(LOCAL_STORAGE_PHONE) || void 0;
1569
+ this.userId = await this.localStorageGetItem(LOCAL_STORAGE_USER_ID) || void 0;
1570
+ this.telegramUserId = await this.localStorageGetItem(LOCAL_STORAGE_TELEGRAM_USER_ID) || void 0;
1571
+ const stringWallets = this.platformUtils.secureStorage ? await this.platformUtils.secureStorage.get(LOCAL_STORAGE_WALLETS) : await this.localStorageGetItem(LOCAL_STORAGE_WALLETS);
1572
+ const _wallets = JSON.parse(stringWallets || "{}");
1573
+ const stringEd25519Wallets = this.platformUtils.secureStorage ? await this.platformUtils.secureStorage.get(LOCAL_STORAGE_ED25519_WALLETS) : await this.localStorageGetItem(LOCAL_STORAGE_ED25519_WALLETS);
1574
+ const _ed25519Wallets = JSON.parse(stringEd25519Wallets || "{}");
1575
+ const wallets = {
1576
+ ...Object.keys(_wallets).reduce((res, key) => {
1577
+ return {
1578
+ ...res,
1579
+ [key]: migrateWallet(_wallets[key])
1580
+ };
1581
+ }, {}),
1582
+ ...Object.keys(_ed25519Wallets).reduce((res, key) => {
1583
+ return {
1584
+ ...res,
1585
+ ...!res[key] ? { [key]: migrateWallet(_ed25519Wallets[key]) } : {}
1586
+ };
1587
+ }, {})
1588
+ };
1589
+ await this.setWallets(wallets);
1590
+ const _currentWalletIds = await this.localStorageGetItem(LOCAL_STORAGE_CURRENT_WALLET_IDS) ?? void 0;
1591
+ const currentWalletIds = [void 0, null, "undefined", "null"].includes(_currentWalletIds) ? {} : (() => {
1592
+ const fromJson = JSON.parse(_currentWalletIds);
1593
+ return Array.isArray(fromJson) ? Object.keys(WalletType2).reduce((acc, type) => {
1594
+ const wallet = Object.values(this.wallets).find(
1595
+ (w) => fromJson.includes(w.id) && WalletSchemeTypeMap[w.scheme][type]
1596
+ );
1597
+ return {
1598
+ ...acc,
1599
+ ...wallet && !acc[type] ? { [type]: [wallet.id] } : {}
1600
+ };
1601
+ }, {}) : fromJson;
1602
+ })();
1603
+ await this.setCurrentWalletIds(currentWalletIds);
1604
+ this.sessionCookie = await this.localStorageGetItem(LOCAL_STORAGE_SESSION_COOKIE) || await this.sessionStorageGetItem(LOCAL_STORAGE_SESSION_COOKIE) || void 0;
1605
+ if (Object.values(this.wallets).filter((w) => this.isWalletOwned(w)).length > 0 && this.currentWalletIdsArray.length === 0) {
1606
+ this.findWalletId(void 0, { forbidPregen: true });
1607
+ }
1608
+ const loginEncryptionKey = await this.sessionStorageGetItem(SESSION_STORAGE_LOGIN_ENCRYPTION_KEY_PAIR);
1609
+ if (loginEncryptionKey && loginEncryptionKey !== "undefined") {
1610
+ this.loginEncryptionKeyPair = this.convertEncryptionKeyPair(JSON.parse(loginEncryptionKey));
1611
+ }
1612
+ const stringExternalWallets = await this.localStorageGetItem(LOCAL_STORAGE_EXTERNAL_WALLETS);
1613
+ const _externalWallets = JSON.parse(stringExternalWallets || "{}");
1614
+ await this.setExternalWallets(_externalWallets);
1615
+ const _currentExternalWalletAddresses = await this.localStorageGetItem(LOCAL_STORAGE_CURRENT_EXTERNAL_WALLET_ADDRESSES) || void 0;
1616
+ this.currentExternalWalletAddresses = _currentExternalWalletAddresses ? JSON.parse(_currentExternalWalletAddresses) : void 0;
1617
+ setupListeners.bind(this)();
1618
+ await this.touchSession();
1619
+ }
1620
+ /**
1621
+ * Sets the email associated with the `ParaCore` instance.
1622
+ * @param email - Email to set.
1623
+ */
1624
+ async setEmail(email) {
1625
+ this.email = email;
1626
+ await this.localStorageSetItem(LOCAL_STORAGE_EMAIL, email);
1627
+ }
1628
+ /**
1629
+ * Sets the Telegram user ID associated with the `ParaCore` instance.
1630
+ * @param telegramUserId - Telegram user ID to set.
1631
+ */
1632
+ async setTelegramUserId(telegramUserId) {
1633
+ this.telegramUserId = telegramUserId;
1634
+ await this.localStorageSetItem(LOCAL_STORAGE_TELEGRAM_USER_ID, telegramUserId);
1635
+ }
1636
+ /**
1637
+ * Sets the phone number associated with the `ParaCore` instance.
1638
+ * @param phone - Phone number to set.
1639
+ * @param countryCode - Country Code to set.
1640
+ */
1641
+ async setPhoneNumber(phone, countryCode) {
1642
+ this.phone = phone;
1643
+ this.countryCode = countryCode;
1644
+ await this.localStorageSetItem(LOCAL_STORAGE_PHONE, phone);
1645
+ await this.localStorageSetItem(LOCAL_STORAGE_COUNTRY_CODE, countryCode);
1646
+ }
1647
+ /**
1648
+ * Sets the farcaster username associated with the `ParaCore` instance.
1649
+ * @param farcasterUsername - Farcaster Username to set.
1650
+ */
1651
+ async setFarcasterUsername(farcasterUsername) {
1652
+ this.farcasterUsername = farcasterUsername;
1653
+ await this.localStorageSetItem(LOCAL_STORAGE_FARCASTER_USERNAME, farcasterUsername);
1654
+ }
1655
+ /**
1656
+ * Sets the external wallet address and type associated with the `ParaCore` instance.
1657
+ * @param externalAddress - External wallet address to set.
1658
+ * @param externalType - Type of external wallet to set.
1659
+ */
1660
+ async setExternalWallet({ address, type, provider, addressBech32 }) {
1661
+ this.externalWallets = {
1662
+ [address]: {
1663
+ id: address,
1664
+ address: addressBech32 ?? address,
1665
+ type,
1666
+ name: provider,
1667
+ isExternal: true,
1668
+ signer: ""
1669
+ }
1670
+ };
1671
+ this.currentExternalWalletAddresses = [address];
1672
+ this.setCurrentExternalWalletAddresses(this.currentExternalWalletAddresses);
1673
+ this.setExternalWallets(this.externalWallets);
1674
+ dispatchEvent(ParaEvent.EXTERNAL_WALLET_CHANGE_EVENT, null);
1675
+ }
1676
+ /**
1677
+ * Sets the user id associated with the `ParaCore` instance.
1678
+ * @param userId - User id to set.
1679
+ */
1680
+ async setUserId(userId) {
1681
+ this.userId = userId;
1682
+ await this.localStorageSetItem(LOCAL_STORAGE_USER_ID, userId);
1683
+ }
1684
+ /**
1685
+ * Sets the wallets associated with the `ParaCore` instance.
1686
+ * @param wallets - Wallets to set.
1687
+ */
1688
+ async setWallets(wallets) {
1689
+ this.wallets = wallets;
1690
+ if (this.platformUtils.secureStorage) {
1691
+ await this.platformUtils.secureStorage.set(LOCAL_STORAGE_WALLETS, JSON.stringify(wallets));
1692
+ return;
1693
+ }
1694
+ await this.localStorageSetItem(LOCAL_STORAGE_WALLETS, JSON.stringify(wallets));
1695
+ }
1696
+ /**
1697
+ * Sets the external wallets associated with the `ParaCore` instance.
1698
+ * @param externalWallets - External wallets to set.
1699
+ */
1700
+ async setExternalWallets(externalWallets) {
1701
+ this.externalWallets = externalWallets;
1702
+ await this.localStorageSetItem(LOCAL_STORAGE_EXTERNAL_WALLETS, JSON.stringify(externalWallets));
1703
+ }
1704
+ async setCurrentExternalWalletAddresses(currentExternalWalletAddresses) {
1705
+ this.currentExternalWalletAddresses = currentExternalWalletAddresses;
1706
+ await this.localStorageSetItem(
1707
+ LOCAL_STORAGE_CURRENT_EXTERNAL_WALLET_ADDRESSES,
1708
+ JSON.stringify(currentExternalWalletAddresses)
1709
+ );
1710
+ }
1711
+ /**
1712
+ * Sets the login encryption key pair associated with the `ParaCore` instance.
1713
+ * @param keyPair - Encryption key pair generated from loginEncryptionKey.
1714
+ */
1715
+ async setLoginEncryptionKeyPair(keyPair) {
1716
+ if (!keyPair) {
1717
+ keyPair = await getAsymmetricKeyPair(this.ctx);
1718
+ }
1719
+ this.loginEncryptionKeyPair = keyPair;
1720
+ await this.sessionStorageSetItem(SESSION_STORAGE_LOGIN_ENCRYPTION_KEY_PAIR, JSON.stringify(keyPair));
1721
+ }
1722
+ async deleteLoginEncryptionKeyPair() {
1723
+ this.loginEncryptionKeyPair = void 0;
1724
+ await this.sessionStorageRemoveItem(SESSION_STORAGE_LOGIN_ENCRYPTION_KEY_PAIR);
1725
+ }
1726
+ /**
1727
+ * Gets the userId associated with the `ParaCore` instance.
1728
+ * @returns - userId associated with the `ParaCore` instance.
1729
+ */
1730
+ getUserId() {
1731
+ return this.userId;
1732
+ }
1733
+ /**
1734
+ * Gets the email associated with the `ParaCore` instance.
1735
+ * @returns - email associated with the `ParaCore` instance.
1736
+ */
1737
+ getEmail() {
1738
+ return this.email;
1739
+ }
1740
+ /**
1741
+ * Gets the phone object associated with the `ParaCore` instance.
1742
+ * @returns - phone object with phone number and country code associated with the `ParaCore` instance.
1743
+ */
1744
+ getPhone() {
1745
+ return { phone: this.phone, countryCode: this.countryCode };
1746
+ }
1747
+ /**
1748
+ * Gets the formatted phone number associated with the `ParaCore` instance.
1749
+ * @returns - formatted phone number associated with the `ParaCore` instance.
1750
+ */
1751
+ getPhoneNumber() {
1752
+ if (!this.phone || !this.countryCode) {
1753
+ return void 0;
1754
+ }
1755
+ return normalizePhoneNumber(this.countryCode, this.phone);
1756
+ }
1757
+ /**
1758
+ * Gets the farcaster username associated with the `ParaCore` instance.
1759
+ * @returns - farcaster username associated with the `ParaCore` instance.
1760
+ */
1761
+ getFarcasterUsername() {
1762
+ return this.farcasterUsername;
1763
+ }
1764
+ async setCurrentWalletIds(currentWalletIds, {
1765
+ needsWallet = false,
1766
+ sessionLookupId,
1767
+ newDeviceSessionLookupId
1768
+ } = {}) {
1769
+ this.currentWalletIds = currentWalletIds;
1770
+ await this.localStorageSetItem(LOCAL_STORAGE_CURRENT_WALLET_IDS, JSON.stringify(this.currentWalletIds));
1771
+ if (sessionLookupId) {
1772
+ await this.ctx.client.setCurrentWalletIds(
1773
+ this.getUserId(),
1774
+ this.currentWalletIds,
1775
+ needsWallet,
1776
+ sessionLookupId,
1777
+ newDeviceSessionLookupId
1778
+ );
1779
+ }
1780
+ dispatchEvent(ParaEvent.WALLETS_CHANGE_EVENT, null);
1781
+ }
1782
+ /**
1783
+ * Validates that a wallet ID is present on the instance, usable, and matches the desired filters.
1784
+ * If no ID is passed, this will instead return the first valid, usable wallet ID that matches the filters.
1785
+ * @param {string} [walletId] the wallet ID to validate.
1786
+ * @param {WalletFilters} [filter={}] a `WalletFilters` object specifying allowed types, schemes, and whether to forbid unclaimed pregen wallets.
1787
+ * @returns {string} the wallet ID originally passed, or the one found.
1788
+ */
1789
+ findWalletId(walletId, filter = {}) {
1790
+ if (walletId) {
1791
+ this.assertIsValidWalletId(walletId, filter);
1792
+ } else {
1793
+ for (const id of [...this.currentWalletIdsUnique, ...Object.keys(this.wallets)]) {
1794
+ if (this.isWalletUsable(id, filter)) {
1795
+ walletId = id;
1796
+ break;
1797
+ }
1798
+ }
1799
+ if (!walletId) {
1800
+ throw new Error(`no valid wallet id found`);
1801
+ }
1802
+ }
1803
+ return walletId;
1804
+ }
1805
+ /**
1806
+ * Retrieves a wallet with the given address, if present.
1807
+ * If no ID is passed, this will instead return the first valid, usable wallet ID that matches the filters.
1808
+ * @param {string} [walletId] the wallet ID to validate.
1809
+ * @param {WalletFilters} [filter={}] a `WalletFilters` object specifying allowed types, schemes, and whether to forbid unclaimed pregen wallets.
1810
+ * @returns {string} the wallet ID originally passed, or the one found.
1811
+ */
1812
+ findWalletByAddress(address, filter) {
1813
+ if (this.externalWallets[address]) {
1814
+ return this.externalWallets[address];
1815
+ }
1816
+ let wallet;
1817
+ Object.entries(this.currentWalletIds).forEach(([type, walletIds]) => {
1818
+ const pregenWalletIds = Object.keys(this.wallets).filter(
1819
+ (id) => this.wallets[id].type === type && this.isPregenWalletClaimable(this.wallets[id])
1820
+ );
1821
+ [...walletIds, ...pregenWalletIds].forEach((id) => {
1822
+ if (address.toLowerCase() === this.getDisplayAddress(id, { addressType: type }).toLowerCase()) {
1823
+ wallet = this.wallets[id];
1824
+ }
1825
+ });
1826
+ });
1827
+ if (!wallet) {
1828
+ throw new Error(`wallet with address ${address} not found`);
1829
+ }
1830
+ this.assertIsValidWalletId(wallet.id, filter);
1831
+ return wallet;
1832
+ }
1833
+ findWallet(idOrAddress, overrideType, filter = {}) {
1834
+ if (!idOrAddress && Object.keys(this.externalWallets).length > 0) {
1835
+ return Object.values(this.externalWallets)[0];
1836
+ }
1837
+ if (this.externalWallets[idOrAddress]) {
1838
+ return this.externalWallets[idOrAddress];
1839
+ }
1840
+ try {
1841
+ const walletId = this.findWalletId(idOrAddress, filter);
1842
+ if (walletId && !!this.wallets[walletId]) {
1843
+ const { signer: _signer, ...wallet } = this.wallets[walletId];
1844
+ const type = overrideType ?? this.currentWalletIdsArray.find(([id]) => id === walletId)?.[1] ?? wallet.type;
1845
+ return {
1846
+ ...wallet,
1847
+ type: WalletType2[type]
1848
+ };
1849
+ }
1850
+ } catch (e) {
1851
+ return void 0;
1852
+ }
1853
+ }
1854
+ get availableWallets() {
1855
+ return [
1856
+ ...this.currentWalletIdsArray.map(([address, type]) => [address, type, false]).map(([id, type]) => {
1857
+ const wallet = this.findWallet(id, type);
1858
+ if (!wallet) return null;
1859
+ return {
1860
+ id: wallet.id,
1861
+ type,
1862
+ address: this.getDisplayAddress(id, { addressType: type }),
1863
+ name: wallet.name
1864
+ };
1865
+ }).filter((obj) => obj !== null),
1866
+ ...Object.values(this.externalWallets ?? {})
1867
+ ];
1868
+ }
1869
+ /**
1870
+ * Retrieves all usable wallets with the provided type (`'EVM' | 'COSMOS' | 'SOLANA'`)
1871
+ * @param {string} type the wallet type to filter by.
1872
+ * @returns {Wallet[]} an array of matching wallets.
1873
+ */
1874
+ getWalletsByType(type) {
1875
+ return Object.values(this.wallets).filter((w) => this.isWalletUsable(w.id, { type: [type] }));
1876
+ }
1877
+ assertIsValidWalletId(walletId, condition = {}) {
1878
+ this.isWalletUsable(walletId, condition, true);
1879
+ }
1880
+ async assertIsValidWalletType(type, walletTypes) {
1881
+ if (!this.#supportedWalletTypes) {
1882
+ await this.touchSession();
1883
+ }
1884
+ if (!type || !Object.values(WalletType2).includes(type) || !(walletTypes ?? this.supportedWalletTypes.map(({ type: type2 }) => type2)).includes(type)) {
1885
+ throw new Error(`wallet type ${type} is not supported`);
1886
+ }
1887
+ return type;
1888
+ }
1889
+ async getMissingTypes() {
1890
+ if (!this.#supportedWalletTypes) {
1891
+ await this.touchSession();
1892
+ }
1893
+ return this.supportedWalletTypes.filter(
1894
+ ({ type: t, optional }) => !optional && Object.values(this.wallets).every((w) => !this.isWalletOwned(w) || !WalletSchemeTypeMap[w.scheme][t])
1895
+ ).map(({ type }) => type);
1896
+ }
1897
+ async getTypesToCreate(types) {
1898
+ if (!this.#supportedWalletTypes) {
1899
+ await this.touchSession();
1900
+ }
1901
+ return getSchemes(types ?? await this.getMissingTypes()).map((scheme) => {
1902
+ switch (scheme) {
1903
+ case WalletScheme2.ED25519:
1904
+ return WalletType2.SOLANA;
1905
+ default:
1906
+ return this.supportedWalletTypes.some(({ type, optional }) => type === WalletType2.COSMOS && !optional) ? WalletType2.COSMOS : WalletType2.EVM;
1907
+ }
1908
+ });
1909
+ }
1910
+ async getPartnerURL(partnerId) {
1911
+ const res = await this.ctx.client.getPartner(partnerId);
1912
+ return res.data.partner.portalUrl;
1913
+ }
1914
+ /**
1915
+ * URL of the portal, which can be associated with a partner id
1916
+ * @param partnerId: string - id of the partner to get the portal URL for
1917
+ * @returns - portal URL
1918
+ */
1919
+ async getPortalURL(partnerId) {
1920
+ return partnerId && await this.getPartnerURL(partnerId) || getPortalBaseURL(this.ctx);
1921
+ }
1922
+ async getWebAuthURLForCreate({
1923
+ webAuthId,
1924
+ ...options
1925
+ }) {
1926
+ return this.constructPortalUrl("createAuth", { ...options, pathId: webAuthId });
1927
+ }
1928
+ async getPasswordURLForCreate({
1929
+ passwordId,
1930
+ ...options
1931
+ }) {
1932
+ return this.constructPortalUrl("createPassword", {
1933
+ ...options,
1934
+ pathId: passwordId
1935
+ });
1936
+ }
1937
+ getShortUrl(compressedUrl) {
1938
+ return constructUrl({
1939
+ base: getPortalBaseURL(this.ctx),
1940
+ path: `/short/${compressedUrl}`
1941
+ });
1942
+ }
1943
+ async shortenLoginLink(link) {
1944
+ const url = await upload(link, this.ctx.client);
1945
+ return this.getShortUrl(url);
1946
+ }
1947
+ /**
1948
+ * Generates a URL for registering a new WebAuth passkey.
1949
+ * @param {GetWebAuthUrlForLoginParams} opts the options object
1950
+ * @returns - the URL for creating a new passkey
1951
+ */
1952
+ async getWebAuthURLForLogin(opts) {
1953
+ return this.constructPortalUrl("loginAuth", opts);
1954
+ }
1955
+ /**
1956
+ * Generates a URL for registering a new user password.
1957
+ * @param {GetWebAuthUrlForLoginParams} opts the options object
1958
+ * @returns - the URL for creating a new password
1959
+ */
1960
+ async getPasswordURLForLogin(opts) {
1961
+ return this.constructPortalUrl("loginPassword", opts);
1962
+ }
1963
+ /**
1964
+ * Generates a URL for registering a new WebAuth passkey for a phone number.
1965
+ * @param {Omit<GetWebAuthUrlForLoginParams, 'authType'>} opts the options object
1966
+ * @returns - web auth url
1967
+ */
1968
+ async getWebAuthURLForLoginForPhone(opts) {
1969
+ return this.constructPortalUrl("loginAuth", {
1970
+ authType: "phone",
1971
+ ...opts
1972
+ });
1973
+ }
1974
+ /**
1975
+ * Gets the private key for the given wallet.
1976
+ * @param {string } [walletId] id of the wallet to get the private key for. Will default to the first wallet if not provided.
1977
+ * @returns - the private key string.
1978
+ */
1979
+ async getPrivateKey(walletId) {
1980
+ const wallets = Object.values(this.wallets);
1981
+ const wallet = walletId ? this.wallets[walletId] : wallets?.[0];
1982
+ if (!wallet) {
1983
+ throw new Error("wallet not found");
1984
+ }
1985
+ if (wallet.scheme !== WalletScheme2.DKLS) {
1986
+ throw new Error("invalid wallet scheme");
1987
+ }
1988
+ return await this.platformUtils.getPrivateKey(
1989
+ this.ctx,
1990
+ this.userId,
1991
+ wallet.id,
1992
+ wallet.signer,
1993
+ this.retrieveSessionCookie()
1994
+ );
1995
+ }
1996
+ /**
1997
+ * Fetches the wallets associated with the user.
1998
+ * @returns {WalletEntity[]} wallets that were fetched.
1999
+ */
2000
+ async fetchWallets() {
2001
+ const res = await (this.isPortal() || this.isParaConnect() ? this.ctx.client.getAllWallets(this.userId) : this.ctx.client.getWallets(this.userId, true));
2002
+ return res.data.wallets.filter(
2003
+ (wallet) => !!wallet.address && (this.isParaConnect() || !this.isParaConnect() && this.isWalletSupported(entityToWallet(wallet)))
2004
+ );
2005
+ }
2006
+ async populateWalletAddresses() {
2007
+ const res = await this.ctx.client.getWallets(this.userId, true);
2008
+ const wallets = res.data.wallets;
2009
+ wallets.forEach((entity) => {
2010
+ if (this.wallets[entity.id]) {
2011
+ this.wallets[entity.id] = {
2012
+ ...entityToWallet(entity),
2013
+ ...this.wallets[entity.id]
2014
+ };
2015
+ }
2016
+ });
2017
+ await this.setWallets(this.wallets);
2018
+ }
2019
+ async populatePregenWalletAddresses() {
2020
+ const res = await this.getPregenWallets();
2021
+ res.forEach((entity) => {
2022
+ if (this.wallets[entity.id]) {
2023
+ this.wallets[entity.id] = {
2024
+ ...entityToWallet(entity),
2025
+ ...this.wallets[entity.id]
2026
+ };
2027
+ }
2028
+ });
2029
+ await this.setWallets(this.wallets);
2030
+ }
2031
+ /**
2032
+ * Checks if a user exists for an email address.
2033
+ * @param {Object} opts the options object
2034
+ * @param {string} opts.email the email to check.
2035
+ * @returns true if user exists, false otherwise.
2036
+ */
2037
+ async checkIfUserExists({ email }) {
2038
+ const res = await this.ctx.client.checkUserExists({ email });
2039
+ return res.data.exists;
2040
+ }
2041
+ /**
2042
+ * Checks if a user exists for a phone number.
2043
+ * @param {Object} opts the options object
2044
+ * @param {string} opts.phone - phone number to check.
2045
+ * @param {string} opts.countryCode - the country code.
2046
+ * @returns true if user exists, false otherwise.
2047
+ */
2048
+ async checkIfUserExistsByPhone({ phone, countryCode }) {
2049
+ const res = await this.ctx.client.checkUserExists({ phone, countryCode });
2050
+ return res.data.exists;
2051
+ }
2052
+ /**
2053
+ * Creates a new user.
2054
+ * @param {Object} opts the options object
2055
+ * @param {string} opts.email the email to use.
2056
+ */
2057
+ async createUser({ email }) {
2058
+ this.requireApiKey();
2059
+ await this.setEmail(email);
2060
+ const { userId } = await this.ctx.client.createUser({
2061
+ email: this.email,
2062
+ ...this.getVerificationEmailProps()
2063
+ });
2064
+ await this.setUserId(userId);
2065
+ }
2066
+ /**
2067
+ * Creates a new user with a phone number.
2068
+ * @param {Object} opts the options object
2069
+ * @param {string} opts.phone - the phone number to use for creating the user.
2070
+ * @param {string} opts.countryCode - the country code to use for creating the user.
2071
+ */
2072
+ async createUserByPhone({ phone, countryCode }) {
2073
+ this.requireApiKey();
2074
+ await this.setPhoneNumber(phone, countryCode);
2075
+ const { userId } = await this.ctx.client.createUser({
2076
+ phone: this.phone,
2077
+ countryCode: this.countryCode
2078
+ });
2079
+ await this.setUserId(userId);
2080
+ }
2081
+ /**
2082
+ * Logs in or creates a new user using an external wallet address.
2083
+ * @param {Object} opts the options object
2084
+ * @param {string} opts.address the external wallet address to use for identification.
2085
+ * @param {WalletType} opts.type type of external wallet to use for identification.
2086
+ * @param {string} opts.provider the name of the provider for the external wallet.
2087
+ */
2088
+ async externalWalletLogin(wallet) {
2089
+ this.requireApiKey();
2090
+ const res = await this.ctx.client.externalWalletLogin({
2091
+ externalAddress: wallet.address,
2092
+ type: wallet.type,
2093
+ externalWalletProvider: wallet.provider,
2094
+ shouldTrackUser: wallet.shouldTrackUser
2095
+ });
2096
+ await this.setExternalWallet(wallet);
2097
+ await this.setUserId(res.userId);
2098
+ return res;
2099
+ }
2100
+ /**
2101
+ * Returns whether or not the user is connected with an external wallet.
2102
+ */
2103
+ isUsingExternalWallet() {
2104
+ return !!Object.keys(this.externalWallets).length;
2105
+ }
2106
+ /**
2107
+ * Passes the email code obtained from the user for verification.
2108
+ * @param {Object} opts the options object
2109
+ * @param {string} verificationCode the six-digit code to check
2110
+ * @returns {string} the web auth url for creating a new credential
2111
+ */
2112
+ async verifyEmail({ verificationCode }) {
2113
+ await this.ctx.client.verifyEmail(this.userId, { verificationCode });
2114
+ return this.getSetUpBiometricsURL();
2115
+ }
2116
+ async verifyExternalWallet({
2117
+ address,
2118
+ signedMessage,
2119
+ cosmosPublicKeyHex,
2120
+ cosmosSigner
2121
+ }) {
2122
+ await this.ctx.client.verifyExternalWallet(this.userId, { address, signedMessage, cosmosPublicKeyHex, cosmosSigner });
2123
+ return this.getSetUpBiometricsURL();
2124
+ }
2125
+ /**
2126
+ * Passes the phone code obtained from the user for verification.
2127
+ * @param {Object} opts the options object
2128
+ * @param {string} verificationCode the six-digit code to check
2129
+ * @returns {string} the web auth url for creating a new credential
2130
+ */
2131
+ async verifyPhone({ verificationCode }) {
2132
+ await this.ctx.client.verifyPhone(this.userId, { verificationCode });
2133
+ return this.getSetUpBiometricsURLForPhone();
2134
+ }
2135
+ /**
2136
+ * Validates the response received from an attempted Telegram login for authenticity, then
2137
+ * creates or retrieves the corresponding Para user and prepares the Para instance to sign in with that user.
2138
+ * @param authResponse - the response JSON object received from the Telegram widget.
2139
+ * @returns `{ isValid: boolean; telegramUserId?: string; userId?: string; isNewUser?: boolean; supportedAuthMethods?: AuthMethod[]; biometricHints?: BiometricLocationHint[] }`
2140
+ */
2141
+ async verifyTelegram(authObject) {
2142
+ const res = await this.ctx.client.verifyTelegram(authObject);
2143
+ if (res.isValid) {
2144
+ await this.setUserId(res.userId);
2145
+ await this.setTelegramUserId(res.telegramUserId);
2146
+ await this.touchSession(true);
2147
+ if (!this.loginEncryptionKeyPair) {
2148
+ await this.setLoginEncryptionKeyPair();
2149
+ }
2150
+ }
2151
+ return res;
2152
+ }
2153
+ /**
2154
+ * Performs 2FA verification.
2155
+ * @param {Object} opts the options object
2156
+ * @param {string} opts.email the email to use for performing a 2FA verification.
2157
+ * @param {string} opts.verificationCode the verification code to received via 2FA.
2158
+ * @returns {Object} `{ address, initiatedAt, status, userId, walletId }`
2159
+ */
2160
+ async verify2FA({ email, verificationCode }) {
2161
+ const res = await this.ctx.client.verify2FA(email, verificationCode);
2162
+ return {
2163
+ initiatedAt: res.data.initiatedAt,
2164
+ status: res.data.status,
2165
+ userId: res.data.userId,
2166
+ wallets: res.data.wallets
2167
+ };
2168
+ }
2169
+ /**
2170
+ * Performs 2FA verification.
2171
+ * @param {Object} opts the options object
2172
+ * @param {string} opts.phone the phone number
2173
+ * @param {string} opts.countryCode - the country code
2174
+ * @param {string} opts.verificationCode - verification code to received via 2FA.
2175
+ * @returns {Object} `{ address, initiatedAt, status, userId, walletId }`
2176
+ */
2177
+ async verify2FAForPhone({
2178
+ phone,
2179
+ countryCode,
2180
+ verificationCode
2181
+ }) {
2182
+ const res = await this.ctx.client.verify2FAForPhone(phone, countryCode, verificationCode);
2183
+ return {
2184
+ initiatedAt: res.data.initiatedAt,
2185
+ status: res.data.status,
2186
+ userId: res.data.userId,
2187
+ wallets: res.data.wallets
2188
+ };
2189
+ }
2190
+ /**
2191
+ * Sets up two-factor authentication for the current user.
2192
+ * @returns {string} uri - uri to use for setting up 2FA
2193
+ * */
2194
+ async setup2FA() {
2195
+ const res = await this.ctx.client.setup2FA(this.userId);
2196
+ return {
2197
+ uri: res.data.uri
2198
+ };
2199
+ }
2200
+ /**
2201
+ * Enables 2FA.
2202
+ * @param {Object} opts the options object
2203
+ * @param {string} opts.verificationCode - the verification code received via 2FA.
2204
+ */
2205
+ async enable2FA({ verificationCode }) {
2206
+ await this.ctx.client.enable2FA(this.userId, verificationCode);
2207
+ }
2208
+ /**
2209
+ * Determines if 2FA has been set up.
2210
+ * @returns {Object} `{ isSetup: boolean }` - true if 2FA is setup, false otherwise
2211
+ */
2212
+ async check2FAStatus() {
2213
+ if (!this.userId) {
2214
+ return { isSetup: false };
2215
+ }
2216
+ const res = await this.ctx.client.check2FAStatus(this.userId);
2217
+ return {
2218
+ isSetup: res.data.isSetup
2219
+ };
2220
+ }
2221
+ /**
2222
+ * Resend a verification email for the current user.
2223
+ */
2224
+ async resendVerificationCode() {
2225
+ await this.ctx.client.resendVerificationCode({
2226
+ userId: this.userId,
2227
+ ...this.getVerificationEmailProps()
2228
+ });
2229
+ }
2230
+ /**
2231
+ * Resend a verification SMS for the current user.
2232
+ */
2233
+ async resendVerificationCodeByPhone() {
2234
+ await this.ctx.client.resendVerificationCodeByPhone({
2235
+ userId: this.userId
2236
+ });
2237
+ }
2238
+ /**
2239
+ * Returns a URL for setting up a new WebAuth passkey.
2240
+ * @param {Object} opts the options object
2241
+ * @param {string} opts.authType - the auth type to use
2242
+ * @param {boolean} opts.isForNewDevice whether the passkey is for a new device of an existing user
2243
+ * @returns {string} the URL
2244
+ */
2245
+ async getSetUpBiometricsURL({
2246
+ authType = "email",
2247
+ isForNewDevice = false
2248
+ } = {}) {
2249
+ const res = await this.ctx.client.addSessionPublicKey(this.userId, {
2250
+ status: PublicKeyStatus.PENDING,
2251
+ type: PublicKeyType.WEB
2252
+ });
2253
+ return this.getWebAuthURLForCreate({
2254
+ authType,
2255
+ isForNewDevice,
2256
+ webAuthId: res.data.id,
2257
+ partnerId: res.data.partnerId
2258
+ });
2259
+ }
2260
+ /**
2261
+ * Returns a URL for setting up a new WebAuth passkey for a phone number.
2262
+ * @param {Object} opts the options object
2263
+ * @param {boolean} opts.isForNewDevice whether the passkey is for a new device of an existing user
2264
+ * @returns {string} the URL
2265
+ */
2266
+ async getSetUpBiometricsURLForPhone({
2267
+ isForNewDevice = false
2268
+ } = {}) {
2269
+ const res = await this.ctx.client.addSessionPublicKey(this.userId, {
2270
+ status: PublicKeyStatus.PENDING,
2271
+ type: PublicKeyType.WEB
2272
+ });
2273
+ return this.getWebAuthURLForCreate({
2274
+ authType: "phone",
2275
+ isForNewDevice,
2276
+ webAuthId: res.data.id,
2277
+ partnerId: res.data.partnerId
2278
+ });
2279
+ }
2280
+ /**
2281
+ * Returns a URL for setting up a new password.
2282
+ * @param {Object} opts the options object
2283
+ * @param {string} opts.authType - the auth type to use
2284
+ * @param {boolean} opts.isForNewDevice whether the passkey is for a new device of an existing user
2285
+ * @param {Theme} [opts.theme] the portal theme to use in place of the partner's default
2286
+ * @returns {string} the URL
2287
+ */
2288
+ async getSetupPasswordURL({
2289
+ authType = "email",
2290
+ isForNewDevice = false,
2291
+ theme
2292
+ } = {}) {
2293
+ const res = await this.ctx.client.addSessionPasswordPublicKey(this.userId, {
2294
+ status: PasswordStatus.PENDING
2295
+ });
2296
+ return this.getPasswordURLForCreate({
2297
+ authType,
2298
+ isForNewDevice,
2299
+ passwordId: res.data.id,
2300
+ partnerId: res.data.partnerId,
2301
+ theme
2302
+ });
2303
+ }
2304
+ /**
2305
+ * Checks if the current session is active.
2306
+ * @returns `true` if active, `false` otherwise
2307
+ */
2308
+ async isSessionActive() {
2309
+ if (this.isUsingExternalWallet()) {
2310
+ return true;
2311
+ }
2312
+ const res = await this.touchSession();
2313
+ return !!res.data.isAuthenticated;
2314
+ }
2315
+ /**
2316
+ * Checks if a session is active and a wallet exists.
2317
+ * @returns `true` if active, `false` otherwise
2318
+ **/
2319
+ async isFullyLoggedIn() {
2320
+ if (this.isUsingExternalWallet()) {
2321
+ return true;
2322
+ }
2323
+ const isSessionActive = await this.isSessionActive();
2324
+ return isSessionActive && this.currentWalletIdsArray.length > 0 && this.currentWalletIdsArray.reduce((acc, [id]) => acc && !!this.wallets[id], true);
2325
+ }
2326
+ async supportedAuthMethods(auth) {
2327
+ const { supportedAuthMethods } = await this.ctx.client.getSupportedAuthMethods(auth);
2328
+ const authMethods = /* @__PURE__ */ new Set();
2329
+ for (const type of supportedAuthMethods) {
2330
+ switch (type) {
2331
+ case "PASSWORD":
2332
+ authMethods.add(AuthMethod.PASSWORD);
2333
+ break;
2334
+ case "BIOMETRIC":
2335
+ authMethods.add(AuthMethod.PASSKEY);
2336
+ break;
2337
+ }
2338
+ }
2339
+ return authMethods;
2340
+ }
2341
+ /**
2342
+ * Get hints associated with the users stored biometrics.
2343
+ * @returns Array containing useragents and AAGuids for stored biometrics
2344
+ */
2345
+ async getUserBiometricLocationHints() {
2346
+ if (!this.email && !this.phone && !this.farcasterUsername && !this.telegramUserId) {
2347
+ throw new Error("one of email, phone or farcaster username are required to get biometric location hints");
2348
+ }
2349
+ return await this.ctx.client.getBiometricLocationHints({
2350
+ email: this.email,
2351
+ phone: this.phone,
2352
+ countryCode: this.countryCode,
2353
+ farcasterUsername: this.farcasterUsername,
2354
+ telegramUserId: this.telegramUserId
2355
+ });
2356
+ }
2357
+ async setAuth(auth) {
2358
+ const authInfo = extractAuthInfo(auth);
2359
+ if (!authInfo) {
2360
+ return void 0;
2361
+ }
2362
+ switch (authInfo.authType) {
2363
+ case "email":
2364
+ await this.setEmail(authInfo.identifier);
2365
+ break;
2366
+ case "phone":
2367
+ await this.setPhoneNumber(authInfo.auth.phone, authInfo.auth.countryCode);
2368
+ break;
2369
+ case "farcaster":
2370
+ await this.setFarcasterUsername(authInfo.identifier);
2371
+ break;
2372
+ case "telegram":
2373
+ await this.setTelegramUserId(authInfo.identifier);
2374
+ break;
2375
+ }
2376
+ return authInfo;
2377
+ }
2378
+ /**
2379
+ * Initiates a login.
2380
+ * @param {Object} opts the options object
2381
+ * @param {String} opts.email - the email to login with
2382
+ * @param {boolean} opts.useShortURL - whether to shorten the link
2383
+ * @returns - the WebAuth URL for logging in
2384
+ **/
2385
+ async initiateUserLogin({ useShortUrl = false, ...auth }) {
2386
+ const authInfo = await this.setAuth(auth);
2387
+ if (!authInfo) {
2388
+ return;
2389
+ }
2390
+ const res = await this.touchSession(true);
2391
+ if (!this.loginEncryptionKeyPair) {
2392
+ await this.setLoginEncryptionKeyPair();
2393
+ }
2394
+ const webAuthLoginURL = await this.getWebAuthURLForLogin({
2395
+ authType: authInfo.authType,
2396
+ sessionId: res.data.sessionId,
2397
+ partnerId: res.data.partnerId,
2398
+ loginEncryptionPublicKey: getPublicKeyHex(this.loginEncryptionKeyPair)
2399
+ });
2400
+ if (!useShortUrl) {
2401
+ return webAuthLoginURL;
2402
+ }
2403
+ return this.shortenLoginLink(webAuthLoginURL);
2404
+ }
2405
+ /**
2406
+ * Initiates a login.
2407
+ * @param email - the email to login with
2408
+ * @returns - a set of supported auth methods for the user
2409
+ **/
2410
+ async initiateUserLoginV2(auth) {
2411
+ const authInfo = await this.setAuth(auth);
2412
+ if (!authInfo) {
2413
+ return;
2414
+ }
2415
+ await this.touchSession(true);
2416
+ if (!this.loginEncryptionKeyPair) {
2417
+ await this.setLoginEncryptionKeyPair();
2418
+ }
2419
+ return await this.supportedAuthMethods(authInfo.auth);
2420
+ }
2421
+ /**
2422
+ * Initiates a login.
2423
+ * @param opts the options object
2424
+ * @param opts.phone the phone number
2425
+ * @param opts.countryCode the country code
2426
+ * @param opts.useShortURL - whether to shorten the link
2427
+ * @returns - the WebAuth URL for logging in
2428
+ **/
2429
+ async initiateUserLoginForPhone({
2430
+ useShortUrl = false,
2431
+ ...auth
2432
+ }) {
2433
+ await this.setAuth(auth);
2434
+ const res = await this.touchSession(true);
2435
+ if (!this.loginEncryptionKeyPair) {
2436
+ await this.setLoginEncryptionKeyPair();
2437
+ }
2438
+ const webAuthLoginURL = await this.getWebAuthURLForLoginForPhone({
2439
+ sessionId: res.data.sessionId,
2440
+ loginEncryptionPublicKey: getPublicKeyHex(this.loginEncryptionKeyPair),
2441
+ partnerId: res.data.partnerId
2442
+ });
2443
+ if (!useShortUrl) {
2444
+ return webAuthLoginURL;
2445
+ }
2446
+ return this.shortenLoginLink(webAuthLoginURL);
2447
+ }
2448
+ /**
2449
+ * Waits for the session to be active.
2450
+ **/
2451
+ async waitForAccountCreation({ popupWindow } = {}) {
2452
+ await this.touchSession();
2453
+ this.currentExternalWalletAddresses = void 0;
2454
+ this.externalWallets = {};
2455
+ this.isAwaitingAccountCreation = true;
2456
+ while (this.isAwaitingAccountCreation) {
2457
+ try {
2458
+ await new Promise((resolve) => setTimeout(resolve, POLLING_INTERVAL_MS));
2459
+ if (await this.isSessionActive()) {
2460
+ this.isAwaitingAccountCreation = false;
2461
+ dispatchEvent(ParaEvent.ACCOUNT_CREATION_EVENT, true);
2462
+ return true;
2463
+ } else {
2464
+ if (popupWindow?.closed) {
2465
+ this.isAwaitingAccountCreation = false;
2466
+ return false;
2467
+ }
2468
+ }
2469
+ } catch (err) {
2470
+ console.error(err);
2471
+ }
2472
+ }
2473
+ return false;
2474
+ }
2475
+ async waitForPasskeyAndCreateWallet({
2476
+ popupWindow
2477
+ } = {}) {
2478
+ await this.waitForAccountCreation({ popupWindow });
2479
+ const pregenWallets = await this.getPregenWallets();
2480
+ let recoverySecret, walletIds = {};
2481
+ if (pregenWallets.length > 0) {
2482
+ recoverySecret = await this.claimPregenWallets();
2483
+ walletIds = this.supportedWalletTypes.reduce((acc, { type }) => {
2484
+ return {
2485
+ ...acc,
2486
+ [type]: [pregenWallets.find((w) => !!WalletSchemeTypeMap[w.scheme][type])?.id]
2487
+ };
2488
+ }, {});
2489
+ }
2490
+ const created = await this.createWalletPerType();
2491
+ recoverySecret = recoverySecret ?? created.recoverySecret;
2492
+ walletIds = { ...walletIds, ...created.walletIds };
2493
+ const resp = { walletIds, recoverySecret };
2494
+ dispatchEvent(ParaEvent.ACCOUNT_SETUP_EVENT, resp);
2495
+ return resp;
2496
+ }
2497
+ /**
2498
+ * Initiates a Farcaster login attempt and return the URI for the user to connect.
2499
+ * You can create a QR code with this URI that works with Farcaster's mobile app.
2500
+ * @return {string} the Farcaster connect URI
2501
+ */
2502
+ async getFarcasterConnectURL() {
2503
+ await this.logout();
2504
+ await this.touchSession(true);
2505
+ const {
2506
+ data: { connect_uri }
2507
+ } = await this.ctx.client.initializeFarcasterLogin();
2508
+ return connect_uri;
2509
+ }
2510
+ /**
2511
+ * Awaits the response from a user's attempt to log in with Farcaster.
2512
+ * If successful, this returns the user's Farcaster username and profile picture and indicates whether the user already exists.
2513
+ * @return {Object} `{userExists: boolean; username: string; pfpUrl?: string | null }` - the user's information and whether the user already exists.
2514
+ */
2515
+ async waitForFarcasterStatus() {
2516
+ this.isAwaitingFarcaster = true;
2517
+ while (this.isAwaitingFarcaster) {
2518
+ try {
2519
+ await new Promise((resolve) => setTimeout(resolve, POLLING_INTERVAL_MS));
2520
+ const res = await this.ctx.client.getFarcasterAuthStatus();
2521
+ if (res.data.state === "completed") {
2522
+ const { userId, userExists, username, pfpUrl } = res.data;
2523
+ await this.setUserId(userId);
2524
+ await this.setFarcasterUsername(username);
2525
+ return {
2526
+ userExists,
2527
+ username,
2528
+ pfpUrl
2529
+ };
2530
+ }
2531
+ } catch (err) {
2532
+ console.error(err);
2533
+ this.isAwaitingFarcaster = false;
2534
+ }
2535
+ }
2536
+ }
2537
+ /**
2538
+ * Generates a URL for the user to log in with OAuth using a desire method.
2539
+ *
2540
+ * @param {Object} opts the options object
2541
+ * @param {OAuthMethod} opts.method the third-party service to use for OAuth.
2542
+ * @param {string} [opts.deeplinkUrl] the deeplink to redirect to after the OAuth flow. This is for mobile only.
2543
+ * @returns {string} the URL for the user to log in with OAuth.
2544
+ */
2545
+ async getOAuthURL({ method, deeplinkUrl }) {
2546
+ await this.logout();
2547
+ const res = await this.touchSession(true);
2548
+ return constructUrl({
2549
+ base: method === OAuthMethod.TELEGRAM ? getPortalBaseURL(this.ctx, true) : getBaseOAuthUrl(this.ctx.env),
2550
+ path: `/auth/${method.toLowerCase()}`,
2551
+ params: {
2552
+ apiKey: this.ctx.apiKey,
2553
+ sessionLookupId: res.data.sessionLookupId,
2554
+ deeplinkUrl
2555
+ }
2556
+ });
2557
+ }
2558
+ /**
2559
+ * Awaits the response from a user's attempt to log in with OAuth.
2560
+ * If successful, this returns the user's email address and indicates whether the user already exists.
2561
+ *
2562
+ * @param {Object} opts the options object.
2563
+ * @param {Window} [opts.popupWindow] the popup window being used for login.
2564
+ * @return {Object} `{ email?: string; isError?: boolean; userExists: boolean; }` the result data
2565
+ */
2566
+ async waitForOAuth({ popupWindow } = {}) {
2567
+ this.isAwaitingOAuth = true;
2568
+ while (this.isAwaitingOAuth) {
2569
+ try {
2570
+ if (popupWindow?.closed) {
2571
+ return { isError: true, userExists: false };
2572
+ }
2573
+ await new Promise((resolve) => setTimeout(resolve, POLLING_INTERVAL_MS));
2574
+ if (this.isAwaitingOAuth) {
2575
+ const res = await this.touchSession();
2576
+ if (res.data.userId) {
2577
+ const { userId, email } = res.data;
2578
+ if (!this.loginEncryptionKeyPair) {
2579
+ await this.setLoginEncryptionKeyPair();
2580
+ }
2581
+ await this.setUserId(userId);
2582
+ await this.setEmail(email);
2583
+ const userExists = await this.checkIfUserExists({ email });
2584
+ this.isAwaitingOAuth = false;
2585
+ return {
2586
+ userExists,
2587
+ email
2588
+ };
2589
+ }
2590
+ }
2591
+ } catch (err) {
2592
+ console.error(err);
2593
+ }
2594
+ }
2595
+ return { userExists: false };
2596
+ }
2597
+ /**
2598
+ * Waits for the session to be active and sets up the user.
2599
+ *
2600
+ * @param {Object} opts the options object
2601
+ * @param {Window} [opts.popupWindow] the popup window being used for login.
2602
+ * @param {boolean} [opts.skipSessionRefresh] whether to skip refreshing the session.
2603
+ * @returns {Object} `{ isComplete: boolean; isError: boolean; needsWallet: boolean; partnerId: string; }` the result data
2604
+ **/
2605
+ async waitForLoginAndSetup({
2606
+ popupWindow,
2607
+ skipSessionRefresh = false
2608
+ } = {}) {
2609
+ this.currentExternalWalletAddresses = void 0;
2610
+ this.externalWallets = {};
2611
+ this.isAwaitingLogin = true;
2612
+ while (this.isAwaitingLogin) {
2613
+ try {
2614
+ await new Promise((resolve) => setTimeout(resolve, POLLING_INTERVAL_MS));
2615
+ if (!await this.isSessionActive()) {
2616
+ if (popupWindow?.closed) {
2617
+ const resp2 = { isComplete: false, isError: true };
2618
+ dispatchEvent(ParaEvent.LOGIN_EVENT, resp2, "failed to setup user");
2619
+ return resp2;
2620
+ }
2621
+ continue;
2622
+ }
2623
+ const postLoginData = await this.userSetupAfterLogin();
2624
+ const needsWallet = postLoginData.data.needsWallet ?? false;
2625
+ if (!needsWallet) {
2626
+ if (this.currentWalletIdsArray.length === 0) {
2627
+ if (popupWindow?.closed) {
2628
+ const resp2 = { isComplete: false, isError: true };
2629
+ dispatchEvent(ParaEvent.LOGIN_EVENT, resp2, "failed to setup user");
2630
+ return resp2;
2631
+ } else {
2632
+ continue;
2633
+ }
2634
+ }
2635
+ }
2636
+ const fetchedWallets = await this.fetchWallets();
2637
+ const tempSharesRes = await this.getTransmissionKeyShares();
2638
+ if (tempSharesRes.data.temporaryShares.length === fetchedWallets.length) {
2639
+ await this.setupAfterLogin({ temporaryShares: tempSharesRes.data.temporaryShares, skipSessionRefresh });
2640
+ await this.claimPregenWallets();
2641
+ const resp2 = {
2642
+ isComplete: true,
2643
+ needsWallet: needsWallet || Object.values(this.wallets).length === 0,
2644
+ partnerId: postLoginData.data.partnerId
2645
+ };
2646
+ dispatchEvent(ParaEvent.LOGIN_EVENT, resp2);
2647
+ return resp2;
2648
+ }
2649
+ } catch (err) {
2650
+ console.error(err);
2651
+ }
2652
+ }
2653
+ const resp = { isComplete: false };
2654
+ dispatchEvent(ParaEvent.LOGIN_EVENT, resp, "exitted login without setting up user");
2655
+ return resp;
2656
+ }
2657
+ /**
2658
+ * Updates the session with the user management server, possibly
2659
+ * opening a popup to refresh the session.
2660
+ *
2661
+ * @param {Object} opts the options object.
2662
+ * @param {boolean} [shouldOpenPopup] - if `true`, the running device will open a popup to reauthenticate the user.
2663
+ * @returns a URL for the user to reauthenticate.
2664
+ **/
2665
+ async refreshSession({ shouldOpenPopup = false } = {}) {
2666
+ const res = await this.touchSession(true);
2667
+ if (!this.loginEncryptionKeyPair) {
2668
+ await this.setLoginEncryptionKeyPair();
2669
+ }
2670
+ const link = await this.getWebAuthURLForLogin({
2671
+ sessionId: res.data.sessionId,
2672
+ loginEncryptionPublicKey: getPublicKeyHex(this.loginEncryptionKeyPair)
2673
+ });
2674
+ if (shouldOpenPopup) {
2675
+ this.platformUtils.openPopup(link);
2676
+ }
2677
+ return link;
2678
+ }
2679
+ /**
2680
+ * Call this method after login to ensure that the user ID is set
2681
+ * internally.
2682
+ **/
2683
+ async userSetupAfterLogin() {
2684
+ const res = await this.touchSession();
2685
+ await this.setUserId(res.data.userId);
2686
+ if (res.data.currentWalletIds && res.data.currentWalletIds !== this.currentWalletIds)
2687
+ await this.setCurrentWalletIds(res.data.currentWalletIds, {
2688
+ sessionLookupId: this.isPortal() ? res.data.sessionLookupId : void 0
2689
+ });
2690
+ return res;
2691
+ }
2692
+ /**
2693
+ * Get transmission shares associated with session.
2694
+ * @param {Object} opts the options object.
2695
+ * @param {boolean} opts.isForNewDevice - true if this device is registering.
2696
+ * @returns - transmission keyshares.
2697
+ **/
2698
+ async getTransmissionKeyShares({ isForNewDevice = false } = {}) {
2699
+ const res = await this.touchSession();
2700
+ const sessionLookupId = isForNewDevice ? `${res.data.sessionLookupId}-new-device` : res.data.sessionLookupId;
2701
+ return this.ctx.client.getTransmissionKeyshares(this.userId, sessionLookupId);
2702
+ }
2703
+ /**
2704
+ * Call this method after login to perform setup.
2705
+ * @param {Object} opts the options object.
2706
+ * @param {any[]} opts.temporaryShares optional temporary shares to use for decryption.
2707
+ * @param {boolean} [opts.skipSessionRefresh] - whether or not to skip refreshing the session.
2708
+ **/
2709
+ async setupAfterLogin({
2710
+ temporaryShares,
2711
+ skipSessionRefresh = false
2712
+ } = {}) {
2713
+ if (!temporaryShares) {
2714
+ temporaryShares = (await this.getTransmissionKeyShares()).data.temporaryShares;
2715
+ }
2716
+ temporaryShares.forEach((share) => {
2717
+ const signer = decryptWithPrivateKey(this.loginEncryptionKeyPair.privateKey, share.encryptedShare, share.encryptedKey);
2718
+ this.wallets[share.walletId] = {
2719
+ id: share.walletId,
2720
+ signer
2721
+ };
2722
+ });
2723
+ await this.deleteLoginEncryptionKeyPair();
2724
+ await this.populateWalletAddresses();
2725
+ await this.touchSession(!skipSessionRefresh);
2726
+ }
2727
+ /**
2728
+ * Distributes a new wallet recovery share.
2729
+ * @param {Object} opts the options object.
2730
+ * @param {string} opts.walletId the wallet to distribute the recovery share for.
2731
+ * @param {string} opts.userShare optional user share generate the recovery share from. Defaults to the signer from the passed in walletId
2732
+ * @param {boolean} opts.skipBiometricShareCreation whether or not to skip biometric share creation. Used when regenerating recovery shares.
2733
+ * @param {boolean} opts.forceRefreshRecovery whether or not to force recovery secret regeneration. Used when regenerating recovery shares.
2734
+ * @returns {string} the recovery share.
2735
+ **/
2736
+ async distributeNewWalletShare({
2737
+ walletId,
2738
+ userShare,
2739
+ skipBiometricShareCreation = false,
2740
+ forceRefresh = false
2741
+ }) {
2742
+ let userSigner = userShare;
2743
+ if (!userSigner) {
2744
+ userSigner = this.wallets[walletId].signer;
2745
+ }
2746
+ const recoveryShare = skipBiometricShareCreation ? await sendRecoveryForShare({
2747
+ ctx: this.ctx,
2748
+ userId: this.userId,
2749
+ walletId,
2750
+ userSigner,
2751
+ emailProps: this.getBackupKitEmailProps(),
2752
+ forceRefresh
2753
+ }) : await distributeNewShare({
2754
+ ctx: this.ctx,
2755
+ userId: this.userId,
2756
+ walletId,
2757
+ userShare: userSigner,
2758
+ emailProps: this.getBackupKitEmailProps()
2759
+ });
2760
+ return recoveryShare;
2761
+ }
2762
+ async waitForWalletAddress(walletId) {
2763
+ let maxPolls = 0;
2764
+ while (true) {
2765
+ try {
2766
+ if (maxPolls === 10) {
2767
+ break;
2768
+ }
2769
+ ++maxPolls;
2770
+ const res = await this.ctx.client.getWallets(this.userId);
2771
+ const wallet = res.data.wallets.find((w) => w.id === walletId);
2772
+ if (wallet && wallet.address) {
2773
+ return;
2774
+ }
2775
+ await new Promise((resolve) => setTimeout(resolve, SHORT_POLLING_INTERVAL_MS));
2776
+ } catch (err) {
2777
+ console.error(err);
2778
+ }
2779
+ }
2780
+ throw new Error("timed out waiting for wallet address");
2781
+ }
2782
+ /**
2783
+ * Waits for a pregen wallet address to be created.
2784
+ *
2785
+ * @param pregenIdentifier - the identifier of the user the pregen wallet is associated with.
2786
+ * @param walletId - the wallet id
2787
+ * @param pregenIdentifierType - the identifier type of the user the pregen wallet is associated with.
2788
+ * @returns - recovery share.
2789
+ **/
2790
+ async waitForPregenWalletAddress(walletId) {
2791
+ let maxPolls = 0;
2792
+ while (true) {
2793
+ try {
2794
+ if (maxPolls === 10) {
2795
+ break;
2796
+ }
2797
+ ++maxPolls;
2798
+ const res = await this.getPregenWallets();
2799
+ const wallet = res.find((w) => w.id === walletId);
2800
+ if (wallet && wallet.address) {
2801
+ return;
2802
+ }
2803
+ await new Promise((resolve) => setTimeout(resolve, SHORT_POLLING_INTERVAL_MS));
2804
+ } catch (err) {
2805
+ console.error(err);
2806
+ }
2807
+ }
2808
+ throw new Error("timed out waiting for wallet address");
2809
+ }
2810
+ /**
2811
+ * Creates several new wallets with the desired types. If no types are provided, this method
2812
+ * will create one for each of the non-optional types specified in the instance's `supportedWalletTypes`
2813
+ * object that are not already present. This is automatically called upon account creation to ensure that
2814
+ * the user has a wallet of each required type.
2815
+ *
2816
+ * @param {Object} [opts] the options object.
2817
+ * @param {boolean} [opts.skipDistribute] if `true`, the wallets' recovery share will not be distributed.
2818
+ * @param {WalletType[]} [opts.types] the types of wallets to create.
2819
+ * @returns {Object} the wallets created, their ids, and the recovery secret.
2820
+ **/
2821
+ async createWalletPerType({
2822
+ skipDistribute = false,
2823
+ types
2824
+ } = {}) {
2825
+ const wallets = [];
2826
+ const walletIds = {};
2827
+ let recoverySecret;
2828
+ for (const type of await this.getTypesToCreate(types)) {
2829
+ const [wallet, recoveryShare] = await this.createWallet({ type, skipDistribute });
2830
+ wallets.push(wallet);
2831
+ getEquivalentTypes(type).filter((t) => !!this.isWalletTypeEnabled[t]).forEach((t) => {
2832
+ walletIds[t] = [wallet.id];
2833
+ });
2834
+ if (recoveryShare) {
2835
+ recoverySecret = recoveryShare;
2836
+ }
2837
+ }
2838
+ return { wallets, walletIds, recoverySecret };
2839
+ }
2840
+ /**
2841
+ * Refresh the current user share for a wallet.
2842
+ *
2843
+ * @param {Object} opts the options object.
2844
+ * @param {string} opts.walletId the wallet id to refresh.
2845
+ * @param {string} opts.share the current user share.
2846
+ * @param {string} [opts.oldPartnerId] the current partner id.
2847
+ * @param {string} [opts.newPartnerId] the new partner id to set, if any.
2848
+ * @param {string} [opts.keyShareProtocolId]
2849
+ * @param {boolean} [opts.redistributeBackupEncryptedShares] whether or not to redistribute backup encrypted shares.
2850
+ * @returns {Object} the new user share and recovery secret.
2851
+ **/
2852
+ async refreshShare({
2853
+ walletId,
2854
+ share,
2855
+ oldPartnerId,
2856
+ newPartnerId,
2857
+ keyShareProtocolId,
2858
+ redistributeBackupEncryptedShares
2859
+ }) {
2860
+ const { signer, protocolId } = await this.platformUtils.refresh(
2861
+ this.ctx,
2862
+ this.retrieveSessionCookie(),
2863
+ this.userId,
2864
+ walletId,
2865
+ share,
2866
+ oldPartnerId,
2867
+ newPartnerId,
2868
+ keyShareProtocolId
2869
+ );
2870
+ const recoverySecret = await distributeNewShare({
2871
+ ctx: this.ctx,
2872
+ userId: this.userId,
2873
+ walletId,
2874
+ userShare: signer,
2875
+ ignoreRedistributingBackupEncryptedShare: !redistributeBackupEncryptedShares,
2876
+ emailProps: this.getBackupKitEmailProps(),
2877
+ partnerId: newPartnerId,
2878
+ protocolId
2879
+ });
2880
+ return { signer, recoverySecret, protocolId };
2881
+ }
2882
+ /**
2883
+ * Creates a new wallet.
2884
+ * @param {Object} opts the options object.
2885
+ * @param {WalletType} opts.type the type of wallet to create.
2886
+ * @param {boolean} opts.skipDistribute - if true, recovery share will not be distributed.
2887
+ * @returns {[Wallet, string | null]} `[wallet, recoveryShare]` - the wallet object and the new recovery share.
2888
+ **/
2889
+ async createWallet({
2890
+ type: _type,
2891
+ skipDistribute = false
2892
+ } = {}) {
2893
+ this.requireApiKey();
2894
+ const walletType = await this.assertIsValidWalletType(
2895
+ _type ?? this.supportedWalletTypes.find(({ optional }) => !optional)?.type
2896
+ );
2897
+ let signer;
2898
+ let wallet;
2899
+ let keygenRes;
2900
+ switch (walletType) {
2901
+ case WalletType2.SOLANA: {
2902
+ keygenRes = await this.platformUtils.ed25519Keygen(
2903
+ this.ctx,
2904
+ this.userId,
2905
+ this.retrieveSessionCookie(),
2906
+ this.getBackupKitEmailProps()
2907
+ );
2908
+ break;
2909
+ }
2910
+ default: {
2911
+ keygenRes = await this.platformUtils.keygen(
2912
+ this.ctx,
2913
+ this.userId,
2914
+ walletType,
2915
+ null,
2916
+ this.retrieveSessionCookie(),
2917
+ this.getBackupKitEmailProps()
2918
+ );
2919
+ break;
2920
+ }
2921
+ }
2922
+ const walletId = keygenRes.walletId;
2923
+ signer = keygenRes.signer;
2924
+ this.wallets[walletId] = {
2925
+ id: walletId,
2926
+ signer,
2927
+ scheme: walletType === WalletType2.SOLANA ? WalletScheme2.ED25519 : WalletScheme2.DKLS,
2928
+ type: walletType
2929
+ };
2930
+ wallet = this.wallets[walletId];
2931
+ await this.waitForWalletAddress(wallet.id);
2932
+ await this.populateWalletAddresses();
2933
+ let recoveryShare = null;
2934
+ if (!skipDistribute) {
2935
+ recoveryShare = await distributeNewShare({
2936
+ ctx: this.ctx,
2937
+ userId: this.userId,
2938
+ walletId: wallet.id,
2939
+ userShare: signer,
2940
+ emailProps: this.getBackupKitEmailProps()
2941
+ });
2942
+ }
2943
+ await this.setCurrentWalletIds({
2944
+ ...this.currentWalletIds,
2945
+ [walletType]: [...this.currentWalletIds[walletType] ?? [], walletId]
2946
+ });
2947
+ const walletNoSigner = { ...wallet };
2948
+ delete walletNoSigner.signer;
2949
+ dispatchEvent(ParaEvent.WALLET_CREATED, {
2950
+ wallet: walletNoSigner,
2951
+ recoverySecret: recoveryShare
2952
+ });
2953
+ return [wallet, recoveryShare];
2954
+ }
2955
+ /**
2956
+ * Creates a new pregenerated wallet.
2957
+ *
2958
+ * @param {Object} opts the options object.
2959
+ * @param {string} opts.pregenIdentifier the identifier associated with the new wallet.
2960
+ * @param {TPregenIdentifierType} [opts.pregenIdentifierType] the identifier type. Defaults to `EMAIL`.
2961
+ * @param {WalletType} [opts.type] the type of wallet to create. Defaults to the first non-optional type in the instance's `supportedWalletTypes` array.
2962
+ * @returns {Wallet} the created wallet.
2963
+ **/
2964
+ async createPregenWallet(opts) {
2965
+ const {
2966
+ type: _type = this.supportedWalletTypes.find(({ optional }) => !optional)?.type,
2967
+ pregenIdentifier,
2968
+ pregenIdentifierType = "EMAIL"
2969
+ } = opts;
2970
+ this.requireApiKey();
2971
+ const walletType = await this.assertIsValidWalletType(
2972
+ _type ?? this.supportedWalletTypes.find(({ optional }) => !optional)?.type
2973
+ );
2974
+ let keygenRes;
2975
+ switch (walletType) {
2976
+ case WalletType2.SOLANA:
2977
+ keygenRes = await this.platformUtils.ed25519PreKeygen(
2978
+ this.ctx,
2979
+ pregenIdentifier,
2980
+ pregenIdentifierType,
2981
+ this.retrieveSessionCookie()
2982
+ );
2983
+ break;
2984
+ default:
2985
+ keygenRes = await this.platformUtils.preKeygen(
2986
+ this.ctx,
2987
+ void 0,
2988
+ pregenIdentifier,
2989
+ pregenIdentifierType,
2990
+ walletType,
2991
+ null,
2992
+ this.retrieveSessionCookie()
2993
+ );
2994
+ break;
2995
+ }
2996
+ const { signer, walletId } = keygenRes;
2997
+ this.wallets[walletId] = {
2998
+ id: walletId,
2999
+ signer,
3000
+ scheme: walletType === WalletType2.SOLANA ? WalletScheme2.ED25519 : WalletScheme2.DKLS,
3001
+ type: walletType,
3002
+ isPregen: true,
3003
+ pregenIdentifier,
3004
+ pregenIdentifierType
3005
+ };
3006
+ await this.waitForPregenWalletAddress(walletId);
3007
+ await this.populatePregenWalletAddresses();
3008
+ return this.wallets[walletId];
3009
+ }
3010
+ /**
3011
+ * Creates new pregenerated wallets for each desired type.
3012
+ * If no types are provided, this method will create one for each of the non-optional types
3013
+ * specified in the instance's `supportedWalletTypes` array that are not already present.
3014
+ * @param {Object} opts the options object.
3015
+ * @param {string} opts.pregenIdentifier the identifier to associate each wallet with.
3016
+ * @param {TPregenIdentifierType} opts.pregenIdentifierType - either `'EMAIL'` or `'PHONE'`.
3017
+ * @param {WalletType[]} [opts.types] the wallet types to create. Defaults to any types the instance supports that are not already present.
3018
+ * @returns {Wallet[]} an array containing the created wallets.
3019
+ **/
3020
+ async createPregenWalletPerType({
3021
+ types,
3022
+ pregenIdentifier,
3023
+ pregenIdentifierType = "EMAIL"
3024
+ }) {
3025
+ const wallets = [];
3026
+ for (const type of await this.getTypesToCreate(types)) {
3027
+ const wallet = await this.createPregenWallet({ type, pregenIdentifier, pregenIdentifierType });
3028
+ wallets.push(wallet);
3029
+ }
3030
+ return wallets;
3031
+ }
3032
+ /**
3033
+ * Claims a pregenerated wallet.
3034
+ *
3035
+ * @param {Object} opts the options object.
3036
+ * @param {string} opts.pregenIdentifier string the identifier of the user claiming the wallet
3037
+ * @param {TPregenIdentifierType} opts.pregenIdentifierType type of the identifier of the user claiming the wallet
3038
+ * @returns {[Wallet, string | null]} `[wallet, recoveryShare]` - the wallet object and the new recovery share.
3039
+ **/
3040
+ async claimPregenWallets({
3041
+ pregenIdentifier,
3042
+ pregenIdentifierType = !!pregenIdentifier ? "EMAIL" : void 0
3043
+ } = {}) {
3044
+ this.requireApiKey();
3045
+ const pregenWallets = pregenIdentifier && pregenIdentifierType ? await this.getPregenWallets({ pregenIdentifier, pregenIdentifierType }) : await this.getPregenWallets();
3046
+ if (pregenWallets.length === 0) {
3047
+ return void 0;
3048
+ }
3049
+ let newRecoverySecret;
3050
+ const { walletIds } = await this.ctx.client.claimPregenWallets({
3051
+ userId: this.userId,
3052
+ walletIds: pregenWallets.map((w) => w.id)
3053
+ });
3054
+ for (const walletId of walletIds) {
3055
+ const wallet = this.wallets[walletId];
3056
+ let refreshedShare;
3057
+ if (wallet.scheme === WalletScheme2.ED25519) {
3058
+ const distributeRes = await distributeNewShare({
3059
+ ctx: this.ctx,
3060
+ userId: this.userId,
3061
+ walletId: wallet.id,
3062
+ userShare: this.wallets[wallet.id].signer,
3063
+ emailProps: this.getBackupKitEmailProps(),
3064
+ partnerId: wallet.partnerId
3065
+ });
3066
+ if (distributeRes.length > 0) {
3067
+ newRecoverySecret = distributeRes;
3068
+ }
3069
+ } else {
3070
+ refreshedShare = await this.refreshShare({
3071
+ walletId: wallet.id,
3072
+ share: this.wallets[wallet.id].signer,
3073
+ oldPartnerId: wallet.partnerId,
3074
+ newPartnerId: wallet.partnerId,
3075
+ redistributeBackupEncryptedShares: true
3076
+ });
3077
+ if (refreshedShare.recoverySecret) {
3078
+ newRecoverySecret = refreshedShare.recoverySecret;
3079
+ }
3080
+ }
3081
+ this.wallets[wallet.id] = {
3082
+ ...this.wallets[wallet.id],
3083
+ signer: refreshedShare?.signer ?? wallet.signer,
3084
+ userId: this.userId,
3085
+ pregenIdentifier: void 0,
3086
+ pregenIdentifierType: void 0
3087
+ };
3088
+ const walletNoSigner = { ...this.wallets[wallet.id] };
3089
+ delete walletNoSigner.signer;
3090
+ dispatchEvent(ParaEvent.PREGEN_WALLET_CLAIMED, {
3091
+ wallet: walletNoSigner,
3092
+ recoverySecret: newRecoverySecret
3093
+ });
3094
+ }
3095
+ await this.setWallets(this.wallets);
3096
+ return newRecoverySecret;
3097
+ }
3098
+ /**
3099
+ * Updates the identifier for a pregen wallet.
3100
+ * @param {Object} opts the options object.
3101
+ * @param {string} opts.walletId the pregen wallet ID
3102
+ * @param {string} opts.newPregenIdentifier the new identtifier
3103
+ * @param {TPregenIdentifierType} opts.newPregenIdentifierType: the new identifier type
3104
+ **/
3105
+ async updatePregenWalletIdentifier({
3106
+ walletId,
3107
+ newPregenIdentifier,
3108
+ newPregenIdentifierType
3109
+ }) {
3110
+ this.requireApiKey();
3111
+ await this.ctx.client.updatePregenWallet(walletId, {
3112
+ pregenIdentifier: newPregenIdentifier,
3113
+ pregenIdentifierType: newPregenIdentifierType
3114
+ });
3115
+ if (!!this.wallets[walletId]) {
3116
+ this.wallets[walletId] = {
3117
+ ...this.wallets[walletId],
3118
+ pregenIdentifier: newPregenIdentifier,
3119
+ pregenIdentifierType: newPregenIdentifierType
3120
+ };
3121
+ await this.setWallets(this.wallets);
3122
+ }
3123
+ }
3124
+ /**
3125
+ * Checks if a pregen Wallet exists for the given identifier with the current partner.
3126
+ * @param {Object} opts the options object.
3127
+ * @param {string} opts.pregenIdentifier string the identifier of the user claiming the wallet
3128
+ * @param {TPregenIdentifierType} opts.pregenIdentifierType type of the string of the identifier of the user claiming the wallet
3129
+ * @returns {boolean} whether the pregen wallet exists
3130
+ **/
3131
+ async hasPregenWallet({
3132
+ pregenIdentifier,
3133
+ pregenIdentifierType
3134
+ }) {
3135
+ this.requireApiKey();
3136
+ const res = await this.getPregenWallets({ pregenIdentifier, pregenIdentifierType });
3137
+ const wallet = res.find((w) => w.pregenIdentifier === pregenIdentifier && w.pregenIdentifierType === pregenIdentifierType);
3138
+ if (!wallet) {
3139
+ return false;
3140
+ }
3141
+ return true;
3142
+ }
3143
+ /**
3144
+ * Get pregen wallets for the given identifier.
3145
+ * @param {Object} opts the options object.
3146
+ * @param {string} opts.pregenIdentifier - the identifier of the user claiming the wallet
3147
+ * @param {TPregenIdentifierType} opts.pregenIdentifierType - type of the identifier of the user claiming the wallet
3148
+ * @returns {Promise<WalletEntity[]>} the array of found wallets
3149
+ **/
3150
+ async getPregenWallets({
3151
+ pregenIdentifier,
3152
+ pregenIdentifierType = !!pregenIdentifier ? "EMAIL" : void 0
3153
+ } = {}) {
3154
+ this.requireApiKey();
3155
+ const res = await this.ctx.client.getPregenWallets(
3156
+ pregenIdentifier && pregenIdentifierType ? { [pregenIdentifierType]: [pregenIdentifier] } : this.pregenIds,
3157
+ this.isPortal(),
3158
+ this.userId
3159
+ );
3160
+ return res.wallets.filter((w) => this.isWalletSupported(entityToWallet(w)));
3161
+ }
3162
+ encodeWalletBase64(wallet) {
3163
+ const walletJson = JSON.stringify(wallet);
3164
+ const base64Wallet = Buffer.from(walletJson).toString("base64");
3165
+ return base64Wallet;
3166
+ }
3167
+ /**
3168
+ * Encodes the current wallets encoded in Base 64.
3169
+ * @returns {string} the encoded wallet string
3170
+ **/
3171
+ getUserShare() {
3172
+ if (Object.values(this.wallets).length === 0) {
3173
+ return null;
3174
+ }
3175
+ return Object.values(this.wallets).map((wallet) => this.encodeWalletBase64(wallet)).join("-");
3176
+ }
3177
+ /**
3178
+ * Sets the current wallets from a Base 64 string.
3179
+ * @param {string} base64Wallet the encoded wallet string
3180
+ **/
3181
+ async setUserShare(base64Wallets) {
3182
+ if (!base64Wallets) {
3183
+ return;
3184
+ }
3185
+ const base64WalletsSplit = base64Wallets.split("-");
3186
+ for (const base64Wallet of base64WalletsSplit) {
3187
+ const walletJson = Buffer.from(base64Wallet, "base64").toString();
3188
+ const wallet = migrateWallet(JSON.parse(walletJson));
3189
+ this.wallets[wallet.id] = wallet;
3190
+ await this.setWallets(this.wallets);
3191
+ }
3192
+ }
3193
+ async getTransactionReviewUrl(transactionId, timeoutMs) {
3194
+ const res = await this.touchSession();
3195
+ return this.constructPortalUrl("txReview", {
3196
+ partnerId: res.data.partnerId,
3197
+ pathId: transactionId,
3198
+ params: {
3199
+ email: this.email,
3200
+ timeoutMs: timeoutMs?.toString()
3201
+ }
3202
+ });
3203
+ }
3204
+ async getOnRampTransactionUrl({
3205
+ purchaseId,
3206
+ providerKey,
3207
+ ...walletParams
3208
+ }) {
3209
+ const res = await this.touchSession();
3210
+ const [key, identifier] = extractWalletRef(walletParams);
3211
+ return this.constructPortalUrl("onRamp", {
3212
+ partnerId: res.data.partnerId,
3213
+ pathId: purchaseId,
3214
+ sessionId: res.data.sessionId,
3215
+ params: {
3216
+ [key]: identifier,
3217
+ providerKey,
3218
+ currentWalletIds: JSON.stringify(this.currentWalletIds)
3219
+ }
3220
+ });
3221
+ }
3222
+ /**
3223
+ * Signs a message using one of the current wallets.
3224
+ *
3225
+ * If you want to sign the keccak256 hash of a message, hash the
3226
+ * message first and then pass in the base64 encoded hash.
3227
+ * @param {Object} opts the options object.
3228
+ * @param {string} opts.walletId the id of the wallet to sign with.
3229
+ * @param {string} opts.messageBase64 the base64 encoding of exact message that should be signed
3230
+ * @param {number} [opts.timeout] optional timeout in milliseconds. If not present, defaults to 30 seconds.
3231
+ * @param {string} [opts.cosmosSignDocBase64] the Cosmos `SignDoc` in base64, if applicable
3232
+ **/
3233
+ async signMessage({
3234
+ walletId,
3235
+ messageBase64,
3236
+ timeoutMs = 3e4,
3237
+ cosmosSignDocBase64
3238
+ }) {
3239
+ this.assertIsValidWalletId(walletId);
3240
+ const wallet = this.wallets[walletId];
3241
+ let signerId = this.userId;
3242
+ if (wallet.partnerId && !wallet.userId) {
3243
+ signerId = wallet.partnerId;
3244
+ }
3245
+ let signRes = await this.signMessageInner({ wallet, signerId, messageBase64, cosmosSignDocBase64 });
3246
+ let timeStart = Date.now();
3247
+ if (signRes.pendingTransactionId) {
3248
+ this.platformUtils.openPopup(
3249
+ await this.getTransactionReviewUrl(signRes.pendingTransactionId, timeoutMs),
3250
+ { type: cosmosSignDocBase64 ? "SIGN_TRANSACTION_REVIEW" /* SIGN_TRANSACTION_REVIEW */ : "SIGN_MESSAGE_REVIEW" /* SIGN_MESSAGE_REVIEW */ }
3251
+ );
3252
+ } else {
3253
+ dispatchEvent(ParaEvent.SIGN_MESSAGE_EVENT, signRes);
3254
+ return signRes;
3255
+ }
3256
+ await new Promise((resolve) => setTimeout(resolve, POLLING_INTERVAL_MS));
3257
+ while (true) {
3258
+ if (Date.now() - timeStart > timeoutMs) {
3259
+ break;
3260
+ }
3261
+ try {
3262
+ await this.ctx.client.getPendingTransaction(this.userId, signRes.pendingTransactionId);
3263
+ } catch (err) {
3264
+ const error = new TransactionReviewDenied();
3265
+ dispatchEvent(ParaEvent.SIGN_MESSAGE_EVENT, signRes, error.message);
3266
+ throw error;
3267
+ }
3268
+ signRes = await this.signMessageInner({ wallet, signerId, messageBase64, cosmosSignDocBase64 });
3269
+ if (signRes.pendingTransactionId) {
3270
+ await new Promise((resolve) => setTimeout(resolve, POLLING_INTERVAL_MS));
3271
+ } else {
3272
+ break;
3273
+ }
3274
+ }
3275
+ if (signRes.pendingTransactionId) {
3276
+ const error = new TransactionReviewTimeout(
3277
+ await this.getTransactionReviewUrl(signRes.pendingTransactionId),
3278
+ signRes.pendingTransactionId
3279
+ );
3280
+ dispatchEvent(ParaEvent.SIGN_MESSAGE_EVENT, signRes, error.message);
3281
+ throw error;
3282
+ }
3283
+ dispatchEvent(ParaEvent.SIGN_MESSAGE_EVENT, signRes);
3284
+ return signRes;
3285
+ }
3286
+ async signMessageInner({
3287
+ wallet,
3288
+ signerId,
3289
+ messageBase64,
3290
+ cosmosSignDocBase64
3291
+ }) {
3292
+ let signRes;
3293
+ switch (wallet.scheme) {
3294
+ case WalletScheme2.ED25519:
3295
+ signRes = await this.platformUtils.ed25519Sign(
3296
+ this.ctx,
3297
+ signerId,
3298
+ wallet.id,
3299
+ wallet.signer,
3300
+ messageBase64,
3301
+ this.retrieveSessionCookie()
3302
+ );
3303
+ break;
3304
+ default:
3305
+ signRes = await this.platformUtils.signMessage(
3306
+ this.ctx,
3307
+ signerId,
3308
+ wallet.id,
3309
+ wallet.signer,
3310
+ messageBase64,
3311
+ this.retrieveSessionCookie(),
3312
+ wallet.scheme === WalletScheme2.DKLS,
3313
+ cosmosSignDocBase64
3314
+ );
3315
+ break;
3316
+ }
3317
+ return signRes;
3318
+ }
3319
+ /**
3320
+ * Signs a transaction.
3321
+ * @param {Object} opts the options object.
3322
+ * @param {string} opts.walletId the id of the wallet to sign with.
3323
+ * @param {string} opts.rlpEncodedTxBase64 the transaction to sign, in RLP base64 encoding
3324
+ * @param {string} [opts.chainId] the EVM chain id of the chain the transaction is being sent on, if applicable
3325
+ * @param {number} [opts.timeoutMs] the amount of time to wait for the user to sign the transaction, in milliseconds
3326
+ **/
3327
+ async signTransaction({
3328
+ walletId,
3329
+ rlpEncodedTxBase64,
3330
+ chainId,
3331
+ timeoutMs = 3e4
3332
+ }) {
3333
+ this.assertIsValidWalletId(walletId);
3334
+ const wallet = this.wallets[walletId];
3335
+ let signerId = this.userId;
3336
+ if (wallet.partnerId && !wallet.userId) {
3337
+ signerId = wallet.partnerId;
3338
+ }
3339
+ let signRes = await this.platformUtils.signTransaction(
3340
+ this.ctx,
3341
+ signerId,
3342
+ walletId,
3343
+ this.wallets[walletId].signer,
3344
+ rlpEncodedTxBase64,
3345
+ chainId,
3346
+ this.retrieveSessionCookie(),
3347
+ wallet.scheme === WalletScheme2.DKLS
3348
+ );
3349
+ let timeStart = Date.now();
3350
+ if (signRes.pendingTransactionId) {
3351
+ this.platformUtils.openPopup(
3352
+ await this.getTransactionReviewUrl(signRes.pendingTransactionId, timeoutMs),
3353
+ { type: "SIGN_TRANSACTION_REVIEW" /* SIGN_TRANSACTION_REVIEW */ }
3354
+ );
3355
+ } else {
3356
+ dispatchEvent(ParaEvent.SIGN_TRANSACTION_EVENT, signRes);
3357
+ return signRes;
3358
+ }
3359
+ await new Promise((resolve) => setTimeout(resolve, POLLING_INTERVAL_MS));
3360
+ while (true) {
3361
+ if (Date.now() - timeStart > timeoutMs) {
3362
+ break;
3363
+ }
3364
+ try {
3365
+ await this.ctx.client.getPendingTransaction(this.userId, signRes.pendingTransactionId);
3366
+ } catch (err) {
3367
+ const error = new TransactionReviewDenied();
3368
+ dispatchEvent(ParaEvent.SIGN_TRANSACTION_EVENT, signRes, error.message);
3369
+ throw error;
3370
+ }
3371
+ signRes = await this.platformUtils.signTransaction(
3372
+ this.ctx,
3373
+ signerId,
3374
+ walletId,
3375
+ this.wallets[walletId].signer,
3376
+ rlpEncodedTxBase64,
3377
+ chainId,
3378
+ this.retrieveSessionCookie(),
3379
+ wallet.scheme === WalletScheme2.DKLS
3380
+ );
3381
+ if (signRes.pendingTransactionId) {
3382
+ await new Promise((resolve) => setTimeout(resolve, POLLING_INTERVAL_MS));
3383
+ } else {
3384
+ break;
3385
+ }
3386
+ }
3387
+ if (signRes.pendingTransactionId) {
3388
+ const error = new TransactionReviewTimeout(
3389
+ await this.getTransactionReviewUrl(signRes.pendingTransactionId),
3390
+ signRes.pendingTransactionId
3391
+ );
3392
+ dispatchEvent(ParaEvent.SIGN_TRANSACTION_EVENT, signRes, error.message);
3393
+ throw error;
3394
+ }
3395
+ dispatchEvent(ParaEvent.SIGN_TRANSACTION_EVENT, signRes);
3396
+ return signRes;
3397
+ }
3398
+ /**
3399
+ * @deprecated
3400
+ * Sends a transaction.
3401
+ * @param walletId - id of the wallet to send the transaction from.
3402
+ * @param rlpEncodedTxBase64 - rlp encoded tx as base64 string
3403
+ * @param chainId - chain id of the chain the transaction is being sent on.
3404
+ **/
3405
+ async sendTransaction({
3406
+ walletId,
3407
+ rlpEncodedTxBase64,
3408
+ chainId
3409
+ }) {
3410
+ this.assertIsValidWalletId(walletId);
3411
+ const wallet = this.wallets[walletId];
3412
+ const signRes = await this.platformUtils.sendTransaction(
3413
+ this.ctx,
3414
+ this.userId,
3415
+ walletId,
3416
+ this.wallets[walletId].signer,
3417
+ rlpEncodedTxBase64,
3418
+ chainId,
3419
+ this.retrieveSessionCookie(),
3420
+ wallet.scheme === WalletScheme2.DKLS
3421
+ );
3422
+ if (signRes.pendingTransactionId) {
3423
+ this.platformUtils.openPopup(
3424
+ await this.getTransactionReviewUrl(signRes.pendingTransactionId),
3425
+ { type: "SIGN_TRANSACTION_REVIEW" /* SIGN_TRANSACTION_REVIEW */ }
3426
+ );
3427
+ const error = new TransactionReviewError(
3428
+ await this.getTransactionReviewUrl(signRes.pendingTransactionId)
3429
+ );
3430
+ throw error;
3431
+ }
3432
+ return signRes;
3433
+ }
3434
+ isProviderModalDisabled() {
3435
+ return !!this.disableProviderModal;
3436
+ }
3437
+ /**
3438
+ * Starts a on-ramp or off-ramp transaction and returns the Para Portal link for the user to finalize and complete it.
3439
+ * @param {Object} opts the options object
3440
+ * @param {OnRampPurchaseCreateParams} opts.params the transaction settings.
3441
+ * @param {boolean} opts.shouldOpenPopup if `true`, a popup window with the link will be opened.
3442
+ * @param {string} opts.walletId the wallet ID to use for the transaction, where funds will be sent or withdrawn.
3443
+ * @param {string} opts.externalWalletAddress the external wallet address to send funds to or withdraw funds from, if using an external wallet.
3444
+ **/
3445
+ async initiateOnRampTransaction(options) {
3446
+ const { params, shouldOpenPopup, ...walletParams } = options;
3447
+ const onRampPurchase = await this.ctx.client.createOnRampPurchase({
3448
+ userId: this.userId,
3449
+ params: {
3450
+ ...params,
3451
+ address: walletParams.externalWalletAddress ?? this.getDisplayAddress(walletParams.walletId, { addressType: params.walletType })
3452
+ },
3453
+ ...walletParams
3454
+ });
3455
+ const portalUrl = await this.getOnRampTransactionUrl({
3456
+ purchaseId: onRampPurchase.id,
3457
+ providerKey: onRampPurchase.providerKey,
3458
+ ...walletParams
3459
+ });
3460
+ if (shouldOpenPopup) {
3461
+ this.platformUtils.openPopup(portalUrl, { type: "ON_RAMP_TRANSACTION" /* ON_RAMP_TRANSACTION */ });
3462
+ }
3463
+ return { onRampPurchase, portalUrl };
3464
+ }
3465
+ /**
3466
+ * Returns `true` if session was successfully kept alive, `false` otherwise.
3467
+ **/
3468
+ async keepSessionAlive() {
3469
+ try {
3470
+ await this.ctx.client.keepSessionAlive(this.userId);
3471
+ return true;
3472
+ } catch (err) {
3473
+ return false;
3474
+ }
3475
+ }
3476
+ /**
3477
+ * Serialize the current session for import by another Para instance.
3478
+ * @returns {string} the serialized session
3479
+ */
3480
+ exportSession() {
3481
+ const sessionInfo = {
3482
+ email: this.email,
3483
+ userId: this.userId,
3484
+ wallets: this.wallets,
3485
+ currentWalletIds: this.currentWalletIds,
3486
+ sessionCookie: this.sessionCookie,
3487
+ phone: this.phone,
3488
+ countryCode: this.countryCode,
3489
+ telegramUserId: this.telegramUserId,
3490
+ farcasterUsername: this.farcasterUsername,
3491
+ externalWallets: this.externalWallets
3492
+ };
3493
+ return Buffer.from(JSON.stringify(sessionInfo)).toString("base64");
3494
+ }
3495
+ /**
3496
+ * Imports a session serialized by another Para instance.
3497
+ * @param {string} serializedInstanceBase64 the serialized session
3498
+ */
3499
+ async importSession(serializedInstanceBase64) {
3500
+ const serializedInstance = Buffer.from(serializedInstanceBase64, "base64").toString("utf8");
3501
+ const sessionInfo = JSON.parse(serializedInstance);
3502
+ await this.setEmail(sessionInfo.email);
3503
+ await this.setTelegramUserId(sessionInfo.telegramUserId);
3504
+ await this.setFarcasterUsername(sessionInfo.farcasterUsername);
3505
+ await this.setUserId(sessionInfo.userId);
3506
+ await this.setWallets(sessionInfo.wallets);
3507
+ await this.setExternalWallets(sessionInfo.externalWallets || {});
3508
+ for (const walletId of Object.keys(this.wallets)) {
3509
+ if (!this.wallets[walletId].userId) {
3510
+ this.wallets[walletId].userId = this.userId;
3511
+ }
3512
+ }
3513
+ if (Object.keys(sessionInfo.currentWalletIds).length !== 0) {
3514
+ await this.setCurrentWalletIds(sessionInfo.currentWalletIds);
3515
+ } else {
3516
+ const currentWalletIds = {};
3517
+ for (const walletId of Object.keys(sessionInfo.wallets)) {
3518
+ currentWalletIds[sessionInfo.wallets[walletId].type] = [
3519
+ ...currentWalletIds[sessionInfo.wallets[walletId].type] ?? [],
3520
+ walletId
3521
+ ];
3522
+ }
3523
+ await this.setCurrentWalletIds(currentWalletIds);
3524
+ }
3525
+ this.persistSessionCookie(sessionInfo.sessionCookie);
3526
+ await this.setPhoneNumber(sessionInfo.phone, sessionInfo.countryCode);
3527
+ }
3528
+ exitAccountCreation() {
3529
+ this.isAwaitingAccountCreation = false;
3530
+ }
3531
+ exitLogin() {
3532
+ this.isAwaitingLogin = false;
3533
+ }
3534
+ exitFarcaster() {
3535
+ this.isAwaitingFarcaster = false;
3536
+ }
3537
+ exitOAuth() {
3538
+ this.isAwaitingOAuth = false;
3539
+ }
3540
+ exitLoops() {
3541
+ this.exitAccountCreation();
3542
+ this.exitLogin();
3543
+ this.exitFarcaster();
3544
+ this.exitOAuth();
3545
+ }
3546
+ /**
3547
+ * Retrieves a token to verify the current session.
3548
+ * @returns {Promise<string>} the ID
3549
+ **/
3550
+ async getVerificationToken() {
3551
+ const { data } = await this.touchSession();
3552
+ return data.sessionLookupId;
3553
+ }
3554
+ /**
3555
+ * Logs the user out.
3556
+ * @param {Object} opts the options object.
3557
+ * @param {boolean} opts.clearPregenWallets if `true`, will remove all pregen wallets from storage
3558
+ **/
3559
+ async logout({ clearPregenWallets = false } = {}) {
3560
+ await this.ctx.client.logout();
3561
+ await this.clearStorage();
3562
+ if (!clearPregenWallets) {
3563
+ Object.entries(this.wallets).forEach(([id, wallet]) => {
3564
+ if (!wallet.pregenIdentifier) {
3565
+ delete this.wallets[id];
3566
+ }
3567
+ });
3568
+ await this.setWallets(this.wallets);
3569
+ } else {
3570
+ this.wallets = {};
3571
+ }
3572
+ this.currentWalletIds = {};
3573
+ this.currentExternalWalletAddresses = void 0;
3574
+ this.externalWallets = {};
3575
+ this.loginEncryptionKeyPair = void 0;
3576
+ this.email = void 0;
3577
+ this.telegramUserId = void 0;
3578
+ this.phone = void 0;
3579
+ this.countryCode = void 0;
3580
+ this.userId = void 0;
3581
+ this.sessionCookie = void 0;
3582
+ dispatchEvent(ParaEvent.LOGOUT_EVENT, null);
3583
+ }
3584
+ async getSupportedCreateAuthMethods() {
3585
+ const res = await this.touchSession();
3586
+ const partnerId = res.data.partnerId;
3587
+ const partnerRes = await this.ctx.client.getPartner(partnerId);
3588
+ let supportedAuthMethods = /* @__PURE__ */ new Set();
3589
+ for (const authMethod of partnerRes.data.partner.supportedAuthMethods) {
3590
+ supportedAuthMethods.add(AuthMethod[authMethod]);
3591
+ }
3592
+ return supportedAuthMethods;
3593
+ }
3594
+ /**
3595
+ * Converts to a string, removing sensitive data when logging this class.
3596
+ *
3597
+ * Doesn't work for all types of logging.
3598
+ **/
3599
+ toString() {
3600
+ const redactedWallets = Object.keys(this.wallets).reduce(
3601
+ (acc, walletId) => ({
3602
+ ...acc,
3603
+ [walletId]: {
3604
+ ...this.wallets[walletId],
3605
+ signer: this.wallets[walletId].signer ? "[REDACTED]" : void 0
3606
+ }
3607
+ }),
3608
+ {}
3609
+ );
3610
+ const obj = {
3611
+ supportedWalletTypes: this.supportedWalletTypes,
3612
+ cosmosPrefix: this.cosmosPrefix,
3613
+ email: this.email,
3614
+ phone: this.phone,
3615
+ countryCode: this.countryCode,
3616
+ telegramUserId: this.telegramUserId,
3617
+ farcasterUsername: this.farcasterUsername,
3618
+ userId: this.userId,
3619
+ pregenIds: this.pregenIds,
3620
+ currentWalletIds: this.currentWalletIds,
3621
+ wallets: redactedWallets,
3622
+ loginEncryptionKeyPair: this.loginEncryptionKeyPair ? "[REDACTED]" : void 0,
3623
+ ctx: {
3624
+ apiKey: this.ctx.apiKey,
3625
+ disableWorkers: this.ctx.disableWorkers,
3626
+ disableWebSockets: this.ctx.disableWebSockets,
3627
+ env: this.ctx.env,
3628
+ offloadMPCComputationURL: this.ctx.offloadMPCComputationURL,
3629
+ useLocalFiles: this.ctx.useLocalFiles,
3630
+ useDKLS: this.ctx.useDKLS,
3631
+ cosmosPrefix: this.ctx.cosmosPrefix
3632
+ }
3633
+ };
3634
+ return `Para ${JSON.stringify(obj, null, 2)}`;
3635
+ }
3636
+ };
3637
+
3638
+ // src/index.ts
3639
+ import {
3640
+ AuthMethod as AuthMethod2,
3641
+ EmailTheme as EmailTheme2,
3642
+ Network,
3643
+ WalletType as WalletType3,
3644
+ WalletScheme as WalletScheme3,
3645
+ OnRampAsset,
3646
+ OnRampPurchaseType,
3647
+ OnRampProvider,
3648
+ OnRampPurchaseStatus,
3649
+ OAuthMethod as OAuthMethod2,
3650
+ NON_ED25519,
3651
+ PREGEN_IDENTIFIER_TYPES
3652
+ } from "@getpara/user-management-client";
3653
+ var paraVersion = ParaCore.version;
3654
+ var src_default = ParaCore;
3655
+ export {
3656
+ AuthMethod2 as AuthMethod,
3657
+ EmailTheme2 as EmailTheme,
3658
+ EnabledFlow,
3659
+ Environment,
3660
+ KeyContainer,
3661
+ NON_ED25519,
3662
+ Network,
3663
+ OAuthMethod2 as OAuthMethod,
3664
+ OnRampAsset,
3665
+ OnRampMethod,
3666
+ OnRampProvider,
3667
+ OnRampPurchaseStatus,
3668
+ OnRampPurchaseType,
3669
+ PREGEN_IDENTIFIER_TYPES,
3670
+ ParaEvent,
3671
+ PopupType,
3672
+ PregenIdentifierType,
3673
+ RecoveryStatus,
3674
+ PREFIX as STORAGE_PREFIX,
3675
+ TransactionReviewDenied,
3676
+ TransactionReviewError,
3677
+ TransactionReviewTimeout,
3678
+ WalletScheme3 as WalletScheme,
3679
+ WalletType3 as WalletType,
3680
+ decimalToHex,
3681
+ decryptPrivateKey,
3682
+ decryptPrivateKeyAndDecryptShare,
3683
+ decryptPrivateKeyWithPassword,
3684
+ decryptWithKeyPair,
3685
+ decryptWithPrivateKey,
3686
+ src_default as default,
3687
+ distributeNewShare,
3688
+ encodePrivateKeyToPemHex,
3689
+ encryptPrivateKey,
3690
+ encryptPrivateKeyWithPassword,
3691
+ encryptWithDerivedPublicKey,
3692
+ entityToWallet,
3693
+ getAsymmetricKeyPair,
3694
+ getBaseMPCNetworkUrl,
3695
+ getBaseOAuthUrl,
3696
+ getBaseUrl,
3697
+ getCosmosAddress,
3698
+ getDerivedPrivateKeyAndDecrypt,
3699
+ getOnRampAssets,
3700
+ getOnRampNetworks,
3701
+ getPortalBaseURL,
3702
+ getPortalDomain,
3703
+ getPublicKeyFromSignature,
3704
+ getPublicKeyHex,
3705
+ getSHA256HashHex,
3706
+ hashPasswordWithSalt,
3707
+ hexStringToBase64,
3708
+ hexToDecimal,
3709
+ hexToSignature,
3710
+ hexToUint8Array,
3711
+ initClient,
3712
+ isWalletSupported,
3713
+ mpcComputationClient_exports as mpcComputationClient,
3714
+ normalizePhoneNumber,
3715
+ paraVersion,
3716
+ publicKeyFromHex,
3717
+ stringToPhoneNumber,
3718
+ toAssetInfoArray,
3719
+ retrieve as transmissionUtilsRetrieve,
3720
+ truncateAddress,
3721
+ waitUntilTrue
3722
+ };