@privy-io/server-auth
Version:
Server-side client for the Privy API
2 lines (1 loc) • 13.6 kB
JavaScript
;var t=require("jose"),e=require("svix"),r=require("ts-case-convert"),a=require("@privy-io/public-api"),s=require("./constants.js"),i=require("./errors.js"),o=require("./http.js"),l=require("./paths.js"),n=require("./utils-D9BZ7JAH.js"),c=require("./wallet-api/index.js");function u(t){if(t&&"object"==typeof t&&"default"in t)return t;var e=Object.create(null);return t&&Object.keys(t).forEach((function(r){if("default"!==r){var a=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,a.get?a:{enumerable:!0,get:function(){return t[r]}})}})),e.default=t,Object.freeze(e)}require("redaxios"),require("node-fetch-native"),require("./wallet-api/import.js"),require("@scure/base"),require("viem"),require("./wallet-api/utils.js"),require("@hpke/chacha20poly1305"),require("@hpke/core"),require("@noble/curves/p256"),require("@noble/hashes/sha256"),require("canonicalize"),require("./wallet-api/mappers.js"),require("./wallet-api/rpc/ethereum.js"),require("./wallet-api/rpc/solana.js"),require("./wallet-api/views.js");var p=/*#__PURE__*/u(t);exports.PrivyClient=class{async getUser(t){return"string"==typeof t?this.getUserById(t):this.getUserFromIdToken(t.idToken)}async getUserById(t){try{let e=l.userPath(t),r=await this.api.get(e);return n.convertUserResponseToUser(r.data)}catch(t){throw i.formatPrivyError(t)}}async getUserByEmail(t){try{let e=l.getUserByEmailPath(),r=await this.api.post(e,{address:t});return n.convertUserResponseToUser(r.data)}catch(t){if(t instanceof i.PrivyApiError&&404===t.status)return null;throw i.formatPrivyError(t)}}async getUserByPhoneNumber(t){try{let e=l.getUserByPhoneNumberPath(),r=await this.api.post(e,{number:t});return n.convertUserResponseToUser(r.data)}catch(t){if(t instanceof i.PrivyApiError&&404===t.status)return null;throw i.formatPrivyError(t)}}async getUserByWalletAddress(t){try{let e=l.getUserByWalletAddressPath(),r=await this.api.post(e,{address:t});return n.convertUserResponseToUser(r.data)}catch(t){if(t instanceof i.PrivyApiError&&404===t.status)return null;throw i.formatPrivyError(t)}}async getUserBySmartWalletAddress(t){try{let e=l.getUserBySmartWalletAddressPath(),r=await this.api.post(e,{address:t});return n.convertUserResponseToUser(r.data)}catch(t){if(t instanceof i.PrivyApiError&&404===t.status)return null;throw i.formatPrivyError(t)}}async getUserByFarcasterId(t){try{let e=l.getUserByFarcasterIdPath(),r=await this.api.post(e,{fid:t});return n.convertUserResponseToUser(r.data)}catch(t){if(t instanceof i.PrivyApiError&&404===t.status)return null;throw i.formatPrivyError(t)}}async getUserByDiscordUsername(t){try{let e=l.getUserByDiscordUsernamePath(),r=await this.api.post(e,{username:t});return n.convertUserResponseToUser(r.data)}catch(t){if(t instanceof i.PrivyApiError&&404===t.status)return null;throw i.formatPrivyError(t)}}async getUserByGithubUsername(t){try{let e=l.getUserByGithubUsernamePath(),r=await this.api.post(e,{username:t});return n.convertUserResponseToUser(r.data)}catch(t){if(t instanceof i.PrivyApiError&&404===t.status)return null;throw i.formatPrivyError(t)}}async getUserByTwitterUsername(t){try{let e=l.getUserByTwitterUsernamePath(),r=await this.api.post(e,{username:t});return n.convertUserResponseToUser(r.data)}catch(t){if(t instanceof i.PrivyApiError&&404===t.status)return null;throw i.formatPrivyError(t)}}async getUserByTwitterSubject(t){try{let e=l.getUserByTwitterSubjectPath(),r=await this.api.post(e,{subject:t});return n.convertUserResponseToUser(r.data)}catch(t){if(t instanceof i.PrivyApiError&&404===t.status)return null;throw i.formatPrivyError(t)}}async getUserByTelegramUserId(t){try{let e=l.getUserByTelegramUserIdPath(),r=await this.api.post(e,{telegram_user_id:t});return n.convertUserResponseToUser(r.data)}catch(t){if(t instanceof i.PrivyApiError&&404===t.status)return null;throw i.formatPrivyError(t)}}async getUserByTelegramUsername(t){try{let e=l.getUserByTelegramUsernamePath(),r=await this.api.post(e,{username:t});return n.convertUserResponseToUser(r.data)}catch(t){if(t instanceof i.PrivyApiError&&404===t.status)return null;throw i.formatPrivyError(t)}}async getUserByCustomAuthId(t){try{let e=l.getUserByCustomAuthIdPath(),r=await this.api.post(e,{custom_user_id:t});return n.convertUserResponseToUser(r.data)}catch(t){if(t instanceof i.PrivyApiError&&404===t.status)return null;throw i.formatPrivyError(t)}}async getUsers(t){try{let e=[],r="string"==typeof t?{searchTerm:t}:{...t},a="",s=0;do{try{let i=void 0===t?await this.api.get(l.usersPath({cursor:a})):await this.api.post(l.searchUsersPath(),{...r,...a?{cursor:a}:{}});if(429===i.status){let t=1e3*Math.pow(2,s);await new Promise((e=>setTimeout(e,t))),s++;continue}e.push(...i.data.data.map((t=>n.convertUserResponseToUser(t)))),a=i.data.next_cursor,s=0}catch(t){if(s>=9)throw i.formatPrivyError(`Exceeded max attempts (9) with error: ${t}`);let e=1e3*Math.pow(2,s);await new Promise((t=>setTimeout(t,e))),s++}}while(null!==a);return e}catch(t){throw i.formatPrivyError(t)}}async deleteUser(t){try{let e=l.userPath(t);await this.api.delete(e)}catch(t){throw i.formatPrivyError(t)}}async importUser({linkedAccounts:t,createEthereumWallet:e,createSolanaWallet:r,createEthereumSmartWallet:a,customMetadata:s,createEmbeddedWallet:o,wallets:c}){let u=n.prepareAccountsForImport(t);try{let t=l.importUserPath(),i=await this.api.post(t,{create_ethereum_wallet:e||o,create_solana_wallet:r,create_ethereum_smart_wallet:a,linked_accounts:u,custom_metadata:s,wallets:n.prepareWalletCreationInput(c)}),p=n.convertUserResponseToUser(i.data);if(!p)throw Error("Failed to convert user response to user object");return p}catch(t){throw i.formatPrivyError(t)}}async createWallets({userId:t,createEthereumWallet:e,createSolanaWallet:r,createEthereumSmartWallet:a,numberOfEthereumWalletsToCreate:s,wallets:o}){try{let i=l.createWalletsPath(this.appId),c=await this.api.post(i,{user_id:t,create_ethereum_wallet:e,create_solana_wallet:r,create_ethereum_smart_wallet:a,number_of_ethereum_wallets_to_create:s,wallets:n.prepareWalletCreationInput(o)});return n.convertUserResponseToUser(c.data)}catch(t){throw i.formatPrivyError(t)}}async getAppSettings(){try{let t=l.appSettingsPath(this.appId),e=await this.api.get(t);return{id:e.data.id,name:e.data.name,verificationKey:e.data.verification_key,logoUrl:e.data.logo_url||void 0,theme:e.data.theme,accentColor:e.data.accent_color||void 0,walletAuth:e.data.wallet_auth,emailAuth:e.data.email_auth,smsAuth:e.data.sms_auth,googleOAuth:e.data.google_oauth,twitterOAuth:e.data.twitter_oauth,discordOAuth:e.data.discord_oauth,githubOAuth:e.data.github_oauth,appleOAuth:e.data.apple_oauth,linkedInOAuth:e.data.linkedin_oauth,tiktokOAuth:e.data.tiktok_oauth,disablePlusEmails:e.data.disable_plus_emails,termsAndConditionsUrl:e.data.terms_and_conditions_url,privacyPolicyUrl:e.data.privacy_policy_url,allowlistEnabled:e.data.allowlist_enabled,allowlistConfig:{errorTitle:e.data.allowlist_config.error_title,errorDetail:e.data.allowlist_config.error_detail,ctaText:e.data.allowlist_config.cta_text,ctaLink:e.data.allowlist_config.cta_link},createdAt:new Date(1e3*e.data.created_at),updatedAt:new Date(1e3*e.data.updated_at)}}catch(t){throw i.formatPrivyError(t)}}async getAllowlist(){try{let t=l.allowlistPath(this.appId);return(await this.api.get(t)).data.map((t=>r.objectToCamel(t)))}catch(t){throw i.formatPrivyError(t)}}async inviteToAllowlist(t){let e=r.objectToSnake(t);try{let t=l.allowlistPath(this.appId),a=await this.api.post(t,e);return r.objectToCamel(a.data)}catch(t){throw i.formatPrivyError(t)}}async removeFromAllowlist(t){let e=r.objectToSnake(t);try{let t=l.allowlistPath(this.appId),a=await this.api.delete(t,e);return r.objectToCamel(a.data)}catch(t){throw i.formatPrivyError(t)}}async verifyAuthToken(t,e=""){let r=t.replace(/^Bearer /,""),a="ES256",s=e||await this.getVerificationKey(),i=await p.importSPKI(s,a),o=await p.jwtVerify(r,i,{typ:"JWT",algorithms:[a],issuer:"privy.io",audience:this.appId});return{appId:o.payload.aud,issuer:o.payload.iss,issuedAt:o.payload.iat,expiration:o.payload.exp,sessionId:o.payload.sid,userId:o.payload.sub}}async getVerificationKey(){if(this.verificationKey)return this.verificationKey;let t=await this.getAppSettings();return this.verificationKey=t.verificationKey,this.verificationKey}async verifyWebhook(t,r,a){try{let s=new e.Webhook(a),i=JSON.stringify(t),o={"svix-id":r.id,"svix-timestamp":r.timestamp,"svix-signature":r.signature};return s.verify(i,o)}catch(t){throw console.error("Webhook verification failed with error: ",t),new i.PrivyClientError("Webhook verification failed")}}async getTestAccessToken(t={}){try{let e,r=await this.api.get(l.getTestCredentialsPath(this.appId));if(!r.data?.data)throw new i.PrivyClientError("Test credentials not enabled for this app");let{email:s,phoneNumber:o}=t,n=r.data.data,c=s?.trim().toLowerCase(),u=o?a.normalizePhoneNumber(o):void 0;if(c||u){if(c&&!u)e=n.find((t=>t.email.toLowerCase()===c));else if(!c&&u)e=n.find((t=>t.phone_number===u));else if(c&&u&&!(e=n.find((t=>t.email.toLowerCase()===c&&t.phone_number===u))))throw new i.PrivyClientError("Email and phone number do not correspond to the same test account")}else e=n[0];if(!e)throw new i.PrivyClientError("Test account not found");let{email:p,otp_code:h}=e;return{accessToken:(await this.api.post(l.passwordlessAuthenticatePath(),{email:p,code:h})).data.token}}catch(t){throw i.formatPrivyError(t)}}async setCustomMetadata(t,e){try{let r=l.setCustomMetadataPath(t),a=await this.api.post(r,{custom_metadata:e}),s=n.convertUserResponseToUser(a.data);if(!s)throw Error("Failed to convert user response to user object");return s}catch(t){throw i.formatPrivyError(t)}}async getUserFromIdToken(t){let e=this.appId,r=await this.getVerificationKey(),a=await p.importSPKI(r,"ES256");try{let{payload:r}=await p.jwtVerify(t,a,{issuer:"privy.io",audience:e});if(!r)throw new i.PrivyClientError("Unable to parse ID token");let s=JSON.parse(r.linked_accounts),o=[];for(let t of s){if("email"===t.type&&o.push({type:"email",address:t.address,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"phone"===t.type&&o.push({type:"phone",number:t.phone_number,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"wallet"===t.type&&o.push({type:"wallet",id:t.id,address:t.address,chainType:t.chain_type,walletClientType:t.wallet_client_type,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"smart_wallet"===t.type&&o.push({type:"smart_wallet",address:t.address,smartWalletType:t.smart_wallet_type,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"farcaster"===t.type&&o.push({type:"farcaster",fid:t.fid,username:t.username,latestVerifiedAt:n.parseDateFromEpoch(t.lv),ownerAddress:t.oa}),"google_oauth"===t.type&&o.push({type:"google_oauth",subject:t.subject,email:t.email,name:t.name,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"twitter_oauth"===t.type){let e=t.pfp?t.pfp:null;e?.startsWith("default")?e=`https://abs.twimg.com/sticky/default_profile_images/${e}`:e?.startsWith("https://")||(e=`https://pbs.twimg.com/profile_images/${e}`),o.push({type:"twitter_oauth",subject:t.subject,username:t.username,name:t.name?t.name:null,profilePictureUrl:e,latestVerifiedAt:n.parseDateFromEpoch(t.lv)})}"discord_oauth"===t.type&&o.push({type:"discord_oauth",subject:t.subject,username:t.username,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"github_oauth"===t.type&&o.push({type:"github_oauth",subject:t.subject,username:t.username,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"spotify_oauth"===t.type&&o.push({type:"spotify_oauth",subject:t.subject,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"instagram_oauth"===t.type&&o.push({type:"instagram_oauth",subject:t.subject,username:t.username,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"tiktok_oauth"===t.type&&o.push({type:"tiktok_oauth",subject:t.subject,username:t.username?t.username:void 0,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"linkedin_oauth"===t.type&&o.push({type:"linkedin_oauth",subject:t.subject,email:t.email,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"apple_oauth"===t.type&&o.push({type:"apple_oauth",subject:t.subject,email:t.email,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"cross_app"===t.type&&o.push({type:"cross_app",subject:t.subject,providerApp:{id:t.provider_app_id},embeddedWallets:t.embedded_wallets,smartWallets:t.smart_wallets,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"custom_auth"===t.type&&o.push({type:"custom_auth",customUserId:t.custom_user_id,latestVerifiedAt:n.parseDateFromEpoch(t.lv)}),"telegram"===t.type&&o.push({type:"telegram",telegramUserId:t.telegram_user_id,username:t.username,latestVerifiedAt:n.parseDateFromEpoch(t.lv)})}let l=r.custom_metadata?JSON.parse(r.custom_metadata):void 0,{walletAccount:c,smartWalletAccount:u,emailAccount:h,phoneAccount:d,googleAccount:m,twitterAccount:y,discordAccount:w,githubAccount:f,appleAccount:v,linkedInAccount:_,tiktokAccount:g,spotifyAccount:U,instagramAccount:A,customJwtAccount:P,farcasterAccount:b,telegramAccount:E}=n.findLatestAccounts(o);return{id:r.sub,createdAt:n.parseDateFromEpoch(parseInt(r.cr)),isGuest:"t"===r.guest,linkedAccounts:o,customMetadata:l,email:h,phone:d,wallet:c,smartWallet:u,google:m,twitter:y,discord:w,github:f,apple:v,linkedin:_,tiktok:g,spotify:U,instagram:A,custom:P,farcaster:b,telegram:E}}catch(t){throw i.formatPrivyError(t)}}constructor(t,e,r={}){this.verificationKey=null;let a=r.apiURL||s.PRIVY_API_URL,i=r.timeout||s.DEFAULT_TIMEOUT_MS;this.appId=t,this.api=new o.Http(t,e,{baseURL:a,timeout:i});let l=r.walletApi?.apiURL||s.PRIVY_WALLET_API_URL;this.walletApi=new c.WalletApi({api:new o.Http(t,e,{baseURL:l,timeout:i}),authorizationPrivateKey:r.walletApi?.authorizationPrivateKey,appId:t})}};