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