@stacknet/keyutils 0.4.7 → 0.5.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/components/index.cjs +2 -2
- package/dist/components/index.d.cts +94 -15
- package/dist/components/index.d.ts +94 -15
- package/dist/components/index.js +2 -2
- package/dist/core/index.cjs +1 -1
- package/dist/core/index.js +1 -1
- package/dist/hooks/index.cjs +2 -2
- package/dist/hooks/index.d.cts +104 -8
- package/dist/hooks/index.d.ts +104 -8
- package/dist/hooks/index.js +2 -2
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/types/index.d.cts +100 -1
- package/dist/types/index.d.ts +100 -1
- package/dist/utils/index.cjs +1 -1
- package/dist/utils/index.d.cts +58 -3
- package/dist/utils/index.d.ts +58 -3
- package/dist/utils/index.js +1 -1
- package/package.json +1 -1
package/dist/hooks/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var react=require('react');require('react/jsx-runtime');var Y=react.createContext(null);function m(){let e=react.useContext(Y);if(!e)throw new Error("useKeyUtilsContext must be used within a KeyUtilsProvider");return e}function Z(e,a){if(typeof e!="string"||e.length===0)return a;let i=e.replace(/[\u0000-\u001F\u007F]/g," ");return i.length>500?i.slice(0,500)+"\u2026":i}async function y(e,a){try{let i=await e.json();if(i&&typeof i=="object"&&"error"in i)return Z(i.error,a)}catch{}return a}function Q(){let{config:e}=m(),[a,i]=react.useState(null),[u,f]=react.useState(true),[d,g]=react.useState(null),r=react.useRef(true),o=react.useRef(e.apiBaseUrl);o.current=e.apiBaseUrl;let l=async()=>{try{r.current&&(f(!0),g(null));let s=await fetch(`${o.current}/api/keys/pricing`,{credentials:"include"});if(!s.ok)throw new Error(await y(s,`Pricing unavailable (${s.status})`));let n=await s.json();r.current&&i(n);}catch(s){r.current&&g(s instanceof Error?s.message:"Failed to fetch pricing");}finally{r.current&&f(false);}};return react.useEffect(()=>{r.current=true,l();let s=setInterval(l,6e4);return ()=>{r.current=false,clearInterval(s);}},[]),{pricing:a,loading:u,error:d,refresh:l}}function ne(e){return {id:e.id||"",keyIndex:e.keyIndex??e.key_index??null,key:e.key||e.keyPrefix||"",userId:e.userId||e.user_id||"",status:e.status||"active",tokenBalance:e.tokenBalance??e.currentTokenBalance??e.current_token_balance??0,maxTokens:e.maxTokens??e.initialTokenBalance??e.initial_token_balance??0,createdAt:String(e.createdAt??e.created_at??""),expiresAt:e.expiresAt,label:e.label||e.keyPrefix||e.key_prefix||void 0,paperWork:e.paperWork||e.paper_work||void 0,stackId:e.stackId,stackName:e.stackName}}function se(){let{config:e}=m(),[a,i]=react.useState([]),[u,f]=react.useState(true),[d,g]=react.useState(null),r=react.useRef(true),o=e.apiBaseUrl,l=react.useCallback(async()=>{try{f(!0),g(null);let n=await fetch(`${o}/api/keys`,{credentials:"include"});if(!n.ok)throw new Error(await y(n,`Failed to fetch keys (${n.status})`));let t=await n.json(),c=Array.isArray(t)?t:t.keys??[];r.current&&i(c.map(ne));}catch(n){r.current&&g(n instanceof Error?n.message:"Failed to fetch keys");}finally{r.current&&f(false);}},[o]);react.useEffect(()=>(r.current=true,l(),()=>{r.current=false;}),[l]);let s=a.reduce((n,t)=>n+t.tokenBalance,0);return {keys:a,totalBalance:s,loading:u,error:d,refresh:l}}function N(e){let a=e.type||e.entry_type||"debit",i=e.amount??e.tokens??e.token_amount??0,u=e.description||e.memo||e.reason||ie(a);return {id:e.id||"",keyId:e.keyId||e.key_id||"",type:a,amount:i,description:u,createdAt:String(e.createdAt??e.created_at??e.timestamp??""),metadata:e.metadata||void 0}}function ie(e){switch(e){case "credit":return "Credit";case "debit":return "Usage";case "mint":return "Mint";case "reward":return "Reward";default:return ""}}function le(e){let{config:a}=m(),[i,u]=react.useState([]),[f,d]=react.useState(false),[g,r]=react.useState(null),o=react.useRef(true),l=a.apiBaseUrl,s=react.useCallback(async()=>{if(e)try{d(!0),r(null);let n=await fetch(`${l}/api/keys/${encodeURIComponent(e)}/ledger`,{credentials:"include"});if(!n.ok)throw new Error(await y(n,`Failed to fetch ledger (${n.status})`));let t=await n.json(),c=Array.isArray(t)?t:t.entries??[];o.current&&u(c.map(N));}catch(n){o.current&&r(n instanceof Error?n.message:"Failed to fetch ledger");}finally{o.current&&d(false);}},[l,e]);return react.useEffect(()=>(o.current=true,s(),()=>{o.current=false;}),[s]),{entries:i,loading:f,error:g,refresh:s}}function k(){if(typeof document>"u")return {};let e=document.cookie.match(/(?:^|;\s*)__csrf=([^;]*)/);return e?{"x-csrf-token":e[1]}:{}}function fe(){let{config:e,callbacks:a}=m(),[i,u]=react.useState(false),[f,d]=react.useState(null),[g,r]=react.useState(null);return {mint:react.useCallback(async(l,s,n=1)=>{try{u(!0),r(null),a.onPaymentComplete?.(l,s);let t=await fetch(`${e.apiBaseUrl}/api/keys/mint`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({paymentMethod:l,paymentRef:s,quantity:n,stackId:e.stackId})});if(!t.ok)throw new Error(await y(t,`Key generation failed (${t.status})`));let c=await t.json(),p=c.keys?.[0]||c,h={success:!0,key:{id:p.keyId||p.id||"",key:p.key||"",userId:p.userId||"",status:"active",tokenBalance:p.tokenBalance??p.currentTokenBalance??0,maxTokens:p.initialTokenBalance??p.tokenBalance??0,createdAt:String(p.createdAt||Date.now())},transactionId:s};return d(h),a.onMintSuccess?.(h),h}catch(t){let c=t instanceof Error?t:new Error("Key generation failed");return r(c.message),a.onMintError?.(c),{success:false,error:c.message}}finally{u(false);}},[e.apiBaseUrl,a]),minting:i,result:f,error:g}}function ge(){let{config:e,callbacks:a}=m(),[i,u]=react.useState(false),[f,d]=react.useState(null),[g,r]=react.useState(null),o=react.useRef(true),l=react.useCallback(async(n,t)=>{try{u(!0),r(null);let c=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(n)}/list`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({askPriceCents:t,stackId:e.stackId,stackName:e.stackName})});if(!c.ok)throw new Error(await y(c,`Listing failed (${c.status})`));let p=await c.json();return o.current&&(d(p),a.onListingCreated?.(p)),p}catch(c){let p=c instanceof Error?c.message:"Listing failed";return o.current&&r(p),null}finally{o.current&&u(false);}},[e.apiBaseUrl,e.stackId,e.stackName,a]),s=react.useCallback(async n=>{try{u(!0),r(null);let t=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(n)}/list`,{method:"DELETE",headers:{...k()},credentials:"include"});if(!t.ok)throw new Error(await y(t,`Delist failed (${t.status})`));return o.current&&d(null),!0}catch(t){let c=t instanceof Error?t.message:"Delist failed";return o.current&&r(c),false}finally{o.current&&u(false);}},[e.apiBaseUrl]);return {listKey:l,delistKey:s,listing:i,result:f,error:g}}function pe(){let{config:e}=m(),[a,i]=react.useState(false),[u,f]=react.useState(null),d=react.useRef(true);return {createSession:react.useCallback(async(r,o)=>{try{i(!0),f(null);let l=await fetch(`${e.apiBaseUrl}/api/keys/stripe-session`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({priceCents:r,quantity:o,stackId:e.stackId,referrerUrl:window.location.href})});if(!l.ok)throw new Error(await y(l,`Checkout failed (${l.status})`));let{url:s}=await l.json();if(!s)throw new Error("No checkout URL returned");let n;try{n=new URL(s);}catch{throw new Error("Invalid checkout URL")}if(n.protocol!=="https:"||!/(^|\.)stripe\.com$/.test(n.hostname))throw new Error("Refusing to redirect to non-Stripe URL");try{sessionStorage.setItem("keyutils_stripe_pending","1"),sessionStorage.setItem("keyutils_stripe_quantity",String(o));}catch{}window.location.href=n.toString();}catch(l){if(d.current){let s=l instanceof Error?l.message:"Checkout failed";f(s),i(false);}}},[e.apiBaseUrl,e.stackId]),loading:a,error:u}}function H(e,a="#"){if(!e||typeof e!="string")return a;let i=e.trim();if(i===""||i==="#")return a;if(i.startsWith("/")||i.startsWith("./")||i.startsWith("../"))return i;try{let u=new URL(i);if(u.protocol==="http:"||u.protocol==="https:")return u.toString()}catch{}return a}var v=/^[1-9A-HJ-NP-Za-km-z]{32,44}$/;function he(){let{config:e}=m(),[a,i]=react.useState(false),[u,f]=react.useState(null);return {pay:react.useCallback(async g=>{if(!e.merchantWallet||!v.test(e.merchantWallet))throw new Error("Merchant wallet not configured");try{i(!0),f(null);let{Connection:r,PublicKey:o,Transaction:l,SystemProgram:s}=await import('@solana/web3.js'),n=typeof window<"u"?window.solana:void 0;if(!n||typeof n!="object"||!n.isPhantom)throw new Error("Phantom wallet not found. Please install Phantom.");let t=n,c=new o(e.merchantWallet),p=await t.connect(),h=new o(p.publicKey.toString()),L="https://api.mainnet-beta.solana.com",T=H(e.solanaRpcUrl,L),j=T==="#"?L:T,D=new r(j),{blockhash:W}=await D.getLatestBlockhash(),R=BigInt(Math.floor(g*1e9)),P=e.protocolTreasuryWallet,B=e.protocolFeeBps??500,b=new l({recentBlockhash:W,feePayer:h});if(P&&v.test(P)&&B>0){let M=R*BigInt(B)/10000n,q=R-M,z=new o(P);b.add(s.transfer({fromPubkey:h,toPubkey:c,lamports:Number(q)}),s.transfer({fromPubkey:h,toPubkey:z,lamports:Number(M)}));}else b.add(s.transfer({fromPubkey:h,toPubkey:c,lamports:Number(R)}));let{signature:J}=await t.signAndSendTransaction(b);return J}catch(r){let o=r instanceof Error?r:new Error("SOL payment failed");throw f(o.message),o}finally{i(false);}},[e.merchantWallet,e.protocolTreasuryWallet,e.protocolFeeBps,e.solanaRpcUrl]),processing:a,error:u}}function be(){let{config:e,callbacks:a}=m(),[i,u]=react.useState(false),[f,d]=react.useState(null),[g,r]=react.useState(null),o=react.useRef(true);return {transferKey:react.useCallback(async(s,n)=>{try{u(!0),r(null);let t=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(s)}/transfer`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({recipientId:n})});if(!t.ok)throw new Error(await y(t,`Transfer failed (${t.status})`));let c=await t.json();return o.current&&(d(c),a.onTransferComplete?.(c)),c}catch(t){let c=t instanceof Error?t.message:"Transfer failed";return o.current&&r(c),null}finally{o.current&&u(false);}},[e.apiBaseUrl,a]),transferring:i,result:f,error:g}}function Ee(){let{config:e,callbacks:a}=m(),[i,u]=react.useState(false),[f,d]=react.useState(null),[g,r]=react.useState(null),o=react.useRef(true),l=react.useCallback(async n=>{try{u(!0),r(null);let t=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(n)}/file`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({stackId:e.stackId})});if(!t.ok)throw new Error(await y(t,`Filing failed (${t.status})`));let c=await t.json();return o.current&&(d(c),a.onFilingComplete?.(c)),c}catch(t){let c=t instanceof Error?t:new Error("Filing failed");return o.current&&r(c.message),a.onFilingError?.(c),null}finally{o.current&&u(false);}},[e.apiBaseUrl,e.stackId,a]),s=react.useCallback(()=>{d(null),r(null);},[]);return {filePaperwork:l,filing:i,result:f,error:g,reset:s}}function Ie(){let{config:e}=m(),[a,i]=react.useState([]),[u,f]=react.useState(true),[d,g]=react.useState(null),r=react.useRef(true),o=e.apiBaseUrl,l=react.useCallback(async()=>{try{f(!0),g(null);let s=await fetch(`${o}/api/keys/filings`,{credentials:"include"});if(!s.ok)throw new Error(await y(s,`Failed to fetch filings (${s.status})`));let n=await s.json(),t=Array.isArray(n)?n:n.filings??[];r.current&&i(t);}catch(s){r.current&&g(s instanceof Error?s.message:"Failed to fetch filings");}finally{r.current&&f(false);}},[o]);return react.useEffect(()=>(r.current=true,l(),()=>{r.current=false;}),[l]),{entries:a,loading:u,error:d,refresh:l}}
|
|
2
|
-
exports.useFilePaperwork=
|
|
1
|
+
'use strict';var react=require('react');require('react/jsx-runtime');var ne=react.createContext(null);function y(){let e=react.useContext(ne);if(!e)throw new Error("useKeyUtilsContext must be used within a KeyUtilsProvider");return e}function se(e,n){if(typeof e!="string"||e.length===0)return n;let t=e.replace(/[\u0000-\u001F\u007F]/g," ");return t.length>500?t.slice(0,500)+"\u2026":t}async function p(e,n){try{let t=await e.json();if(t&&typeof t=="object"&&"error"in t)return se(t.error,n)}catch{}return n}function ie(){let{config:e}=y(),[n,t]=react.useState(null),[f,d]=react.useState(true),[m,u]=react.useState(null),i=react.useRef(true),o=react.useRef(e.apiBaseUrl);o.current=e.apiBaseUrl;let a=async()=>{try{i.current&&(d(!0),u(null));let s=await fetch(`${o.current}/api/keys/pricing`,{credentials:"include"});if(!s.ok)throw new Error(await p(s,`Pricing unavailable (${s.status})`));let r=await s.json();i.current&&t(r);}catch(s){i.current&&u(s instanceof Error?s.message:"Failed to fetch pricing");}finally{i.current&&d(false);}};return react.useEffect(()=>{i.current=true,a();let s=setInterval(a,6e4);return ()=>{i.current=false,clearInterval(s);}},[]),{pricing:n,loading:f,error:m,refresh:a}}function ue(e){return {id:e.id||"",keyIndex:e.keyIndex??e.key_index??null,key:e.id||e.key||e.keyPrefix||"",userId:e.userId||e.user_id||"",status:e.status||"active",tokenBalance:e.tokenBalance??e.currentTokenBalance??e.current_token_balance??0,maxTokens:e.maxTokens??e.initialTokenBalance??e.initial_token_balance??0,createdAt:String(e.createdAt??e.created_at??""),expiresAt:e.expiresAt,label:e.label||void 0,paperWork:e.paperWork||e.paper_work||void 0,stackId:e.stackId,stackName:e.stackName}}function fe(){let{config:e}=y(),[n,t]=react.useState([]),[f,d]=react.useState(true),[m,u]=react.useState(null),i=react.useRef(true),o=e.apiBaseUrl,a=react.useCallback(async()=>{try{d(!0),u(null);let r=await fetch(`${o}/api/keys`,{credentials:"include"});if(!r.ok)throw new Error(await p(r,`Failed to fetch keys (${r.status})`));let c=await r.json(),l=Array.isArray(c)?c:c.keys??[];i.current&&t(l.map(ue));}catch(r){i.current&&u(r instanceof Error?r.message:"Failed to fetch keys");}finally{i.current&&d(false);}},[o]);react.useEffect(()=>(i.current=true,a(),()=>{i.current=false;}),[a]);let s=n.reduce((r,c)=>r+c.tokenBalance,0);return {keys:n,totalBalance:s,loading:f,error:m,refresh:a}}var N=false;function k(){if(typeof document>"u")return {};let e=document.cookie.match(/(?:^|;\s*)__csrf=([^;]*)/);if(!e)return N||(N=true,console.warn("[keyutils] __csrf cookie not found; mutations will be sent without a CSRF token")),{};let n=e[1];try{n=decodeURIComponent(n);}catch{}return {"x-csrf-token":n}}function _(e){let n=e.type||e.entry_type||"debit",t=e.amount??e.tokens??e.token_amount??0,f=e.description||e.memo||e.reason||de(n);return {id:e.id||"",keyId:e.keyId||e.key_id||"",type:n,amount:t,description:f,createdAt:String(e.createdAt??e.created_at??e.timestamp??""),metadata:e.metadata||void 0}}function de(e){switch(e){case "credit":return "Credit";case "debit":return "Usage";case "mint":return "Mint";case "reward":return "Reward";default:return ""}}function ge(e){let{config:n}=y(),[t,f]=react.useState([]),[d,m]=react.useState(false),[u,i]=react.useState(null),o=react.useRef(true),a=n.apiBaseUrl,s=react.useCallback(async()=>{if(e)try{m(!0),i(null);let r=await fetch(`${a}/api/keys/${encodeURIComponent(e)}/ledger`,{credentials:"include"});if(!r.ok)throw new Error(await p(r,`Failed to fetch ledger (${r.status})`));let c=await r.json(),l=Array.isArray(c)?c:c.entries??[];o.current&&f(l.map(_));}catch(r){o.current&&i(r instanceof Error?r.message:"Failed to fetch ledger");}finally{o.current&&m(false);}},[a,e]);return react.useEffect(()=>(o.current=true,s(),()=>{o.current=false;}),[s]),{entries:t,loading:d,error:u,refresh:s}}function he(){let{config:e,callbacks:n}=y(),[t,f]=react.useState(false),[d,m]=react.useState(null),[u,i]=react.useState(null);return {mint:react.useCallback(async(a,s,r=1)=>{try{f(!0),i(null),n.onPaymentComplete?.(a,s);let c=await fetch(`${e.apiBaseUrl}/api/keys/mint`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({paymentMethod:a,paymentRef:s,quantity:r,stackId:e.stackId})});if(!c.ok)throw new Error(await p(c,`Key generation failed (${c.status})`));let l=await c.json(),g=l.keys?.[0]||l,h={success:!0,key:{id:g.keyId||g.id||"",key:g.key||"",userId:g.userId||"",status:"active",tokenBalance:g.tokenBalance??g.currentTokenBalance??0,maxTokens:g.initialTokenBalance??g.tokenBalance??0,createdAt:String(g.createdAt||Date.now())},transactionId:s};return m(h),n.onMintSuccess?.(h),h}catch(c){let l=c instanceof Error?c:new Error("Key generation failed");return i(l.message),n.onMintError?.(l),{success:false,error:l.message}}finally{f(false);}},[e.apiBaseUrl,n]),minting:t,result:d,error:u}}function Pe(){let{config:e,callbacks:n}=y(),[t,f]=react.useState(false),[d,m]=react.useState(null),[u,i]=react.useState(null),o=react.useRef(true),a=react.useCallback(async(r,c)=>{try{f(!0),i(null);let l=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(r)}/list`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({askPriceCents:c,stackId:e.stackId,stackName:e.stackName})});if(!l.ok)throw new Error(await p(l,`Listing failed (${l.status})`));let g=await l.json();return o.current&&(m(g),n.onListingCreated?.(g)),g}catch(l){let g=l instanceof Error?l.message:"Listing failed";return o.current&&i(g),null}finally{o.current&&f(false);}},[e.apiBaseUrl,e.stackId,e.stackName,n]),s=react.useCallback(async r=>{try{f(!0),i(null);let c=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(r)}/list`,{method:"DELETE",headers:{...k()},credentials:"include"});if(!c.ok)throw new Error(await p(c,`Delist failed (${c.status})`));return o.current&&m(null),!0}catch(c){let l=c instanceof Error?c.message:"Delist failed";return o.current&&i(l),false}finally{o.current&&f(false);}},[e.apiBaseUrl]);return {listKey:a,delistKey:s,listing:t,result:d,error:u}}function we(){let{config:e}=y(),[n,t]=react.useState(false),[f,d]=react.useState(null),m=react.useRef(true);return {createSession:react.useCallback(async(i,o)=>{try{t(!0),d(null);let a=await fetch(`${e.apiBaseUrl}/api/keys/stripe-session`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({priceCents:i,quantity:o,stackId:e.stackId,referrerUrl:window.location.href})});if(!a.ok)throw new Error(await p(a,`Checkout failed (${a.status})`));let{url:s}=await a.json();if(!s)throw new Error("No checkout URL returned");let r;try{r=new URL(s);}catch{throw new Error("Invalid checkout URL")}if(r.protocol!=="https:"||!/(^|\.)stripe\.com$/.test(r.hostname))throw new Error("Refusing to redirect to non-Stripe URL");try{sessionStorage.setItem("keyutils_stripe_pending","1"),sessionStorage.setItem("keyutils_stripe_quantity",String(o));}catch{}window.location.href=r.toString();}catch(a){if(m.current){let s=a instanceof Error?a.message:"Checkout failed";d(s),t(false);}}},[e.apiBaseUrl,e.stackId]),loading:n,error:f}}function O(e,n="#"){if(!e||typeof e!="string")return n;let t=e.trim();if(t===""||t==="#")return n;if(t.startsWith("/")||t.startsWith("./")||t.startsWith("../"))return t;try{let f=new URL(t);if(f.protocol==="http:"||f.protocol==="https:")return f.toString()}catch{}return n}var W=/^[1-9A-HJ-NP-Za-km-z]{32,44}$/;function Ce(){let{config:e}=y(),[n,t]=react.useState(false),[f,d]=react.useState(null);return {pay:react.useCallback(async u=>{if(!e.merchantWallet||!W.test(e.merchantWallet))throw new Error("Merchant wallet not configured");try{t(!0),d(null);let{Connection:i,PublicKey:o,Transaction:a,SystemProgram:s}=await import('@solana/web3.js'),r=typeof window<"u"?window.solana:void 0;if(!r||typeof r!="object"||!r.isPhantom)throw new Error("Phantom wallet not found. Please install Phantom.");let c=r,l=new o(e.merchantWallet),g=await c.connect(),h=new o(g.publicKey.toString()),M="https://api.mainnet-beta.solana.com",$=O(e.solanaRpcUrl,M),X=$==="#"?M:$,Y=new i(X),{blockhash:Z}=await Y.getLatestBlockhash(),P=BigInt(Math.floor(u*1e9)),b=e.protocolTreasuryWallet,F=e.protocolFeeBps??500,U=new a({recentBlockhash:Z,feePayer:h});if(b&&W.test(b)&&F>0){let A=P*BigInt(F)/10000n,Q=P-A,ee=new o(b);U.add(s.transfer({fromPubkey:h,toPubkey:l,lamports:Number(Q)}),s.transfer({fromPubkey:h,toPubkey:ee,lamports:Number(A)}));}else U.add(s.transfer({fromPubkey:h,toPubkey:l,lamports:Number(P)}));let{signature:G}=await c.signAndSendTransaction(U);return G}catch(i){let o=i instanceof Error?i:new Error("SOL payment failed");throw d(o.message),o}finally{t(false);}},[e.merchantWallet,e.protocolTreasuryWallet,e.protocolFeeBps,e.solanaRpcUrl]),processing:n,error:f}}function xe(){let{config:e,callbacks:n}=y(),[t,f]=react.useState(false),[d,m]=react.useState(null),[u,i]=react.useState(null),o=react.useRef(true);return {transferKey:react.useCallback(async(s,r)=>{try{f(!0),i(null);let c=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(s)}/transfer`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({recipientId:r})});if(!c.ok)throw new Error(await p(c,`Transfer failed (${c.status})`));let l=await c.json();return o.current&&(m(l),n.onTransferComplete?.(l)),l}catch(c){let l=c instanceof Error?c.message:"Transfer failed";return o.current&&i(l),null}finally{o.current&&f(false);}},[e.apiBaseUrl,n]),transferring:t,result:d,error:u}}function Le(){let{config:e,callbacks:n}=y(),[t,f]=react.useState(false),[d,m]=react.useState(null),[u,i]=react.useState(null),o=react.useRef(true);react.useEffect(()=>(o.current=true,()=>{o.current=false;}),[]);let a=react.useCallback(async(r,c)=>{try{f(!0),i(null);let l={stackId:e.stackId};c&&(l.payoutMethod=c);let g=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(r)}/file`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify(l)});if(!g.ok)throw new Error(await p(g,`Filing failed (${g.status})`));let h=await g.json();return o.current&&(m(h),n.onFilingComplete?.(h)),h}catch(l){let g=l instanceof Error?l:new Error("Filing failed");return o.current&&i(g.message),n.onFilingError?.(g),null}finally{o.current&&f(false);}},[e.apiBaseUrl,e.stackId,n]),s=react.useCallback(()=>{m(null),i(null);},[]);return {filePaperwork:a,filing:t,result:d,error:u,reset:s}}function Fe(){let{config:e}=y(),[n,t]=react.useState([]),[f,d]=react.useState(true),[m,u]=react.useState(null),i=react.useRef(true),o=e.apiBaseUrl,a=react.useCallback(async()=>{try{d(!0),u(null);let s=await fetch(`${o}/api/keys/filings`,{credentials:"include"});if(!s.ok)throw new Error(await p(s,`Failed to fetch filings (${s.status})`));let r=await s.json(),c=Array.isArray(r)?r:r.filings??[];i.current&&t(c);}catch(s){i.current&&u(s instanceof Error?s.message:"Failed to fetch filings");}finally{i.current&&d(false);}},[o]);return react.useEffect(()=>(i.current=true,a(),()=>{i.current=false;}),[a]),{entries:n,loading:f,error:m,refresh:a}}function _e(e){let{config:n}=y(),t=e??n.stackId,f=n.apiBaseUrl,[d,m]=react.useState(null),[u,i]=react.useState(!!t),[o,a]=react.useState(null),s=react.useRef(true),r=react.useCallback(async()=>{if(!t){m(null),i(false);return}try{i(!0),a(null);let c=await fetch(`${f}/api/stacks/${encodeURIComponent(t)}/payout-capabilities`,{credentials:"include"});if(!c.ok)throw new Error(await p(c,`Failed to load payout capabilities (${c.status})`));let l=await c.json();s.current&&m(l);}catch(c){s.current&&a(c instanceof Error?c.message:"Failed to load payout capabilities");}finally{s.current&&i(false);}},[f,t]);return react.useEffect(()=>(s.current=true,r(),()=>{s.current=false;}),[r]),{caps:d,loading:u,error:o,refresh:r}}var je=5e3;function We(e){return e==="paid"||e==="failed"}function Je(e){let{config:n}=y(),t=n.apiBaseUrl,[f,d]=react.useState(null),[m,u]=react.useState(!!e),[i,o]=react.useState(null),a=react.useRef(true),s=react.useCallback(async()=>{if(!e){d(null),u(false);return}try{o(null);let r=await fetch(`${t}/api/keys/filings/${encodeURIComponent(e)}`,{credentials:"include"});if(!r.ok)throw new Error(await p(r,`Failed to load filing (${r.status})`));let c=await r.json();a.current&&d(c);}catch(r){a.current&&o(r instanceof Error?r.message:"Failed to load filing");}finally{a.current&&u(false);}},[t,e]);return react.useEffect(()=>{if(a.current=true,!e)return d(null),u(false),()=>{a.current=false;};u(true),s();let r=setInterval(()=>{a.current&&(f&&We(f.status)||s());},je);return ()=>{a.current=false,clearInterval(r);}},[e,s,f]),{detail:f,loading:m,error:i,refresh:s}}function ze(){let{config:e}=y(),[n,t]=react.useState(null),[f,d]=react.useState(true),[m,u]=react.useState(null),[i,o]=react.useState(false),a=react.useRef(true),s=e.apiBaseUrl,r=react.useCallback(async()=>{try{d(!0),u(null);let l=await fetch(`${s}/api/payout`,{credentials:"include"});if(!l.ok)throw new Error(await p(l,`Failed to load payout account (${l.status})`));let g=await l.json();a.current&&t(g);}catch(l){a.current&&u(l instanceof Error?l.message:"Failed to load payout account");}finally{a.current&&d(false);}},[s]);react.useEffect(()=>(a.current=true,r(),()=>{a.current=false;}),[r]);let c=react.useCallback(async()=>{try{o(!0),u(null);let l=await fetch(`${s}/api/payout`,{method:"DELETE",headers:{...k()},credentials:"include"});if(!l.ok&&l.status!==204)throw new Error(await p(l,`Disconnect failed (${l.status})`));return a.current&&t({method:null}),!0}catch(l){return a.current&&u(l instanceof Error?l.message:"Disconnect failed"),false}finally{a.current&&o(false);}},[s]);return {account:n,loading:f,error:m,refresh:r,disconnect:c,disconnecting:i}}function Ye(){let{config:e}=y(),[n,t]=react.useState(false),[f,d]=react.useState(null);return {startStripeConnect:react.useCallback(async()=>{try{t(!0),d(null);let u=await fetch(`${e.apiBaseUrl}/api/payout/stripe/start`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({stackId:e.stackId})});if(!u.ok)throw new Error(await p(u,`Stripe Connect start failed (${u.status})`));let i=await u.json();if(typeof window<"u"&&i.onboardingUrl){let o;try{o=new URL(i.onboardingUrl);}catch{throw new Error("Invalid onboarding URL")}if(o.protocol!=="https:"||!/(^|\.)stripe\.com$/.test(o.hostname))throw new Error("Refusing to redirect to non-Stripe URL");window.location.href=o.toString();return}}catch(u){d(u instanceof Error?u.message:"Stripe Connect start failed");}finally{t(false);}},[e.apiBaseUrl,e.stackId]),starting:n,error:f}}function Ge(){if(typeof window>"u")return null;let e=window,n=e.solana,t=e.phantom?.solana;return ((n&&n.isPhantom?n:null)||(t&&t.isPhantom?t:null))??null}function Qe(e){let n="";for(let t=0;t<e.length;t+=1)n+=String.fromCharCode(e[t]);return typeof btoa=="function"?btoa(n):Buffer.from(e).toString("base64")}function et(){let{config:e}=y(),[n,t]=react.useState(false),[f,d]=react.useState(null);return {connectAndVerify:react.useCallback(async()=>{try{t(!0),d(null);let u=Ge();if(!u)throw new Error("Phantom wallet not found. Install Phantom to continue.");let o=(await u.connect()).publicKey.toString(),a=await fetch(`${e.apiBaseUrl}/api/payout/crypto/nonce`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({address:o})});if(!a.ok)throw new Error(await p(a,`Nonce request failed (${a.status})`));let{nonce:s,message:r}=await a.json(),c=new TextEncoder().encode(r),l=await u.signMessage(c,"utf8"),g=Qe(l.signature),h=await fetch(`${e.apiBaseUrl}/api/payout/crypto/verify`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({address:o,nonce:s,signature:g})});if(!h.ok)throw new Error(await p(h,`Verification failed (${h.status})`));return {address:o}}catch(u){let i=u instanceof Error?u:new Error("Wallet verification failed");return d(i.message),null}finally{t(false);}},[e.apiBaseUrl]),connecting:n,error:f}}
|
|
2
|
+
exports.useCryptoConnect=et;exports.useFilePaperwork=Le;exports.useFilingDetail=Je;exports.useFilingHistory=Fe;exports.useKeyLedger=ge;exports.useKeys=fe;exports.useListKey=Pe;exports.useMintKey=he;exports.usePayoutAccount=ze;exports.usePricing=ie;exports.useSolanaPayment=Ce;exports.useStackPayoutCapabilities=_e;exports.useStripeCheckout=we;exports.useStripeConnect=Ye;exports.useTransferKey=xe;
|
package/dist/hooks/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PricingInfo, NodeKeyInfo, LedgerEntry, PaymentMethod, MintResult, ListingResult, DirectTransferResult, FilingResult, FilingHistoryEntry } from '../types/index.cjs';
|
|
1
|
+
import { PricingInfo, NodeKeyInfo, LedgerEntry, PaymentMethod, MintResult, ListingResult, DirectTransferResult, PayoutMethod, FilingResult, FilingHistoryEntry, StackPayoutCapabilities, FilingDetail, PayoutAccount } from '../types/index.cjs';
|
|
2
2
|
|
|
3
3
|
interface UsePricingReturn {
|
|
4
4
|
pricing: PricingInfo | null;
|
|
@@ -72,7 +72,7 @@ interface UseTransferKeyReturn {
|
|
|
72
72
|
declare function useTransferKey(): UseTransferKeyReturn;
|
|
73
73
|
|
|
74
74
|
interface UseFilePaperworkReturn {
|
|
75
|
-
filePaperwork: (keyId: string) => Promise<FilingResult | null>;
|
|
75
|
+
filePaperwork: (keyId: string, payoutMethod?: PayoutMethod | null) => Promise<FilingResult | null>;
|
|
76
76
|
filing: boolean;
|
|
77
77
|
result: FilingResult | null;
|
|
78
78
|
error: string | null;
|
|
@@ -82,11 +82,17 @@ interface UseFilePaperworkReturn {
|
|
|
82
82
|
* File paperwork against an eligible NodeKey to redeem Paper.
|
|
83
83
|
*
|
|
84
84
|
* Backend contract: POST {apiBaseUrl}/api/keys/{keyId}/file
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
85
|
+
* Request body: { stackId?, payoutMethod? }
|
|
86
|
+
* - On stacknet versions that read from `user_payout_accounts`, the body
|
|
87
|
+
* can omit everything user-controlled — the server derives the method
|
|
88
|
+
* and destination from the user's saved earnings account.
|
|
89
|
+
* - For backward compatibility with stacknet versions that still REQUIRE
|
|
90
|
+
* `payoutMethod` in the body, callers can pass the method they read
|
|
91
|
+
* from `usePayoutAccount()`. The server (new path) verifies the hint
|
|
92
|
+
* matches the saved record and rejects mismatches with 400.
|
|
93
|
+
* - Memo, amount, beneficiary are always server-derived.
|
|
94
|
+
* Response: FilingResult JSON with `filingId` (used to look up the detail /
|
|
95
|
+
* tracker view at /files/{filingId}).
|
|
90
96
|
*/
|
|
91
97
|
declare function useFilePaperwork(): UseFilePaperworkReturn;
|
|
92
98
|
|
|
@@ -104,4 +110,94 @@ interface UseFilingHistoryReturn {
|
|
|
104
110
|
*/
|
|
105
111
|
declare function useFilingHistory(): UseFilingHistoryReturn;
|
|
106
112
|
|
|
107
|
-
|
|
113
|
+
interface UseStackPayoutCapabilitiesReturn {
|
|
114
|
+
caps: StackPayoutCapabilities | null;
|
|
115
|
+
loading: boolean;
|
|
116
|
+
error: string | null;
|
|
117
|
+
refresh: () => Promise<void>;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Fetch per-stack payout capabilities (which methods are configured + the
|
|
121
|
+
* default destination address). Drives the payout-method picker — Stripe
|
|
122
|
+
* tile is rendered disabled with "disabled by {stackName} stack" UX when
|
|
123
|
+
* `caps.stripe.enabled === false`.
|
|
124
|
+
*
|
|
125
|
+
* Backend contract: GET {apiBaseUrl}/api/stacks/{stackId}/payout-capabilities
|
|
126
|
+
*
|
|
127
|
+
* Falls back gracefully when no stackId is configured — returns null caps.
|
|
128
|
+
*/
|
|
129
|
+
declare function useStackPayoutCapabilities(stackIdOverride?: string): UseStackPayoutCapabilitiesReturn;
|
|
130
|
+
|
|
131
|
+
interface UseFilingDetailReturn {
|
|
132
|
+
detail: FilingDetail | null;
|
|
133
|
+
loading: boolean;
|
|
134
|
+
error: string | null;
|
|
135
|
+
refresh: () => Promise<void>;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Fetch a single filing's detail (status, tracker, tx sigs, etc.) and poll
|
|
139
|
+
* every 5 s while non-terminal. Stops polling once status is `paid` or
|
|
140
|
+
* `failed`. Used by both the inline post-submit tracker and the standalone
|
|
141
|
+
* /files/{id} route.
|
|
142
|
+
*
|
|
143
|
+
* Backend contract: GET {apiBaseUrl}/api/keys/filings/{filingId}
|
|
144
|
+
*/
|
|
145
|
+
declare function useFilingDetail(filingId: string | null | undefined): UseFilingDetailReturn;
|
|
146
|
+
|
|
147
|
+
interface UsePayoutAccountReturn {
|
|
148
|
+
account: PayoutAccount | null;
|
|
149
|
+
loading: boolean;
|
|
150
|
+
error: string | null;
|
|
151
|
+
refresh: () => Promise<void>;
|
|
152
|
+
/** Disconnect the current method (deletes saved payout config). */
|
|
153
|
+
disconnect: () => Promise<boolean>;
|
|
154
|
+
disconnecting: boolean;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Read + manage the user's payout account.
|
|
158
|
+
*
|
|
159
|
+
* Backend contract:
|
|
160
|
+
* GET {apiBaseUrl}/api/payout → PayoutAccount
|
|
161
|
+
* DELETE {apiBaseUrl}/api/payout → 204
|
|
162
|
+
*
|
|
163
|
+
* The account is per-user (not per-stack). Switching methods (e.g. crypto →
|
|
164
|
+
* stripe) replaces the previous record server-side.
|
|
165
|
+
*/
|
|
166
|
+
declare function usePayoutAccount(): UsePayoutAccountReturn;
|
|
167
|
+
|
|
168
|
+
interface UseStripeConnectReturn {
|
|
169
|
+
/**
|
|
170
|
+
* Kick off Stripe Connect Express onboarding. Server creates an Express
|
|
171
|
+
* connected account under the stack's platform Stripe credentials,
|
|
172
|
+
* generates an AccountLink, and returns its URL. The browser is then
|
|
173
|
+
* redirected to that URL — Stripe hosts the rest of the onboarding flow
|
|
174
|
+
* (KYC, bank details, payouts opt-in) and bounces back to
|
|
175
|
+
* `/settings?tab=account&stripe_return=1` when complete.
|
|
176
|
+
*/
|
|
177
|
+
startStripeConnect: () => Promise<void>;
|
|
178
|
+
starting: boolean;
|
|
179
|
+
error: string | null;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Backend contract: POST {apiBaseUrl}/api/payout/stripe/start
|
|
183
|
+
* body: { stackId? } — optional override; server defaults to the stack
|
|
184
|
+
* the user's session is currently scoped to.
|
|
185
|
+
* response: StripeConnectStartResponse
|
|
186
|
+
*/
|
|
187
|
+
declare function useStripeConnect(): UseStripeConnectReturn;
|
|
188
|
+
|
|
189
|
+
interface UseCryptoConnectReturn {
|
|
190
|
+
/**
|
|
191
|
+
* Connect Phantom, request a nonce from the server, sign it, and POST the
|
|
192
|
+
* signature back for verification. On success the server saves the address
|
|
193
|
+
* as the user's payout destination.
|
|
194
|
+
*/
|
|
195
|
+
connectAndVerify: () => Promise<{
|
|
196
|
+
address: string;
|
|
197
|
+
} | null>;
|
|
198
|
+
connecting: boolean;
|
|
199
|
+
error: string | null;
|
|
200
|
+
}
|
|
201
|
+
declare function useCryptoConnect(): UseCryptoConnectReturn;
|
|
202
|
+
|
|
203
|
+
export { useCryptoConnect, useFilePaperwork, useFilingDetail, useFilingHistory, useKeyLedger, useKeys, useListKey, useMintKey, usePayoutAccount, usePricing, useSolanaPayment, useStackPayoutCapabilities, useStripeCheckout, useStripeConnect, useTransferKey };
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PricingInfo, NodeKeyInfo, LedgerEntry, PaymentMethod, MintResult, ListingResult, DirectTransferResult, FilingResult, FilingHistoryEntry } from '../types/index.js';
|
|
1
|
+
import { PricingInfo, NodeKeyInfo, LedgerEntry, PaymentMethod, MintResult, ListingResult, DirectTransferResult, PayoutMethod, FilingResult, FilingHistoryEntry, StackPayoutCapabilities, FilingDetail, PayoutAccount } from '../types/index.js';
|
|
2
2
|
|
|
3
3
|
interface UsePricingReturn {
|
|
4
4
|
pricing: PricingInfo | null;
|
|
@@ -72,7 +72,7 @@ interface UseTransferKeyReturn {
|
|
|
72
72
|
declare function useTransferKey(): UseTransferKeyReturn;
|
|
73
73
|
|
|
74
74
|
interface UseFilePaperworkReturn {
|
|
75
|
-
filePaperwork: (keyId: string) => Promise<FilingResult | null>;
|
|
75
|
+
filePaperwork: (keyId: string, payoutMethod?: PayoutMethod | null) => Promise<FilingResult | null>;
|
|
76
76
|
filing: boolean;
|
|
77
77
|
result: FilingResult | null;
|
|
78
78
|
error: string | null;
|
|
@@ -82,11 +82,17 @@ interface UseFilePaperworkReturn {
|
|
|
82
82
|
* File paperwork against an eligible NodeKey to redeem Paper.
|
|
83
83
|
*
|
|
84
84
|
* Backend contract: POST {apiBaseUrl}/api/keys/{keyId}/file
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
85
|
+
* Request body: { stackId?, payoutMethod? }
|
|
86
|
+
* - On stacknet versions that read from `user_payout_accounts`, the body
|
|
87
|
+
* can omit everything user-controlled — the server derives the method
|
|
88
|
+
* and destination from the user's saved earnings account.
|
|
89
|
+
* - For backward compatibility with stacknet versions that still REQUIRE
|
|
90
|
+
* `payoutMethod` in the body, callers can pass the method they read
|
|
91
|
+
* from `usePayoutAccount()`. The server (new path) verifies the hint
|
|
92
|
+
* matches the saved record and rejects mismatches with 400.
|
|
93
|
+
* - Memo, amount, beneficiary are always server-derived.
|
|
94
|
+
* Response: FilingResult JSON with `filingId` (used to look up the detail /
|
|
95
|
+
* tracker view at /files/{filingId}).
|
|
90
96
|
*/
|
|
91
97
|
declare function useFilePaperwork(): UseFilePaperworkReturn;
|
|
92
98
|
|
|
@@ -104,4 +110,94 @@ interface UseFilingHistoryReturn {
|
|
|
104
110
|
*/
|
|
105
111
|
declare function useFilingHistory(): UseFilingHistoryReturn;
|
|
106
112
|
|
|
107
|
-
|
|
113
|
+
interface UseStackPayoutCapabilitiesReturn {
|
|
114
|
+
caps: StackPayoutCapabilities | null;
|
|
115
|
+
loading: boolean;
|
|
116
|
+
error: string | null;
|
|
117
|
+
refresh: () => Promise<void>;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Fetch per-stack payout capabilities (which methods are configured + the
|
|
121
|
+
* default destination address). Drives the payout-method picker — Stripe
|
|
122
|
+
* tile is rendered disabled with "disabled by {stackName} stack" UX when
|
|
123
|
+
* `caps.stripe.enabled === false`.
|
|
124
|
+
*
|
|
125
|
+
* Backend contract: GET {apiBaseUrl}/api/stacks/{stackId}/payout-capabilities
|
|
126
|
+
*
|
|
127
|
+
* Falls back gracefully when no stackId is configured — returns null caps.
|
|
128
|
+
*/
|
|
129
|
+
declare function useStackPayoutCapabilities(stackIdOverride?: string): UseStackPayoutCapabilitiesReturn;
|
|
130
|
+
|
|
131
|
+
interface UseFilingDetailReturn {
|
|
132
|
+
detail: FilingDetail | null;
|
|
133
|
+
loading: boolean;
|
|
134
|
+
error: string | null;
|
|
135
|
+
refresh: () => Promise<void>;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Fetch a single filing's detail (status, tracker, tx sigs, etc.) and poll
|
|
139
|
+
* every 5 s while non-terminal. Stops polling once status is `paid` or
|
|
140
|
+
* `failed`. Used by both the inline post-submit tracker and the standalone
|
|
141
|
+
* /files/{id} route.
|
|
142
|
+
*
|
|
143
|
+
* Backend contract: GET {apiBaseUrl}/api/keys/filings/{filingId}
|
|
144
|
+
*/
|
|
145
|
+
declare function useFilingDetail(filingId: string | null | undefined): UseFilingDetailReturn;
|
|
146
|
+
|
|
147
|
+
interface UsePayoutAccountReturn {
|
|
148
|
+
account: PayoutAccount | null;
|
|
149
|
+
loading: boolean;
|
|
150
|
+
error: string | null;
|
|
151
|
+
refresh: () => Promise<void>;
|
|
152
|
+
/** Disconnect the current method (deletes saved payout config). */
|
|
153
|
+
disconnect: () => Promise<boolean>;
|
|
154
|
+
disconnecting: boolean;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Read + manage the user's payout account.
|
|
158
|
+
*
|
|
159
|
+
* Backend contract:
|
|
160
|
+
* GET {apiBaseUrl}/api/payout → PayoutAccount
|
|
161
|
+
* DELETE {apiBaseUrl}/api/payout → 204
|
|
162
|
+
*
|
|
163
|
+
* The account is per-user (not per-stack). Switching methods (e.g. crypto →
|
|
164
|
+
* stripe) replaces the previous record server-side.
|
|
165
|
+
*/
|
|
166
|
+
declare function usePayoutAccount(): UsePayoutAccountReturn;
|
|
167
|
+
|
|
168
|
+
interface UseStripeConnectReturn {
|
|
169
|
+
/**
|
|
170
|
+
* Kick off Stripe Connect Express onboarding. Server creates an Express
|
|
171
|
+
* connected account under the stack's platform Stripe credentials,
|
|
172
|
+
* generates an AccountLink, and returns its URL. The browser is then
|
|
173
|
+
* redirected to that URL — Stripe hosts the rest of the onboarding flow
|
|
174
|
+
* (KYC, bank details, payouts opt-in) and bounces back to
|
|
175
|
+
* `/settings?tab=account&stripe_return=1` when complete.
|
|
176
|
+
*/
|
|
177
|
+
startStripeConnect: () => Promise<void>;
|
|
178
|
+
starting: boolean;
|
|
179
|
+
error: string | null;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Backend contract: POST {apiBaseUrl}/api/payout/stripe/start
|
|
183
|
+
* body: { stackId? } — optional override; server defaults to the stack
|
|
184
|
+
* the user's session is currently scoped to.
|
|
185
|
+
* response: StripeConnectStartResponse
|
|
186
|
+
*/
|
|
187
|
+
declare function useStripeConnect(): UseStripeConnectReturn;
|
|
188
|
+
|
|
189
|
+
interface UseCryptoConnectReturn {
|
|
190
|
+
/**
|
|
191
|
+
* Connect Phantom, request a nonce from the server, sign it, and POST the
|
|
192
|
+
* signature back for verification. On success the server saves the address
|
|
193
|
+
* as the user's payout destination.
|
|
194
|
+
*/
|
|
195
|
+
connectAndVerify: () => Promise<{
|
|
196
|
+
address: string;
|
|
197
|
+
} | null>;
|
|
198
|
+
connecting: boolean;
|
|
199
|
+
error: string | null;
|
|
200
|
+
}
|
|
201
|
+
declare function useCryptoConnect(): UseCryptoConnectReturn;
|
|
202
|
+
|
|
203
|
+
export { useCryptoConnect, useFilePaperwork, useFilingDetail, useFilingHistory, useKeyLedger, useKeys, useListKey, useMintKey, usePayoutAccount, usePricing, useSolanaPayment, useStackPayoutCapabilities, useStripeCheckout, useStripeConnect, useTransferKey };
|
package/dist/hooks/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {createContext,useState,useRef,useEffect,useCallback,useContext}from'react';import'react/jsx-runtime';var Y=createContext(null);function m(){let e=useContext(Y);if(!e)throw new Error("useKeyUtilsContext must be used within a KeyUtilsProvider");return e}function Z(e,a){if(typeof e!="string"||e.length===0)return a;let i=e.replace(/[\u0000-\u001F\u007F]/g," ");return i.length>500?i.slice(0,500)+"\u2026":i}async function y(e,a){try{let i=await e.json();if(i&&typeof i=="object"&&"error"in i)return Z(i.error,a)}catch{}return a}function Q(){let{config:e}=m(),[a,i]=useState(null),[u,f]=useState(true),[d,g]=useState(null),r=useRef(true),o=useRef(e.apiBaseUrl);o.current=e.apiBaseUrl;let l=async()=>{try{r.current&&(f(!0),g(null));let s=await fetch(`${o.current}/api/keys/pricing`,{credentials:"include"});if(!s.ok)throw new Error(await y(s,`Pricing unavailable (${s.status})`));let n=await s.json();r.current&&i(n);}catch(s){r.current&&g(s instanceof Error?s.message:"Failed to fetch pricing");}finally{r.current&&f(false);}};return useEffect(()=>{r.current=true,l();let s=setInterval(l,6e4);return ()=>{r.current=false,clearInterval(s);}},[]),{pricing:a,loading:u,error:d,refresh:l}}function ne(e){return {id:e.id||"",keyIndex:e.keyIndex??e.key_index??null,key:e.key||e.keyPrefix||"",userId:e.userId||e.user_id||"",status:e.status||"active",tokenBalance:e.tokenBalance??e.currentTokenBalance??e.current_token_balance??0,maxTokens:e.maxTokens??e.initialTokenBalance??e.initial_token_balance??0,createdAt:String(e.createdAt??e.created_at??""),expiresAt:e.expiresAt,label:e.label||e.keyPrefix||e.key_prefix||void 0,paperWork:e.paperWork||e.paper_work||void 0,stackId:e.stackId,stackName:e.stackName}}function se(){let{config:e}=m(),[a,i]=useState([]),[u,f]=useState(true),[d,g]=useState(null),r=useRef(true),o=e.apiBaseUrl,l=useCallback(async()=>{try{f(!0),g(null);let n=await fetch(`${o}/api/keys`,{credentials:"include"});if(!n.ok)throw new Error(await y(n,`Failed to fetch keys (${n.status})`));let t=await n.json(),c=Array.isArray(t)?t:t.keys??[];r.current&&i(c.map(ne));}catch(n){r.current&&g(n instanceof Error?n.message:"Failed to fetch keys");}finally{r.current&&f(false);}},[o]);useEffect(()=>(r.current=true,l(),()=>{r.current=false;}),[l]);let s=a.reduce((n,t)=>n+t.tokenBalance,0);return {keys:a,totalBalance:s,loading:u,error:d,refresh:l}}function N(e){let a=e.type||e.entry_type||"debit",i=e.amount??e.tokens??e.token_amount??0,u=e.description||e.memo||e.reason||ie(a);return {id:e.id||"",keyId:e.keyId||e.key_id||"",type:a,amount:i,description:u,createdAt:String(e.createdAt??e.created_at??e.timestamp??""),metadata:e.metadata||void 0}}function ie(e){switch(e){case "credit":return "Credit";case "debit":return "Usage";case "mint":return "Mint";case "reward":return "Reward";default:return ""}}function le(e){let{config:a}=m(),[i,u]=useState([]),[f,d]=useState(false),[g,r]=useState(null),o=useRef(true),l=a.apiBaseUrl,s=useCallback(async()=>{if(e)try{d(!0),r(null);let n=await fetch(`${l}/api/keys/${encodeURIComponent(e)}/ledger`,{credentials:"include"});if(!n.ok)throw new Error(await y(n,`Failed to fetch ledger (${n.status})`));let t=await n.json(),c=Array.isArray(t)?t:t.entries??[];o.current&&u(c.map(N));}catch(n){o.current&&r(n instanceof Error?n.message:"Failed to fetch ledger");}finally{o.current&&d(false);}},[l,e]);return useEffect(()=>(o.current=true,s(),()=>{o.current=false;}),[s]),{entries:i,loading:f,error:g,refresh:s}}function k(){if(typeof document>"u")return {};let e=document.cookie.match(/(?:^|;\s*)__csrf=([^;]*)/);return e?{"x-csrf-token":e[1]}:{}}function fe(){let{config:e,callbacks:a}=m(),[i,u]=useState(false),[f,d]=useState(null),[g,r]=useState(null);return {mint:useCallback(async(l,s,n=1)=>{try{u(!0),r(null),a.onPaymentComplete?.(l,s);let t=await fetch(`${e.apiBaseUrl}/api/keys/mint`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({paymentMethod:l,paymentRef:s,quantity:n,stackId:e.stackId})});if(!t.ok)throw new Error(await y(t,`Key generation failed (${t.status})`));let c=await t.json(),p=c.keys?.[0]||c,h={success:!0,key:{id:p.keyId||p.id||"",key:p.key||"",userId:p.userId||"",status:"active",tokenBalance:p.tokenBalance??p.currentTokenBalance??0,maxTokens:p.initialTokenBalance??p.tokenBalance??0,createdAt:String(p.createdAt||Date.now())},transactionId:s};return d(h),a.onMintSuccess?.(h),h}catch(t){let c=t instanceof Error?t:new Error("Key generation failed");return r(c.message),a.onMintError?.(c),{success:false,error:c.message}}finally{u(false);}},[e.apiBaseUrl,a]),minting:i,result:f,error:g}}function ge(){let{config:e,callbacks:a}=m(),[i,u]=useState(false),[f,d]=useState(null),[g,r]=useState(null),o=useRef(true),l=useCallback(async(n,t)=>{try{u(!0),r(null);let c=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(n)}/list`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({askPriceCents:t,stackId:e.stackId,stackName:e.stackName})});if(!c.ok)throw new Error(await y(c,`Listing failed (${c.status})`));let p=await c.json();return o.current&&(d(p),a.onListingCreated?.(p)),p}catch(c){let p=c instanceof Error?c.message:"Listing failed";return o.current&&r(p),null}finally{o.current&&u(false);}},[e.apiBaseUrl,e.stackId,e.stackName,a]),s=useCallback(async n=>{try{u(!0),r(null);let t=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(n)}/list`,{method:"DELETE",headers:{...k()},credentials:"include"});if(!t.ok)throw new Error(await y(t,`Delist failed (${t.status})`));return o.current&&d(null),!0}catch(t){let c=t instanceof Error?t.message:"Delist failed";return o.current&&r(c),false}finally{o.current&&u(false);}},[e.apiBaseUrl]);return {listKey:l,delistKey:s,listing:i,result:f,error:g}}function pe(){let{config:e}=m(),[a,i]=useState(false),[u,f]=useState(null),d=useRef(true);return {createSession:useCallback(async(r,o)=>{try{i(!0),f(null);let l=await fetch(`${e.apiBaseUrl}/api/keys/stripe-session`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({priceCents:r,quantity:o,stackId:e.stackId,referrerUrl:window.location.href})});if(!l.ok)throw new Error(await y(l,`Checkout failed (${l.status})`));let{url:s}=await l.json();if(!s)throw new Error("No checkout URL returned");let n;try{n=new URL(s);}catch{throw new Error("Invalid checkout URL")}if(n.protocol!=="https:"||!/(^|\.)stripe\.com$/.test(n.hostname))throw new Error("Refusing to redirect to non-Stripe URL");try{sessionStorage.setItem("keyutils_stripe_pending","1"),sessionStorage.setItem("keyutils_stripe_quantity",String(o));}catch{}window.location.href=n.toString();}catch(l){if(d.current){let s=l instanceof Error?l.message:"Checkout failed";f(s),i(false);}}},[e.apiBaseUrl,e.stackId]),loading:a,error:u}}function H(e,a="#"){if(!e||typeof e!="string")return a;let i=e.trim();if(i===""||i==="#")return a;if(i.startsWith("/")||i.startsWith("./")||i.startsWith("../"))return i;try{let u=new URL(i);if(u.protocol==="http:"||u.protocol==="https:")return u.toString()}catch{}return a}var v=/^[1-9A-HJ-NP-Za-km-z]{32,44}$/;function he(){let{config:e}=m(),[a,i]=useState(false),[u,f]=useState(null);return {pay:useCallback(async g=>{if(!e.merchantWallet||!v.test(e.merchantWallet))throw new Error("Merchant wallet not configured");try{i(!0),f(null);let{Connection:r,PublicKey:o,Transaction:l,SystemProgram:s}=await import('@solana/web3.js'),n=typeof window<"u"?window.solana:void 0;if(!n||typeof n!="object"||!n.isPhantom)throw new Error("Phantom wallet not found. Please install Phantom.");let t=n,c=new o(e.merchantWallet),p=await t.connect(),h=new o(p.publicKey.toString()),L="https://api.mainnet-beta.solana.com",T=H(e.solanaRpcUrl,L),j=T==="#"?L:T,D=new r(j),{blockhash:W}=await D.getLatestBlockhash(),R=BigInt(Math.floor(g*1e9)),P=e.protocolTreasuryWallet,B=e.protocolFeeBps??500,b=new l({recentBlockhash:W,feePayer:h});if(P&&v.test(P)&&B>0){let M=R*BigInt(B)/10000n,q=R-M,z=new o(P);b.add(s.transfer({fromPubkey:h,toPubkey:c,lamports:Number(q)}),s.transfer({fromPubkey:h,toPubkey:z,lamports:Number(M)}));}else b.add(s.transfer({fromPubkey:h,toPubkey:c,lamports:Number(R)}));let{signature:J}=await t.signAndSendTransaction(b);return J}catch(r){let o=r instanceof Error?r:new Error("SOL payment failed");throw f(o.message),o}finally{i(false);}},[e.merchantWallet,e.protocolTreasuryWallet,e.protocolFeeBps,e.solanaRpcUrl]),processing:a,error:u}}function be(){let{config:e,callbacks:a}=m(),[i,u]=useState(false),[f,d]=useState(null),[g,r]=useState(null),o=useRef(true);return {transferKey:useCallback(async(s,n)=>{try{u(!0),r(null);let t=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(s)}/transfer`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({recipientId:n})});if(!t.ok)throw new Error(await y(t,`Transfer failed (${t.status})`));let c=await t.json();return o.current&&(d(c),a.onTransferComplete?.(c)),c}catch(t){let c=t instanceof Error?t.message:"Transfer failed";return o.current&&r(c),null}finally{o.current&&u(false);}},[e.apiBaseUrl,a]),transferring:i,result:f,error:g}}function Ee(){let{config:e,callbacks:a}=m(),[i,u]=useState(false),[f,d]=useState(null),[g,r]=useState(null),o=useRef(true),l=useCallback(async n=>{try{u(!0),r(null);let t=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(n)}/file`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({stackId:e.stackId})});if(!t.ok)throw new Error(await y(t,`Filing failed (${t.status})`));let c=await t.json();return o.current&&(d(c),a.onFilingComplete?.(c)),c}catch(t){let c=t instanceof Error?t:new Error("Filing failed");return o.current&&r(c.message),a.onFilingError?.(c),null}finally{o.current&&u(false);}},[e.apiBaseUrl,e.stackId,a]),s=useCallback(()=>{d(null),r(null);},[]);return {filePaperwork:l,filing:i,result:f,error:g,reset:s}}function Ie(){let{config:e}=m(),[a,i]=useState([]),[u,f]=useState(true),[d,g]=useState(null),r=useRef(true),o=e.apiBaseUrl,l=useCallback(async()=>{try{f(!0),g(null);let s=await fetch(`${o}/api/keys/filings`,{credentials:"include"});if(!s.ok)throw new Error(await y(s,`Failed to fetch filings (${s.status})`));let n=await s.json(),t=Array.isArray(n)?n:n.filings??[];r.current&&i(t);}catch(s){r.current&&g(s instanceof Error?s.message:"Failed to fetch filings");}finally{r.current&&f(false);}},[o]);return useEffect(()=>(r.current=true,l(),()=>{r.current=false;}),[l]),{entries:a,loading:u,error:d,refresh:l}}
|
|
2
|
-
export{
|
|
1
|
+
import {createContext,useState,useRef,useEffect,useCallback,useContext}from'react';import'react/jsx-runtime';var ne=createContext(null);function y(){let e=useContext(ne);if(!e)throw new Error("useKeyUtilsContext must be used within a KeyUtilsProvider");return e}function se(e,n){if(typeof e!="string"||e.length===0)return n;let t=e.replace(/[\u0000-\u001F\u007F]/g," ");return t.length>500?t.slice(0,500)+"\u2026":t}async function p(e,n){try{let t=await e.json();if(t&&typeof t=="object"&&"error"in t)return se(t.error,n)}catch{}return n}function ie(){let{config:e}=y(),[n,t]=useState(null),[f,d]=useState(true),[m,u]=useState(null),i=useRef(true),o=useRef(e.apiBaseUrl);o.current=e.apiBaseUrl;let a=async()=>{try{i.current&&(d(!0),u(null));let s=await fetch(`${o.current}/api/keys/pricing`,{credentials:"include"});if(!s.ok)throw new Error(await p(s,`Pricing unavailable (${s.status})`));let r=await s.json();i.current&&t(r);}catch(s){i.current&&u(s instanceof Error?s.message:"Failed to fetch pricing");}finally{i.current&&d(false);}};return useEffect(()=>{i.current=true,a();let s=setInterval(a,6e4);return ()=>{i.current=false,clearInterval(s);}},[]),{pricing:n,loading:f,error:m,refresh:a}}function ue(e){return {id:e.id||"",keyIndex:e.keyIndex??e.key_index??null,key:e.id||e.key||e.keyPrefix||"",userId:e.userId||e.user_id||"",status:e.status||"active",tokenBalance:e.tokenBalance??e.currentTokenBalance??e.current_token_balance??0,maxTokens:e.maxTokens??e.initialTokenBalance??e.initial_token_balance??0,createdAt:String(e.createdAt??e.created_at??""),expiresAt:e.expiresAt,label:e.label||void 0,paperWork:e.paperWork||e.paper_work||void 0,stackId:e.stackId,stackName:e.stackName}}function fe(){let{config:e}=y(),[n,t]=useState([]),[f,d]=useState(true),[m,u]=useState(null),i=useRef(true),o=e.apiBaseUrl,a=useCallback(async()=>{try{d(!0),u(null);let r=await fetch(`${o}/api/keys`,{credentials:"include"});if(!r.ok)throw new Error(await p(r,`Failed to fetch keys (${r.status})`));let c=await r.json(),l=Array.isArray(c)?c:c.keys??[];i.current&&t(l.map(ue));}catch(r){i.current&&u(r instanceof Error?r.message:"Failed to fetch keys");}finally{i.current&&d(false);}},[o]);useEffect(()=>(i.current=true,a(),()=>{i.current=false;}),[a]);let s=n.reduce((r,c)=>r+c.tokenBalance,0);return {keys:n,totalBalance:s,loading:f,error:m,refresh:a}}var N=false;function k(){if(typeof document>"u")return {};let e=document.cookie.match(/(?:^|;\s*)__csrf=([^;]*)/);if(!e)return N||(N=true,console.warn("[keyutils] __csrf cookie not found; mutations will be sent without a CSRF token")),{};let n=e[1];try{n=decodeURIComponent(n);}catch{}return {"x-csrf-token":n}}function _(e){let n=e.type||e.entry_type||"debit",t=e.amount??e.tokens??e.token_amount??0,f=e.description||e.memo||e.reason||de(n);return {id:e.id||"",keyId:e.keyId||e.key_id||"",type:n,amount:t,description:f,createdAt:String(e.createdAt??e.created_at??e.timestamp??""),metadata:e.metadata||void 0}}function de(e){switch(e){case "credit":return "Credit";case "debit":return "Usage";case "mint":return "Mint";case "reward":return "Reward";default:return ""}}function ge(e){let{config:n}=y(),[t,f]=useState([]),[d,m]=useState(false),[u,i]=useState(null),o=useRef(true),a=n.apiBaseUrl,s=useCallback(async()=>{if(e)try{m(!0),i(null);let r=await fetch(`${a}/api/keys/${encodeURIComponent(e)}/ledger`,{credentials:"include"});if(!r.ok)throw new Error(await p(r,`Failed to fetch ledger (${r.status})`));let c=await r.json(),l=Array.isArray(c)?c:c.entries??[];o.current&&f(l.map(_));}catch(r){o.current&&i(r instanceof Error?r.message:"Failed to fetch ledger");}finally{o.current&&m(false);}},[a,e]);return useEffect(()=>(o.current=true,s(),()=>{o.current=false;}),[s]),{entries:t,loading:d,error:u,refresh:s}}function he(){let{config:e,callbacks:n}=y(),[t,f]=useState(false),[d,m]=useState(null),[u,i]=useState(null);return {mint:useCallback(async(a,s,r=1)=>{try{f(!0),i(null),n.onPaymentComplete?.(a,s);let c=await fetch(`${e.apiBaseUrl}/api/keys/mint`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({paymentMethod:a,paymentRef:s,quantity:r,stackId:e.stackId})});if(!c.ok)throw new Error(await p(c,`Key generation failed (${c.status})`));let l=await c.json(),g=l.keys?.[0]||l,h={success:!0,key:{id:g.keyId||g.id||"",key:g.key||"",userId:g.userId||"",status:"active",tokenBalance:g.tokenBalance??g.currentTokenBalance??0,maxTokens:g.initialTokenBalance??g.tokenBalance??0,createdAt:String(g.createdAt||Date.now())},transactionId:s};return m(h),n.onMintSuccess?.(h),h}catch(c){let l=c instanceof Error?c:new Error("Key generation failed");return i(l.message),n.onMintError?.(l),{success:false,error:l.message}}finally{f(false);}},[e.apiBaseUrl,n]),minting:t,result:d,error:u}}function Pe(){let{config:e,callbacks:n}=y(),[t,f]=useState(false),[d,m]=useState(null),[u,i]=useState(null),o=useRef(true),a=useCallback(async(r,c)=>{try{f(!0),i(null);let l=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(r)}/list`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({askPriceCents:c,stackId:e.stackId,stackName:e.stackName})});if(!l.ok)throw new Error(await p(l,`Listing failed (${l.status})`));let g=await l.json();return o.current&&(m(g),n.onListingCreated?.(g)),g}catch(l){let g=l instanceof Error?l.message:"Listing failed";return o.current&&i(g),null}finally{o.current&&f(false);}},[e.apiBaseUrl,e.stackId,e.stackName,n]),s=useCallback(async r=>{try{f(!0),i(null);let c=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(r)}/list`,{method:"DELETE",headers:{...k()},credentials:"include"});if(!c.ok)throw new Error(await p(c,`Delist failed (${c.status})`));return o.current&&m(null),!0}catch(c){let l=c instanceof Error?c.message:"Delist failed";return o.current&&i(l),false}finally{o.current&&f(false);}},[e.apiBaseUrl]);return {listKey:a,delistKey:s,listing:t,result:d,error:u}}function we(){let{config:e}=y(),[n,t]=useState(false),[f,d]=useState(null),m=useRef(true);return {createSession:useCallback(async(i,o)=>{try{t(!0),d(null);let a=await fetch(`${e.apiBaseUrl}/api/keys/stripe-session`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({priceCents:i,quantity:o,stackId:e.stackId,referrerUrl:window.location.href})});if(!a.ok)throw new Error(await p(a,`Checkout failed (${a.status})`));let{url:s}=await a.json();if(!s)throw new Error("No checkout URL returned");let r;try{r=new URL(s);}catch{throw new Error("Invalid checkout URL")}if(r.protocol!=="https:"||!/(^|\.)stripe\.com$/.test(r.hostname))throw new Error("Refusing to redirect to non-Stripe URL");try{sessionStorage.setItem("keyutils_stripe_pending","1"),sessionStorage.setItem("keyutils_stripe_quantity",String(o));}catch{}window.location.href=r.toString();}catch(a){if(m.current){let s=a instanceof Error?a.message:"Checkout failed";d(s),t(false);}}},[e.apiBaseUrl,e.stackId]),loading:n,error:f}}function O(e,n="#"){if(!e||typeof e!="string")return n;let t=e.trim();if(t===""||t==="#")return n;if(t.startsWith("/")||t.startsWith("./")||t.startsWith("../"))return t;try{let f=new URL(t);if(f.protocol==="http:"||f.protocol==="https:")return f.toString()}catch{}return n}var W=/^[1-9A-HJ-NP-Za-km-z]{32,44}$/;function Ce(){let{config:e}=y(),[n,t]=useState(false),[f,d]=useState(null);return {pay:useCallback(async u=>{if(!e.merchantWallet||!W.test(e.merchantWallet))throw new Error("Merchant wallet not configured");try{t(!0),d(null);let{Connection:i,PublicKey:o,Transaction:a,SystemProgram:s}=await import('@solana/web3.js'),r=typeof window<"u"?window.solana:void 0;if(!r||typeof r!="object"||!r.isPhantom)throw new Error("Phantom wallet not found. Please install Phantom.");let c=r,l=new o(e.merchantWallet),g=await c.connect(),h=new o(g.publicKey.toString()),M="https://api.mainnet-beta.solana.com",$=O(e.solanaRpcUrl,M),X=$==="#"?M:$,Y=new i(X),{blockhash:Z}=await Y.getLatestBlockhash(),P=BigInt(Math.floor(u*1e9)),b=e.protocolTreasuryWallet,F=e.protocolFeeBps??500,U=new a({recentBlockhash:Z,feePayer:h});if(b&&W.test(b)&&F>0){let A=P*BigInt(F)/10000n,Q=P-A,ee=new o(b);U.add(s.transfer({fromPubkey:h,toPubkey:l,lamports:Number(Q)}),s.transfer({fromPubkey:h,toPubkey:ee,lamports:Number(A)}));}else U.add(s.transfer({fromPubkey:h,toPubkey:l,lamports:Number(P)}));let{signature:G}=await c.signAndSendTransaction(U);return G}catch(i){let o=i instanceof Error?i:new Error("SOL payment failed");throw d(o.message),o}finally{t(false);}},[e.merchantWallet,e.protocolTreasuryWallet,e.protocolFeeBps,e.solanaRpcUrl]),processing:n,error:f}}function xe(){let{config:e,callbacks:n}=y(),[t,f]=useState(false),[d,m]=useState(null),[u,i]=useState(null),o=useRef(true);return {transferKey:useCallback(async(s,r)=>{try{f(!0),i(null);let c=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(s)}/transfer`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({recipientId:r})});if(!c.ok)throw new Error(await p(c,`Transfer failed (${c.status})`));let l=await c.json();return o.current&&(m(l),n.onTransferComplete?.(l)),l}catch(c){let l=c instanceof Error?c.message:"Transfer failed";return o.current&&i(l),null}finally{o.current&&f(false);}},[e.apiBaseUrl,n]),transferring:t,result:d,error:u}}function Le(){let{config:e,callbacks:n}=y(),[t,f]=useState(false),[d,m]=useState(null),[u,i]=useState(null),o=useRef(true);useEffect(()=>(o.current=true,()=>{o.current=false;}),[]);let a=useCallback(async(r,c)=>{try{f(!0),i(null);let l={stackId:e.stackId};c&&(l.payoutMethod=c);let g=await fetch(`${e.apiBaseUrl}/api/keys/${encodeURIComponent(r)}/file`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify(l)});if(!g.ok)throw new Error(await p(g,`Filing failed (${g.status})`));let h=await g.json();return o.current&&(m(h),n.onFilingComplete?.(h)),h}catch(l){let g=l instanceof Error?l:new Error("Filing failed");return o.current&&i(g.message),n.onFilingError?.(g),null}finally{o.current&&f(false);}},[e.apiBaseUrl,e.stackId,n]),s=useCallback(()=>{m(null),i(null);},[]);return {filePaperwork:a,filing:t,result:d,error:u,reset:s}}function Fe(){let{config:e}=y(),[n,t]=useState([]),[f,d]=useState(true),[m,u]=useState(null),i=useRef(true),o=e.apiBaseUrl,a=useCallback(async()=>{try{d(!0),u(null);let s=await fetch(`${o}/api/keys/filings`,{credentials:"include"});if(!s.ok)throw new Error(await p(s,`Failed to fetch filings (${s.status})`));let r=await s.json(),c=Array.isArray(r)?r:r.filings??[];i.current&&t(c);}catch(s){i.current&&u(s instanceof Error?s.message:"Failed to fetch filings");}finally{i.current&&d(false);}},[o]);return useEffect(()=>(i.current=true,a(),()=>{i.current=false;}),[a]),{entries:n,loading:f,error:m,refresh:a}}function _e(e){let{config:n}=y(),t=e??n.stackId,f=n.apiBaseUrl,[d,m]=useState(null),[u,i]=useState(!!t),[o,a]=useState(null),s=useRef(true),r=useCallback(async()=>{if(!t){m(null),i(false);return}try{i(!0),a(null);let c=await fetch(`${f}/api/stacks/${encodeURIComponent(t)}/payout-capabilities`,{credentials:"include"});if(!c.ok)throw new Error(await p(c,`Failed to load payout capabilities (${c.status})`));let l=await c.json();s.current&&m(l);}catch(c){s.current&&a(c instanceof Error?c.message:"Failed to load payout capabilities");}finally{s.current&&i(false);}},[f,t]);return useEffect(()=>(s.current=true,r(),()=>{s.current=false;}),[r]),{caps:d,loading:u,error:o,refresh:r}}var je=5e3;function We(e){return e==="paid"||e==="failed"}function Je(e){let{config:n}=y(),t=n.apiBaseUrl,[f,d]=useState(null),[m,u]=useState(!!e),[i,o]=useState(null),a=useRef(true),s=useCallback(async()=>{if(!e){d(null),u(false);return}try{o(null);let r=await fetch(`${t}/api/keys/filings/${encodeURIComponent(e)}`,{credentials:"include"});if(!r.ok)throw new Error(await p(r,`Failed to load filing (${r.status})`));let c=await r.json();a.current&&d(c);}catch(r){a.current&&o(r instanceof Error?r.message:"Failed to load filing");}finally{a.current&&u(false);}},[t,e]);return useEffect(()=>{if(a.current=true,!e)return d(null),u(false),()=>{a.current=false;};u(true),s();let r=setInterval(()=>{a.current&&(f&&We(f.status)||s());},je);return ()=>{a.current=false,clearInterval(r);}},[e,s,f]),{detail:f,loading:m,error:i,refresh:s}}function ze(){let{config:e}=y(),[n,t]=useState(null),[f,d]=useState(true),[m,u]=useState(null),[i,o]=useState(false),a=useRef(true),s=e.apiBaseUrl,r=useCallback(async()=>{try{d(!0),u(null);let l=await fetch(`${s}/api/payout`,{credentials:"include"});if(!l.ok)throw new Error(await p(l,`Failed to load payout account (${l.status})`));let g=await l.json();a.current&&t(g);}catch(l){a.current&&u(l instanceof Error?l.message:"Failed to load payout account");}finally{a.current&&d(false);}},[s]);useEffect(()=>(a.current=true,r(),()=>{a.current=false;}),[r]);let c=useCallback(async()=>{try{o(!0),u(null);let l=await fetch(`${s}/api/payout`,{method:"DELETE",headers:{...k()},credentials:"include"});if(!l.ok&&l.status!==204)throw new Error(await p(l,`Disconnect failed (${l.status})`));return a.current&&t({method:null}),!0}catch(l){return a.current&&u(l instanceof Error?l.message:"Disconnect failed"),false}finally{a.current&&o(false);}},[s]);return {account:n,loading:f,error:m,refresh:r,disconnect:c,disconnecting:i}}function Ye(){let{config:e}=y(),[n,t]=useState(false),[f,d]=useState(null);return {startStripeConnect:useCallback(async()=>{try{t(!0),d(null);let u=await fetch(`${e.apiBaseUrl}/api/payout/stripe/start`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({stackId:e.stackId})});if(!u.ok)throw new Error(await p(u,`Stripe Connect start failed (${u.status})`));let i=await u.json();if(typeof window<"u"&&i.onboardingUrl){let o;try{o=new URL(i.onboardingUrl);}catch{throw new Error("Invalid onboarding URL")}if(o.protocol!=="https:"||!/(^|\.)stripe\.com$/.test(o.hostname))throw new Error("Refusing to redirect to non-Stripe URL");window.location.href=o.toString();return}}catch(u){d(u instanceof Error?u.message:"Stripe Connect start failed");}finally{t(false);}},[e.apiBaseUrl,e.stackId]),starting:n,error:f}}function Ge(){if(typeof window>"u")return null;let e=window,n=e.solana,t=e.phantom?.solana;return ((n&&n.isPhantom?n:null)||(t&&t.isPhantom?t:null))??null}function Qe(e){let n="";for(let t=0;t<e.length;t+=1)n+=String.fromCharCode(e[t]);return typeof btoa=="function"?btoa(n):Buffer.from(e).toString("base64")}function et(){let{config:e}=y(),[n,t]=useState(false),[f,d]=useState(null);return {connectAndVerify:useCallback(async()=>{try{t(!0),d(null);let u=Ge();if(!u)throw new Error("Phantom wallet not found. Install Phantom to continue.");let o=(await u.connect()).publicKey.toString(),a=await fetch(`${e.apiBaseUrl}/api/payout/crypto/nonce`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({address:o})});if(!a.ok)throw new Error(await p(a,`Nonce request failed (${a.status})`));let{nonce:s,message:r}=await a.json(),c=new TextEncoder().encode(r),l=await u.signMessage(c,"utf8"),g=Qe(l.signature),h=await fetch(`${e.apiBaseUrl}/api/payout/crypto/verify`,{method:"POST",headers:{"Content-Type":"application/json",...k()},credentials:"include",body:JSON.stringify({address:o,nonce:s,signature:g})});if(!h.ok)throw new Error(await p(h,`Verification failed (${h.status})`));return {address:o}}catch(u){let i=u instanceof Error?u:new Error("Wallet verification failed");return d(i.message),null}finally{t(false);}},[e.apiBaseUrl]),connecting:n,error:f}}
|
|
2
|
+
export{et as useCryptoConnect,Le as useFilePaperwork,Je as useFilingDetail,Fe as useFilingHistory,ge as useKeyLedger,fe as useKeys,Pe as useListKey,he as useMintKey,ze as usePayoutAccount,ie as usePricing,Ce as useSolanaPayment,_e as useStackPayoutCapabilities,we as useStripeCheckout,Ye as useStripeConnect,xe as useTransferKey};
|