@privy-io/expo
Version:
Expo client for the Privy Auth API
2 lines (1 loc) • 9.7 kB
JavaScript
import{a as D,b as q,d as m,f as F,g as M}from"./chunk-QTVIWU3N.js";import{base58 as u,base64 as B}from"@scure/base";import*as c from"expo-linking";import{useState as X,useEffect as N,useRef as J,useCallback as Z}from"react";import C from"tweetnacl";import{createStore as ee}from"zustand";var E=F(M),v=(t,i,s)=>`${t}/ul/v1/${i}?${s.toString()}`,U=(t,i)=>{if(!i)throw new Error("missing shared secret");let s=C.randomBytes(24),h=C.box.after(Buffer.from(JSON.stringify(t)),s,i);return{nonce:u.encode(s),data:u.encode(h)}},K=(t,i,s)=>{if(!s)throw new Error("missing shared secret");let h=C.box.open.after(u.decode(t),u.decode(i),s);if(!h)throw new Error("Unable to decrypt data");return JSON.parse(Buffer.from(h).toString("utf8"))},ne=t=>JSON.stringify({publicKey:Array.from(t.publicKey),secretKey:Array.from(t.secretKey)}),re=t=>{let i=JSON.parse(t);return{publicKey:new Uint8Array(i.publicKey),secretKey:new Uint8Array(i.secretKey)}},z="wallet_keypair",x=6e4,W=({baseUrl:t,appUrl:i,redirectUri:s="/",autoReconnect:h=!0,encryptionPublicKeyName:l})=>{if(!t||!i||!s||!l)throw new Error("baseUrl, appUrl, redirectUri, and encryptionPublicKeyName are required");let{connection:p,setConnection:b,isConnected:P,sharedSecretRef:w}=te({baseUrl:t,autoReconnect:h}),e=J(null),$=Z(a=>m(void 0,null,function*(){var f;if(!a)return;let n=new URL(a).searchParams,d=n.get("wallet_id");if(!d||d!==l)return;if(n.get("errorCode")){let r=Object.fromEntries([...n]),g=(f=r==null?void 0:r.errorMessage)!=null?f:JSON.stringify(Object.fromEntries([...n]),null,2);console.error("Error from wallet provider: ",g);return}switch(n.get("wallet_action")){case"onConnect":try{if(!n.get("data")||!n.get("nonce")||!n.get(l))throw console.error("missing required fields in response"),new Error("missing required fields in response");let r=yield L(),g=C.box.before(u.decode(n.get(l)),r.secretKey),y=K(n.get("data"),n.get("nonce"),g);w.current=g,b(y),yield E.put(`${t}-key`,B.encode(g)),yield E.put(`${t}-data`,JSON.stringify(y))}catch(r){console.error("Failed to process connect response:",r)}break;case"onSignMessage":try{if(!e.current||e.current.type!=="signMessage"){console.warn("Received signature response but no pending signature request");return}if(!n.get("data")||!n.get("nonce"))throw console.error("missing required fields in response"),new Error("missing required fields in response");let r=K(n.get("data"),n.get("nonce"),w.current);e.current.resolve(r),e.current=null}catch(r){console.error("Failed to process signature response:",r),e.current&&(e.current.reject(r),e.current=null)}break;case"onSignTransaction":try{if(!e.current||e.current.type!=="signTransaction"){console.warn("Received signature response but no pending signature request");return}if(!n.get("data")||!n.get("nonce"))throw console.error("missing required fields in response"),new Error("missing required fields in response");let r=K(n.get("data"),n.get("nonce"),w.current);e.current.resolve(r),e.current=null}catch(r){console.error("Failed to process transaction response:",r),e.current&&(e.current.reject(r),e.current=null)}break;case"onSignAndSendTransaction":try{if(!e.current||e.current.type!=="signAndSendTransaction"){console.warn("Received signature response but no pending signature request");return}if(!n.get("data")||!n.get("nonce"))throw console.error("missing required fields in response"),new Error("missing required fields in response");let r=K(n.get("data"),n.get("nonce"),w.current);e.current.resolve(r),e.current=null}catch(r){console.error("Failed to process transaction response:",r),e.current&&(e.current.reject(r),e.current=null)}break;case"onSignAllTransactions":try{if(!e.current||e.current.type!=="signAllTransactions"){console.warn("Received signature response but no pending signature request");return}if(!n.get("data")||!n.get("nonce"))throw console.error("missing required fields in response"),new Error("missing required fields in response");let r=K(n.get("data"),n.get("nonce"),w.current);e.current.resolve(r),e.current=null}catch(r){console.error("Failed to process transaction response:",r),e.current&&(e.current.reject(r),e.current=null)}break;case"onDisconnect":b(null);break}}),[t,l,b,w]);N(()=>{(()=>m(void 0,null,function*(){let n=yield c.getInitialURL();n&&$(n)}))();let o=c.addEventListener("url",({url:n})=>$(n).catch(d=>{e.current&&(e.current.reject(d),e.current=null)}));return()=>{o.remove()}},[l,$]);let I=()=>m(void 0,null,function*(){try{let a=yield L();if(!a)throw new Error("No dapp key pair found");let o={session:p==null?void 0:p.session},{nonce:n,data:d}=U(o,w.current),S=new URLSearchParams({nonce:n,dapp_encryption_public_key:u.encode(a.publicKey),redirect_link:`${c.createURL(s)}?wallet_action=onDisconnect&wallet_id=${l}`,payload:d}),f=v(t,"disconnect",S);yield c.openURL(f)}catch(a){throw console.error("Failed to disconnect:",a),a}}),Y=a=>m(void 0,null,function*(){if(!P||!p)throw new Error("Wallet not connected");try{let o=yield L();if(!o)throw new Error("No dapp key pair found");let n={session:p.session,message:u.encode(Buffer.from(a)),display:"utf8"},{nonce:d,data:S}=U(n,w.current),f=new URLSearchParams({dapp_encryption_public_key:u.encode(o.publicKey),nonce:d,payload:S,redirect_link:`${c.createURL(s)}?wallet_action=onSignMessage&wallet_id=${l}`}),r=v(t,"signMessage",f);return new Promise((g,y)=>{c.openURL(r);let T=setTimeout(()=>{e.current&&(y(new Error("Signature request timed out")),e.current=null)},x),k=R=>{clearTimeout(T),g(R)},A=R=>{clearTimeout(T),y(R)};e.current={type:"signMessage",payload:a,resolve:k,reject:A}})}catch(o){throw e.current=null,console.error("Failed to sign message:",o),o}}),G=(a,o)=>m(void 0,null,function*(){if(!P||!p)throw new Error("Wallet not connected");try{let n=yield L();if(!n)throw new Error("No dapp key pair found");let d=a.serialize({requireAllSignatures:!1}),S={session:p.session,transaction:u.encode(d),sendOptions:o},{nonce:f,data:r}=U(S,w.current),g=new URLSearchParams({nonce:f,dapp_encryption_public_key:u.encode(n.publicKey),redirect_link:`${c.createURL(s)}?wallet_action=onSignAndSendTransaction&wallet_id=${l}`,payload:r}),y=v(t,"signAndSendTransaction",g);return new Promise((T,k)=>{c.openURL(y);let A=setTimeout(()=>{e.current&&(k(new Error("Signature request timed out")),e.current=null)},x),R=O=>{clearTimeout(A),T(O)},_=O=>{clearTimeout(A),k(O)};e.current={type:"signAndSendTransaction",payload:a,resolve:R,reject:_}})}catch(n){throw e.current=null,console.error("Failed to sign and send transaction:",n),n}}),H=a=>m(void 0,null,function*(){if(!P||!p)throw new Error("Wallet not connected");try{let o=yield L();if(!o)throw new Error("No dapp key pair found");let d={transactions:a.map(y=>u.encode(y.serialize({requireAllSignatures:!1}))),session:p.session},{nonce:S,data:f}=U(d,w.current),r=new URLSearchParams({nonce:S,dapp_encryption_public_key:u.encode(o.publicKey),redirect_link:`${c.createURL(s)}?wallet_action=onSignAllTransactions&wallet_id=${l}`,payload:f}),g=v(t,"signAllTransactions",r);return new Promise((y,T)=>{c.openURL(g);let k=setTimeout(()=>{e.current&&(T(new Error("Signature request timed out")),e.current=null)},x),A=_=>{clearTimeout(k),y(_)},R=_=>{clearTimeout(k),T(_)};e.current={type:"signAllTransactions",payload:a,resolve:A,reject:R}})}catch(o){throw e.current=null,console.error("Failed to sign all transactions:",o),o}}),Q=a=>m(void 0,null,function*(){if(!P||!p)throw new Error("Wallet not connected");try{let o=yield L();if(!o)throw new Error("No dapp key pair found");let n=a.serialize({requireAllSignatures:!1}),d={session:p.session,transaction:u.encode(n)},{nonce:S,data:f}=U(d,w.current),r=new URLSearchParams({nonce:S,dapp_encryption_public_key:u.encode(o.publicKey),redirect_link:`${c.createURL(s)}?wallet_action=onSignTransaction&wallet_id=${l}`,payload:f}),g=v(t,"signTransaction",r);return new Promise((y,T)=>{c.openURL(g);let k=setTimeout(()=>{e.current&&(T(new Error("Signature request timed out")),e.current=null)},x),A=_=>{clearTimeout(k),y(_)},R=_=>{clearTimeout(k),T(_)};e.current={type:"signTransaction",payload:a,resolve:A,reject:R}})}catch(o){throw e.current=null,console.error("Failed to sign transaction:",o),o}}),V=()=>m(void 0,null,function*(){let a=yield L();if(!a)throw new Error("No dapp key pair found");try{let o=new URLSearchParams({dapp_encryption_public_key:u.encode(a.publicKey),app_url:i,redirect_link:`${c.createURL(s)}?wallet_action=onConnect&wallet_id=${l}`}),n=v(t,"connect",o);yield c.openURL(n)}catch(o){console.error("Failed to open wallet connection:",o)}});return{address:p==null?void 0:p.public_key,connect:V,signMessage:Y,signTransaction:Q,signAndSendTransaction:G,signAllTransactions:H,disconnect:I,isConnected:P}},te=({autoReconnect:t,baseUrl:i})=>{let[s,h]=X(null),l=J(null);return N(()=>{let p=()=>m(void 0,null,function*(){let b=yield E.get(`${i}-key`),P=yield E.get(`${i}-data`);b&&P&&(l.current=B.decode(b),h(JSON.parse(P)))});t&&!l.current&&p().catch(console.warn)},[t,i]),{connection:s,setConnection:h,isConnected:!!s,sharedSecretRef:l}},j=ee(()=>({dappKeyPair:null})),L=()=>m(void 0,null,function*(){let t=j.getState().dappKeyPair;if(t)return t;try{let i=yield E.get(z);if(i&&typeof i=="string"){let s=re(i);return j.setState({dappKeyPair:s}),s}else{let s=C.box.keyPair();return j.setState({dappKeyPair:s}),yield E.put(z,ne(s)),s}}catch(i){throw console.error("Failed to initialize key pair:",i),i}});var de=t=>W(q(D({},t),{baseUrl:"https://phantom.app",encryptionPublicKeyName:"phantom_encryption_public_key"}));var we=t=>W(q(D({},t),{baseUrl:"https://backpack.app",encryptionPublicKeyName:"wallet_encryption_public_key"}));export{we as useBackpackDeeplinkWalletConnector,W as useDeeplinkWalletConnector,de as usePhantomDeeplinkWalletConnector};