@privy-io/react-auth
Version:
React client for the Privy Auth API
104 lines (96 loc) • 9.68 kB
JavaScript
import{jsx as e,jsxs as r}from"react/jsx-runtime";import o from"@heroicons/react/20/solid/CheckIcon";import t from"@heroicons/react/24/outline/EnvelopeIcon";import i from"@heroicons/react/24/outline/PhoneIcon";import{useState as n,useEffect as a}from"react";import{isMobile as s}from"react-device-detect";import{styled as c}from"styled-components";import{H as l}from"./Layouts-BlFm53ED.mjs";import{L as d}from"./Link-DJ5gq9Di.mjs";import{u as p,q as m}from"./context-DLtU3JQy.mjs";import{u,e as v,b as f,k as h}from"./internal-context-Z-fyxadS.mjs";import{a as y,u as g}from"./privy-context-DrMxzgOR.mjs";import{s as x}from"./shouldProceedtoEmbeddedWalletCreationFlow-D2ZT5lW9.mjs";import{S as E}from"./ScreenLayout-D1p_ntex.mjs";import"@privy-io/js-sdk-core";import"tinycolor2";import"ofetch";import"@privy-io/are-addresses-equal";import"./index-YDEix4mU.mjs";import"uuid";import"jose";import"eventemitter3";import"./useActiveWallet-CvP7iYvj.mjs";import"zustand";import"./use-export-wallet-_wu5ex5t.mjs";import"./useWallets-BzNCTucF.mjs";import"viem";import"viem/utils";import"./events-context-CI0iqAXA.mjs";import"@coinbase/wallet-sdk";import"@privy-io/ethereum";import"mipd";import"@privy-io/popup";import"./paths-3HW55qZg.mjs";import"./usePrivy-C_sY2Duk.mjs";import"@scure/base";import"@headlessui/react";import"@walletconnect/ethereum-provider";import"@privy-io/urls";import"./PrivyPluginContext-2QN2dVUw.mjs";import"./getEmbeddedConnectedWallet-JzK4iD-L.mjs";import"js-cookie";import"./frame-uzTmvtww.mjs";import"@privy-io/routes";import"x402/client";import"@privy-io/api-base";import"viem/accounts";import"./use-sign-with-user-signer-Do5Oi_rb.mjs";import"./ModalHeader-BnVmXtvG.mjs";import"@heroicons/react/24/outline/ArrowLeftIcon";import"@heroicons/react/24/outline/ArrowRightIcon";import"@heroicons/react/24/outline/QuestionMarkCircleIcon";import"@heroicons/react/24/outline/XMarkIcon";import"./Screen-Cycy3IzT.mjs";import"./index-Dq_xe9dz.mjs";const b=({contactMethod:c,authFlow:p,appName:m="Privy",whatsAppEnabled:u=!1,onBack:v,onCodeSubmit:f,onResend:h,errorMessage:y,success:g=!1,resendCountdown:x=0,onInvalidInput:b,onClearError:A})=>{let[w,T]=n(S);a((()=>{y||T(S)}),[y]);let k=async e=>{e.preventDefault();let r=e.currentTarget.value.replace(" ","");if(""===r)return;if(isNaN(Number(r)))return void b?.("Code should be numeric");A?.();let o=Number(e.currentTarget.name?.charAt(5)),t=[...r||[""]].slice(0,C-o),i=[...w.slice(0,o),...t,...w.slice(o+t.length)];T(i);let n=Math.min(Math.max(o+t.length,0),C-1);if(!isNaN(Number(e.currentTarget.value))){let e=document.querySelector(`input[name=code-${n}]`);e?.focus()}if(i.every((e=>e&&!isNaN(+e)))){let e=document.querySelector(`input[name=code-${n}]`);e?.blur(),await(f?.(i.join("")))}};/*#__PURE__*/return e(E,{title:"Enter confirmation code",subtitle:/*#__PURE__*/r("span","email"===p?{children:["Please check ",/*#__PURE__*/e(M,{children:c})," for an email from privy.io and enter your code below."]}:{children:["Please check ",/*#__PURE__*/e(M,{children:c})," for a",u?" WhatsApp":""," message from ",m," and enter your code below."]}),icon:"email"===p?t:i,onBack:v,showBack:!0,helpText:/*#__PURE__*/r(L,{children:[/*#__PURE__*/r("span",{children:["Didn't get ","email"===p?"an email":"a message","?"]}),x?/*#__PURE__*/r(R,{children:[/*#__PURE__*/e(o,{color:"var(--privy-color-foreground)",strokeWidth:1.33,height:"12px",width:"12px"}),/*#__PURE__*/e("span",{children:"Code sent"})]}):/*#__PURE__*/e(d,{as:"button",size:"sm",onClick:h,children:"Resend code"})]}),children:/*#__PURE__*/e(_,{children:/*#__PURE__*/e(l,{children:/*#__PURE__*/r(j,{children:[/*#__PURE__*/e("div",{children:w.map(((r,o)=>/*#__PURE__*/e("input",{name:`code-${o}`,type:"text",value:w[o],onChange:k,onKeyUp:e=>{"Backspace"===e.key&&(e=>{if(A?.(),T([...w.slice(0,e),"",...w.slice(e+1)]),e>0){let r=document.querySelector(`input[name=code-${e-1}]`);r?.focus()}})(o)},inputMode:"numeric",autoFocus:0===o,pattern:"[0-9]",className:`${g?"success":""} ${y?"fail":""}`,autoComplete:s?"one-time-code":"off"},o)))}),/*#__PURE__*/e(I,{$fail:!!y,$success:g,children:/*#__PURE__*/e("span",{children:"Invalid or expired verification code"===y?"Incorrect code":y||(g?"Success!":"")})})]})})})})};let C=6,S=Array(6).fill("");var A,w,T=((A=T||{})[A.RESET_AFTER_DELAY=0]="RESET_AFTER_DELAY",A[A.CLEAR_ON_NEXT_VALID_INPUT=1]="CLEAR_ON_NEXT_VALID_INPUT",A),k=((w=k||{})[w.EMAIL=0]="EMAIL",w[w.SMS=1]="SMS",w);const N={component:()=>{let{navigate:r,lastScreen:o,navigateBack:t,setModalData:i,onUserCloseViaDialogOrKeybindRef:s}=y(),c=p(),{closePrivyModal:l,resendEmailCode:d,resendSmsCode:E,getAuthMeta:C,loginWithCode:S,updateWallets:A,createAnalyticsEvent:w}=u(),{authenticated:T,logout:k,user:N}=g(),{whatsAppEnabled:_}=p(),[j,I]=n(!1),[L,R]=n(null),[M,D]=n(null),[O,P]=n(0);s.current=()=>null;let U=C()?.email?0:1,W=0===U?C()?.email||"":C()?.phoneNumber||"",F=m-500;a((()=>{if(O){let e=setTimeout((()=>{P(O-1)}),1e3);return()=>clearTimeout(e)}}),[O]),a((()=>{if(T&&j&&N){if(c?.legal.requireUsersAcceptTerms&&!N.hasAcceptedTerms){let e=setTimeout((()=>{r("AffirmativeConsentScreen")}),F);return()=>clearTimeout(e)}if(x(N,c.embeddedWallets)){let e=setTimeout((()=>{i({createWallet:{onSuccess:()=>{},onFailure:e=>{console.error(e),w({eventName:"embedded_wallet_creation_failure_logout",payload:{error:e,screen:"AwaitingPasswordlessCodeScreen"}}),k()},callAuthOnSuccessOnClose:!0}}),r("EmbeddedWalletOnAccountCreateScreen")}),F);return()=>clearTimeout(e)}{A();let e=setTimeout((()=>l({shouldCallAuthOnSuccess:!0,isSuccess:!0})),m);return()=>clearTimeout(e)}}}),[T,j,N]),a((()=>{if(L&&0===M){let e=setTimeout((()=>{R(null),D(null);let e=document.querySelector("input[name=code-0]");e?.focus()}),1400);return()=>clearTimeout(e)}}),[L,M]);/*#__PURE__*/return e(b,{contactMethod:W,authFlow:0===U?"email":"sms",appName:c?.name,whatsAppEnabled:_,onBack:()=>t(),onCodeSubmit:async e=>{try{await S(e),I(!0)}catch(e){if(e instanceof v&&e.privyErrorCode===f.INVALID_CREDENTIALS)R("Invalid or expired verification code"),D(0);else if(e instanceof v&&e.privyErrorCode===f.CANNOT_LINK_MORE_OF_TYPE)R(e.message);else{if(e instanceof v&&e.privyErrorCode===f.USER_LIMIT_REACHED)return console.error(new h(e).toString()),void r("UserLimitReachedScreen");if(e instanceof v&&e.privyErrorCode===f.USER_DOES_NOT_EXIST)return void r("AccountNotFoundScreen");if(e instanceof v&&e.privyErrorCode===f.LINKED_TO_ANOTHER_USER)return i({errorModalData:{error:e,previousScreen:o??"AwaitingPasswordlessCodeScreen"}}),void r("ErrorScreen",!1);if(e instanceof v&&e.privyErrorCode===f.DISALLOWED_PLUS_EMAIL)return i({inlineError:{error:e}}),void r("ConnectOrCreateScreen",!1);if(e instanceof v&&e.privyErrorCode===f.ACCOUNT_TRANSFER_REQUIRED&&e.data?.data?.nonce)return i({accountTransfer:{nonce:e.data?.data?.nonce,account:W,displayName:e.data?.data?.account?.displayName,linkMethod:0===U?"email":"sms",embeddedWalletAddress:e.data?.data?.otherUser?.embeddedWalletAddress}}),void r("LinkConflictScreen");R("Issue verifying code"),D(0)}}},onResend:async()=>{P(30),0===U?await d():await E()},errorMessage:L||void 0,success:j,resendCountdown:O,onInvalidInput:e=>{R(e),D(1)},onClearError:()=>{1===M&&(R(null),D(null))}})}};let _=c.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: auto;
gap: 16px;
flex-grow: 1;
width: 100%;
`,j=c.div`
display: flex;
flex-direction: column;
width: 100%;
gap: 12px;
> div:first-child {
display: flex;
justify-content: center;
gap: 0.5rem;
width: 100%;
border-radius: var(--privy-border-radius-sm);
> input {
border: 1px solid var(--privy-color-foreground-4);
background: var(--privy-color-background);
border-radius: var(--privy-border-radius-sm);
padding: 8px 10px;
height: 48px;
width: 40px;
text-align: center;
font-size: 18px;
font-weight: 600;
color: var(--privy-color-foreground);
transition: all 0.2s ease;
}
> input:focus {
border: 1px solid var(--privy-color-foreground);
box-shadow: 0 0 0 1px var(--privy-color-foreground);
}
> input:invalid {
border: 1px solid var(--privy-color-error);
}
> input.success {
border: 1px solid var(--privy-color-border-success);
background: var(--privy-color-success-bg);
}
> input.fail {
border: 1px solid var(--privy-color-border-error);
background: var(--privy-color-error-bg);
animation: shake 180ms;
animation-iteration-count: 2;
}
}
@keyframes shake {
0% {
transform: translate(1px, 0px);
}
33% {
transform: translate(-1px, 0px);
}
67% {
transform: translate(-1px, 0px);
}
100% {
transform: translate(1px, 0px);
}
}
`,I=c.div`
line-height: 20px;
min-height: 20px;
font-size: 14px;
font-weight: 400;
color: ${e=>e.$success?"var(--privy-color-success-dark)":e.$fail?"var(--privy-color-error-dark)":"transparent"};
display: flex;
justify-content: center;
width: 100%;
text-align: center;
`,L=c.div`
display: flex;
gap: 8px;
align-items: center;
justify-content: center;
width: 100%;
color: var(--privy-color-foreground-2);
`,R=c.div`
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--privy-border-radius-sm);
padding: 2px 8px;
gap: 4px;
background: var(--privy-color-background-2);
color: var(--privy-color-foreground-2);
`,M=c.span`
font-weight: 500;
word-break: break-all;
color: var(--privy-color-foreground);
`;export{N as AwaitingPasswordlessCodeScreen,b as AwaitingPasswordlessCodeScreenView,N as default};