@tempoxyz/id 0.0.0-pr-192.sha-c86b4e7 → 0.0.0-pr-192.sha-13bd367
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/app/server/index.js
CHANGED
|
@@ -480,7 +480,7 @@ params: ${n}`),this.query=t,this.params=n,this.cause=r,Error.captureStackTrace(t
|
|
|
480
480
|
`)}function HF(e){let t=String(e);return/[\s"=]/.test(t)||t===``?JSON.stringify(t):t}function UF(){return!1}function WF(...e){console.error(ZF(XF(...e),{level:`error`}))}function GF(...e){console.info(ZF(XF(...e),{level:`info`}))}function KF(e){return e.req.matchedRoutes.find(e=>!e.path.includes(`*`))?.path??`/*`}function qF(...e){console.warn(ZF(XF(...e),{level:`warn`}))}function JF(e){return Object.fromEntries(Object.entries(e).filter(e=>e[1]!==void 0))}function YF(e,t={depth:0}){if(!(e instanceof Error))return{name:`NonError`,type:typeof e};let n=(()=>{let t=QF(e,{key:`shortMessage`});if(typeof t==`string`)return t;let n=QF(e,{key:`query`});return typeof n==`string`&&Array.isArray(Reflect.get(e,`params`))?`Failed query: ${n}`:e.message})(),r=QF(e,{key:`status`});return JF({cause:e.cause!==void 0&&t.depth<3?YF(e.cause,{depth:t.depth+1}):void 0,code:QF(e,{key:`code`}),message:n,name:e.name,stack:e.stack?.split(`
|
|
481
481
|
`).filter(e=>/^\s+at /.test(e)).map(e=>e.trim()).join(`
|
|
482
482
|
`),status:typeof r==`number`?r:void 0})}function XF(...e){let[t,n]=e.length===2?e:[void 0,e[0]],{error:r,fields:i,message:a}=n;return JF({...i,error:r===void 0?void 0:YF(r),message:a,request:t?JF({id:t.get(`requestId`),method:t.req.method,path:KF(t)}):void 0})}function ZF(e,t){return UF()?VF(e,t):e}function QF(e,t){let n=Reflect.get(e,t.key);return typeof n==`string`||typeof n==`number`?n:void 0}var $F=`https://github.com/tempoxyz/id/blob/main/docs/errors.md`,eI={already_decided:{description:`The user code was already approved or denied.`,error:`invalid_request`,status:409},approval_pending:{description:`The user has not decided the device code yet.`,error:`authorization_pending`,status:400},authorization_expired:{description:`The app's authorization request that sign-in or the approval page continues is forged or expired.`,error:`invalid_request`,status:400},body_too_large:{description:`The request body exceeds 64 KiB.`,error:`invalid_request`,status:413},challenge_not_permitted:{description:"A request carries a challenge, and its app lacks the `tempo-id:sign` scope.",error:`unauthorized_client`,status:403},cross_site_request:{description:`A form or body-less write came from another site.`,error:`access_denied`,status:403},device_code_expired:{description:`The device code is unknown, expired, or already redeemed.`,error:`expired_token`,status:400},duplicate_limit:{description:`Two limits name the same token.`,error:`invalid_authorization_details`,status:400},duplicate_scope:{description:`Two scopes name the same call on one token.`,error:`invalid_authorization_details`,status:400},empty_limits:{description:"`limits` is an empty list.",error:`invalid_authorization_details`,status:400},empty_scopes:{description:"`scopes` is an empty list.",error:`invalid_authorization_details`,status:400},expiry_exceeds_maximum:{description:`A headless key lasts longer than a year.`,error:`invalid_authorization_details`,status:403},expiry_passed:{description:`The key expiry has passed.`,error:`invalid_authorization_details`,status:400},foreign_account:{description:`The request names a Tempo Account that is not the user's in the app's realms.`,error:`access_denied`,status:403},invalid_chain:{description:`The key chain ID is 0.`,error:`invalid_authorization_details`,status:400},invalid_code:{description:`The emailed code is wrong or expired.`,error:`invalid_grant`,status:401},invalid_expiry:{description:`The key expiry is 0, which never expires.`,error:`invalid_authorization_details`,status:400},invalid_field:{description:`A field is missing or malformed.`,error:`invalid_request`,status:400},invalid_id_token_hint:{description:`The ID token hint is not an ID token that Tempo ID signed for the app.`,error:`invalid_request`,status:400},invalid_origin:{description:`A headless request came from an origin its redirect URI does not allow.`,error:`unauthorized_client`,status:403},invalid_period:{description:"A limit's `period` is not a whole number of seconds.",error:`invalid_authorization_details`,status:400},invalid_public_key:{description:`The key public key is not a valid point.`,error:`invalid_authorization_details`,status:400},invalid_recipients:{description:"A scope's `recipients` names the zero address, or one address twice.",error:`invalid_authorization_details`,status:400},limit_exceeds_maximum:{description:`A headless key limit exceeds the token’s ceiling.`,error:`invalid_authorization_details`,status:403},logout_not_permitted:{description:`The app that the ID token hint names may not end the session at the end-session endpoint.`,error:`unauthorized_client`,status:403},malformed_body:{description:`The request body is not valid JSON.`,error:`invalid_request`,status:400},missing_key:{description:`The key authorization names no key.`,error:`invalid_authorization_details`,status:400},missing_permissions:{description:"A third-party app's key request leaves out `expiry`, `limits`, or `scopes`.",error:`invalid_authorization_details`,status:400},missing_recipients:{description:"An `approve` scope names no spenders.",error:`invalid_authorization_details`,status:400},passkey_link_expired:{description:`The email step's link to a wallet.tempo passkey expired, or the browser holds no link for it.`,error:`invalid_request`,status:400},passkey_not_permitted:{description:`A passkey sign-in names an app, or reaches a realm, that holds no passkeys for Tempo ID.`,error:`unauthorized_client`,status:403},passkey_limit:{description:`The user holds the most passkeys that Tempo ID registers for one user.`,error:`access_denied`,status:403},polling_too_fast:{description:`The device polled before its interval passed.`,error:`slow_down`,status:400},post_logout_redirect_not_permitted:{description:`The post-logout redirect URI is not one of the post-logout redirect URIs the app registered.`,error:`invalid_request`,status:400},rate_limited:{description:`Tempo ID, or a service it depends on, is rate limiting the request.`,error:`temporarily_unavailable`,status:429},reauthentication_required:{description:`The request needs a session that signed in within the last 10 minutes.`,error:`login_required`,status:401},rejected:{description:`The issuer refused the authorization request.`,error:`invalid_request`,status:400},request_denied:{description:`The user denied the device code.`,error:`access_denied`,status:400},return_to_not_permitted:{description:`The page that a provider sign-in returns to is on neither Tempo ID's origin nor the app's.`,error:`invalid_request`,status:400},scope_without_limit:{description:`A scope calls a token no limit names.`,error:`invalid_authorization_details`,status:400},session_changed:{description:`The signed-in session differs from the one that the approval page showed.`,error:`invalid_request`,status:409},session_required:{description:`The request needs a signed-in session.`,error:`login_required`,status:401},unexpected:{description:`An unexpected failure.`,error:`server_error`,status:500},unknown_code:{description:`The user code is wrong or expired.`,error:`invalid_request`,status:404},unknown_endpoint:{description:`No API endpoint matches this method and path.`,error:`invalid_request`,status:404},unknown_provider:{description:`The sign-in names a provider that Tempo ID does not offer.`,error:`invalid_request`,status:404},unsupported_call:{description:`A scope calls a function a key may not call.`,error:`invalid_authorization_details`,status:400},unsupported_token:{description:`A limit names a token that is not supported on the chain.`,error:`invalid_authorization_details`,status:400},upstream_unavailable:{description:`A service Tempo ID depends on failed or did not respond.`,error:`temporarily_unavailable`,status:503},webauthn_rejected:{description:`A passkey ceremony failed: its challenge is unknown, spent, or expired, or its response does not verify.`,error:`access_denied`,status:401},webauthn_required:{description:`A request without a page names a Tempo Account whose passkey signs only on a Tempo ID page.`,error:`interaction_required`,status:403}},tI=class extends Wv{name=`ErrorResponse.ResponseError`;response;constructor(e){let t=eI[e.reason].status;super(t,{res:Response.json(e,{status:t})}),this.response=e}};function nI(e){return class extends tI{static reason=e;constructor(t){super(uI({...t,reason:e}))}}}var rI=class extends nI(`cross_site_request`){name=`ErrorResponse.CrossSiteRequestError`;constructor(){super({error_description:`Cross-site request refused. Send JSON from an allowed origin.`})}},iI=class extends nI(`malformed_body`){name=`ErrorResponse.MalformedBodyError`;constructor(){super({error_description:"Malformed request body. Send a JSON object with `Content-Type: application/json`."})}},aI=class extends nI(`rate_limited`){name=`ErrorResponse.RateLimitedError`;retryAfter;constructor(e={}){let{retryAfter:t}=e;super({error_description:`Rate limited by an upstream service. Try again ${t?`in ${pI({seconds:t})}`:`later`}.`,...t?{meta:{retryAfter:t}}:{}}),this.retryAfter=t}},oI=class extends nI(`unexpected`){name=`ErrorResponse.UnexpectedError`;constructor(){super({error_description:`Unexpected error. Try again.`})}},sI=class extends nI(`unknown_endpoint`){name=`ErrorResponse.UnknownEndpointError`;constructor(){super({error_description:`Unknown endpoint. Check the method and path against the API reference at /openapi.json.`})}},cI=class extends nI(`upstream_unavailable`){name=`ErrorResponse.UpstreamUnavailableError`;constructor(){super({error_description:`An upstream service is unavailable. Retry later.`})}},lI;(function(e){let t=e.base=z({error:R().meta({description:"The OAuth error code (RFC 6749, OIDC Core, RFC 8628, RFC 9396), which `reason` determines."}),error_description:R().meta({description:`What went wrong and how to fix it, for people. Its wording may change.`}),error_uri:Dn().meta({description:"The errors page, at the refusal’s `reason`."}),field:R().optional().meta({description:`Extension: the request field at fault, as a dotted path.`}),meta:gn(R(),_n([Cn(),R()])).readonly().optional().meta({description:`Extension: the values the refusal compared. Base units are decimal strings.`}),reason:R().meta({description:`Extension: a stable name for the refusal, to branch on.`}),request_id:R().optional().meta({description:"Extension: the request ID, which `X-Request-Id` also carries. The Worker adds it to every error response."})}),n={already_decided:{error_description:`Code already approved or denied.`,field:`code`},approval_pending:{error_description:"Approval pending. Poll again after `interval` seconds."},authorization_expired:{error_description:`Expired authorization request: the request from the app is no longer valid. Return to the app, and start again.`,field:`oauth_query`},body_too_large:{error_description:`Invalid request body: exceeds the 65536-byte maximum. Send a body of 65536 bytes or fewer.`},challenge_not_permitted:{error_description:"Challenge not permitted: the app lacks the `tempo-id:sign` scope. Remove `challenge`, or grant the app the scope.",field:`challenge`},cross_site_request:{error_description:`Cross-site request refused. Send JSON from an allowed origin.`},device_code_expired:{error_description:`Device code expired. Request a new code.`},duplicate_limit:{error_description:`Duplicate limit for 0x20c0000000000000000000000000000000000001. Limit each token once.`,field:`key_authorization.limits.1.token`},duplicate_scope:{error_description:`Duplicate scope for 0xa9059cbb on OUSD. Name each call on a token once.`,field:`key_authorization.scopes.1.selector`},empty_limits:{error_description:"Empty `limits`. Name at least one token, or omit `limits`.",field:`key_authorization.limits`},empty_scopes:{error_description:"Empty `scopes`. Name at least one call, or omit `scopes`.",field:`key_authorization.scopes`},expiry_exceeds_maximum:{error_description:"Invalid `expiry`: Sat, 01 Jan 2028 00:00:00 GMT exceeds the one-year maximum. Use an earlier expiry, or authorize through a redirect or device grant.",field:`key_authorization.expiry`},expiry_passed:{error_description:"Invalid `expiry`: Wed, 01 Jan 2025 00:00:00 GMT has passed. Use a future Unix time.",field:`key_authorization.expiry`},foreign_account:{error_description:`Access denied to Tempo Account 0x8C3b5d0e2A4f6B1c9D7e3F5a0B2c4D6e8F1a3B5c. Name one of the user's accounts in the app's realms.`,field:`account`},invalid_chain:{error_description:"Invalid `chainId`: 0. Use a Tempo chain ID, such as 4217.",field:`key_authorization.chainId`},invalid_code:{error_description:`Invalid or expired code. Request a new one.`,field:`code`},invalid_expiry:{error_description:"Invalid `expiry`: 0 never expires. Use a future Unix time.",field:`key_authorization.expiry`},invalid_field:{error_description:"Invalid request. `email`: Invalid email address.",field:`email`},invalid_id_token_hint:{error_description:`Invalid id_token_hint: it is not an ID token that this issuer signed for the app. Send the ID token that the app received at sign-in.`,field:`id_token_hint`},invalid_origin:{error_description:"Invalid `Origin`: https://other.example.com. Requests for this redirect URI must come from https://app.example.com.",field:`Origin`},invalid_period:{error_description:"Invalid `period` on the OUSD limit: 1.5. Use a whole number of seconds, or 0 for a one-time limit.",field:`key_authorization.limits.0.period`},invalid_public_key:{error_description:"Invalid `publicKey`. Provide an uncompressed public key, or `address`.",field:`key_authorization.publicKey`},invalid_recipients:{error_description:`Invalid recipient 0x0000000000000000000000000000000000000000 for 0x095ea7b3 on OUSD. Name each recipient once, and never the zero address.`,field:`key_authorization.scopes.0.recipients.0`},limit_exceeds_maximum:{error_description:`Invalid OUSD limit: 5000 exceeds the 1000 maximum. Lower the limit, or authorize through a redirect or device grant.`,field:`key_authorization.limits.0.limit`},logout_not_permitted:{error_description:`Logout not permitted: the app client_01JZ8Q6W3N1R5B4V7C2X9K0M3T may not end the session. Register the app for logout, then retry.`},malformed_body:{error_description:"Malformed request body. Send a JSON object with `Content-Type: application/json`."},missing_key:{error_description:"Missing `address` or `publicKey`. Provide the access key.",field:`key_authorization.address`},missing_permissions:{error_description:"Missing `limits` and `scopes`. Name the expiry, limits, and scopes of the key, since a third-party app receives no defaults.",field:`key_authorization.limits`},missing_recipients:{error_description:"Missing `recipients` for `approve` on OUSD. Name the allowed spenders.",field:`key_authorization.scopes.0.recipients`},passkey_link_expired:{error_description:`Expired passkey sign-in: the link from the passkey step is no longer valid. Enter the code again to sign in with email only, or sign in with the passkey again.`,field:`link`},passkey_not_permitted:{error_description:`Passkey not permitted: the app client_01JZ8Q6W3N1R5B4V7C2X9K0M3T holds no passkeys. Sign in with an emailed code.`},passkey_limit:{error_description:`Passkey limit reached: the user holds 10 registered passkeys, the most that Tempo ID registers. Sign in with one of them.`},polling_too_fast:{error_description:"Polling too fast. Add 5 seconds to `interval`."},post_logout_redirect_not_permitted:{error_description:`Invalid post_logout_redirect_uri: https://app.example/elsewhere is not registered for the app. Use one of its post-logout redirect URIs, or leave it out.`,field:`post_logout_redirect_uri`},rate_limited:{error_description:`Too many requests. Try again in 30 seconds.`},reauthentication_required:{error_description:`Sign in again: adding a passkey needs a sign-in within the last 10 minutes.`},rejected:{error_description:"Authorization request rejected. Check `client_id`, `redirect_uri`, and `scope` against the app's registration."},request_denied:{error_description:`The user denied the request.`},return_to_not_permitted:{error_description:`Invalid return_to: https://example.org is not an origin of the app's redirect URIs. Return to a page on one of them, and pass the app's client_id.`,field:`return_to`},scope_without_limit:{error_description:`Scope on 0x20c0000000000000000000000000000000000002 has no limit. Add a limit for it, or remove the scope.`,field:`key_authorization.scopes.0.address`},session_changed:{error_description:`Changed session: the signed-in account differs from the one that this page showed. Reload the page, and check the account before the decision.`,field:`session_id`},session_required:{error_description:`Sign in first.`},unexpected:{error_description:`Unexpected error. Try again.`},unknown_code:{error_description:`Invalid or expired code. Check the code in the terminal.`,field:`code`},unknown_endpoint:{error_description:`Unknown endpoint. Check the method and path against the API reference at /openapi.json.`},unknown_provider:{error_description:`Unknown provider: github is not offered. Request GET /v1/auth/providers for the providers offered.`,field:`provider`},unsupported_call:{error_description:"Unsupported call on OUSD: any function. Use `transfer`, `transferWithMemo`, or `approve`.",field:`key_authorization.scopes.0.selector`},unsupported_token:{error_description:`Unsupported token on chain 4217: 0x20c00000000000000000000000000000000000ff. Use a supported token, such as OUSD.`,field:`key_authorization.limits.0.token`},upstream_unavailable:{error_description:`An upstream service is unavailable. Retry later.`},webauthn_rejected:{error_description:`Passkey rejected. Request new options, then try again with the same passkey or another one.`},webauthn_required:{error_description:`Passkey required: Tempo Account 0x8C3b5d0e2A4f6B1c9D7e3F5a0B2c4D6e8F1a3B5c signs key authorizations only with its passkey, on a Tempo ID page. Authorize through a redirect, popup, or device grant, or name another account.`,field:`key_authorization.account`}},r=new Map(Object.entries(eI).map(([e,r])=>{let i=n[e],a=t.extend({error:xn(r.error).meta(t.shape.error.meta()),error_description:t.shape.error_description.meta({...t.shape.error_description.meta(),examples:[i.error_description]}),error_uri:t.shape.error_uri.meta({...t.shape.error_uri.meta(),examples:[`${$F}#${e}`]}),reason:xn(e).meta(t.shape.reason.meta()),request_id:t.shape.request_id.meta({...t.shape.request_id.meta(),examples:[`8f1c2a3b4d5e6f70-SJC`]})});return[e,(i.field?a.extend({field:t.shape.field.meta({...t.shape.field.meta(),examples:[i.field]})}):a.omit({field:!0})).meta({description:`\`${r.error}\` (${r.status}): ${r.description}`,id:`ErrorResponse.${e}`})]}));function i(e){return r.get(e)}e.of=i})(lI||={});function uI(e){let{error_description:t,field:n,meta:r,reason:i}=e;return{error:eI[i].error,error_description:t,error_uri:`${$F}#${i}`,...n?{field:n}:{},...r?{meta:r}:{},reason:i}}function dI(e){if(e instanceof Wv)return;let t=`status`in e?e.status:void 0;if(t===429)return new aI({retryAfter:(()=>{if(e instanceof Response){let t=Number(e.headers.get(`retry-after`));return Number.isInteger(t)&&t>0?t:void 0}return`retryAfter`in e&&typeof e.retryAfter==`number`?e.retryAfter:void 0})()});let n=`status`in e&&t===void 0;if(typeof t==`number`&&(t===408||t>=500)||n||e instanceof Error&&e.name===`TimeoutError`)return new cI}(function(e){e.errors=[aI,cI]})(dI||={});function fI(e,t){if(e instanceof tI)return X(t,e);if(e instanceof Wv&&e.status===400)return X(t,new iI);if(e instanceof Wv&&e.status===403)return X(t,new rI);let n=dI(e);return n?(qF(t,{error:e,message:`An upstream service refused a request.`}),X(t,n)):(WF(t,{error:e,message:`The API failed a request.`}),X(t,new oI))}function X(e,t){let{response:n}=t;return t instanceof aI&&t.retryAfter&&e.header(`retry-after`,String(t.retryAfter)),e.json(n,eI[n.reason].status)}function pI(e){let{seconds:t}=e,[n,r]=t<60?[t,`second`]:t<3600?[Math.ceil(t/60),`minute`]:[Math.ceil(t/3600),`hour`];return new Intl.NumberFormat(`en`,{style:`unit`,unit:r,unitDisplay:`long`}).format(n)}async function mI(e,{signal:t}={}){return new Promise((n,r)=>{if(t?.aborted){r(Nt(t));return}let i=()=>t?.removeEventListener(`abort`,o),a=setTimeout(()=>{i(),n()},e),o=()=>{clearTimeout(a),i(),r(Nt(t))};t?.addEventListener(`abort`,o,{once:!0})})}function hI(e,{delay:t=100,retryCount:n=2,shouldRetry:r=()=>!0,signal:i}={}){return new Promise((a,o)=>{let s=async({count:c=0}={})=>{if(i?.aborted){o(Nt(i));return}let l=async({error:e})=>{let n=typeof t==`function`?t({count:c,error:e}):t;if(n)try{await mI(n,{signal:i})}catch(e){o(e);return}return s({count:c+1})};try{a(await e())}catch(e){if(i?.aborted){o(Nt(i));return}if(tn(e)){o(e);return}if(c<n&&await r({count:c,error:e}))return l({error:e});o(e)}};s().catch(o)})}var gI=256,_I=gI,vI;function yI(e=11){if(!vI||_I+e>gI*2){vI=``,_I=0;for(let e=0;e<gI;e++)vI+=(256+Math.random()*256|0).toString(16).substring(1)}return vI.substring(_I,_I+++e)}function bI(e){let{batch:t,chain:n,ccipRead:r,dataSuffix:i,key:a=`base`,name:o=`Base Client`,tokens:s,type:c=`base`}=e,l=e.experimental_blockTag??(typeof n?.experimental_preconfirmationTime==`number`?`pending`:void 0),u=n?.blockTime??12e3,d=Math.min(Math.max(Math.floor(u/2),500),4e3),f=e.pollingInterval??d,p=e.cacheTime??f,m=e.account?Ht(e.account):void 0,{config:h,request:g,value:_}=e.transport({account:m,chain:n,pollingInterval:f}),v={account:m,batch:t,cacheTime:p,ccipRead:r,chain:n,dataSuffix:i,key:a,name:o,pollingInterval:f,request:g,tokens:s,transport:{...h,..._},type:c,uid:yI(),...l?{experimental_blockTag:l}:{}};function y(e){return t=>{let n=t(e);for(let e in v)delete n[e];let r={...e,...n};for(let t in n){let i=e[t],a=n[t];xI(i)&&xI(a)&&(r[t]={...i,...a})}return Object.assign(r,{extend:y(r)})}}return Object.assign(v,{extend:y(v)})}function xI(e){if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}var SI=new en(8192);function CI(e,{enabled:t=!0,id:n}){if(!t||!n)return e();if(SI.get(n))return SI.get(n);let r=e().finally(()=>SI.delete(n));return SI.set(n,r),r}function wI(e,t={}){return async(n,r={})=>{let{dedupe:i=!1,methods:a,retryDelay:o=150,retryCount:s=3,signal:c,uid:l}={...t,...r},{method:u}=n;if(a?.exclude?.includes(u)||a?.include&&!a.include.includes(u))throw new et(Error(`method not supported`),{method:u});if(c?.aborted)throw Nt(c);return CI(()=>hI(async()=>{try{return await e(n,c?{signal:c}:void 0)}catch(e){if(c?.aborted)throw Nt(c);if(tn(e))throw e;let t=e;switch(t.code){case We.code:throw new We(t);case Qe.code:throw new Qe(t);case nt.code:throw new nt(t,{method:n.method});case Xe.code:throw new Xe(t);case lt.code:throw new lt(t);case xt.code:throw new xt(t);case Ot.code:throw new Ot(t);case qe.code:throw new qe(t);case Ie.code:throw new Ie(t);case et.code:throw new et(t,{method:n.method});case ft.code:throw new ft(t);case ht.code:throw new ht(t);case st.code:throw new st(t);case Se.code:throw new Se(t);case Pe.code:throw new Pe(t);case Ct.code:throw new Ct(t);case vt.code:throw new vt(t);case Tt.code:throw new Tt(t);case we.code:throw new we(t);case Ee.code:throw new Ee(t);case Je.code:throw new Je(t);case wt.code:throw new wt(t);case mt.code:throw new mt(t);case it.code:throw new it(t);case Ge.code:throw new Ge(t);case 5e3:throw new st(t);case be.code:throw new be(t);default:throw e instanceof kt?e:new Re(t)}}},{delay:({count:e,error:t})=>{if(t&&t instanceof Ft){let e=t?.headers?.get(`Retry-After`);if(e?.match(/\d/))return Number.parseInt(e,10)*1e3}return~~(1<<e)*o},retryCount:s,signal:c,shouldRetry:({error:e})=>TI(e)}),{enabled:i,id:i?EI(`${l}.${Yt(n)}`):void 0})}}function TI(e){return tn(e)?!1:`code`in e&&typeof e.code==`number`?e.code===-1||e.code===ft.code||e.code===lt.code||e.code===429||e.code===-32007:e instanceof Ft&&e.status?e.status===403||e.status===408||e.status===413||e.status===429||e.status===500||e.status===502||e.status===503||e.status===504:!0}function EI(e,t=0){let n=3735928559^t,r=1103547991^t;for(let t=0;t<e.length;t++){let i=e.charCodeAt(t);n=Math.imul(n^i,2654435761),r=Math.imul(r^i,1597334677)}return n=Math.imul(n^n>>>16,2246822507),n^=Math.imul(r^r>>>16,3266489909),r=Math.imul(r^r>>>16,2246822507),r^=Math.imul(n^n>>>16,3266489909),(4294967296*(2097151&r)+(n>>>0)).toString(36)}function DI(e,{errorInstance:t=Error(`timed out`),timeout:n,signal:r}){return new Promise((i,a)=>{(async()=>{let o,s=new AbortController;try{n>0&&(o=setTimeout(()=>{r?s.abort():a(t)},n)),i(await e({signal:s?.signal||null}))}catch(e){if(s?.signal.aborted&&tn(e)){a(t);return}a(e)}finally{clearTimeout(o)}})()})}function OI(){return{current:0,take(){return this.current++},reset(){this.current=0}}}var kI=OI(),AI=10485760;function jI(e,t={}){let{url:n,headers:r}=PI(e);return{async request(e){let{body:i,fetchFn:a=t.fetchFn??fetch,maxResponseBodySize:o=t.maxResponseBodySize??AI,onRequest:s=t.onRequest,onResponse:c=t.onResponse,timeout:l=t.timeout??1e4}=e,u={...t.fetchOptions??{},...e.fetchOptions??{}},{headers:d,method:f,signal:p}=u;try{let{response:e,responseBody:t}=await DI(async({signal:e})=>{let{signal:t,cleanup:m}=MI([p,l>0?e:null]);try{let e={...u,body:Yt(Array.isArray(i)?i.map(e=>({jsonrpc:`2.0`,id:e.id??kI.take(),...e})):{jsonrpc:`2.0`,id:i.id??kI.take(),...i}),headers:{...r,"Content-Type":`application/json`,...d},method:f||`POST`,signal:t},l=new Request(n,e),p=await s?.(l,e)??{...e,url:n},m=await a(p.url??n,p);return c&&await c(m),{response:m,responseBody:await NI(m,{maxResponseBodySize:o})}}finally{m()}},{errorInstance:new Ut({body:i,url:n}),timeout:l,signal:!0}),m;if(e.headers.get(`Content-Type`)?.startsWith(`application/json`))m=JSON.parse(t);else{m=t;try{m=JSON.parse(m||`{}`)}catch(t){if(e.ok)throw t;m={error:m}}}if(!e.ok){if(typeof m.error?.code==`number`&&typeof m.error?.message==`string`)return m;throw new Ft({body:i,details:Yt(m.error)||e.statusText,headers:e.headers,status:e.status,url:n})}return m}catch(e){throw p?.aborted?Nt(p):tn(e)||e instanceof Ft||e instanceof Wt||e instanceof Ut?e:new Ft({body:i,cause:e,url:n})}}}}function MI(e){let t=e.filter(e=>!!e);if(t.length<2)return{signal:t[0]??null,cleanup:()=>{}};let n=new AbortController,r=()=>{i(),n.abort(t.find(e=>e.aborted)?.reason)},i=()=>{for(let e of t)e.removeEventListener(`abort`,r)};for(let e of t){if(e.aborted){i(),n.abort(e.reason);break}e.addEventListener(`abort`,r)}return{signal:n.signal,cleanup:i}}async function NI(e,{maxResponseBodySize:t}){if(t===!1)return e.text();let n=e.headers.get(`Content-Length`);if(n){let e=Number(n);if(e>t)throw new Wt({maxSize:t,size:e})}if(!e.body){let n=await e.text(),r=new TextEncoder().encode(n).length;if(r>t)throw new Wt({maxSize:t,size:r});return n}let r=e.body.getReader(),i=new TextDecoder,a=``,o=0;try{for(;;){let{done:e,value:n}=await r.read();if(e)break;if(o+=n.byteLength,o>t)throw await r.cancel(),new Wt({maxSize:t,size:o});a+=i.decode(n,{stream:!0})}return a+=i.decode(),a}finally{r.releaseLock()}}function PI(e){try{let t=new URL(e),n=(()=>{if(t.username){let e=`${decodeURIComponent(t.username)}:${decodeURIComponent(t.password)}`;return t.username=``,t.password=``,{url:t.toString(),headers:{Authorization:`Basic ${btoa(e)}`}}}})();return{url:t.toString(),...n}}catch{return{url:e}}}function FI({key:e,methods:t,name:n,request:r,retryCount:i=3,retryDelay:a=150,timeout:o,type:s},c){let l=yI();return{config:{key:e,methods:t,name:n,request:r,retryCount:i,retryDelay:a,timeout:o,type:s},request:wI(r,{methods:t,retryCount:i,retryDelay:a,uid:l}),value:c}}var II=class extends kt{constructor(){super(`No URL was provided to the Transport. Please provide a valid RPC URL to the Transport.`,{docsPath:`/docs/clients/intro`,name:`UrlRequiredError`})}},LI=0,RI=new WeakMap;function zI(e){if(!e)return`default`;let t=RI.get(e);if(t!==void 0)return t;let n=LI++;return RI.set(e,n),n}function BI(e,t={}){let{batch:n,fetchFn:r,fetchOptions:i,key:a=`http`,maxResponseBodySize:o,methods:s,name:c=`HTTP JSON-RPC`,onFetchRequest:l,onFetchResponse:u,retryDelay:d,raw:f}=t;return({chain:p,retryCount:m,timeout:h})=>{let{batchSize:g=1e3,wait:_=0}=typeof n==`object`?n:{},v=t.retryCount??m,y=h??t.timeout??1e4,b=e||p?.rpcUrls.default.http[0];if(!b)throw new II;let x=jI(b,{fetchFn:r,fetchOptions:i,maxResponseBodySize:o,onRequest:l,onResponse:u,timeout:y});return FI({key:a,methods:s,name:c,async request({method:e,params:t},r){let i={method:e,params:t},a=r?.signal?{signal:r.signal}:void 0,{schedule:o}=Kt({id:`${b}.${zI(r?.signal)}`,wait:_,shouldSplitBatch(e){return e.length>g},fn:e=>x.request({body:e,fetchOptions:a}),sort:(e,t)=>e.id-t.id}),[{error:s,result:c}]=await(async e=>n?o(e):[await x.request({body:e,fetchOptions:a})])(i);if(f)return{error:s,result:c};if(s)throw new At({body:i,error:s,url:b});return c},retryCount:v,retryDelay:d,timeout:y,type:`http`},{fetchOptions:i,url:b})}}var VI=de({...O,id:31318,name:`Tempo Devnet`,hardfork:`t3`,blockExplorers:{default:{name:`Tempo Explorer`,url:`https://explore.devnet.tempo.xyz`}},nativeCurrency:{name:`USD`,symbol:`USD`,decimals:6},rpcUrls:{default:{http:[`https://rpc.devnet.tempoxyz.dev`],webSocket:[`wss://rpc.devnet.tempoxyz.dev`]}},testnet:!0}),HI=de({...O,id:1337,name:`Tempo`,hardfork:`t3`,nativeCurrency:{name:`USD`,symbol:`USD`,decimals:6},rpcUrls:{default:{http:[`http://localhost:8545`]}}});function UI(e){let{addresses:t,currency:n,decimals:r,name:i,popular:a,symbol:o}=e;function s(e){let s=t[e];if(!s)throw Error(`Token has no address for chain id "${e}".`);return{address:s,currency:n,decimals:r,name:i,popular:a,symbol:o}}return Object.defineProperties(s,{addresses:{enumerable:!0,value:t},currency:{enumerable:!0,value:n},decimals:{enumerable:!0,value:r},name:{enumerable:!0,value:i},popular:{enumerable:!0,value:a},symbol:{enumerable:!0,value:o}})}var WI=UI({addresses:{42431:`0x20c0000000000000000000000000000000000001`},currency:`USD`,decimals:6,name:`AlphaUSD`,symbol:`alphaUSD`}),GI=UI({addresses:{42431:`0x20c0000000000000000000000000000000000002`},currency:`USD`,decimals:6,name:`BetaUSD`,symbol:`betaUSD`}),KI=UI({addresses:{4217:`0x20c000000000000000000000f047dd7018e50367`},currency:`BRL`,decimals:6,name:`BRLA Token`,symbol:`BRLA`}),qI=UI({addresses:{4217:`0x20c000000000000000000000c412ec89d0c08be5`},currency:`BTC`,decimals:6,name:`Coinbase Wrapped BTC`,symbol:`cbBTC`}),JI=UI({addresses:{4217:`0x20c00000000000000000000042109aef2f8b28e1`},currency:`CHF`,decimals:6,name:`AllUnity CHF`,symbol:`CHFAU`}),YI=UI({addresses:{1:`0x72DFB2E44f59C5AD2bAFE84314E5b99a7cd5075E`,5042:`0x171A4217b86A807A64eB94757Db6849fb4bDbAA0`,5042002:`0xf0C4a4CE82A5746AbAAd9425360Ab04fbBA432BF`,11155111:`0x3a3fe695F684Bf9b9e43CF43C2b895Ea5e392bB3`},currency:`BTC`,decimals:8,name:`Circle Wrapped Bitcoin`,symbol:`cirBTC`}),XI=UI({addresses:{4217:`0x20c0000000000000000000000520792dcccccccc`},currency:`USD`,decimals:6,name:`Cap USD`,symbol:`cUSD`}),ZI=UI({addresses:{4217:`0x20c0000000000000000000006fd9a167923ba194`},currency:`USD`,decimals:6,name:`Deel USD`,symbol:`DLUSD`}),QI=UI({addresses:{4217:`0x20c0000000000000000000009a4a4b17e0dc6651`},currency:`EUR`,decimals:6,name:`AllUnity EUR`,symbol:`EURAU`}),$I=UI({addresses:{1:`0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c`,25:`0xA6dE01a2d62C6B5f3525d768f34d276652C554c8`,338:`0x31f7538adb53cF16350e6B0c89d03D91b7D12c46`,480:`0x1C60ba0A0eD1019e8Eb035E6daF4155A5cE2380B`,4801:`0xe479EcA5740Ac65d6E1823bea2f1C08Bc14e954F`,5042:`0xbEf5f6d51CB62b58e6A8f77868681825C6fe21c1`,8453:`0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42`,9745:`0x3EE196E78d4d4248b849B8E1C7F44C5457FAFD2C`,43113:`0x5E44db7996c682E92a960b65AC713a54AD815c6B`,43114:`0xC891EB4cbdEFf6e073e859e987815Ed1505c2ACD`,84532:`0x808456652fdb597867f38412077A9182bf77359F`,5042002:`0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a`,11155111:`0x08210F9170F89Ab7658F0B5E3fF39b0E03C594D4`},currency:`EUR`,decimals:6,name:`EURC`,symbol:`EURC`}),eL=UI({addresses:{4217:`0x20c0000000000000000000001621e21f71cf12fb`,42431:`0x20c000000000000000000000d72572838bbee59c`},currency:`EUR`,decimals:6,name:`Bridged EURC (Stargate)`,symbol:`EURC.e`}),tL=UI({addresses:{4217:`0x20c0000000000000000000003554d28269e0f3c2`},currency:`USD`,decimals:6,name:`Frax USD`,symbol:`frxUSD`}),nL=UI({addresses:{4217:`0x20c0000000000000000000000a6da882d075a4c3`},currency:`GBP`,decimals:6,name:`Agant GBP`,symbol:`GBPA`}),rL=UI({addresses:{4217:`0x20c0000000000000000000005c0bac7cef389a11`},currency:`USD`,decimals:6,name:`Generic USD`,symbol:`GUSD`}),iL=UI({addresses:{4217:`0x20c000000000000000000000ab02d39df30bd17e`},currency:`USD`,decimals:6,name:`InfiniFi USD`,symbol:`iUSD`}),aL=UI({addresses:{1:`0x9f6F3991D525015a6F8CaF062C83b62fD3AC4436`,4217:`0x20c0000000000000000000006a37DA5C996874BE`,8453:`0xB2000000000000000000002fEb517dFeC7415344`},currency:`USD`,decimals:6,name:`OpenUSD`,popular:!0,symbol:`OUSD`}),oL=UI({addresses:{4217:`0x20c0000000000000000000000000000000000000`,42431:`0x20c0000000000000000000000000000000000000`},currency:`USD`,decimals:6,name:`PathUSD`,symbol:`pathUSD`}),sL=UI({addresses:{4217:`0x20c000000000000000000000383a23bacb546ab9`},currency:`USD`,decimals:6,name:`Re Protocol reUSD`,symbol:`reUSD`}),cL=UI({addresses:{4217:`0x20c0000000000000000000007f7ba549dd0251b9`},currency:`USD`,decimals:6,name:`Reservoir Stablecoin`,symbol:`rUSD`}),lL=UI({addresses:{4217:`0x20c000000000000000000000ae247a1130450f09`},currency:`USD`,decimals:6,name:`Stable Coin`,symbol:`SBC`}),uL=UI({addresses:{4217:`0x20c000000000000000000000048c8f36df1c9a4a`},currency:`siUSD`,decimals:6,name:`InfiniFi Staked USD`,symbol:`siUSD`}),dL=UI({addresses:{4217:`0x20c0000000000000000000008ee4fcff88888888`},currency:`stcUSD`,decimals:6,name:`Staked Cap USD`,symbol:`stcUSD`}),fL=UI({addresses:{4217:`0x20c000000000000000000000bd95bfb69fbe6ce3`},currency:`sUSDe`,decimals:6,name:`Staked USDe`,symbol:`sUSDe`}),pL=UI({addresses:{4217:`0x20c0000000000000000000008191667423f70e67`},currency:`syrupUSDC`,decimals:6,name:`Syrup USDC`,symbol:`syrupUSDC`}),mL=UI({addresses:{42431:`0x20c0000000000000000000000000000000000003`},currency:`USD`,decimals:6,name:`ThetaUSD`,symbol:`thetaUSD`}),hL=UI({addresses:{4217:`0x20c000000000000000000000111111111e910f0f`},currency:`USD`,decimals:6,name:`USD1`,symbol:`USD1`}),gL=UI({addresses:{4217:`0x20c0000000000000000000003158081efd85bfc2`},currency:`USD`,decimals:6,name:`USDBridge`,symbol:`USDB`}),_L=UI({addresses:{1:`0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`,10:`0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85`,25:`0x3D7F2C478aAfdB65542BCB44bCeeC05849999d2D`,50:`0xfA2958CB79b0491CC627c1557F441eF849Ca8eb1`,51:`0xb5AB69F7bBada22B28e79C8FFAECe55eF1c771D4`,130:`0x078D782b760474a361dDA0AF3839290b0EF57AD6`,137:`0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359`,143:`0x754704Bc059F8C67012fEd69BC8A327a5aafb603`,146:`0x29219dd400f2Bf60E5a23d13Be72B486D4038894`,196:`0xB6CEceAB302E2E4948951eE7843FC24E92933061`,300:`0xAe045DE5638162fa134807Cb558E15A3F5A7F853`,324:`0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4`,338:`0xEb33dc5fac03833e132593659e1dE7256aB59794`,480:`0x79A02482A880bCE3F13e09Da970dC34db4CD24d1`,998:`0x2B3370eE501B4a559b57D449569354196457D8Ab`,999:`0xb88339CB7199b77E23DB6E890353E22632Ba630f`,1301:`0x31d0220469e10c4E71834a79b1f276d740d3768F`,1328:`0x4fCF1784B31630811181f670Aea7A7bEF803eaED`,1329:`0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392`,1439:`0x0C382e685bbeeFE5d3d9C29e29E341fEE8E84C5d`,1672:`0xC879C018dB60520F4355C26eD1a6D572cdAC1815`,1776:`0xa00C59fF5a080D2b954d0c75e46E22a0c371235a`,1952:`0xDec90b78111Ba2fc6FC6d84d8B9ec159A2d4b9B3`,2818:`0xCfb1186F4e93D60E60a8bDd997427D1F33bc372B`,2910:`0x7433b41C6c5e1d58D4Da99483609520255ab661B`,3343:`0x98d2919b9A214E6Fa5384AC81E6864bA686Ad74c`,4801:`0x66145f38cBAC35Ca6F1Dfb4914dF98F1614aeA88`,5042:`0x3600000000000000000000000000000000000000`,8453:`0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`,9745:`0x2d661C89D812261039AF9764eceaAee884f5F67F`,10143:`0x534b2f3A21130d7a60830c2Df862319e593943A3`,33431:`0x2d9F7CAD728051AA35Ecdc472a14cf8cDF5CFD6B`,42161:`0xaf88d065e77c8cC2239327C5EDb3A432268e5831`,42220:`0xcebA9300f2b948710d2653dD7B07f33A8B32118C`,43113:`0x5425890298aed601595a70AB815c96711a31Bc65`,43114:`0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E`,57054:`0xA4879Fed32Ecbef99399e5cbC247E533421C4eC6`,57073:`0x2D270e6886d130D724215A266106e6832161EAEd`,59141:`0xFEce4462D57bD51A6A552365A011b95f0E16d9B7`,59144:`0x176211869cA2b568f2A7D4EE941E073a821EE1ff`,64165:`0x0BA304580ee7c9a980CF72e55f5Ed2E9fd30Bc51`,80002:`0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582`,81224:`0xd996633a415985DBd7D6D12f4A4343E31f5037cf`,84532:`0x036CbD53842c5426634e7929541eC2318f3dCF7e`,98866:`0x222365EF19F7947e5484218551B56bb3965Aa7aF`,98867:`0xcB5f30e335672893c7eb944B374c196392C19D18`,421614:`0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d`,688689:`0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B`,763373:`0xFabab97dCE620294D2B0b0e46C68964e326300Ac`,812242:`0x6d7f141b6819C2c9CC2f818e6ad549E7Ca090F8f`,5042002:`0x3600000000000000000000000000000000000000`,11142220:`0x01C5C0122039549AD1493B8220cABEdD739BC44E`,11155111:`0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238`,11155420:`0x5fd84259d66Cd46123540766Be93DFE6D43130D7`},currency:`USD`,decimals:6,name:`USD Coin`,popular:!0,symbol:`USDC`}),vL=UI({addresses:{4217:`0x20c000000000000000000000b9537d11c60e8b50`,42431:`0x20c0000000000000000000009e8d7eb59b783726`},currency:`USD`,decimals:6,name:`Bridged USDC (Stargate)`,symbol:`USDC.e`}),yL=UI({addresses:{4217:`0x20c0000000000000000000002f52d5cc21a3207b`},currency:`USD`,decimals:6,name:`USDe`,symbol:`USDe`}),bL=UI({addresses:{4217:`0x20c00000000000000000000014f22ca97301eb73`},currency:`USD`,decimals:6,name:`USDT0`,symbol:`USDT0`}),xL=UI({addresses:{1:`0x136471a34f6ef19fE571EFFC1CA711fdb8E49f2b`,56:`0x8D0fA28f221eB5735BC71d3a0Da67EE5bC821311`,97:`0x109656Aba6F175c634c63C9874f29CeAAAB8E606`,5042002:`0xe9185F0c5F296Ed1797AaE4238D26CCaBEadb86C`,11155111:`0x38D3A3f8717F4DB1CcB4Ad7D8C755919440848A3`},currency:`USD`,decimals:6,name:`US Yield Coin`,symbol:`USYC`}),SL=UI({addresses:{4217:`0x20c000000000000000000000aeed2ec36a54d0e5`},currency:`wsrUSD`,decimals:6,name:`Wrapped Savings rUSD`,symbol:`wsrUSD`}),CL={all:[WI,GI,KI,qI,JI,YI,XI,ZI,QI,$I,eL,tL,nL,rL,iL,aL,oL,sL,cL,lL,uL,dL,fL,pL,mL,hL,gL,_L,vL,yL,bL,xL,SL],popular:[aL,_L],tempo:[WI,GI,KI,qI,JI,XI,ZI,QI,eL,tL,nL,rL,iL,aL,oL,sL,cL,lL,uL,dL,fL,pL,mL,hL,gL,vL,yL,bL,SL]},wL=class extends nI(`challenge_not_permitted`){name=`KeyAuthorization.ChallengeNotPermittedError`;constructor(e){let{clientId:t}=e;super({error_description:`Challenge not permitted: the app lacks the \`${vF}\` scope. Remove \`challenge\`, or grant the app the scope.`,field:`challenge`,meta:{client_id:t,scope:vF}})}},TL=class extends nI(`duplicate_limit`){name=`KeyAuthorization.DuplicateLimitError`},EL=class extends nI(`duplicate_scope`){name=`KeyAuthorization.DuplicateScopeError`},DL=class extends nI(`empty_limits`){name=`KeyAuthorization.EmptyLimitsError`},OL=class extends nI(`empty_scopes`){name=`KeyAuthorization.EmptyScopesError`},kL=class extends nI(`expiry_exceeds_maximum`){name=`KeyAuthorization.ExpiryExceedsMaximumError`},AL=class extends nI(`expiry_passed`){name=`KeyAuthorization.ExpiryPassedError`},jL=class extends nI(`invalid_chain`){name=`KeyAuthorization.InvalidChainError`},ML=class extends nI(`invalid_expiry`){name=`KeyAuthorization.InvalidExpiryError`},NL=class extends nI(`invalid_period`){name=`KeyAuthorization.InvalidPeriodError`},PL=class extends nI(`invalid_public_key`){name=`KeyAuthorization.InvalidPublicKeyError`},FL=class extends nI(`invalid_recipients`){name=`KeyAuthorization.InvalidRecipientsError`},IL=class extends nI(`limit_exceeds_maximum`){name=`KeyAuthorization.LimitExceedsMaximumError`},LL=class extends nI(`missing_key`){name=`KeyAuthorization.MissingKeyError`},RL=class extends nI(`missing_permissions`){name=`KeyAuthorization.MissingPermissionsError`},zL=class extends nI(`missing_recipients`){name=`KeyAuthorization.MissingRecipientsError`},BL=class extends nI(`scope_without_limit`){name=`KeyAuthorization.ScopeWithoutLimitError`},VL=class extends nI(`unsupported_call`){name=`KeyAuthorization.UnsupportedCallError`},HL=class extends nI(`unsupported_token`){name=`KeyAuthorization.UnsupportedTokenError`},UL=class extends nI(`webauthn_required`){name=`KeyAuthorization.WebAuthnRequiredError`;constructor(e){super({error_description:e.description??`Passkey required: Tempo Account ${e.account} signs key authorizations only with its passkey, on a Tempo ID page. Authorize through a redirect, popup, or device grant, or name another account.`,field:`key_authorization.account`,meta:{account:e.account}})}},WL=vn([`0x`,R().regex(/^[0-9a-fA-F]*$/)]).meta({pattern:`^0x[0-9a-fA-F]*$`}),GL=vn([`0x`,R().regex(/^[0-9a-fA-F]{40}$/)]).meta({pattern:`^0x[0-9a-fA-F]{40}$`}),KL=vn([`0x`,R().regex(/^[0-9a-fA-F]{0,64}$/)]).meta({pattern:`^0x[0-9a-fA-F]{0,64}$`}),qL=vn([`0x`,R().regex(/^[0-9a-fA-F]{64}$/)]).meta({pattern:`^0x[0-9a-fA-F]{64}$`});function JL(e){return Nn(_n([KL.meta({examples:e.examples}),wn()]),wn(),{decode:e=>typeof e==`bigint`?e:e===`0x`?0n:Pt(e),encode:e=>Bt(e)})}var YL=z({account:bn(GL).meta({description:`The Tempo Account the key acts for. Defaults to the account selected at sign-in, or else the oldest account.`,examples:[`0x9a073914db0d149375ac2b7fbb72c68c0780fb5f`]}),address:bn(GL).meta({description:"The access key's address. Required unless `publicKey` is present.",examples:[`0x81c0f22bd173c115d18eeea0f6a38e935ecf52fb`]}),chainId:bn(JL({examples:[`0x1079`]})).meta({description:`The chain ID the key acts on, as a hex quantity. Defaults to Tempo mainnet.`}),expiry:bn(Cn()).meta({description:`When the key expires, in Unix seconds. Defaults to one year after the request, for a first-party app. A third-party app names it. A headless request allows at most one year.`,examples:[1893456e3]}),keyType:bn(Sn([`p256`,`secp256k1`,`webAuthn`])).meta({description:"The signature scheme of the access key. Defaults to `secp256k1`.",examples:[`secp256k1`]}),limits:bn(Mn(z({limit:JL({examples:[`0x989680`]}).meta({description:"The most of the token the key may spend, in base units, as a hex quantity. Applies per period when `period` is set."}),period:bn(Cn()).meta({description:`Seconds after which the limit resets. Omitted or 0 for a one-time limit.`,examples:[86400]}),token:GL.meta({description:`The TIP-20 token the limit applies to.`,examples:[`0x20c0000000000000000000006a37DA5C996874BE`]})})).readonly()).meta({description:`The spending limit on each token. Defaults to the cap of each token the scopes call, or else of OUSD, for a first-party app. A third-party app names it.`}),publicKey:bn(WL).meta({description:"The access key's uncompressed public key, as hex. Tempo ID derives `address` from it when `address` is absent.",examples:[`0x0438ef39ed22456a6956f380ebc18c50bd18c0402658bc52903817cc8a1e8b2f7ed1da68afc7f343c1debc44c04ac60e62e96bbb261d2226e7a7b96e64fd0f0765`]}),scopes:bn(Mn(z({address:GL.meta({description:`The TIP-20 token contract the key may call.`,examples:[`0x20c0000000000000000000006a37DA5C996874BE`]}),recipients:bn(Mn(GL).readonly()).meta({description:"The only addresses the call may name as recipient or spender. Required for `approve`.",examples:[[`0xff5deded16eb46018387144ff8bf41f26afb41af`]]}),selector:bn(_n([WL,R().max(256)])).meta({description:"The function the key may call, as a 4-byte selector or a function signature: `transfer`, `transferWithMemo`, or `approve`. A scope without a selector is refused.",examples:[`0xa9059cbb`,`transfer(address,uint256)`]})})).readonly()).meta({description:"The calls the key may make. Defaults to `transfer` and `transferWithMemo` on each token the key limits, for a first-party app. A third-party app names it."})}),XL;(function(e){e.account=GL.meta({description:`The Tempo Account the key acts for.`,examples:[`0x9a073914db0d149375ac2b7fbb72c68c0780fb5f`]}),e.request=bn(YL.transform(mR)).meta({description:"A key authorization for the app's own key: the shape of the Accounts SDK's `wallet_connect` `authorizeAccessKey` capability. Omitted fields default to the headless ceiling.",id:`KeyAuthorizationRequest`}),e.description=z({account:GL.optional().meta({description:`The Tempo Account the request names. Absent when the request names none.`,examples:[`0x9a073914db0d149375ac2b7fbb72c68c0780fb5f`]}),expiry:Cn().meta({description:`Unix seconds.`,examples:[1893456e3]}),limits:Mn(z({amount:R().meta({description:`In whole units.`,examples:[`1000`]}),currency:R().meta({description:"The tokens' currency, such as `USD`. A yield-bearing token names its own.",examples:[`USD`]}),period:Cn().optional().meta({description:`Seconds after which the amount resets. Omitted for a one-time limit.`,examples:[86400]}),tokens:Mn(z({amount:R().meta({description:`The token's own limit, in whole units.`,examples:[`1000`]}),symbol:R().meta({description:`The token's symbol, or its address when the token has no symbol.`,examples:[`OUSD`]})})).readonly().meta({description:`The tokens the amount spans.`})})).readonly().meta({description:`The spending limits, totaled for each currency and period.`})}).meta({description:`What a key authorization grants, for approval screens.`,id:`KeyAuthorizationDescription`});let t=jn(`type`,[z({r:WL.meta({description:"The signature's 32-byte `r` value.",examples:[`0x12fe6a88b99377b94d6a628a86b9df544202c7b03827f44b16ee1a266ab98e17`]}),s:WL.meta({description:"The signature's 32-byte `s` value.",examples:[`0x4b6aa3723402498e07fb1f071673bd969d9f49a286af15ac60581d07ade24b77`]}),type:xn(`secp256k1`).meta({description:`A secp256k1 ECDSA signature.`}),v:WL.optional().meta({description:"The legacy recovery value, which `yParity` replaces. Absent in most envelopes.",examples:[`0x1c`]}),yParity:WL.meta({description:"The parity of the y-coordinate of the curve point, `0x0` or `0x1`.",examples:[`0x1`]})}).meta({description:`A secp256k1 signature.`}),z({preHash:On().meta({description:`Whether the signer hashed the digest with SHA-256 before signing it, as WebCrypto keys do.`,examples:[!0]}),pubKeyX:WL.meta({description:`The 32-byte x-coordinate of the signer's P256 public key.`,examples:[`0xdae3e3e5faba0a2aca73d4d2a4b84ad46460f3f23af8a60b17b8a13537cfd440`]}),pubKeyY:WL.meta({description:`The 32-byte y-coordinate of the signer's P256 public key.`,examples:[`0x816438c87ffd782cd0e37355eb83fbe1d4e5e905eaafa22fa27c32cc4abf7802`]}),r:WL.meta({description:"The signature's 32-byte `r` value.",examples:[`0x9da52cc71c005844434ce6996f7ea3b3262f84ec3a5d54f1d22d0bba9f2e5ea9`]}),s:WL.meta({description:"The signature's 32-byte `s` value.",examples:[`0x4b6aa3723402498e07fb1f071673bd969d9f49a286af15ac60581d07ade24b77`]}),type:xn(`p256`).meta({description:`A P256 (secp256r1) signature.`})}).meta({description:`A P256 signature, with its public key.`}),z({pubKeyX:WL.meta({description:`The 32-byte x-coordinate of the passkey's P256 public key.`,examples:[`0xdae3e3e5faba0a2aca73d4d2a4b84ad46460f3f23af8a60b17b8a13537cfd440`]}),pubKeyY:WL.meta({description:`The 32-byte y-coordinate of the passkey's P256 public key.`,examples:[`0x816438c87ffd782cd0e37355eb83fbe1d4e5e905eaafa22fa27c32cc4abf7802`]}),r:WL.meta({description:"The signature's 32-byte `r` value.",examples:[`0x9da52cc71c005844434ce6996f7ea3b3262f84ec3a5d54f1d22d0bba9f2e5ea9`]}),s:WL.meta({description:"The signature's 32-byte `s` value.",examples:[`0x4b6aa3723402498e07fb1f071673bd969d9f49a286af15ac60581d07ade24b77`]}),type:xn(`webAuthn`).meta({description:`A WebAuthn passkey signature.`}),webauthnData:WL.meta({description:"The assertion's authenticator data followed by its `clientDataJSON`, as hex.",examples:[`0xa7cb28053c8ee4e5394fc67a0018dc1c622dad5ce3591b8ca13094ae86d11ba605000000007b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a2271334a306257467a6157356e6247567a6157647559585231636d566b6157646c633352765a6d746c65574631644767222c226f726967696e223a2268747470733a2f2f617574682e74656d706f2e78797a222c2263726f73734f726967696e223a66616c73657d`]})}).meta({description:`A WebAuthn signature, with its public key.`})]).meta({description:`A signature by one key, as secp256k1, P256, or WebAuthn.`});e.rpc=z({account:GL.nullable().optional().meta({description:`The Tempo Account the key is bound to (TIP-1049). Absent or null when the key has no account binding.`,examples:[`0x9a073914db0d149375ac2b7fbb72c68c0780fb5f`]}),allowedCalls:Mn(z({selectorRules:Mn(z({recipients:Mn(GL).readonly().optional().meta({description:`The only addresses the call may name as recipient or spender. Absent when any address may receive.`,examples:[[`0xff5deded16eb46018387144ff8bf41f26afb41af`]]}),selector:WL.meta({description:`The 4-byte selector of the function the key may call.`,examples:[`0xa9059cbb`]})})).readonly().optional().meta({description:`The functions the key may call on the target. Absent when the key may call any function on it.`}),target:GL.meta({description:`The contract the key may call.`,examples:[`0x20c0000000000000000000006a37DA5C996874BE`]})})).readonly().optional().meta({description:`The calls the key may make. Absent when the key may make any call.`}),chainId:WL.meta({description:`The chain ID the key acts on, as a hex quantity.`,examples:[`0xa5bf`]}),expiry:WL.nullable().optional().meta({description:`When the key expires, in Unix seconds, as a hex quantity. Absent or null when the key never expires.`,examples:[`0x6acdc1b4`]}),keyId:GL.meta({description:`The access key's address.`,examples:[`0x81c0f22bd173c115d18eeea0f6a38e935ecf52fb`]}),keyType:R().meta({description:"The signature scheme of the access key: `secp256k1`, `p256`, or `webAuthn`. The node names a configurable account key `multisig`.",examples:[`secp256k1`]}),limits:Mn(z({limit:WL.meta({description:"The most of the token the key may spend, in base units, as a hex quantity. Applies per period when `period` is set.",examples:[`0x989680`]}),period:WL.optional().meta({description:"Seconds after which the limit resets, as a hex quantity. Absent or `0x0` for a one-time limit.",examples:[`0x15180`]}),token:GL.meta({description:`The TIP-20 token the limit applies to.`,examples:[`0x20c0000000000000000000006a37DA5C996874BE`]})})).readonly().optional().meta({description:`The spending limit on each token. Absent when spending is unlimited. An empty list allows no spending.`}),signature:_n([WL.meta({description:`A configurable account's RLP-encoded signature, which carries its owner approvals.`,examples:[`0xf8a094ff5deded16eb46018387144ff8bf41f26afb41afc0f87cf87a80a012fe6a88b99377b94d6a628a86b9df544202c7b03827f44b16ee1a266ab98e17a04b6aa3723402498e07fb1f071673bd969d9f49a286af15ac60581d07ade24b77`]}),t,z({keyId:GL.optional().meta({description:"The address of the access key that signed. Recovered from `signature` when absent.",examples:[`0x624f27c462b885a83c698cac444a106a8c519e25`]}),signature:t.meta({description:`The access key's own signature.`}),type:xn(`keychain`).meta({description:`A signature by an access key for an account.`}),userAddress:GL.meta({description:`The Tempo Account the access key signs for.`,examples:[`0x9a073914db0d149375ac2b7fbb72c68c0780fb5f`]}),version:Sn([`v1`,`v2`]).optional().meta({description:"The keychain signature version. `v2` binds the signature to `userAddress`. Defaults to `v1`.",examples:[`v2`]})}).meta({description:`An access key signature that wraps a primitive signature.`})]).meta({description:`The owner's signature envelope, in the node's format.`}),witness:qL.optional().meta({description:`The witness the signature binds, when the request sent one.`,examples:[`0xf1e22f902be2546fe35d49388503ef7ea5c6c0e95a0f4b89d474e58793b64dec`]})}).meta({description:`A signed key authorization (TIP-1011), in the node's RPC format.`,id:`KeyAuthorization`})})(XL||={});var ZL=31536e3,QL=aL(ce.id).address,$L=[ce,ne,VI,HI],eR=ce.id,tR={BRL:`5000`,BTC:`0.01`,CHF:`800`,EUR:`850`,GBP:`750`,USD:`1000`},nR=new Map(CL.tempo.flatMap(e=>$L.flatMap(t=>{let n=e.addresses,r=n[t.id]??(t.id===HI.id?n[ne.id]:void 0)??(e.symbol===`OUSD`?n[ce.id]:void 0);if(!r)return[];let i=tR[e.currency??``]??tR.USD;return[[`${t.id}:${r.toLowerCase()}`,{address:De(r),cap:Te(i,e.decimals),currency:e.currency,decimals:e.decimals,symbol:e.symbol??r}]]}))),rR={approve:nb(`approve(address,uint256)`),transfer:nb(`transfer(address,uint256)`),transferWithMemo:nb(`transferWithMemo(address,uint256,bytes32)`)};function iR(e,t){return t.challenge===void 0?e:{...e,witness:Be(t.challenge)}}function aR(e){let t=Math.floor(Date.now()/1e3);if(!e.chainId)return new jL({error_description:"Invalid `chainId`: 0. Use a Tempo chain ID, such as 4217.",field:`key_authorization.chainId`,meta:{chain_id:0}});let n=Number(e.chainId);if(!e.address&&!e.publicKey)return new LL({error_description:"Missing `address` or `publicKey`. Provide the access key.",field:`key_authorization.address`});if(e.address===`0x0000000000000000000000000000000000000000`)return new LL({error_description:"Invalid `address`: the zero address holds no key. Provide the address of the access key.",field:`key_authorization.address`});if(e.publicKey&&!yR(e.publicKey))return new PL({error_description:"Invalid `publicKey`. Provide an uncompressed public key, or `address`.",field:`key_authorization.publicKey`});if(!Number.isSafeInteger(e.expiry))return new ML({error_description:`Invalid \`expiry\`: ${e.expiry} is not a whole number of seconds. Use a future Unix time in seconds.`,field:`key_authorization.expiry`,meta:{expiry:e.expiry}});if(e.expiry===0)return new ML({error_description:"Invalid `expiry`: 0 never expires. Use a future Unix time.",field:`key_authorization.expiry`,meta:{expiry:0}});if(e.expiry<=t)return new AL({error_description:`Invalid \`expiry\`: ${vR(e.expiry)} has passed. Use a future Unix time.`,field:`key_authorization.expiry`,meta:{expiry:e.expiry,now:t}});if(!e.limits.length)return new DL({error_description:"Empty `limits`. Name at least one token, or omit `limits`.",field:`key_authorization.limits`});if(!e.scopes.length)return new OL({error_description:"Empty `scopes`. Name at least one call, or omit `scopes`.",field:`key_authorization.scopes`});for(let[t,r]of e.scopes.entries())if(!hR(e,r.address))return new HL({error_description:`Unsupported token on chain ${n}: ${r.address}. Use a supported token, such as OUSD.`,field:`key_authorization.scopes.${t}.address`,meta:{chain_id:n,token:r.address}});let r=new Set;for(let[t,i]of e.limits.entries()){if(r.has(i.token.toLowerCase()))return new TL({error_description:`Duplicate limit for ${i.token}. Limit each token once.`,field:`key_authorization.limits.${t}.token`,meta:{token:i.token}});r.add(i.token.toLowerCase());let a=hR(e,i.token);if(!a)return new HL({error_description:`Unsupported token on chain ${n}: ${i.token}. Use a supported token, such as OUSD.`,field:`key_authorization.limits.${t}.token`,meta:{chain_id:n,token:i.token}});if(i.period!==void 0&&(!Number.isSafeInteger(i.period)||i.period<0))return new NL({error_description:`Invalid \`period\` on the ${a.symbol} limit: ${i.period}. Use a whole number of seconds, or 0 for a one-time limit.`,field:`key_authorization.limits.${t}.period`,meta:{period:i.period,symbol:a.symbol,token:a.address}})}let i=new Set;for(let[t,n]of e.scopes.entries()){let r=e.limits.some(e=>Ae(e.token,n.address))?hR(e,n.address):void 0;if(!r)return new BL({error_description:`Scope on ${n.address} has no limit. Add a limit for it, or remove the scope.`,field:`key_authorization.scopes.${t}.address`,meta:{token:n.address}});let a=n.selector?gR(n.selector):void 0,o=a||(n.selector?`an unknown function`:`any function`);if(a===rR.approve&&!n.recipients?.length)return new zL({error_description:`Missing \`recipients\` for \`approve\` on ${r.symbol}. Name the allowed spenders.`,field:`key_authorization.scopes.${t}.recipients`,meta:{symbol:r.symbol,token:r.address}});if(a!==rR.approve&&a!==rR.transfer&&a!==rR.transferWithMemo)return new VL({error_description:`Unsupported call on ${r.symbol}: ${o}. Use \`transfer\`, \`transferWithMemo\`, or \`approve\`.`,field:`key_authorization.scopes.${t}.selector`,meta:{...a?{selector:a}:{},symbol:r.symbol,token:r.address}});let s=`${r.address.toLowerCase()}:${a}`;if(i.has(s))return new EL({error_description:`Duplicate scope for ${a} on ${r.symbol}. Name each call on a token once.`,field:`key_authorization.scopes.${t}.selector`,meta:{selector:a,symbol:r.symbol,token:r.address}});i.add(s);let c=(n.recipients??[]).map(e=>e.toLowerCase()),l=new Set,u=c.findIndex(e=>e===`0x0000000000000000000000000000000000000000`||l.has(e)?!0:(l.add(e),!1)),d=n.recipients?.[u];if(d)return new FL({error_description:`Invalid recipient ${d} for ${a} on ${r.symbol}. Name each recipient once, and never the zero address.`,field:`key_authorization.scopes.${t}.recipients.${u}`,meta:{recipient:d,symbol:r.symbol,token:r.address}})}}(function(e){e.errors=[TL,EL,DL,OL,AL,jL,ML,NL,PL,FL,LL,zL,BL,VL,HL]})(aR||={});function oR(e){let{app:t,clientId:n,key:r}=e;if(r?.witness&&!t?.sign)return new wL({clientId:n})}(function(e){e.errors=[wL]})(oR||={});function sR(e){let t=typeof e==`object`&&e?{...e}:{},n=[`expiry`,`limits`,`scopes`].filter(e=>t[e]===void 0),[r]=n;if(!r)return;let i=n.map(e=>`\`${e}\``);return new RL({error_description:`Missing ${i.length===1?i[0]:i.length===2?`${i[0]} and ${i[1]}`:`${i.slice(0,-1).join(`, `)}, and ${i.at(-1)}`}. Name the expiry, limits, and scopes of the key, since a third-party app receives no defaults.`,field:`key_authorization.${r}`,meta:{missing:n.join(` `)}})}(function(e){e.errors=[RL]})(sR||={});function cR(e){let t=aR(e);if(t)return t;let n=Math.floor(Date.now()/1e3),r=Number(e.chainId);if(e.expiry>n+31536e3)return new kL({error_description:`Invalid \`expiry\`: ${vR(e.expiry)} exceeds the one-year maximum. Use an earlier expiry, or authorize through a redirect or device grant.`,field:`key_authorization.expiry`,meta:{expiry:e.expiry,maximum:n+ZL}});for(let[t,i]of e.limits.entries()){let a=hR(e,i.token),o=i.period?BigInt(Math.ceil((e.expiry-n)/i.period)):1n,s=i.limit*o;if(s>a.cap)return new IL({error_description:`Invalid ${a.symbol} limit: ${Le(s,a.decimals)}${o>1n?` over ${o} periods before the key expires`:``} exceeds the ${Le(a.cap,a.decimals)} maximum. ${o>1n?`Lower the limit or shorten the expiry`:`Lower the limit`}, or authorize through a redirect or device grant.`,field:`key_authorization.limits.${t}.limit`,meta:{chain_id:r,limit:s.toString(),maximum:a.cap.toString(),periods:Number(o),symbol:a.symbol,token:a.address}})}}(function(e){e.errors=[...aR.errors,kL,IL]})(cR||={});function lR(e){let t=new Map;for(let n of e.limits){let r=hR(e,n.token),i=n.period??0,a=`${r.currency}\0${i}`,o=t.get(a);if(!o){t.set(a,{amount:n.limit,currency:r.currency,decimals:r.decimals,period:i,tokens:[{amount:Le(n.limit,r.decimals),symbol:r.symbol}]});continue}o.tokens.push({amount:Le(n.limit,r.decimals),symbol:r.symbol});let s=Math.max(o.decimals,r.decimals);o.amount=o.amount*10n**BigInt(s-o.decimals)+n.limit*10n**BigInt(s-r.decimals),o.decimals=s}return{account:e.account,expiry:e.expiry,limits:[...t.values()].map(e=>({amount:Le(e.amount,e.decimals),currency:e.currency,...e.period?{period:e.period}:{},tokens:e.tokens}))}}function uR(e){let{key:t,...n}=_R(e.key);return Oe({...n,address:t.address,type:t.type,...e.witness?{witness:e.witness}:{}})}function dR(e){let t=`${e.chainId}:`;return[...nR].flatMap(e=>e[0].startsWith(t)?[e[1]]:[])}async function fR(e,t){return _t(await He(e,_R(t.key)))}async function pR(e,t){let{metadata:n,signature:r}=ct(e),i=uR({key:t.key}),a=Fe(t.publicKey);return await fR(ut({keyType:`webAuthn`,publicKey:a,sign(e){return e.hash===i?Promise.resolve(ve({metadata:{authenticatorData:n.authenticatorData,clientDataJSON:n.clientDataJSON},publicKey:a,signature:r,type:`webAuthn`})):Promise.reject(Error(`The assertion signs another key authorization.`))}}),{key:t.key})}function mR(e){let t=e.chainId??BigInt(eR),n=e.scopes?.length?[...new Set(e.scopes.map(e=>e.address.toLowerCase()))]:[QL.toLowerCase()],r=e.limits??n.map(e=>{let n=nR.get(`${t}:${e}`);return n?{limit:n.cap,token:n.address}:{limit:0n,token:De(e)}}),i=e.scopes??r.flatMap(e=>[rR.transfer,rR.transferWithMemo].map(t=>({address:e.token,selector:t})));return{...e,chainId:t,expiry:e.expiry??Math.floor(Date.now()/1e3)+31536e3,limits:r,scopes:i}}function hR(e,t){return nR.get(`${Number(e.chainId)}:${t.toLowerCase()}`)}function gR(e){if(/^0x[0-9a-fA-F]{8}$/.test(e))return e.toLowerCase();try{return nb(e)}catch{return}}function _R(e){return{chainId:e.chainId,expiry:e.expiry,key:{address:e.address??yR(e.publicKey),type:e.keyType??`secp256k1`},limits:e.limits,scopes:e.scopes,...e.witness?{witness:e.witness}:{}}}function vR(e){return new Date(e*1e3).toUTCString()}function yR(e){try{return gt(Ve(e))}catch{return}}var bR=class extends nI(`invalid_field`){name=`Validation.InvalidFieldError`;constructor(e){let{issues:t}=e;super({error_description:`Invalid request. ${t.map(e=>`${xR(e)?`\`${xR(e)}\``:`Body`}: ${e.message}.`).join(` `)}`,field:t[0]&&xR(t[0])?xR(t[0]):void 0})}};function xR(e){return(e.path??[]).map(e=>String(typeof e==`object`?e.key:e)).join(`.`)}var SR=class extends nI(`invalid_origin`){name=`Authorize.InvalidOriginError`},CR=class extends nI(`rejected`){name=`Authorize.RejectedError`;constructor(e={}){super({error_description:e.description??"Authorization request rejected. Check `client_id`, `redirect_uri`, and `scope` against the app's registration."})}},wR;(function(e){let t=e.tokens=z({access_token:R().meta({description:`The access token, a JWT that Tempo ID signs. APIs verify it against Tempo ID's JSON Web Key Set.`,examples:[`eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyIn0.c2lnbmF0dXJl`]}),expires_in:Cn().meta({description:`Seconds until the access token expires.`,examples:[300]}),id_token:R().optional().meta({description:"The OIDC ID token, a JWT about the user. Absent when the request did not ask for the `openid` scope.",examples:[`eyJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJhcHAifQ.c2lnbmF0dXJl`]}),refresh_token:R().optional().meta({description:"The refresh token, which the app redeems at `/oauth2/token` for new tokens. Absent without the `offline_access` scope.",examples:[`yAjhKk7QnRZ3vD9pLm2Xc8Ws5Tf1Ub4N`]}),token_type:R().meta({description:`The type of the access token (RFC 6749 §7.1).`,examples:[`Bearer`]})}).meta({description:`OAuth tokens for a public app.`,id:`Tokens`}),n=e.challenge=R().min(1).max(1024).optional().meta({description:"A message, such as a sign-in challenge from the app's backend, whose EIP-191 hash becomes the key authorization's `witness` (TIP-1053). Requires `key_authorization`, and the app's `tempo-id:sign` scope.",examples:[`Sign in to app.example.com
|
|
483
|
-
Nonce: 7f3a9c2e5b1d4f60`]});e.request=z({challenge:n,client_id:R().min(1).max(255).meta({description:`The app's client ID.`,examples:[`Qk3vT9xZbLmN2pRw8YcHjF6sDaE4uGtK`]}),code_challenge:R().regex(/^[\w-]{43}$/).optional().meta({description:`The S256 PKCE challenge of a verifier that the app's backend holds (RFC 7636). With one, the app receives a code. Without one, a public app receives tokens.`,examples:[`E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM`]}),key_authorization:XL.request,redirect_uri:Dn({protocol:/^(?!(?:blob|data|file|javascript|vbscript)$)[a-z][a-z\d+.-]*$/}).meta({description:`A registered redirect URI of a web app, whose origin the page calls from.`,examples:[`https://app.example.com/callback`]}),scope:R().regex(/^[\w:.-]+( [\w:.-]+)*$/).max(256).optional().meta({description:"Space-separated OAuth scopes. Defaults to `openid`.",examples:[`openid email offline_access`]}),state:R().min(1).max(256).optional().meta({description:`An opaque value that the response returns unchanged, to bind it to the request (RFC 6749 §4.1.1).`,examples:[`af0ifjsldkj`]})}).refine(e=>!e.challenge||e.key_authorization,{message:"A challenge requires `key_authorization`, whose witness binds it",path:[`challenge`]}).transform(e=>e.key_authorization?{...e,key_authorization:iR(e.key_authorization,{challenge:e.challenge})}:e).meta({description:`An app's headless authorization request.`,id:`AuthorizationRequest`}),e.redirect=z({challenge:n,key_authorization:XL.request}).refine(e=>!e.challenge||e.key_authorization,{message:"A challenge requires `key_authorization`, whose witness binds it",path:[`challenge`]}).transform(e=>e.key_authorization?iR(e.key_authorization,{challenge:e.challenge}):void 0),e.response=z({account:XL.account.optional(),code:R().optional().meta({description:"The authorization code, when the request sent a `code_challenge`. The app's backend redeems it at `/oauth2/token`.",examples:[`Vb7mQ2xLkP9sTzR4`]}),key_authorization:XL.rpc.optional(),state:R().optional().meta({description:"The request's `state`, unchanged. Absent when the request sent none.",examples:[`af0ifjsldkj`]}),tokens:t.optional().meta({description:"The tokens, when the request sent no `code_challenge`."})}).meta({description:`An authorization: a code or tokens, with the signed key authorization when the request asks for one.`,id:`Authorization`})})(wR||={});function TR(e,t){let{app:n,origin:r}=t;if(!n||!n.redirectUris.includes(e.redirect_uri))return new CR;if(!n.firstParty)return new CR({description:"Headless authorization refused: the app is not a first-party app. Send the user to `/oauth2/authorize`, and receive the code at the redirect URI."});if(n.type===`native`)return new CR({description:"Headless authorization refused: a native app's request does not prove which app sends it. Open `/oauth2/authorize` in an authentication sheet, and receive the code at the redirect URI."});let i=new URL(e.redirect_uri);if(r!==i.origin)return new SR({error_description:`Invalid \`Origin\`: ${r??`none`}. Requests for this redirect URI must come from ${i.origin}.`,field:`Origin`,meta:{expected:i.origin,...r?{origin:r}:{}}});let a=e.key_authorization;if(a)return n.secret?new CR({description:`Key authorization refused: the app holds a client secret, which a headless request does not prove. Authorize the key through a redirect or the device grant.`}):cR(a)??oR({app:n,clientId:e.client_id,key:a})}(function(e){e.errors=[...cR.errors,...oR.errors,SR,CR]})(TR||={});function ER(e){let{app:t,clientId:n,codeChallenge:r,key:i,query:a}=e;return r?(OF(n)?sR(jR(a.get(`key_authorization`)??``)):void 0)??aR(i)??oR({app:t,clientId:n,key:i}):new CR({description:"Key authorization refused: the request names no `code_challenge`, whose verifier receives the key. Send an S256 `code_challenge`."})}(function(e){e.errors=[...aR.errors,...sR.errors,...oR.errors,CR]})(ER||={});function DR(e){let t=AR.find(t=>e.getAll(t).length>1);if(t)return new bR({issues:[{message:`Repeated parameter. Send it once`,path:[t]}]});let n=e.get(`key_authorization`),r=wR.redirect.safeParse({challenge:e.get(`challenge`)??void 0,key_authorization:n===null?void 0:jR(n)});return r.success?r.data:new bR({issues:r.error.issues})}function OR(e){if(!e.has(`key_authorization`))return e;let t=new URLSearchParams(e),n=new Set((t.get(`prompt`)??``).split(` `).filter(Boolean));n.add(`consent`),t.set(`prompt`,[...n].join(` `));let[r,...i]=t.getAll(`key_authorization`),a=r&&!i.length?jR(r):void 0;return!OF(t.get(`client_id`)??``)&&typeof a==`object`&&a&&!Array.isArray(a)&&!(`expiry`in a)&&t.set(`key_authorization`,ot(JSON.stringify({...a,expiry:Math.floor(Date.now()/1e3)+ZL}),kR)),t}var kR={pad:!1,url:!0},AR=[`challenge`,`key_authorization`];function jR(e){try{return JSON.parse(Me(e))}catch{return null}}var MR=class extends nI(`already_decided`){name=`Device.AlreadyDecidedError`;constructor(){super({error_description:`Code already approved or denied.`,field:`code`})}},NR=class extends nI(`approval_pending`){name=`Device.ApprovalPendingError`;constructor(){super({error_description:"Approval pending. Poll again after `interval` seconds."})}},PR=class extends nI(`device_code_expired`){name=`Device.DeviceCodeExpiredError`;constructor(){super({error_description:`Device code expired. Request a new code.`})}},FR=class extends nI(`polling_too_fast`){name=`Device.PollingTooFastError`;constructor(){super({error_description:"Polling too fast. Add 5 seconds to `interval`."})}},IR=class extends nI(`request_denied`){name=`Device.RequestDeniedError`;constructor(){super({error_description:`The user denied the request.`})}},LR=class extends nI(`unknown_code`){name=`Device.UnknownCodeError`;constructor(){super({error_description:`Invalid or expired code. Check the code in the terminal.`,field:`code`})}},RR=`tempo-cli`,zR=`openid email offline_access`,BR=`BCDFGHJKLMNPQRSTVWXZ`;async function VR(e,t){return(await e.update(eP).set({userId:t.userId}).where(cM(Y(eP.id,t.id),Y(eP.status,`pending`),_M(eP.userId),dM(eP.expiresAt,new Date))).returning({id:eP.id})).length>0}async function HR(e,t){let n=await KR(e,t);if(n&&n.status===`pending`&&!n.userId)return n.clientId}async function UR(e,t){let{challenge:n,device:r,deviceCode:i,expiresAt:a,ip:o,location:s}=t,c=t.key?JSON.parse(JSON.stringify(t.key,(e,t)=>typeof t==`bigint`?Bt(t):t)):null,l=e.select({id:eP.id}).from(eP).where(Y(eP.deviceCode,i));await e.insert(SP).values({challenge:n,device:r,expiresAt:a,id:q`(${l})`,ip:o,key:c,location:s})}async function WR(e,t){return(await e.update(eP).set({status:t.status}).where(cM(Y(eP.id,t.id),Y(eP.status,`pending`),Y(eP.userId,t.userId),dM(eP.expiresAt,new Date))).returning({id:eP.id})).length>0}function GR(e){return`${e.slice(0,4)}-${e.slice(4)}`}async function KR(e,t){let[n]=await e.select({appName:iP.name,challenge:SP.challenge,clientId:eP.clientId,createdAt:SP.createdAt,device:SP.device,expiresAt:eP.expiresAt,id:eP.id,ip:SP.ip,key:SP.key,location:SP.location,status:eP.status,userCode:eP.userCode,userId:eP.userId}).from(eP).leftJoin(SP,Y(SP.id,eP.id)).leftJoin(iP,Y(iP.clientId,eP.clientId)).where(cM(Y(eP.userCode,t.userCode),dM(eP.expiresAt,new Date)));if(!n?.clientId)return;let r=n.key?wR.redirect.parse({challenge:n.challenge??void 0,key_authorization:n.key}):void 0;return{...n.appName?{appName:n.appName}:{},...n.challenge?{challenge:n.challenge}:{},clientId:n.clientId,createdAt:n.createdAt??new Date(n.expiresAt.getTime()-6e5),...n.device?{device:n.device}:{},id:n.id,...n.ip?{ip:n.ip}:{},...r?{key:r}:{},...n.location?{location:n.location}:{},status:ez(n.status),userCode:GR(n.userCode),...n.userId?{userId:n.userId}:{}}}async function qR(e,t){let{id:n,key:r,userId:i}=t;return(await e.update(SP).set({account:r.account,keyAuthorization:r.keyAuthorization}).where(cM(Y(SP.id,n),_M(SP.keyAuthorization),yM(e.select({id:eP.id}).from(eP).where(cM(Y(eP.id,n),Y(eP.status,`pending`),Y(eP.userId,i),dM(eP.expiresAt,new Date)))))).returning({id:SP.id})).length>0}async function JR(e,t){let{id:n,key:r}=t;await e.update(SP).set({account:null,keyAuthorization:null}).where(cM(Y(SP.id,n),q`${SP.keyAuthorization} = ${JSON.stringify(r.keyAuthorization)}::jsonb`,yM(e.select({id:eP.id}).from(eP).where(cM(Y(eP.id,n),Y(eP.status,`pending`))))))}async function YR(e,t){let[n]=await e.select({id:eP.id}).from(eP).where(Y(eP.deviceCode,t.deviceCode));return n?.id}function XR(e){let t=e.toUpperCase().replace(/[^A-Z]/g,``);if(!(t.length!==8||[...t].some(e=>!BR.includes(e))))return t}var ZR=`/device`;function QR(e,t){if(!e||!e.startsWith(`/`)||/^\/[/\\]/.test(e))return;let n=new URL(t.origin),r=URL.parse(e,n);if(!r||r.origin!==n.origin||r.pathname!==`/device`||r.hash)return;let i=[...r.searchParams.keys()];if(i.length===0)return ZR;let[a]=i;if(i.length>1||a!==`code`&&a!==`user_code`)return;let o=XR(r.searchParams.get(a)??``);if(o)return`${ZR}?${new URLSearchParams({code:GR(o)})}`}async function $R(e,t){let[n]=await e.delete(SP).where(Y(SP.id,t.id)).returning({account:SP.account,keyAuthorization:SP.keyAuthorization});if(n?.account&&n.keyAuthorization)return{account:n.account,keyAuthorization:n.keyAuthorization}}function ez(e){return e===`approved`||e===`denied`?e:`pending`}var tz=`BCDFGHJKLMNPQRSTVWXZ`,nz=`0123456789ABCDEFGHJKMNPQRSTVWXYZ`;function rz(){return`user_${az()}`}function iz(){let e=[];for(;e.length<8;)for(let t of crypto.getRandomValues(new Uint8Array(16)))t<240&&e.length<8&&e.push(tz[t%20]);return e.join(``)}function az(){let e=Date.now();return Array.from({length:10},(t,n)=>{let r=5*(9-n);return nz[Math.floor(e/2**r)%32]}).join(``)+Array.from(crypto.getRandomValues(new Uint8Array(16)),e=>nz[e%32]).join(``)}function oz(e){return e}function sz(e){return e}function cz(e){let t=e=>Math.floor(e.getTime()/1e3),n=e.map(()=>0),r=[];for(;;){let i=e.reduce((r,i,a)=>{let o=i[n[a]];if(!o)return r;if(r===void 0)return a;let s=e[r][n[r]];return t(o.createdAt)<t(s.createdAt)?a:r},void 0);if(i===void 0)return r;r.push(e[i][n[i]]),n[i]=n[i]+1}}async function lz(e,t){await e.execute(q`select pg_advisory_xact_lock(hashtextextended(${`tempo-account:${t.userId}`}, 0))`)}async function uz(e,t){let{expiresAt:n,identifier:r,others:i=[],value:a}=t,o=new Date,s=e.select({id:yP.id}).from(yP).where(cM(hM(yP.identifier,[r,...i]),dM(yP.expiresAt,o))),[c]=await e.insert(yP).select(q`select ${o.toISOString()}::timestamp, ${n.toISOString()}::timestamp, ${r}, ${r}, ${o.toISOString()}::timestamp, ${a} where not exists (${s})`).onConflictDoUpdate({set:{createdAt:o,expiresAt:n,updatedAt:o,value:a},setWhere:mM(yP.expiresAt,o),target:yP.id}).returning({id:yP.id});return c!==void 0}var dz=class extends nI(`passkey_limit`){name=`Passkey.LimitError`;constructor(){super({error_description:`Passkey limit reached: the user holds 10 registered passkeys, the most that Tempo ID registers. Sign in with one of them.`,meta:{limit:10}})}},fz=class extends nI(`passkey_link_expired`){name=`Passkey.LinkExpiredError`;constructor(){super({error_description:`Expired passkey sign-in: the link from the passkey step is no longer valid. Enter the code again to sign in with email only, or sign in with the passkey again.`,field:`link`})}},pz=class extends nI(`passkey_not_permitted`){name=`Passkey.NotPermittedError`;constructor(e={}){let{clientId:t,origin:n}=e;super(t&&n?{error_description:`Passkey not permitted: no realm of the app ${t} holds passkeys for ${n}. Sign in with an emailed code.`,meta:{client_id:t,origin:n}}:t?{error_description:`Passkey not permitted: the app ${t} holds no passkeys. Sign in with an emailed code.`,meta:{client_id:t}}:{error_description:`Passkey not permitted: no realm holds passkeys for this sign-in. Sign in with an emailed code.`})}},mz=class extends nI(`reauthentication_required`){name=`Passkey.ReauthenticationRequiredError`;constructor(){super({error_description:`Sign in again: adding a passkey needs a sign-in within the last 10 minutes.`})}},hz=class extends nI(`webauthn_rejected`){name=`Passkey.WebAuthnRejectedError`;constructor(){super({error_description:`Passkey rejected. Request new options, then try again with the same passkey or another one.`})}},gz=`passkey-challenge:`,_z=`passkey-registration-proof:`,vz=`passkey-registration:`,yz=`passkey-signature:`,bz=ZL,xz=`passkey-signature-spent:`,Sz=`passkey-sign-in-spent:`,Cz;(function(e){let t=R().regex(/^[A-Za-z0-9_-]+$/),n=vn([`0x`,R().regex(/^[0-9a-fA-F]*$/)]),r=e.credentialId=t.min(1).max(1364);e.assertion=z({id:r.meta({description:`The credential ID of the passkey that signed, base64url.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),metadata:z({authenticatorData:n.meta({description:`The authenticator data the passkey signed, as hex: the relying party ID hash, flags, and signature counter.`,examples:[`0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000`]}),challengeIndex:Cn().int().nonnegative().optional().meta({description:'The character offset of `"challenge"` in `clientDataJSON`. Absent, verification searches for it.',examples:[23]}),clientDataJSON:R().max(4096).meta({description:`The client data the browser collected, as a JSON string, which holds the type, challenge, and origin.`,examples:[`{"type":"webauthn.get","challenge":"9jEFijuhEWrM4SOW-tChJbUEHEP44VcjcJ-Bqo1fTM8","origin":"https://id.tempo.xyz","crossOrigin":false}`]}),typeIndex:Cn().int().nonnegative().optional().meta({description:'The character offset of `"type"` in `clientDataJSON`. Absent, verification searches for it.',examples:[1]}),userVerificationRequired:On().optional().meta({description:`Whether the client required user verification. Verification ignores it and always requires user verification.`,examples:[!0]})}).meta({description:"The signed data that verification reads with `signature`, decoded from the browser response."}),raw:z({authenticatorAttachment:R().nullable().default(null).meta({description:"How the authenticator attaches to the client, such as `platform` or `cross-platform`. Defaults to `null` when the browser reports none.",examples:[`platform`]}),id:t.meta({description:`The credential ID, base64url, as the browser returns it.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),rawId:t.meta({description:`The bytes of the credential ID, base64url.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),response:z({clientDataJSON:t.meta({description:`The client data JSON, base64url.`,examples:[`eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiOWpFRmlqdWhFV3JNNFNPVy10Q2hKYlVFSEVQNDRWY2pjSi1CcW8xZlRNOCIsIm9yaWdpbiI6Imh0dHBzOi8vaWQudGVtcG8ueHl6IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ`]})}).meta({description:"The authenticator's response. Verification keeps only `clientDataJSON` and drops other fields."}),type:R().meta({description:`The credential type.`,examples:[`public-key`]})}).meta({description:"The `PublicKeyCredential` that `navigator.credentials.get()` returns, serialized as JSON."}),signature:n.meta({description:"The P-256 signature over the authenticator data and the client data hash, as 64-byte hex: `r` then `s`.",examples:[`0x6c3f1e0a9b7d24f58e1c3a6b9d0f2e4a7c5b8d1e3f6a9c2b4d7e0f1a3c5b8d9e1f2a7c4b6d8e0f3a5c7b9d1e4f6a8c0b2d5e7f9a1c3b6d8e0f2a4c7b9d1e3f5a`]})}).meta({description:"The assertion, serialized as `webauthx/client` returns it.",id:`PasskeyAssertion`}),e.clientData=z({challenge:t,crossOrigin:On().optional()}),e.credential=z({attestationObject:t.max(16384).meta({description:`The authenticator's attestation object, base64url, which holds the new public key.`,examples:[`o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjF`]}),clientDataJSON:t.max(4096).meta({description:`The client data the browser collected, base64url, which holds the type, challenge, and origin.`,examples:[`eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiOWpFRmlqdWhFV3JNNFNPVy10Q2hKYlVFSEVQNDRWY2pjSi1CcW8xZlRNOCIsIm9yaWdpbiI6Imh0dHBzOi8vaWQudGVtcG8ueHl6IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ`]}),id:r.meta({description:`The credential ID of the new passkey, base64url.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),publicKey:vn([`0x`,R().regex(/^04[0-9a-fA-F]{128}$/)]).meta({description:"The new passkey's uncompressed P256 public key, as hex. Verification reads the key from `attestationObject` and ignores this copy.",examples:[`0x04f6310589abb21116acc6e123967ed0a125b5041c43f8e157237093e07eaa354c6c3f1e0a9b7d24f58e1c3a6b9d0f2e4a7c5b8d1e3f6a9c2b4d7e0f1a3c5b8d`]}),raw:z({authenticatorAttachment:R().nullable().default(null).meta({description:"How the authenticator attaches to the client, such as `platform` or `cross-platform`. Defaults to `null` when the browser reports none.",examples:[`platform`]}),id:t.max(1364).meta({description:`The credential ID, base64url, as the browser returns it.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),rawId:t.max(1364).meta({description:`The bytes of the credential ID, base64url.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),response:z({clientDataJSON:t.max(4096).meta({description:`The client data JSON, base64url.`,examples:[`eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiOWpFRmlqdWhFV3JNNFNPVy10Q2hKYlVFSEVQNDRWY2pjSi1CcW8xZlRNOCIsIm9yaWdpbiI6Imh0dHBzOi8vaWQudGVtcG8ueHl6IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ`]})}).meta({description:"The authenticator's response. Verification keeps only `clientDataJSON`, and reads the top-level `attestationObject`."}),type:R().max(32).meta({description:`The credential type.`,examples:[`public-key`]})}).meta({description:"The `PublicKeyCredential` that `navigator.credentials.create()` returns, serialized as JSON."})}).meta({description:"The new passkey, serialized as `webauthx/client` returns it.",id:`PasskeyCredential`}),e.link=z({address:R(),createdAt:Cn().nullable(),expiresAt:Cn(),host:R(),id:R(),nonce:R(),publicKey:vn([`0x`,R()]),rpId:R()}),e.proof=z({id:R(),publicKey:n,rpId:R()}),e.registration=z({rpId:R()}),e.signature=z({account:R(),clientId:R(),credential:z({id:R(),publicKey:n,rpId:R()})}),e.step=z({step:z({options:z({publicKey:z({allowCredentials:Mn(z({id:r.meta({description:`The credential ID of the account's passkey, base64url.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),type:xn(`public-key`).meta({description:`The credential type.`})}).meta({description:`The passkey that must sign.`})).meta({description:`The account's passkey, the only one the browser offers.`}),challenge:vn([`0x`,R()]).meta({description:`The key authorization's digest, as hex. It is single-use, and expires after 5 minutes.`,examples:[`0xf6310589abb21116acc6e123967ed0a125b5041c43f8e157237093e07eaa354c`]}),rpId:R().meta({description:`The relying party ID of the account's passkey.`,examples:[`tempo.xyz`]}),userVerification:xn(`required`).meta({description:`Every passkey signature requires user verification.`})}).meta({description:"The `PublicKeyCredentialRequestOptions`, serialized with the challenge as hex."})}).meta({description:"The options for `navigator.credentials.get()`."}),type:xn(`passkey`).meta({description:"Sign the options with the passkey, then repeat the approval with `passkey: { assertion }`."})}).meta({description:`The next step: the passkey's signature over the key authorization's digest.`})}).meta({description:`An approval that continues when the passkey signs the key authorization.`,id:`PasskeyStep`}),e.user=z({createdAt:En(),email:R(),emailVerified:On(),id:R(),image:R().nullable(),name:R(),updatedAt:En()}),e.value=z({authorize:yn().optional(),clientId:R().nullable(),link:R().optional(),origin:R().optional(),realmId:R().optional(),rpId:R(),witness:vn([`0x`,R()]).optional()})})(Cz||={});async function wz(e,t){let n=(t.oneTap?.digest??Zt(crypto.getRandomValues(new Uint8Array(32)))).toLowerCase(),r=gz+n,i={expiresAt:new Date(Date.now()+3e5),id:crypto.randomUUID(),identifier:r,value:JSON.stringify(Cz.value.parse({authorize:t.authorize,clientId:t.clientId,link:t.link,origin:t.origin,realmId:t.realmId,rpId:t.rpId,witness:t.oneTap?.witness}))};return t.oneTap?await uz(e,i)?n:void 0:(await e.insert(yP).values(i),n)}function Tz(e){let{app:t,clientId:n,origin:r}=e;if(!n)return new SR({error_description:`Invalid \`Origin\`: ${r??`none`}. A passkey sign-in from an app's page sends the app's \`client_id\`.`,field:`Origin`,...r?{meta:{origin:r}}:{}});if(!t||!t.firstParty)return new CR({description:`Passkey sign-in refused: ${n} is not a first-party app. Send the user to \`/oauth2/authorize\`, which offers passkey sign-in.`});if(t.type===`native`)return new CR({description:"Passkey sign-in refused: a native app's request does not prove which app sends it. Open `/oauth2/authorize` in an authentication sheet."});let i=t.redirectUris.flatMap(e=>{let t=URL.parse(e);return t?.protocol===`https:`||t?.protocol===`http:`?[t.origin]:[]});if(!r||!i.includes(r))return new SR({error_description:`Invalid \`Origin\`: ${r??`none`}. Passkey sign-in for ${n} must come from the origin of one of its redirect URIs.`,field:`Origin`,...r?{meta:{origin:r}}:{}})}(function(e){e.errors=[SR,CR]})(Tz||={});function Ez(e){try{let t=Cz.clientData.parse(JSON.parse(e.clientDataJSON));return at(t.challenge)}catch{return}}async function Dz(e,t){let[n]=await e.select().from(wP).where(cM(Y(wP.id,t.id),Y(wP.rpId,t.rpId)));return n}async function Oz(e,t){let{credential:n,id:r,rpId:i,userId:a}=t;return await e.transaction(async e=>{await lz(e,{userId:a}),await e.insert(EP).values({realmId:`default`,rpId:i}).onConflictDoNothing();let[t]=await e.insert(wP).values({address:n.address.toLowerCase(),...n.createdAt===null?{}:{createdAt:new Date(n.createdAt)},id:r,publicKey:n.publicKey,rpId:i,source:`tempo-wallet`,type:`passkey`,userId:a}).onConflictDoNothing().returning({userId:wP.userId});return t?t.userId:(await Dz(e,{id:r,rpId:i}))?.userId})}async function kz(e){let t=new TextEncoder,n=await crypto.subtle.importKey(`raw`,t.encode(e),`HKDF`,!1,[`deriveBits`]),r=await crypto.subtle.deriveBits({hash:`SHA-256`,info:t.encode(`tempo-id:passkey-link:v1`),name:`HKDF`,salt:new Uint8Array},n,256);return Zt(new Uint8Array(r))}async function Az(e,t){return await e.select({id:wP.id,registered:q`(${Pz(t)})`,rpId:wP.rpId}).from(wP).where(Y(wP.userId,t.userId)).orderBy(DM(wP.createdAt),DM(wP.id))}function jz(){return{endpoints:{signInPasskey:Gn.serverOnly({body:z({oauth_query:R().optional(),user:Cz.user.optional(),userId:R()}),method:`POST`},async e=>{let{user:t,userId:n}=e.body,r=t?.id===n?t:await e.context.internalAdapter.findUserById(n);if(!r)throw Error(`The passkey user is missing.`);let i=await e.context.internalAdapter.createSession(r.id);return await Dr(e,{session:i,user:r}),e.json({user:{email:r.email,id:r.id}})})},id:`tempo-id-passkey`}}async function Mz(e,t){let[n]=await e.select({count:q`count(*)::int`}).from(wP).where(Pz(t));return n?.count??0}async function Nz(e,t){let{id:n,publicKey:r,rpId:i,userId:a}=t;return await e.transaction(async e=>{await lz(e,{userId:a});let t=e.$with(`counted`).as(e.select({count:q`count(*)::int`.as(`count`)}).from(wP).where(Pz({userId:a}))),o=e.$with(`stored`).as(e.insert(EP).select(q`select now(), 'default', ${i} from ${t} where ${t.count} < ${10}`).onConflictDoNothing().returning({rpId:EP.rpId})),s=e.select({rpId:EP.rpId}).from(EP).where(Y(EP.realmId,`default`)).for(`update`),[c]=await e.with(t,o).select({count:t.count,rpId:q`coalesce((select ${o.rpId} from ${o}), (${s}))`}).from(t);if((c?.count??0)>=10)return`limit`;if((c?.rpId?{rpId:c.rpId}:(await s)[0])?.rpId!==i)return`stale`;let[l]=await e.insert(wP).values({address:gt(Fe(r)).toLowerCase(),id:n,publicKey:r,rpId:i,source:`tempo-id`,type:`passkey`,userId:a}).onConflictDoNothing().returning({id:wP.id});return l?`stored`:`held`})}function Pz(e){return cM(hM(wP.source,[`registered`,`tempo-id`]),vM(wP.address),Y(wP.userId,e.userId))}function Fz(e,t){let n=[t.origin,t.page].flatMap(e=>e?[new URL(e).hostname]:[]);for(let t of e){let e=t.passkeys?.rpId;if(e!==void 0&&n.every(t=>t===e||t.endsWith(`.${e}`)))return{realmId:t.id,rpId:e}}}async function Iz(e,t){let{credential:n,rpId:r,userId:i}=t,a=Zt(crypto.getRandomValues(new Uint8Array(32)));return await e.insert(yP).values({expiresAt:new Date(Date.now()+3e5),id:crypto.randomUUID(),identifier:Rz({challenge:a,prefix:_z,userId:i}),value:JSON.stringify(Cz.proof.parse({...n,rpId:r}))}),a}async function Lz(e,t){let n=Zt(crypto.getRandomValues(new Uint8Array(32)));return await e.insert(yP).values({expiresAt:new Date(Date.now()+3e5),id:crypto.randomUUID(),identifier:Rz({challenge:n,prefix:vz,userId:t.userId}),value:JSON.stringify(Cz.registration.parse({rpId:t.rpId}))}),n}function Rz(e){return e.prefix+JSON.stringify([e.userId,e.challenge.toLowerCase()])}async function zz(e,t){let{account:n,clientId:r,credential:i,digest:a,userId:o}=t;await e.insert(yP).values({expiresAt:new Date(Date.now()+3e5),id:crypto.randomUUID(),identifier:Jz({account:n,clientId:r,credentialId:i.id,digest:a,userId:o}),value:JSON.stringify(Cz.signature.parse({account:n.toLowerCase(),clientId:r,credential:i}))})}async function Bz(e,t){return await Zr({data:JSON.stringify(Cz.link.parse(e)),key:await kz(t.secret)})}async function Vz(e,t){let n=Ez(t);if(!n)return;let[r]=await e.delete(yP).where(cM(Y(yP.identifier,gz+n.toLowerCase()),dM(yP.expiresAt,new Date))).returning({value:yP.value});if(r)return Hz(r.value,{challenge:n})}function Hz(e,t){let n=Cz.value.parse(JSON.parse(e));return{authorize:n.authorize,challenge:t.challenge,clientId:n.clientId,link:n.link,origin:n.origin,realmId:n.realmId,rpId:n.rpId,witness:n.witness}}async function Uz(e,t){let n=Ez(t);if(!n)return;let r=e.$with(`spent`).as(e.delete(yP).where(cM(Y(yP.identifier,gz+n.toLowerCase()),dM(yP.expiresAt,new Date))).returning({value:yP.value})),[i]=await e.with(r).select({key:{id:wP.id,publicKey:wP.publicKey,userId:wP.userId},user:_P,value:r.value}).from(r).leftJoin(wP,cM(Y(wP.id,t.id),Y(wP.rpId,q`(${r.value})::jsonb ->> 'rpId'`))).leftJoin(_P,Y(_P.id,wP.userId));if(i)return{challenge:Hz(i.value,{challenge:n}),key:i.key&&i.user?{...i.key,user:i.user}:void 0}}async function Wz(e,t){let n=(()=>{try{let e=Cz.clientData.parse(JSON.parse(t.clientDataJSON));return at(e.challenge)}catch{return}})();if(!n)return;let[r]=await e.delete(yP).where(cM(Y(yP.identifier,Rz({challenge:n,prefix:_z,userId:t.userId})),dM(yP.expiresAt,new Date))).returning({value:yP.value});if(r)return{...Cz.proof.parse(JSON.parse(r.value)),challenge:n}}async function Gz(e,t){let n=(()=>{try{let e=Cz.clientData.parse(JSON.parse(Me(t.clientDataJSON)));return at(e.challenge)}catch{return}})();if(!n)return;let[r]=await e.delete(yP).where(cM(Y(yP.identifier,Rz({challenge:n,prefix:vz,userId:t.userId})),dM(yP.expiresAt,new Date))).returning({value:yP.value});if(r)return{challenge:n,rpId:Cz.registration.parse(JSON.parse(r.value)).rpId}}async function Kz(e,t){let n=Yz(t),r=Sz+n.slice(24);return await e.transaction(async e=>(await e.execute(q`select pg_advisory_xact_lock(hashtextextended(${n}, 0))`),await uz(e,{expiresAt:new Date(Math.min(Math.max(t.expiry*1e3,Date.now()+3e5),Date.now()+bz*1e3)),identifier:r,others:[n],value:`{}`})))}async function qz(e,t){let n=(()=>{try{let e=Cz.clientData.parse(JSON.parse(t.clientDataJSON));return at(e.challenge)}catch{return}})();if(!n)return;let r=Yz(t);return await e.transaction(async e=>{await e.execute(q`select pg_advisory_xact_lock(hashtextextended(${r}, 0))`);let[i]=await e.select({id:yP.id}).from(yP).where(cM(Y(yP.identifier,r),dM(yP.expiresAt,new Date))),[a]=await e.delete(yP).where(cM(Y(yP.identifier,Jz({...t,digest:n})),dM(yP.expiresAt,new Date))).returning({value:yP.value});if(!a||i)return;let o={...Cz.signature.parse(JSON.parse(a.value)),digest:n};if(t.verify(o))return await e.insert(yP).values({expiresAt:new Date(Math.min(Math.max(t.expiry*1e3,Date.now()+3e5),Date.now()+bz*1e3)),id:crypto.randomUUID(),identifier:r,value:`{}`}),o})}function Jz(e){return yz+JSON.stringify([e.userId,e.clientId,e.account.toLowerCase(),e.credentialId,e.digest.toLowerCase()])}function Yz(e){return xz+yt($t(e.authenticatorData,e.signature))}async function Xz(e,t){let n=await Ln({data:e,key:await kz(t.secret)}).then(e=>Cz.link.safeParse(JSON.parse(e))).catch(()=>void 0);if(n?.success&&n.data.host===t.host&&!(n.data.expiresAt<=Date.now()/1e3))return n.data}function Zz(e,t){try{return!Cz.clientData.parse(JSON.parse(e.metadata.clientDataJSON)).crossOrigin&&TS({...e,metadata:{...e.metadata,userVerificationRequired:!0}},{challenge:t.challenge,origin:t.origin,publicKey:t.publicKey,rpId:t.rpId})}catch{return!1}}function Qz(e,t){try{if(Cz.clientData.parse(JSON.parse(Me(e.clientDataJSON))).crossOrigin)return;let n=kS(e,{attestation:`none`,challenge:t.challenge,origin:t.origin,rpId:t.rpId,userVerification:`required`});return{id:n.credential.id,publicKey:n.credential.publicKey}}catch{return}}var $z=class extends nI(`authorization_expired`){name=`Auth.AuthorizationExpiredError`;constructor(){super({error_description:`Expired authorization request: the request from the app is no longer valid. Return to the app, and start again.`,field:`oauth_query`})}},eB=class extends nI(`invalid_code`){name=`Auth.InvalidCodeError`;constructor(){super({error_description:`Invalid or expired code. Request a new one.`,field:`code`})}},tB=class extends nI(`session_changed`){name=`Auth.SessionChangedError`;constructor(){super({error_description:`Changed session: the signed-in account differs from the one that this page showed. Reload the page, and check the account before the decision.`,field:`session_id`})}},nB=class extends nI(`session_required`){name=`Auth.SessionRequiredError`;constructor(){super({error_description:`Sign in first.`})}},rB=`tempo-id-session`;function iB(e){let{accountStep:t,baseURL:n,cache:r,db:i,google:a,metadataFetch:o,pendingKey:s,secret:c,sendCode:l,sessionCreated:u,waitUntil:d}=e;return{account:{updateAccountOnSignIn:!1},advanced:{backgroundTasks:{handler:d},cookies:{session_token:{name:rB}},database:{generateId:e=>e.model===`user`?rz():crypto.randomUUID(),joins:!0},ipAddress:{ipAddressHeaders:[`cf-connecting-ip`]}},basePath:`/`,baseURL:n,database:aN(i,{provider:`pg`,schema:bP}),databaseHooks:{account:{create:{before:()=>Promise.resolve({data:{accessToken:null,accessTokenExpiresAt:null,idToken:null,refreshToken:null,refreshTokenExpiresAt:null}})}},session:{create:{after:e=>(u?.({id:e.id,userId:e.userId}),Promise.resolve())}},user:{create:{before:e=>Promise.resolve(e.emailVerified===!0)}}},onAPIError:{errorURL:`${n}/error`},plugins:[nO({allowedAttempts:3,expiresIn:600,otpLength:6,sendVerificationOTP:e=>l({code:e.otp,email:e.email}),storeOTP:`hashed`}),jz(),...DF({accountStep:t,baseURL:n,cache:r,metadataFetch:o,pendingKey:s}),SO({expiresIn:`600s`,generateUserCode:iz,interval:`5s`,verificationUri:ZR}),{id:`tempo-id-indexes`,schema:{account:{fields:{},indexes:[{fields:[`providerId`,`accountId`]}]},deviceCode:{fields:{},indexes:[{fields:[`expiresAt`]}]},oauthAccessToken:{fields:{},indexes:[{fields:[`expiresAt`]}]},oauthClientAssertion:{fields:{},indexes:[{fields:[`expiresAt`]}]},oauthRefreshToken:{fields:{},indexes:[{fields:[`expiresAt`]}]},session:{fields:{},indexes:[{fields:[`expiresAt`]}]},verification:{fields:{},indexes:[{fields:[`expiresAt`]}]}}}],rateLimit:{enabled:!1},secret:c,socialProviders:a?{google:{clientId:a.clientId,clientSecret:a.clientSecret,prompt:`select_account`}}:{},verification:{disableCleanup:!0}}}var aB=e=>e;async function Z(e,t,n,r){let i=e.var.timing,a=performance.now(),o={closed:1/0,...r?{description:r}:{},duration:0,name:n,opened:i.events++,start:a-i.start};i.spans.push(o);try{return await t}finally{o.closed=i.events++,o.duration=performance.now()-a}}var oB=aB(async(e,t)=>{let n={events:0,spans:[],start:performance.now()};e.set(`timing`,n),await t();let r=performance.now()-n.start,i=sB(n.spans);e.res.headers.append(`server-timing`,[`total;dur=${cB(r)}`,...i.map(lB)].join(`, `)),!UF()&&GF({fields:{duration:cB(r),errorCode:e.var.refusal?.error,method:e.req.method,reason:e.var.refusal?.reason,requestId:e.var.requestId,route:KF(e),spans:i.map(e=>`${e.name};dur=${cB(e.duration)};start=${cB(e.start)}`).join(`, `),status:e.res.status},message:`The Worker timed a request.`})});function sB(e){return e.map((e,t)=>({settles:e.opened-t,span:e})).toSorted((e,t)=>e.settles===t.settles?e.span.closed===t.span.closed?e.span.opened-t.span.opened:e.span.closed>t.span.closed?-1:1:e.settles-t.settles).map(e=>e.span)}function cB(e){return Math.round(e*10)/10}function lB(e){let t=`${e.name};dur=${cB(e.duration)}`;return e.description?`${t};desc="${e.description.replace(/["\\]/g,`\\$&`)}"`:t}var uB=class extends Error{name=`Balance.UnknownChainError`;constructor(e){super(`Unknown chain: ${e.chainId}.`)}},dB=3e3,fB;(function(e){e.balance=z({amount:R().meta({description:`The sum in USD, as a decimal string.`,examples:[`12.5`]}),currency:xn(`USD`).meta({description:"The currency of `amount`."})}).meta({description:`An account's holdings of USD tokens.`,id:`Balance`})})(fB||={});async function pB(e){let{address:t,chainId:n}=e,r=$L.find(e=>e.id===n);if(!r)throw new uB({chainId:n});let i=bI({chain:r,transport:BI(e.rpcUrl,{batch:!0,retryCount:0,timeout:dB})}),a=dR({chainId:n}).filter(e=>e.currency===`USD`),o=await Promise.all(a.map(async e=>je(i,Ua.call({account:t,token:e.address})).catch(e=>{if(mB(e))return 0n;throw e}))),s=Math.max(0,...a.map(e=>e.decimals)),c=a.reduce((e,t,n)=>e+o[n]*10n**BigInt(s-t.decimals),0n);return{amount:Le(c,s),currency:`USD`}}function mB(e){if(!(e instanceof kt))return!1;let t=e.walk(e=>e instanceof Lt);return t instanceof Lt&&t.data?.errorName===`Uninitialized`}function hB(e,t){let{accounts:n,chainId:r,rpcUrl:i}=t;return Promise.all(n.map(t=>Z(e,pB({address:t.address,chainId:r,rpcUrl:i}),`Balance.get`).catch(t=>(qF(e,{error:t,fields:{chainId:r},message:`A balance failed to load.`}),null))))}var gB=`Payload Too Large`,_B=e=>{let t=e.onError||(()=>{throw new Wv(413,{res:new Response(gB,{status:413})})}),n=e.maxSize;return async function(e,r){if(!e.req.raw.body)return r();let i=e.req.raw.headers.has(`transfer-encoding`);if(e.req.raw.headers.has(`content-length`)&&!i)return parseInt(e.req.raw.headers.get(`content-length`)||`0`,10)>n?t(e):r();let a=0,o=[],s=e.req.raw.body.getReader();for(;;){let{done:r,value:i}=await s.read();if(r)break;if(a+=i.length,a>n)return t(e);o.push(i)}let c={body:new ReadableStream({start(e){for(let t of o)e.enqueue(t);e.close()}}),duplex:`half`};return e.req.raw=new Request(e.req.raw,c),r()}},vB=class extends nI(`body_too_large`){name=`BodyLimit.BodyTooLargeError`;constructor(){super({error_description:`Invalid request body: exceeds the ${bB}-byte maximum. Send a body of ${bB} bytes or fewer.`,meta:{maximum:bB}})}},yB=[vB],bB=65536,xB=_B({maxSize:bB,onError:e=>X(e,new vB)});function SB(e){let{max:t=1e3,ttl:n}=e,r=new Map,i=0;return{async get(e,a,o={}){let{keep:s=()=>!0}=o,c=Math.min(o.ttl??n,n),l=JSON.stringify(a);if(c<=0||l.length>256)return await e();let u=r.get(l);if(u&&u.expires>Date.now())return u.value;let d=++i,f=await e();if(!s(f))return f;let p=r.get(l);if(p&&p.load>d)return f;let m=Date.now();if(r.delete(l),r.size>=t)for(let[e,t]of r)t.expires<=m&&r.delete(e);if(r.size>=t){let e=r.keys().next().value;e!==void 0&&r.delete(e)}return r.set(l,{expires:m+c,load:d,value:f}),f}}}async function CB(e,t,n,r={}){let i=e.var.cache;return i?await i.get(t,n,r):await t()}var wB=e=>e.__COMPOSED_HANDLER?wB(e[py]):e,TB=(e,t,n)=>{let r=e.req.raw.headers.get(`Cookie`);if(typeof t==`string`){if(!r)return;let e=t;return n===`secure`?e=`__Secure-`+t:n===`host`&&(e=`__Host-`+t),le(r,e)[e]}return r?le(r):{}},EB=async(e,t,n,r)=>{let i=e.req.raw.headers.get(`Cookie`);if(typeof n==`string`){if(!i)return;let e=n;return r===`secure`?e=`__Secure-`+n:r===`host`&&(e=`__Host-`+n),(await I(i,t,e))[e]}return i?await I(i,t):{}},DB=(e,t,n)=>{let r;return r=n?.prefix===`secure`?oe(`__Secure-`+e,t,{path:`/`,...n,secure:!0}):n?.prefix===`host`?oe(`__Host-`+e,t,{...n,path:`/`,secure:!0,domain:void 0}):oe(e,t,{path:`/`,...n}),r},OB=(e,t,n,r)=>{let i=DB(t,n,r);e.header(`Set-Cookie`,i,{append:!0})},kB=(e,t,n)=>{let r=TB(e,t,n?.prefix);return OB(e,t,``,{...n,maxAge:0}),r},AB=/^application\/([a-z-\.]+\+)?json(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/i,jB=/^multipart\/form-data(;\s?boundary=[a-zA-Z0-9'"()+_,\-./:=?]+)?$/i,MB=/^application\/x-www-form-urlencoded(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/i,NB=(e,t)=>async(n,r)=>{let i={},a=n.req.header(`Content-Type`);switch(e){case`json`:if(!a||!AB.test(a))break;try{i=await n.req.json()}catch{throw new Wv(400,{message:`Malformed JSON in request body`})}break;case`form`:{if(!a||!(jB.test(a)||MB.test(a)))break;let e;if(n.req.bodyCache.formData)e=await n.req.bodyCache.formData;else try{e=await Kv(await n.req.arrayBuffer(),a),n.req.bodyCache.formData=e}catch(e){let t=`Malformed FormData request.`;throw t+=e instanceof Error?` ${e.message}`:` ${String(e)}`,new Wv(400,{message:t})}let t=Object.create(null);e.forEach((e,n)=>{n.endsWith(`[]`)?(t[n]??=[]).push(e):Array.isArray(t[n])?t[n].push(e):Object.hasOwn(t,n)?t[n]=[t[n],e]:t[n]=e}),i=t;break}case`query`:i=Object.fromEntries(Object.entries(n.req.queries()).map(([e,t])=>t.length===1?[e,t[0]]:[e,t]));break;case`param`:i=n.req.param();break;case`header`:i=n.req.header();break;case`cookie`:i=TB(n)}let o=await t(i,n);return o instanceof Response?o:(n.req.addValidatedData(e,o),await r())},PB={header:[`cookie`]};function FB(e,t,n){if(!(n in PB))return e;let r=PB[n]||[];return t===`arktype`?IB(e,r):t===`valibot`?LB(e,r):e}function IB(e,t){return e.map(e=>{if(e&&typeof e==`object`&&`data`in e&&typeof e.data==`object`&&e.data!==null&&!Array.isArray(e.data)){let n={...e.data};for(let e of t)delete n[e];let r=Object.create(Object.getPrototypeOf(e));return Object.assign(r,e,{data:n}),r}return e})}function LB(e,t){return e.map(e=>{if(e&&typeof e==`object`&&`path`in e&&Array.isArray(e.path)){for(let n of e.path)if(typeof n==`object`&&`input`in n&&typeof n.input==`object`&&n.input!==null&&!Array.isArray(n.input))for(let e of t)delete n.input[e]}return e})}var RB=(e,t,n)=>NB(e,async(r,i)=>{let a=await t[`~standard`].validate(r);if(n){let t=await n(a.issues?{data:r,error:a.issues,success:!1,target:e}:{data:r,success:!0,target:e},i);if(t){if(t instanceof Response)return t;if(typeof t==`object`&&`response`in t)return t.response}}if(a.issues){let n=FB(a.issues,t[`~standard`].vendor,e);return i.json({data:r,error:n,success:!1},400)}return a.value}),zB=Symbol(`openapi`),BB=`__HonoOpenAPIValidator__`,VB=[`GET`,`PUT`,`POST`,`DELETE`,`OPTIONS`,`HEAD`,`PATCH`,`TRACE`],HB=e=>{let t=e;if(t.startsWith(`:`)){let e=t.match(/^:([^{?]+)(?:{(.+)})?(\?)?$/);e?t=`{${e[1]}}`:(t=t.slice(1,t.length),t.endsWith(`?`)&&(t=t.slice(0,-1)),t=`{${t}}`)}return t},UB=e=>e.split(`/`).map(HB).join(`/`),WB=e=>e.split(/[\W_]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``),GB=e=>{let t=e.method.toLowerCase();if(e.path===`/`)return`${t}Index`;for(let n of e.path.split(`/`)){let e=HB(n);e.charCodeAt(0)===123?t+=`By${WB(e.slice(1,-1))}`:t+=WB(e)}return t},KB=e=>`$ref`in e?e.$ref:`${e.in} ${e.name}`;function qB(...e){let t=e.flatMap(e=>e??[]).reduce((e,t)=>(e.set(KB(t),t),e),new Map);return Array.from(t.values())}var JB=new Map;function YB(e,t){let n=[];for(let[r,i]of t){if(!i)continue;let t=r.endsWith(`/*`)?r.slice(0,-2):r;(e===t||e.startsWith(`${t}/`))&&n.push(i)}return n}function XB(e,t){return!e||!t||`$ref`in e||`$ref`in t?t:{...e,...t,content:{...e.content,...t.content}}}function ZB(e,...t){return t.reduce((t,n)=>{if(!n||!t)return t;for(let[r,i]of Object.entries(n))if(i!=null){if(r in t&&(typeof i==`object`||typeof i==`function`&&r===`operationId`)){if(Array.isArray(i)){let e=[...t[r]??[],...i];t[r]=r===`tags`?Array.from(new Set(e)):r===`parameters`?qB(e):e}else typeof i==`function`?t[r]=i(e):r===`parameters`?t[r]=qB(t[r],i):r===`requestBody`?t.requestBody=XB(t.requestBody,i):t[r]={...t[r],...i}}else t[r]=i}return t},{operationId:GB(e)})}function QB({route:e,specs:t,paths:n},r=JB){let i=UB(e.path),a=e.method.toLowerCase();if(a===`all`){if(!t)return;if(r.has(i)){let n=r.get(i)??{};r.set(i,ZB(e,n,t))}else r.set(i,t)}else{let o=YB(i,r);i in n||(n[i]={}),n[i]&&(n[i][a]=ZB(e,...o,n[i]?.[a],t))}}function $B(e,t){let{exclude:n,excludeStaticFile:r}=t.options,i={},a=Array.isArray(n)?n:[n];for(let[n,o]of Object.entries(e)){if(o==null||a.some(e=>typeof e==`string`?n===e:e.test(n))||n.includes(`*`)&&!n.includes(`{`))continue;if(r){let e=n.includes(`{`),t=(n.split(`/`).pop()||``).includes(`.`);if(!e&&t)continue}for(let e of Object.keys(o)){let r=o[e];if(r==null)continue;let i=r[BB]===!0;if(delete r[BB],n.includes(`{`)){r.parameters=r.parameters?[...r.parameters]:[];let e=n.split(`/`).filter(e=>e.startsWith(`{`)&&!r.parameters.find(t=>t.in===`path`&&t.name===e.slice(1,e.length-1)));for(let n of e){let e=n.slice(1,n.length-1);r.parameters.findIndex(n=>{if(`$ref`in n){let r=n.$ref.split(`/`).pop();if(r){let n=t.components.parameters?.[r];if(n&&!(`$ref`in n))return n.in===`path`&&n.name===e}return!1}return n.in===`path`&&n.name===e})===-1&&r.parameters.push({schema:{type:`string`},in:`path`,name:e,required:!0})}}if(r.responses||={200:{}},i&&t.options.defaultValidationErrorResponse!==!1&&!r.responses[400]){let e=t.options.defaultValidationErrorResponse;typeof e==`object`?r.responses[400]=structuredClone(e):t.validationErrorResponse&&(r.responses[400]=structuredClone(t.validationErrorResponse))}}let e={};for(let t of Object.keys(o))o[t]!=null&&(e[t]=o[t]);Object.keys(e).length>0&&(i[n]=e)}return i}var eV={documentation:{},excludeStaticFile:!0,exclude:[],excludeMethods:[`OPTIONS`],excludeTags:[],defaultValidationErrorResponse:!0},tV={description:`Validation Error`,content:{"application/json":{schema:{type:`object`,properties:{success:{type:`boolean`,enum:[!1]},error:{type:`array`,items:{}},data:{}},required:[`success`,`error`,`data`]}}}};async function nV(e,t=eV,n){let r={components:{},options:{...eV,...t},validationErrorResponse:tV},i=r.options.documentation??{},a={...i,components:i.components&&{...i.components}},o=await rV(e,r);for(let e in o)for(let t in o[e])iV({valueOrFunc:o[e][t]?.hide,method:t,path:e,c:n})&&(o[e][t]=void 0);let s=a.components?.responses?await lV(a.components.responses):void 0;s&&a.components&&(a.components.responses=s.responses);let c=dV(a.components,s?.components,r.components);return{openapi:`3.1.0`,...a,tags:a.tags?.filter(e=>!r.options.excludeTags?.includes(e?.name)),info:{title:`Hono Documentation`,description:`Development documentation`,version:`0.0.0`,...a.info},paths:{...$B(o,r),...a.paths},components:c}}async function rV(e,t){let n={},r=new Map;for(let i of e.routes){let e=wB(i.handler)[zB];if(!e){t.options.includeEmptyPaths&&QB({route:i,paths:n},r);continue}let a=i.method;if(a!==`ALL`&&(t.options.excludeMethods?.includes(a)||!VB.includes(a)))continue;let{schema:o,components:s={}}=await aV(e,t.options.defaultOptions?.[a]&&{...t.options.defaultOptions[a]},t.components.parameters);t.components=dV(t.components,s),QB({route:i,specs:o,paths:n},r)}return n}function iV(e){let{valueOrFunc:t,c:n,method:r,path:i}=e;if(t!=null){if(typeof t==`boolean`)return t;if(typeof t==`function`)return t({c:n,method:r,path:i})}return!1}async function aV(e,t,n){if(`spec`in e){let n={...t,...e.spec,responses:{...t?.responses,...e.spec.responses}},r={};if(n.responses){let e=await lV(n.responses);n.responses=e.responses,r=e.components}if(n.requestBody&&`content`in n.requestBody){let e=await cV(n.requestBody.content);n.requestBody={...n.requestBody,content:e.content},r=dV(r,e.components)}return{schema:n,components:r}}let r=await e.toOpenAPISchema();uV(r);let i={...t,[BB]:!0};if(e.target===`form`||e.target===`json`){let t=e.options?.media??(e.target===`json`?`application/json`:`multipart/form-data`);!i.requestBody||!(`content`in i.requestBody)||!i.requestBody.content?i.requestBody={required:!0,content:{[t]:{schema:r.schema}}}:i.requestBody.content[t]={schema:r.schema}}else{let t=[];if(`$ref`in r.schema){let i=r.schema.$ref.split(`/`).pop();if(i&&r.components?.schemas?.[i]){let a=r.components.schemas[i],o=oV(e.target,a,r.components.schemas),s=o.length===1?o[0]:void 0,c=n?.[i];s&&(!c||`in`in c&&c.in===s.in&&c.name===s.name)?(r.components.parameters??={},r.components.parameters[i]=s,t.push({$ref:`#/components/parameters/${i}`}),delete r.components.schemas[i]):t=o}}else t=oV(e.target,r.schema,r.components?.schemas);i.parameters=t}return{schema:i,components:r.components}}function oV(e,t,n){let r=[];for(let[i,a]of sV(t,n)){let t={in:e===`param`?`path`:e,name:i,schema:a.schema};a.required&&(t.required=!0),t.schema&&`description`in t.schema&&t.schema.description&&(t.description=t.schema.description,t.schema={...t.schema,description:void 0}),r.push(t)}return r}function sV(e,t){let n=new Map,r=new Set,i=e=>{for(let[t,r]of Object.entries(e.properties??{})){let i=n.get(t);n.set(t,{schema:i?{allOf:[i.schema,r]}:r,required:!!e.required?.includes(t)||i?.required})}for(let n of e.allOf??[])if(`$ref`in n){if(!n.$ref.startsWith(`#/components/schemas/`))continue;let e=n.$ref.slice(21).replaceAll(`~1`,`/`).replaceAll(`~0`,`~`),a=t?.[e];a&&!r.has(e)&&(r.add(e),i(a),r.delete(e))}else i(n)};return i(e),n}async function cV(e){let t={},n={};for(let[r,i]of Object.entries(e))if(i){if(i.schema&&`toOpenAPISchema`in i.schema){let e=await i.schema.toOpenAPISchema();uV(e),n[r]={...i,schema:e.schema},e.components&&(t=dV(t,e.components))}else n[r]=i}return{content:n,components:t}}async function lV(e){let t={},n={};for(let[r,i]of Object.entries(e)){if(!i||!(`content`in i)||!i.content){n[r]=i;continue}let e=await cV(i.content);n[r]={...i,content:e.content},t=dV(t,e.components)}return{responses:n,components:t}}function uV(e){let t=e.schema.$defs;t&&typeof t==`object`&&(e.components??={},e.components.schemas={...t,...e.components.schemas},delete e.schema.$defs)}function dV(...e){return e.reduce((e,t,n)=>(t==null||n===0||((e.schemas&&Object.keys(e.schemas).length>0||t.schemas&&Object.keys(t.schemas).length>0)&&(e.schemas={...e.schemas,...t.schemas}),(e.parameters&&Object.keys(e.parameters).length>0||t.parameters&&Object.keys(t.parameters).length>0)&&(e.parameters={...e.parameters,...t.parameters})),e),e[0]??{})}var fV=e=>e.base,pV=e=>{e.zodSchema._zod.def.type===`date`&&(e.jsonSchema.type=`string`,e.jsonSchema.format=`date-time`)};function mV(e,t){let n=e[`~standard`].vendor;return{vendor:n,validate:e[`~standard`].validate,toJSONSchema:n=>Wa(e,{...t,...n}),toOpenAPISchema:r=>Ga(e,{...t,...r,...n===`arktype`?hV(t,r):void 0,...n===`zod`?gV(e,t,r):void 0})}}function hV(e,t){let n=e?.options,r=t?.options;if(!(e?.fallback||n?.fallback||t?.fallback||r?.fallback))return{options:{fallback:fV,...n,...r}}}function gV(e,t,n){if(!(`_zod`in e))return;let r=t?.options,i=n?.options;if(!(t?.override||r?.override||n?.override||i?.override))return{options:{unrepresentable:`any`,override:pV,...r,...i}}}function _V(e,t,n,r){let i=RB(e,t,n);return Object.defineProperty(i,"name",{value:`validator`,configurable:!0}),Object.assign(i,{[zB]:{target:e,...mV(t,r),options:r}})}function vV(e){let t=async(e,t)=>{await t()};return Object.defineProperty(t,"name",{value:`describeRoute`,configurable:!0}),Object.assign(t,{[zB]:{spec:e}})}var yV={options:{override:e=>{let{jsonSchema:t}=e;delete t.readOnly;let n=t.anyOf?.filter(e=>Object.keys(e).length>0);n&&n.length!==t.anyOf.length&&(n.length===1?(delete t.anyOf,Object.assign(t,n[0])):t.anyOf=n)},unrepresentable:`any`}},bV={integrity:`sha384-U11tb2XnKvmwt8RlTvnwUnYgrN+ur4Xyh9htLhjajWNR/Oyl5AX5DEz00qRmlrmK`,src:`https://cdn.jsdelivr.net/npm/@scalar/api-reference@1.72.1/dist/browser/standalone.js`},xV={description:"Tempo ID signs users in to Tempo apps, authorizes apps for them, and signs key authorizations on their Tempo Accounts. Every refusal is an OAuth error response (RFC 6749 §5.2) whose `reason` determines its `error` and status.",title:`Tempo ID`,version:`0.0.0`};function SV(e){let t=kV.get(e);if(t)return t;let n=AV(e);return kV.set(e,n),n.catch(()=>kV.delete(e)),n}var CV=`<!doctype html>
|
|
483
|
+
Nonce: 7f3a9c2e5b1d4f60`]});e.request=z({challenge:n,client_id:R().min(1).max(255).meta({description:`The app's client ID.`,examples:[`Qk3vT9xZbLmN2pRw8YcHjF6sDaE4uGtK`]}),code_challenge:R().regex(/^[\w-]{43}$/).optional().meta({description:`The S256 PKCE challenge of a verifier that the app's backend holds (RFC 7636). With one, the app receives a code. Without one, a public app receives tokens.`,examples:[`E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM`]}),key_authorization:XL.request,redirect_uri:Dn({protocol:/^(?!(?:blob|data|file|javascript|vbscript)$)[a-z][a-z\d+.-]*$/}).meta({description:`A registered redirect URI of a web app, whose origin the page calls from.`,examples:[`https://app.example.com/callback`]}),scope:R().regex(/^[\w:.-]+( [\w:.-]+)*$/).max(256).optional().meta({description:"Space-separated OAuth scopes. Defaults to `openid`.",examples:[`openid email offline_access`]}),state:R().min(1).max(256).optional().meta({description:`An opaque value that the response returns unchanged, to bind it to the request (RFC 6749 §4.1.1).`,examples:[`af0ifjsldkj`]})}).refine(e=>!e.challenge||e.key_authorization,{message:"A challenge requires `key_authorization`, whose witness binds it",path:[`challenge`]}).transform(e=>e.key_authorization?{...e,key_authorization:iR(e.key_authorization,{challenge:e.challenge})}:e).meta({description:`An app's headless authorization request.`,id:`AuthorizationRequest`}),e.redirect=z({challenge:n,key_authorization:XL.request}).refine(e=>!e.challenge||e.key_authorization,{message:"A challenge requires `key_authorization`, whose witness binds it",path:[`challenge`]}).transform(e=>e.key_authorization?iR(e.key_authorization,{challenge:e.challenge}):void 0),e.response=z({account:XL.account.optional(),code:R().optional().meta({description:"The authorization code, when the request sent a `code_challenge`. The app's backend redeems it at `/oauth2/token`.",examples:[`Vb7mQ2xLkP9sTzR4`]}),key_authorization:XL.rpc.optional(),state:R().optional().meta({description:"The request's `state`, unchanged. Absent when the request sent none.",examples:[`af0ifjsldkj`]}),tokens:t.optional().meta({description:"The tokens, when the request sent no `code_challenge`."})}).meta({description:`An authorization: a code or tokens, with the signed key authorization when the request asks for one.`,id:`Authorization`})})(wR||={});function TR(e,t){let{app:n,origin:r}=t;if(!n||!n.redirectUris.includes(e.redirect_uri))return new CR;if(!n.firstParty)return new CR({description:"Headless authorization refused: the app is not a first-party app. Send the user to `/oauth2/authorize`, and receive the code at the redirect URI."});if(n.type===`native`)return new CR({description:"Headless authorization refused: a native app's request does not prove which app sends it. Open `/oauth2/authorize` in an authentication sheet, and receive the code at the redirect URI."});let i=new URL(e.redirect_uri);if(r!==i.origin)return new SR({error_description:`Invalid \`Origin\`: ${r??`none`}. Requests for this redirect URI must come from ${i.origin}.`,field:`Origin`,meta:{expected:i.origin,...r?{origin:r}:{}}});let a=e.key_authorization;if(a)return n.secret?new CR({description:`Key authorization refused: the app holds a client secret, which a headless request does not prove. Authorize the key through a redirect or the device grant.`}):cR(a)??oR({app:n,clientId:e.client_id,key:a})}(function(e){e.errors=[...cR.errors,...oR.errors,SR,CR]})(TR||={});function ER(e){let{app:t,clientId:n,codeChallenge:r,key:i,query:a}=e;return r?(OF(n)?sR(jR(a.get(`key_authorization`)??``)):void 0)??aR(i)??oR({app:t,clientId:n,key:i}):new CR({description:"Key authorization refused: the request names no `code_challenge`, whose verifier receives the key. Send an S256 `code_challenge`."})}(function(e){e.errors=[...aR.errors,...sR.errors,...oR.errors,CR]})(ER||={});function DR(e){let t=AR.find(t=>e.getAll(t).length>1);if(t)return new bR({issues:[{message:`Repeated parameter. Send it once`,path:[t]}]});let n=e.get(`key_authorization`),r=wR.redirect.safeParse({challenge:e.get(`challenge`)??void 0,key_authorization:n===null?void 0:jR(n)});return r.success?r.data:new bR({issues:r.error.issues})}function OR(e){if(!e.has(`key_authorization`))return e;let t=new URLSearchParams(e),n=new Set((t.get(`prompt`)??``).split(` `).filter(Boolean));n.add(`consent`),t.set(`prompt`,[...n].join(` `));let[r,...i]=t.getAll(`key_authorization`),a=r&&!i.length?jR(r):void 0;return!OF(t.get(`client_id`)??``)&&typeof a==`object`&&a&&!Array.isArray(a)&&!(`expiry`in a)&&t.set(`key_authorization`,ot(JSON.stringify({...a,expiry:Math.floor(Date.now()/1e3)+ZL}),kR)),t}var kR={pad:!1,url:!0},AR=[`challenge`,`key_authorization`];function jR(e){try{return JSON.parse(Me(e))}catch{return null}}var MR=class extends nI(`already_decided`){name=`Device.AlreadyDecidedError`;constructor(){super({error_description:`Code already approved or denied.`,field:`code`})}},NR=class extends nI(`approval_pending`){name=`Device.ApprovalPendingError`;constructor(){super({error_description:"Approval pending. Poll again after `interval` seconds."})}},PR=class extends nI(`device_code_expired`){name=`Device.DeviceCodeExpiredError`;constructor(){super({error_description:`Device code expired. Request a new code.`})}},FR=class extends nI(`polling_too_fast`){name=`Device.PollingTooFastError`;constructor(){super({error_description:"Polling too fast. Add 5 seconds to `interval`."})}},IR=class extends nI(`request_denied`){name=`Device.RequestDeniedError`;constructor(){super({error_description:`The user denied the request.`})}},LR=class extends nI(`unknown_code`){name=`Device.UnknownCodeError`;constructor(){super({error_description:`Invalid or expired code. Check the code in the terminal.`,field:`code`})}},RR=`tempo-cli`,zR=`openid email offline_access`,BR=`BCDFGHJKLMNPQRSTVWXZ`;async function VR(e,t){return(await e.update(eP).set({userId:t.userId}).where(cM(Y(eP.id,t.id),Y(eP.status,`pending`),_M(eP.userId),dM(eP.expiresAt,new Date))).returning({id:eP.id})).length>0}async function HR(e,t){let n=await KR(e,t);if(n&&n.status===`pending`&&!n.userId)return n.clientId}async function UR(e,t){let{challenge:n,device:r,deviceCode:i,expiresAt:a,ip:o,location:s}=t,c=t.key?JSON.parse(JSON.stringify(t.key,(e,t)=>typeof t==`bigint`?Bt(t):t)):null,l=e.select({id:eP.id}).from(eP).where(Y(eP.deviceCode,i));await e.insert(SP).values({challenge:n,device:r,expiresAt:a,id:q`(${l})`,ip:o,key:c,location:s})}async function WR(e,t){return(await e.update(eP).set({status:t.status}).where(cM(Y(eP.id,t.id),Y(eP.status,`pending`),Y(eP.userId,t.userId),dM(eP.expiresAt,new Date))).returning({id:eP.id})).length>0}function GR(e){return`${e.slice(0,4)}-${e.slice(4)}`}async function KR(e,t){let[n]=await e.select({appName:iP.name,challenge:SP.challenge,clientId:eP.clientId,createdAt:SP.createdAt,device:SP.device,expiresAt:eP.expiresAt,id:eP.id,ip:SP.ip,key:SP.key,location:SP.location,status:eP.status,userCode:eP.userCode,userId:eP.userId}).from(eP).leftJoin(SP,Y(SP.id,eP.id)).leftJoin(iP,Y(iP.clientId,eP.clientId)).where(cM(Y(eP.userCode,t.userCode),dM(eP.expiresAt,new Date)));if(!n?.clientId)return;let r=n.key?wR.redirect.parse({challenge:n.challenge??void 0,key_authorization:n.key}):void 0;return{...n.appName?{appName:n.appName}:{},...n.challenge?{challenge:n.challenge}:{},clientId:n.clientId,createdAt:n.createdAt??new Date(n.expiresAt.getTime()-6e5),...n.device?{device:n.device}:{},id:n.id,...n.ip?{ip:n.ip}:{},...r?{key:r}:{},...n.location?{location:n.location}:{},status:ez(n.status),userCode:GR(n.userCode),...n.userId?{userId:n.userId}:{}}}async function qR(e,t){let{id:n,key:r,userId:i}=t;return(await e.update(SP).set({account:r.account,keyAuthorization:r.keyAuthorization}).where(cM(Y(SP.id,n),_M(SP.keyAuthorization),yM(e.select({id:eP.id}).from(eP).where(cM(Y(eP.id,n),Y(eP.status,`pending`),Y(eP.userId,i),dM(eP.expiresAt,new Date)))))).returning({id:SP.id})).length>0}async function JR(e,t){let{id:n,key:r}=t;await e.update(SP).set({account:null,keyAuthorization:null}).where(cM(Y(SP.id,n),q`${SP.keyAuthorization} = ${JSON.stringify(r.keyAuthorization)}::jsonb`,yM(e.select({id:eP.id}).from(eP).where(cM(Y(eP.id,n),Y(eP.status,`pending`))))))}async function YR(e,t){let[n]=await e.select({id:eP.id}).from(eP).where(Y(eP.deviceCode,t.deviceCode));return n?.id}function XR(e){let t=e.toUpperCase().replace(/[^A-Z]/g,``);if(!(t.length!==8||[...t].some(e=>!BR.includes(e))))return t}var ZR=`/device`;function QR(e,t){if(!e||!e.startsWith(`/`)||/^\/[/\\]/.test(e))return;let n=new URL(t.origin),r=URL.parse(e,n);if(!r||r.origin!==n.origin||r.pathname!==`/device`||r.hash)return;let i=[...r.searchParams.keys()];if(i.length===0)return ZR;let[a]=i;if(i.length>1||a!==`code`&&a!==`user_code`)return;let o=XR(r.searchParams.get(a)??``);if(o)return`${ZR}?${new URLSearchParams({code:GR(o)})}`}async function $R(e,t){let[n]=await e.delete(SP).where(Y(SP.id,t.id)).returning({account:SP.account,keyAuthorization:SP.keyAuthorization});if(n?.account&&n.keyAuthorization)return{account:n.account,keyAuthorization:n.keyAuthorization}}function ez(e){return e===`approved`||e===`denied`?e:`pending`}var tz=`BCDFGHJKLMNPQRSTVWXZ`,nz=`0123456789ABCDEFGHJKMNPQRSTVWXYZ`;function rz(){return`user_${az()}`}function iz(){let e=[];for(;e.length<8;)for(let t of crypto.getRandomValues(new Uint8Array(16)))t<240&&e.length<8&&e.push(tz[t%20]);return e.join(``)}function az(){let e=Date.now();return Array.from({length:10},(t,n)=>{let r=5*(9-n);return nz[Math.floor(e/2**r)%32]}).join(``)+Array.from(crypto.getRandomValues(new Uint8Array(16)),e=>nz[e%32]).join(``)}function oz(e){return e}function sz(e){return e}function cz(e){let t=e=>Math.floor(e.getTime()/1e3),n=e.map(()=>0),r=[];for(;;){let i=e.reduce((r,i,a)=>{let o=i[n[a]];if(!o)return r;if(r===void 0)return a;let s=e[r][n[r]];return t(o.createdAt)<t(s.createdAt)?a:r},void 0);if(i===void 0)return r;r.push(e[i][n[i]]),n[i]=n[i]+1}}async function lz(e,t){await e.execute(q`select pg_advisory_xact_lock(hashtextextended(${`tempo-account:${t.userId}`}, 0))`)}async function uz(e,t){let{expiresAt:n,identifier:r,others:i=[],value:a}=t,o=new Date,s=e.select({id:yP.id}).from(yP).where(cM(hM(yP.identifier,[r,...i]),dM(yP.expiresAt,o))),[c]=await e.insert(yP).select(q`select ${o.toISOString()}::timestamp, ${n.toISOString()}::timestamp, ${r}, ${r}, ${o.toISOString()}::timestamp, ${a} where not exists (${s})`).onConflictDoUpdate({set:{createdAt:o,expiresAt:n,updatedAt:o,value:a},setWhere:mM(yP.expiresAt,o),target:yP.id}).returning({id:yP.id});return c!==void 0}var dz=class extends nI(`passkey_limit`){name=`Passkey.LimitError`;constructor(){super({error_description:`Passkey limit reached: the user holds 10 registered passkeys, the most that Tempo ID registers. Sign in with one of them.`,meta:{limit:10}})}},fz=class extends nI(`passkey_link_expired`){name=`Passkey.LinkExpiredError`;constructor(){super({error_description:`Expired passkey sign-in: the link from the passkey step is no longer valid. Enter the code again to sign in with email only, or sign in with the passkey again.`,field:`link`})}},pz=class extends nI(`passkey_not_permitted`){name=`Passkey.NotPermittedError`;constructor(e={}){let{clientId:t,origin:n}=e;super(t&&n?{error_description:`Passkey not permitted: no realm of the app ${t} holds passkeys for ${n}. Sign in with an emailed code.`,meta:{client_id:t,origin:n}}:t?{error_description:`Passkey not permitted: the app ${t} holds no passkeys. Sign in with an emailed code.`,meta:{client_id:t}}:{error_description:`Passkey not permitted: no realm holds passkeys for this sign-in. Sign in with an emailed code.`})}},mz=class extends nI(`reauthentication_required`){name=`Passkey.ReauthenticationRequiredError`;constructor(){super({error_description:`Sign in again: adding a passkey needs a sign-in within the last 10 minutes.`})}},hz=class extends nI(`webauthn_rejected`){name=`Passkey.WebAuthnRejectedError`;constructor(){super({error_description:`Passkey rejected. Request new options, then try again with the same passkey or another one.`})}},gz=`passkey-challenge:`,_z=`passkey-registration-proof:`,vz=`passkey-registration:`,yz=`passkey-signature:`,bz=ZL,xz=`passkey-signature-spent:`,Sz=`passkey-sign-in-spent:`,Cz;(function(e){let t=R().regex(/^[A-Za-z0-9_-]+$/),n=vn([`0x`,R().regex(/^[0-9a-fA-F]*$/)]),r=e.credentialId=t.min(1).max(1364);e.assertion=z({id:r.meta({description:`The credential ID of the passkey that signed, base64url.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),metadata:z({authenticatorData:n.meta({description:`The authenticator data the passkey signed, as hex: the relying party ID hash, flags, and signature counter.`,examples:[`0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000`]}),challengeIndex:Cn().int().nonnegative().optional().meta({description:'The character offset of `"challenge"` in `clientDataJSON`. Absent, verification searches for it.',examples:[23]}),clientDataJSON:R().max(4096).meta({description:`The client data the browser collected, as a JSON string, which holds the type, challenge, and origin.`,examples:[`{"type":"webauthn.get","challenge":"9jEFijuhEWrM4SOW-tChJbUEHEP44VcjcJ-Bqo1fTM8","origin":"https://id.tempo.xyz","crossOrigin":false}`]}),typeIndex:Cn().int().nonnegative().optional().meta({description:'The character offset of `"type"` in `clientDataJSON`. Absent, verification searches for it.',examples:[1]}),userVerificationRequired:On().optional().meta({description:`Whether the client required user verification. Verification ignores it and always requires user verification.`,examples:[!0]})}).meta({description:"The signed data that verification reads with `signature`, decoded from the browser response."}),raw:z({authenticatorAttachment:R().nullable().default(null).meta({description:"How the authenticator attaches to the client, such as `platform` or `cross-platform`. Defaults to `null` when the browser reports none.",examples:[`platform`]}),id:t.meta({description:`The credential ID, base64url, as the browser returns it.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),rawId:t.meta({description:`The bytes of the credential ID, base64url.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),response:z({clientDataJSON:t.meta({description:`The client data JSON, base64url.`,examples:[`eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiOWpFRmlqdWhFV3JNNFNPVy10Q2hKYlVFSEVQNDRWY2pjSi1CcW8xZlRNOCIsIm9yaWdpbiI6Imh0dHBzOi8vaWQudGVtcG8ueHl6IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ`]})}).meta({description:"The authenticator's response. Verification keeps only `clientDataJSON` and drops other fields."}),type:R().meta({description:`The credential type.`,examples:[`public-key`]})}).meta({description:"The `PublicKeyCredential` that `navigator.credentials.get()` returns, serialized as JSON."}),signature:n.meta({description:"The P-256 signature over the authenticator data and the client data hash, as 64-byte hex: `r` then `s`.",examples:[`0x6c3f1e0a9b7d24f58e1c3a6b9d0f2e4a7c5b8d1e3f6a9c2b4d7e0f1a3c5b8d9e1f2a7c4b6d8e0f3a5c7b9d1e4f6a8c0b2d5e7f9a1c3b6d8e0f2a4c7b9d1e3f5a`]})}).meta({description:"The assertion, serialized as `webauthx/client` returns it.",id:`PasskeyAssertion`}),e.clientData=z({challenge:t,crossOrigin:On().optional()}),e.credential=z({attestationObject:t.max(16384).meta({description:`The authenticator's attestation object, base64url, which holds the new public key.`,examples:[`o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjF`]}),clientDataJSON:t.max(4096).meta({description:`The client data the browser collected, base64url, which holds the type, challenge, and origin.`,examples:[`eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiOWpFRmlqdWhFV3JNNFNPVy10Q2hKYlVFSEVQNDRWY2pjSi1CcW8xZlRNOCIsIm9yaWdpbiI6Imh0dHBzOi8vaWQudGVtcG8ueHl6IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ`]}),id:r.meta({description:`The credential ID of the new passkey, base64url.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),publicKey:vn([`0x`,R().regex(/^04[0-9a-fA-F]{128}$/)]).meta({description:"The new passkey's uncompressed P256 public key, as hex. Verification reads the key from `attestationObject` and ignores this copy.",examples:[`0x04f6310589abb21116acc6e123967ed0a125b5041c43f8e157237093e07eaa354c6c3f1e0a9b7d24f58e1c3a6b9d0f2e4a7c5b8d1e3f6a9c2b4d7e0f1a3c5b8d`]}),raw:z({authenticatorAttachment:R().nullable().default(null).meta({description:"How the authenticator attaches to the client, such as `platform` or `cross-platform`. Defaults to `null` when the browser reports none.",examples:[`platform`]}),id:t.max(1364).meta({description:`The credential ID, base64url, as the browser returns it.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),rawId:t.max(1364).meta({description:`The bytes of the credential ID, base64url.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),response:z({clientDataJSON:t.max(4096).meta({description:`The client data JSON, base64url.`,examples:[`eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiOWpFRmlqdWhFV3JNNFNPVy10Q2hKYlVFSEVQNDRWY2pjSi1CcW8xZlRNOCIsIm9yaWdpbiI6Imh0dHBzOi8vaWQudGVtcG8ueHl6IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ`]})}).meta({description:"The authenticator's response. Verification keeps only `clientDataJSON`, and reads the top-level `attestationObject`."}),type:R().max(32).meta({description:`The credential type.`,examples:[`public-key`]})}).meta({description:"The `PublicKeyCredential` that `navigator.credentials.create()` returns, serialized as JSON."})}).meta({description:"The new passkey, serialized as `webauthx/client` returns it.",id:`PasskeyCredential`}),e.link=z({address:R(),createdAt:Cn().nullable(),expiresAt:Cn(),host:R(),id:R(),nonce:R(),publicKey:vn([`0x`,R()]),rpId:R()}),e.proof=z({id:R(),publicKey:n,rpId:R()}),e.registration=z({rpId:R()}),e.signature=z({account:R(),clientId:R(),credential:z({id:R(),publicKey:n,rpId:R()})}),e.step=z({step:z({options:z({publicKey:z({allowCredentials:Mn(z({id:r.meta({description:`The credential ID of the account's passkey, base64url.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),type:xn(`public-key`).meta({description:`The credential type.`})}).meta({description:`The passkey that must sign.`})).meta({description:`The account's passkey, the only one the browser offers.`}),challenge:vn([`0x`,R()]).meta({description:`The key authorization's digest, as hex. It is single-use, and expires after 5 minutes.`,examples:[`0xf6310589abb21116acc6e123967ed0a125b5041c43f8e157237093e07eaa354c`]}),rpId:R().meta({description:`The relying party ID of the account's passkey.`,examples:[`tempo.xyz`]}),userVerification:xn(`required`).meta({description:`Every passkey signature requires user verification.`})}).meta({description:"The `PublicKeyCredentialRequestOptions`, serialized with the challenge as hex."})}).meta({description:"The options for `navigator.credentials.get()`."}),type:xn(`passkey`).meta({description:"Sign the options with the passkey, then repeat the approval with `passkey: { assertion }`."})}).meta({description:`The next step: the passkey's signature over the key authorization's digest.`})}).meta({description:`An approval that continues when the passkey signs the key authorization.`,id:`PasskeyStep`}),e.user=z({createdAt:En(),email:R(),emailVerified:On(),id:R(),image:R().nullable(),name:R(),updatedAt:En()}),e.value=z({authorize:yn().optional(),clientId:R().nullable(),link:R().optional(),origin:R().optional(),realmId:R().optional(),rpId:R(),witness:vn([`0x`,R()]).optional()})})(Cz||={});async function wz(e,t){let n=(t.oneTap?.digest??Zt(crypto.getRandomValues(new Uint8Array(32)))).toLowerCase(),r=gz+n,i={expiresAt:new Date(Date.now()+3e5),id:crypto.randomUUID(),identifier:r,value:JSON.stringify(Cz.value.parse({authorize:t.authorize,clientId:t.clientId,link:t.link,origin:t.origin,realmId:t.realmId,rpId:t.rpId,witness:t.oneTap?.witness}))};return t.oneTap?await uz(e,i)?n:void 0:(await e.insert(yP).values(i),n)}function Tz(e){let{app:t,clientId:n,origin:r}=e;if(!n)return new SR({error_description:`Invalid \`Origin\`: ${r??`none`}. A passkey sign-in from an app's page sends the app's \`client_id\`.`,field:`Origin`,...r?{meta:{origin:r}}:{}});if(!t||!t.firstParty)return new CR({description:`Passkey sign-in refused: ${n} is not a first-party app. Send the user to \`/oauth2/authorize\`, which offers passkey sign-in.`});if(t.type===`native`)return new CR({description:"Passkey sign-in refused: a native app's request does not prove which app sends it. Open `/oauth2/authorize` in an authentication sheet."});let i=t.redirectUris.flatMap(e=>{let t=URL.parse(e);return t?.protocol===`https:`||t?.protocol===`http:`?[t.origin]:[]});if(!r||!i.includes(r))return new SR({error_description:`Invalid \`Origin\`: ${r??`none`}. Passkey sign-in for ${n} must come from the origin of one of its redirect URIs.`,field:`Origin`,...r?{meta:{origin:r}}:{}})}(function(e){e.errors=[SR,CR]})(Tz||={});function Ez(e){try{let t=Cz.clientData.parse(JSON.parse(e.clientDataJSON));return at(t.challenge)}catch{return}}async function Dz(e,t){let[n]=await e.select().from(wP).where(cM(Y(wP.id,t.id),Y(wP.rpId,t.rpId)));return n}async function Oz(e,t){let{credential:n,id:r,rpId:i,userId:a}=t;return await e.transaction(async e=>{await lz(e,{userId:a}),await e.insert(EP).values({realmId:`default`,rpId:i}).onConflictDoNothing();let[t]=await e.insert(wP).values({address:n.address.toLowerCase(),...n.createdAt===null?{}:{createdAt:new Date(n.createdAt)},id:r,publicKey:n.publicKey,rpId:i,source:`tempo-wallet`,type:`passkey`,userId:a}).onConflictDoNothing().returning({userId:wP.userId});return t?t.userId:(await Dz(e,{id:r,rpId:i}))?.userId})}async function kz(e){let t=new TextEncoder,n=await crypto.subtle.importKey(`raw`,t.encode(e),`HKDF`,!1,[`deriveBits`]),r=await crypto.subtle.deriveBits({hash:`SHA-256`,info:t.encode(`tempo-id:passkey-link:v1`),name:`HKDF`,salt:new Uint8Array},n,256);return Zt(new Uint8Array(r))}async function Az(e,t){return await e.select({id:wP.id,registered:q`(${Pz(t)})`,rpId:wP.rpId}).from(wP).where(Y(wP.userId,t.userId)).orderBy(DM(wP.createdAt),DM(wP.id))}function jz(){return{endpoints:{signInPasskey:Gn.serverOnly({body:z({oauth_query:R().optional(),user:Cz.user.optional(),userId:R()}),method:`POST`},async e=>{let{user:t,userId:n}=e.body,r=t?.id===n?t:await e.context.internalAdapter.findUserById(n);if(!r)throw Error(`The passkey user is missing.`);let i=await e.context.internalAdapter.createSession(r.id);return await Dr(e,{session:i,user:r}),e.json({user:{email:r.email,id:r.id}})})},id:`tempo-id-passkey`}}async function Mz(e,t){let[n]=await e.select({count:q`count(*)::int`}).from(wP).where(Pz(t));return n?.count??0}async function Nz(e,t){let{id:n,publicKey:r,rpId:i,userId:a}=t;return await e.transaction(async e=>{await lz(e,{userId:a});let t=e.$with(`counted`).as(e.select({count:q`count(*)::int`.as(`count`)}).from(wP).where(Pz({userId:a}))),o=e.$with(`stored`).as(e.insert(EP).select(q`select now(), 'default', ${i} from ${t} where ${t.count} < ${10}`).onConflictDoNothing().returning({rpId:EP.rpId})),s=e.select({rpId:EP.rpId}).from(EP).where(Y(EP.realmId,`default`)).for(`update`),[c]=await e.with(t,o).select({count:t.count,rpId:q`coalesce((select ${o.rpId} from ${o}), (${s}))`}).from(t);if((c?.count??0)>=10)return`limit`;if((c?.rpId?{rpId:c.rpId}:(await s)[0])?.rpId!==i)return`stale`;let[l]=await e.insert(wP).values({address:gt(Fe(r)).toLowerCase(),id:n,publicKey:r,rpId:i,source:`tempo-id`,type:`passkey`,userId:a}).onConflictDoNothing().returning({id:wP.id});return l?`stored`:`held`})}function Pz(e){return cM(hM(wP.source,[`registered`,`tempo-id`]),vM(wP.address),Y(wP.userId,e.userId))}function Fz(e,t){let n=[t.origin,t.page].flatMap(e=>e?[new URL(e).hostname]:[]);for(let t of e){let e=t.passkeys?.rpId;if(e!==void 0&&n.every(t=>t===e||t.endsWith(`.${e}`)))return{realmId:t.id,rpId:e}}}async function Iz(e,t){let{credential:n,rpId:r,userId:i}=t,a=Zt(crypto.getRandomValues(new Uint8Array(32)));return await e.insert(yP).values({expiresAt:new Date(Date.now()+3e5),id:crypto.randomUUID(),identifier:Rz({challenge:a,prefix:_z,userId:i}),value:JSON.stringify(Cz.proof.parse({...n,rpId:r}))}),a}async function Lz(e,t){let n=Zt(crypto.getRandomValues(new Uint8Array(32)));return await e.insert(yP).values({expiresAt:new Date(Date.now()+3e5),id:crypto.randomUUID(),identifier:Rz({challenge:n,prefix:vz,userId:t.userId}),value:JSON.stringify(Cz.registration.parse({rpId:t.rpId}))}),n}function Rz(e){return e.prefix+JSON.stringify([e.userId,e.challenge.toLowerCase()])}async function zz(e,t){let{account:n,clientId:r,credential:i,digest:a,userId:o}=t;await e.insert(yP).values({expiresAt:new Date(Date.now()+3e5),id:crypto.randomUUID(),identifier:Jz({account:n,clientId:r,credentialId:i.id,digest:a,userId:o}),value:JSON.stringify(Cz.signature.parse({account:n.toLowerCase(),clientId:r,credential:i}))})}async function Bz(e,t){return await Zr({data:JSON.stringify(Cz.link.parse(e)),key:await kz(t.secret)})}async function Vz(e,t){let n=Ez(t);if(!n)return;let[r]=await e.delete(yP).where(cM(Y(yP.identifier,gz+n.toLowerCase()),dM(yP.expiresAt,new Date))).returning({value:yP.value});if(r)return Hz(r.value,{challenge:n})}function Hz(e,t){let n=Cz.value.parse(JSON.parse(e));return{authorize:n.authorize,challenge:t.challenge,clientId:n.clientId,link:n.link,origin:n.origin,realmId:n.realmId,rpId:n.rpId,witness:n.witness}}async function Uz(e,t){let n=Ez(t);if(!n)return;let r=e.$with(`spent`).as(e.delete(yP).where(cM(Y(yP.identifier,gz+n.toLowerCase()),dM(yP.expiresAt,new Date))).returning({value:yP.value})),[i]=await e.with(r).select({key:{id:wP.id,publicKey:wP.publicKey,userId:wP.userId},user:_P,value:r.value}).from(r).leftJoin(wP,cM(Y(wP.id,t.id),Y(wP.rpId,q`(${r.value})::jsonb ->> 'rpId'`))).leftJoin(_P,Y(_P.id,wP.userId));if(i)return{challenge:Hz(i.value,{challenge:n}),key:i.key&&i.user?{...i.key,user:i.user}:void 0}}async function Wz(e,t){let n=(()=>{try{let e=Cz.clientData.parse(JSON.parse(t.clientDataJSON));return at(e.challenge)}catch{return}})();if(!n)return;let[r]=await e.delete(yP).where(cM(Y(yP.identifier,Rz({challenge:n,prefix:_z,userId:t.userId})),dM(yP.expiresAt,new Date))).returning({value:yP.value});if(r)return{...Cz.proof.parse(JSON.parse(r.value)),challenge:n}}async function Gz(e,t){let n=(()=>{try{let e=Cz.clientData.parse(JSON.parse(Me(t.clientDataJSON)));return at(e.challenge)}catch{return}})();if(!n)return;let[r]=await e.delete(yP).where(cM(Y(yP.identifier,Rz({challenge:n,prefix:vz,userId:t.userId})),dM(yP.expiresAt,new Date))).returning({value:yP.value});if(r)return{challenge:n,rpId:Cz.registration.parse(JSON.parse(r.value)).rpId}}async function Kz(e,t){let n=Yz(t),r=Sz+n.slice(24);return await e.transaction(async e=>(await e.execute(q`select pg_advisory_xact_lock(hashtextextended(${n}, 0))`),await uz(e,{expiresAt:new Date(Math.min(Math.max(t.expiry*1e3,Date.now()+3e5),Date.now()+bz*1e3)),identifier:r,others:[n],value:`{}`})))}async function qz(e,t){let n=(()=>{try{let e=Cz.clientData.parse(JSON.parse(t.clientDataJSON));return at(e.challenge)}catch{return}})();if(!n)return;let r=Yz(t);return await e.transaction(async e=>{await e.execute(q`select pg_advisory_xact_lock(hashtextextended(${r}, 0))`);let[i]=await e.select({id:yP.id}).from(yP).where(cM(Y(yP.identifier,r),dM(yP.expiresAt,new Date))),[a]=await e.delete(yP).where(cM(Y(yP.identifier,Jz({...t,digest:n})),dM(yP.expiresAt,new Date))).returning({value:yP.value});if(!a||i)return;let o={...Cz.signature.parse(JSON.parse(a.value)),digest:n};if(t.verify(o))return await e.insert(yP).values({expiresAt:new Date(Math.min(Math.max(t.expiry*1e3,Date.now()+3e5),Date.now()+bz*1e3)),id:crypto.randomUUID(),identifier:r,value:`{}`}),o})}function Jz(e){return yz+JSON.stringify([e.userId,e.clientId,e.account.toLowerCase(),e.credentialId,e.digest.toLowerCase()])}function Yz(e){return xz+yt($t(e.authenticatorData,e.signature))}async function Xz(e,t){let n=await Ln({data:e,key:await kz(t.secret)}).then(e=>Cz.link.safeParse(JSON.parse(e))).catch(()=>void 0);if(n?.success&&n.data.host===t.host&&!(n.data.expiresAt<=Date.now()/1e3))return n.data}function Zz(e,t){try{return!Cz.clientData.parse(JSON.parse(e.metadata.clientDataJSON)).crossOrigin&&TS({...e,metadata:{...e.metadata,userVerificationRequired:!0}},{challenge:t.challenge,origin:t.origin,publicKey:t.publicKey,rpId:t.rpId})}catch{return!1}}function Qz(e,t){try{if(Cz.clientData.parse(JSON.parse(Me(e.clientDataJSON))).crossOrigin)return;let n=kS(e,{attestation:`none`,challenge:t.challenge,origin:t.origin,rpId:t.rpId,userVerification:`required`});return{id:n.credential.id,publicKey:n.credential.publicKey}}catch{return}}var $z=class extends nI(`authorization_expired`){name=`Auth.AuthorizationExpiredError`;constructor(){super({error_description:`Expired authorization request: the request from the app is no longer valid. Return to the app, and start again.`,field:`oauth_query`})}},eB=class extends nI(`invalid_code`){name=`Auth.InvalidCodeError`;constructor(){super({error_description:`Invalid or expired code. Request a new one.`,field:`code`})}},tB=class extends nI(`session_changed`){name=`Auth.SessionChangedError`;constructor(){super({error_description:`Changed session: the signed-in account differs from the one that this page showed. Reload the page, and check the account before the decision.`,field:`session_id`})}},nB=class extends nI(`session_required`){name=`Auth.SessionRequiredError`;constructor(){super({error_description:`Sign in first.`})}},rB=`tempo-id-session`;function iB(e){let{accountStep:t,baseURL:n,cache:r,db:i,google:a,metadataFetch:o,pendingKey:s,secret:c,sendCode:l,sessionCreated:u,waitUntil:d}=e;return{account:{updateAccountOnSignIn:!1},advanced:{backgroundTasks:{handler:d},cookies:{session_token:{name:rB}},database:{generateId:e=>e.model===`user`?rz():crypto.randomUUID(),joins:!0},ipAddress:{ipAddressHeaders:[`cf-connecting-ip`]}},basePath:`/`,baseURL:n,database:aN(i,{provider:`pg`,schema:bP}),databaseHooks:{account:{create:{before:()=>Promise.resolve({data:{accessToken:null,accessTokenExpiresAt:null,idToken:null,refreshToken:null,refreshTokenExpiresAt:null}})}},session:{create:{after:e=>(u?.({id:e.id,userId:e.userId}),Promise.resolve())}},user:{create:{before:e=>Promise.resolve(e.emailVerified===!0)}}},onAPIError:{errorURL:`${n}/error`},plugins:[nO({allowedAttempts:3,expiresIn:600,otpLength:6,sendVerificationOTP:e=>l({code:e.otp,email:e.email}),storeOTP:`hashed`}),jz(),...DF({accountStep:t,baseURL:n,cache:r,metadataFetch:o,pendingKey:s}),SO({expiresIn:`600s`,generateUserCode:iz,interval:`5s`,verificationUri:ZR}),{id:`tempo-id-indexes`,schema:{account:{fields:{},indexes:[{fields:[`providerId`,`accountId`]}]},deviceCode:{fields:{},indexes:[{fields:[`expiresAt`]}]},oauthAccessToken:{fields:{},indexes:[{fields:[`expiresAt`]}]},oauthClientAssertion:{fields:{},indexes:[{fields:[`expiresAt`]}]},oauthRefreshToken:{fields:{},indexes:[{fields:[`expiresAt`]}]},session:{fields:{},indexes:[{fields:[`expiresAt`]}]},verification:{fields:{},indexes:[{fields:[`expiresAt`]}]}}}],rateLimit:{enabled:!1},secret:c,socialProviders:a?{google:{clientId:a.clientId,clientSecret:a.clientSecret,prompt:`select_account`}}:{},verification:{disableCleanup:!0}}}var aB=e=>e;async function Z(e,t,n,r){let i=e.var.timing,a=performance.now(),o={closed:1/0,...r?{description:r}:{},duration:0,name:n,opened:i.events++,start:a-i.start};i.spans.push(o);try{return await t}finally{o.closed=i.events++,o.duration=performance.now()-a}}var oB=aB(async(e,t)=>{let n={events:0,spans:[],start:performance.now()};e.set(`timing`,n),await t();let r=performance.now()-n.start,i=sB(n.spans);e.res.headers.append(`server-timing`,[`total;dur=${cB(r)}`,...i.map(lB)].join(`, `)),!UF()&&GF({fields:{duration:cB(r),errorCode:e.var.refusal?.error,method:e.req.method,reason:e.var.refusal?.reason,requestId:e.var.requestId,route:KF(e),spans:i.map(e=>`${e.name};dur=${cB(e.duration)};start=${cB(e.start)}`).join(`, `),status:e.res.status},message:`The Worker timed a request.`})});function sB(e){return e.map((e,t)=>({settles:e.opened-t,span:e})).toSorted((e,t)=>e.settles===t.settles?e.span.closed===t.span.closed?e.span.opened-t.span.opened:e.span.closed>t.span.closed?-1:1:e.settles-t.settles).map(e=>e.span)}function cB(e){return Math.round(e*10)/10}function lB(e){let t=`${e.name};dur=${cB(e.duration)}`;return e.description?`${t};desc="${e.description.replace(/["\\]/g,`\\$&`)}"`:t}var uB=class extends Error{name=`Balance.UnknownChainError`;constructor(e){super(`Unknown chain: ${e.chainId}.`)}},dB=3e3,fB;(function(e){e.balance=z({amount:R().meta({description:`The sum in USD, as a decimal string.`,examples:[`12.5`]}),currency:xn(`USD`).meta({description:"The currency of `amount`."})}).meta({description:`An account's holdings of USD tokens.`,id:`Balance`})})(fB||={});async function pB(e){let{address:t,chainId:n}=e,r=$L.find(e=>e.id===n);if(!r)throw new uB({chainId:n});let i=bI({chain:r,transport:BI(e.rpcUrl,{retryCount:0,timeout:dB})}),a=dR({chainId:n}).filter(e=>e.currency===`USD`),o=await Promise.all(a.map(async e=>je(i,Ua.call({account:t,token:e.address})).catch(e=>{if(mB(e))return 0n;throw e}))),s=Math.max(0,...a.map(e=>e.decimals)),c=a.reduce((e,t,n)=>e+o[n]*10n**BigInt(s-t.decimals),0n);return{amount:Le(c,s),currency:`USD`}}function mB(e){if(!(e instanceof kt))return!1;let t=e.walk(e=>e instanceof Lt);return t instanceof Lt&&t.data?.errorName===`Uninitialized`}function hB(e,t){let{accounts:n,chainId:r,rpcUrl:i}=t;return Promise.all(n.map(t=>Z(e,pB({address:t.address,chainId:r,rpcUrl:i}),`Balance.get`).catch(t=>(qF(e,{error:t,fields:{chainId:r},message:`A balance failed to load.`}),null))))}var gB=`Payload Too Large`,_B=e=>{let t=e.onError||(()=>{throw new Wv(413,{res:new Response(gB,{status:413})})}),n=e.maxSize;return async function(e,r){if(!e.req.raw.body)return r();let i=e.req.raw.headers.has(`transfer-encoding`);if(e.req.raw.headers.has(`content-length`)&&!i)return parseInt(e.req.raw.headers.get(`content-length`)||`0`,10)>n?t(e):r();let a=0,o=[],s=e.req.raw.body.getReader();for(;;){let{done:r,value:i}=await s.read();if(r)break;if(a+=i.length,a>n)return t(e);o.push(i)}let c={body:new ReadableStream({start(e){for(let t of o)e.enqueue(t);e.close()}}),duplex:`half`};return e.req.raw=new Request(e.req.raw,c),r()}},vB=class extends nI(`body_too_large`){name=`BodyLimit.BodyTooLargeError`;constructor(){super({error_description:`Invalid request body: exceeds the ${bB}-byte maximum. Send a body of ${bB} bytes or fewer.`,meta:{maximum:bB}})}},yB=[vB],bB=65536,xB=_B({maxSize:bB,onError:e=>X(e,new vB)});function SB(e){let{max:t=1e3,ttl:n}=e,r=new Map,i=0;return{async get(e,a,o={}){let{keep:s=()=>!0}=o,c=Math.min(o.ttl??n,n),l=JSON.stringify(a);if(c<=0||l.length>256)return await e();let u=r.get(l);if(u&&u.expires>Date.now())return u.value;let d=++i,f=await e();if(!s(f))return f;let p=r.get(l);if(p&&p.load>d)return f;let m=Date.now();if(r.delete(l),r.size>=t)for(let[e,t]of r)t.expires<=m&&r.delete(e);if(r.size>=t){let e=r.keys().next().value;e!==void 0&&r.delete(e)}return r.set(l,{expires:m+c,load:d,value:f}),f}}}async function CB(e,t,n,r={}){let i=e.var.cache;return i?await i.get(t,n,r):await t()}var wB=e=>e.__COMPOSED_HANDLER?wB(e[py]):e,TB=(e,t,n)=>{let r=e.req.raw.headers.get(`Cookie`);if(typeof t==`string`){if(!r)return;let e=t;return n===`secure`?e=`__Secure-`+t:n===`host`&&(e=`__Host-`+t),le(r,e)[e]}return r?le(r):{}},EB=async(e,t,n,r)=>{let i=e.req.raw.headers.get(`Cookie`);if(typeof n==`string`){if(!i)return;let e=n;return r===`secure`?e=`__Secure-`+n:r===`host`&&(e=`__Host-`+n),(await I(i,t,e))[e]}return i?await I(i,t):{}},DB=(e,t,n)=>{let r;return r=n?.prefix===`secure`?oe(`__Secure-`+e,t,{path:`/`,...n,secure:!0}):n?.prefix===`host`?oe(`__Host-`+e,t,{...n,path:`/`,secure:!0,domain:void 0}):oe(e,t,{path:`/`,...n}),r},OB=(e,t,n,r)=>{let i=DB(t,n,r);e.header(`Set-Cookie`,i,{append:!0})},kB=(e,t,n)=>{let r=TB(e,t,n?.prefix);return OB(e,t,``,{...n,maxAge:0}),r},AB=/^application\/([a-z-\.]+\+)?json(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/i,jB=/^multipart\/form-data(;\s?boundary=[a-zA-Z0-9'"()+_,\-./:=?]+)?$/i,MB=/^application\/x-www-form-urlencoded(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/i,NB=(e,t)=>async(n,r)=>{let i={},a=n.req.header(`Content-Type`);switch(e){case`json`:if(!a||!AB.test(a))break;try{i=await n.req.json()}catch{throw new Wv(400,{message:`Malformed JSON in request body`})}break;case`form`:{if(!a||!(jB.test(a)||MB.test(a)))break;let e;if(n.req.bodyCache.formData)e=await n.req.bodyCache.formData;else try{e=await Kv(await n.req.arrayBuffer(),a),n.req.bodyCache.formData=e}catch(e){let t=`Malformed FormData request.`;throw t+=e instanceof Error?` ${e.message}`:` ${String(e)}`,new Wv(400,{message:t})}let t=Object.create(null);e.forEach((e,n)=>{n.endsWith(`[]`)?(t[n]??=[]).push(e):Array.isArray(t[n])?t[n].push(e):Object.hasOwn(t,n)?t[n]=[t[n],e]:t[n]=e}),i=t;break}case`query`:i=Object.fromEntries(Object.entries(n.req.queries()).map(([e,t])=>t.length===1?[e,t[0]]:[e,t]));break;case`param`:i=n.req.param();break;case`header`:i=n.req.header();break;case`cookie`:i=TB(n)}let o=await t(i,n);return o instanceof Response?o:(n.req.addValidatedData(e,o),await r())},PB={header:[`cookie`]};function FB(e,t,n){if(!(n in PB))return e;let r=PB[n]||[];return t===`arktype`?IB(e,r):t===`valibot`?LB(e,r):e}function IB(e,t){return e.map(e=>{if(e&&typeof e==`object`&&`data`in e&&typeof e.data==`object`&&e.data!==null&&!Array.isArray(e.data)){let n={...e.data};for(let e of t)delete n[e];let r=Object.create(Object.getPrototypeOf(e));return Object.assign(r,e,{data:n}),r}return e})}function LB(e,t){return e.map(e=>{if(e&&typeof e==`object`&&`path`in e&&Array.isArray(e.path)){for(let n of e.path)if(typeof n==`object`&&`input`in n&&typeof n.input==`object`&&n.input!==null&&!Array.isArray(n.input))for(let e of t)delete n.input[e]}return e})}var RB=(e,t,n)=>NB(e,async(r,i)=>{let a=await t[`~standard`].validate(r);if(n){let t=await n(a.issues?{data:r,error:a.issues,success:!1,target:e}:{data:r,success:!0,target:e},i);if(t){if(t instanceof Response)return t;if(typeof t==`object`&&`response`in t)return t.response}}if(a.issues){let n=FB(a.issues,t[`~standard`].vendor,e);return i.json({data:r,error:n,success:!1},400)}return a.value}),zB=Symbol(`openapi`),BB=`__HonoOpenAPIValidator__`,VB=[`GET`,`PUT`,`POST`,`DELETE`,`OPTIONS`,`HEAD`,`PATCH`,`TRACE`],HB=e=>{let t=e;if(t.startsWith(`:`)){let e=t.match(/^:([^{?]+)(?:{(.+)})?(\?)?$/);e?t=`{${e[1]}}`:(t=t.slice(1,t.length),t.endsWith(`?`)&&(t=t.slice(0,-1)),t=`{${t}}`)}return t},UB=e=>e.split(`/`).map(HB).join(`/`),WB=e=>e.split(/[\W_]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``),GB=e=>{let t=e.method.toLowerCase();if(e.path===`/`)return`${t}Index`;for(let n of e.path.split(`/`)){let e=HB(n);e.charCodeAt(0)===123?t+=`By${WB(e.slice(1,-1))}`:t+=WB(e)}return t},KB=e=>`$ref`in e?e.$ref:`${e.in} ${e.name}`;function qB(...e){let t=e.flatMap(e=>e??[]).reduce((e,t)=>(e.set(KB(t),t),e),new Map);return Array.from(t.values())}var JB=new Map;function YB(e,t){let n=[];for(let[r,i]of t){if(!i)continue;let t=r.endsWith(`/*`)?r.slice(0,-2):r;(e===t||e.startsWith(`${t}/`))&&n.push(i)}return n}function XB(e,t){return!e||!t||`$ref`in e||`$ref`in t?t:{...e,...t,content:{...e.content,...t.content}}}function ZB(e,...t){return t.reduce((t,n)=>{if(!n||!t)return t;for(let[r,i]of Object.entries(n))if(i!=null){if(r in t&&(typeof i==`object`||typeof i==`function`&&r===`operationId`)){if(Array.isArray(i)){let e=[...t[r]??[],...i];t[r]=r===`tags`?Array.from(new Set(e)):r===`parameters`?qB(e):e}else typeof i==`function`?t[r]=i(e):r===`parameters`?t[r]=qB(t[r],i):r===`requestBody`?t.requestBody=XB(t.requestBody,i):t[r]={...t[r],...i}}else t[r]=i}return t},{operationId:GB(e)})}function QB({route:e,specs:t,paths:n},r=JB){let i=UB(e.path),a=e.method.toLowerCase();if(a===`all`){if(!t)return;if(r.has(i)){let n=r.get(i)??{};r.set(i,ZB(e,n,t))}else r.set(i,t)}else{let o=YB(i,r);i in n||(n[i]={}),n[i]&&(n[i][a]=ZB(e,...o,n[i]?.[a],t))}}function $B(e,t){let{exclude:n,excludeStaticFile:r}=t.options,i={},a=Array.isArray(n)?n:[n];for(let[n,o]of Object.entries(e)){if(o==null||a.some(e=>typeof e==`string`?n===e:e.test(n))||n.includes(`*`)&&!n.includes(`{`))continue;if(r){let e=n.includes(`{`),t=(n.split(`/`).pop()||``).includes(`.`);if(!e&&t)continue}for(let e of Object.keys(o)){let r=o[e];if(r==null)continue;let i=r[BB]===!0;if(delete r[BB],n.includes(`{`)){r.parameters=r.parameters?[...r.parameters]:[];let e=n.split(`/`).filter(e=>e.startsWith(`{`)&&!r.parameters.find(t=>t.in===`path`&&t.name===e.slice(1,e.length-1)));for(let n of e){let e=n.slice(1,n.length-1);r.parameters.findIndex(n=>{if(`$ref`in n){let r=n.$ref.split(`/`).pop();if(r){let n=t.components.parameters?.[r];if(n&&!(`$ref`in n))return n.in===`path`&&n.name===e}return!1}return n.in===`path`&&n.name===e})===-1&&r.parameters.push({schema:{type:`string`},in:`path`,name:e,required:!0})}}if(r.responses||={200:{}},i&&t.options.defaultValidationErrorResponse!==!1&&!r.responses[400]){let e=t.options.defaultValidationErrorResponse;typeof e==`object`?r.responses[400]=structuredClone(e):t.validationErrorResponse&&(r.responses[400]=structuredClone(t.validationErrorResponse))}}let e={};for(let t of Object.keys(o))o[t]!=null&&(e[t]=o[t]);Object.keys(e).length>0&&(i[n]=e)}return i}var eV={documentation:{},excludeStaticFile:!0,exclude:[],excludeMethods:[`OPTIONS`],excludeTags:[],defaultValidationErrorResponse:!0},tV={description:`Validation Error`,content:{"application/json":{schema:{type:`object`,properties:{success:{type:`boolean`,enum:[!1]},error:{type:`array`,items:{}},data:{}},required:[`success`,`error`,`data`]}}}};async function nV(e,t=eV,n){let r={components:{},options:{...eV,...t},validationErrorResponse:tV},i=r.options.documentation??{},a={...i,components:i.components&&{...i.components}},o=await rV(e,r);for(let e in o)for(let t in o[e])iV({valueOrFunc:o[e][t]?.hide,method:t,path:e,c:n})&&(o[e][t]=void 0);let s=a.components?.responses?await lV(a.components.responses):void 0;s&&a.components&&(a.components.responses=s.responses);let c=dV(a.components,s?.components,r.components);return{openapi:`3.1.0`,...a,tags:a.tags?.filter(e=>!r.options.excludeTags?.includes(e?.name)),info:{title:`Hono Documentation`,description:`Development documentation`,version:`0.0.0`,...a.info},paths:{...$B(o,r),...a.paths},components:c}}async function rV(e,t){let n={},r=new Map;for(let i of e.routes){let e=wB(i.handler)[zB];if(!e){t.options.includeEmptyPaths&&QB({route:i,paths:n},r);continue}let a=i.method;if(a!==`ALL`&&(t.options.excludeMethods?.includes(a)||!VB.includes(a)))continue;let{schema:o,components:s={}}=await aV(e,t.options.defaultOptions?.[a]&&{...t.options.defaultOptions[a]},t.components.parameters);t.components=dV(t.components,s),QB({route:i,specs:o,paths:n},r)}return n}function iV(e){let{valueOrFunc:t,c:n,method:r,path:i}=e;if(t!=null){if(typeof t==`boolean`)return t;if(typeof t==`function`)return t({c:n,method:r,path:i})}return!1}async function aV(e,t,n){if(`spec`in e){let n={...t,...e.spec,responses:{...t?.responses,...e.spec.responses}},r={};if(n.responses){let e=await lV(n.responses);n.responses=e.responses,r=e.components}if(n.requestBody&&`content`in n.requestBody){let e=await cV(n.requestBody.content);n.requestBody={...n.requestBody,content:e.content},r=dV(r,e.components)}return{schema:n,components:r}}let r=await e.toOpenAPISchema();uV(r);let i={...t,[BB]:!0};if(e.target===`form`||e.target===`json`){let t=e.options?.media??(e.target===`json`?`application/json`:`multipart/form-data`);!i.requestBody||!(`content`in i.requestBody)||!i.requestBody.content?i.requestBody={required:!0,content:{[t]:{schema:r.schema}}}:i.requestBody.content[t]={schema:r.schema}}else{let t=[];if(`$ref`in r.schema){let i=r.schema.$ref.split(`/`).pop();if(i&&r.components?.schemas?.[i]){let a=r.components.schemas[i],o=oV(e.target,a,r.components.schemas),s=o.length===1?o[0]:void 0,c=n?.[i];s&&(!c||`in`in c&&c.in===s.in&&c.name===s.name)?(r.components.parameters??={},r.components.parameters[i]=s,t.push({$ref:`#/components/parameters/${i}`}),delete r.components.schemas[i]):t=o}}else t=oV(e.target,r.schema,r.components?.schemas);i.parameters=t}return{schema:i,components:r.components}}function oV(e,t,n){let r=[];for(let[i,a]of sV(t,n)){let t={in:e===`param`?`path`:e,name:i,schema:a.schema};a.required&&(t.required=!0),t.schema&&`description`in t.schema&&t.schema.description&&(t.description=t.schema.description,t.schema={...t.schema,description:void 0}),r.push(t)}return r}function sV(e,t){let n=new Map,r=new Set,i=e=>{for(let[t,r]of Object.entries(e.properties??{})){let i=n.get(t);n.set(t,{schema:i?{allOf:[i.schema,r]}:r,required:!!e.required?.includes(t)||i?.required})}for(let n of e.allOf??[])if(`$ref`in n){if(!n.$ref.startsWith(`#/components/schemas/`))continue;let e=n.$ref.slice(21).replaceAll(`~1`,`/`).replaceAll(`~0`,`~`),a=t?.[e];a&&!r.has(e)&&(r.add(e),i(a),r.delete(e))}else i(n)};return i(e),n}async function cV(e){let t={},n={};for(let[r,i]of Object.entries(e))if(i){if(i.schema&&`toOpenAPISchema`in i.schema){let e=await i.schema.toOpenAPISchema();uV(e),n[r]={...i,schema:e.schema},e.components&&(t=dV(t,e.components))}else n[r]=i}return{content:n,components:t}}async function lV(e){let t={},n={};for(let[r,i]of Object.entries(e)){if(!i||!(`content`in i)||!i.content){n[r]=i;continue}let e=await cV(i.content);n[r]={...i,content:e.content},t=dV(t,e.components)}return{responses:n,components:t}}function uV(e){let t=e.schema.$defs;t&&typeof t==`object`&&(e.components??={},e.components.schemas={...t,...e.components.schemas},delete e.schema.$defs)}function dV(...e){return e.reduce((e,t,n)=>(t==null||n===0||((e.schemas&&Object.keys(e.schemas).length>0||t.schemas&&Object.keys(t.schemas).length>0)&&(e.schemas={...e.schemas,...t.schemas}),(e.parameters&&Object.keys(e.parameters).length>0||t.parameters&&Object.keys(t.parameters).length>0)&&(e.parameters={...e.parameters,...t.parameters})),e),e[0]??{})}var fV=e=>e.base,pV=e=>{e.zodSchema._zod.def.type===`date`&&(e.jsonSchema.type=`string`,e.jsonSchema.format=`date-time`)};function mV(e,t){let n=e[`~standard`].vendor;return{vendor:n,validate:e[`~standard`].validate,toJSONSchema:n=>Wa(e,{...t,...n}),toOpenAPISchema:r=>Ga(e,{...t,...r,...n===`arktype`?hV(t,r):void 0,...n===`zod`?gV(e,t,r):void 0})}}function hV(e,t){let n=e?.options,r=t?.options;if(!(e?.fallback||n?.fallback||t?.fallback||r?.fallback))return{options:{fallback:fV,...n,...r}}}function gV(e,t,n){if(!(`_zod`in e))return;let r=t?.options,i=n?.options;if(!(t?.override||r?.override||n?.override||i?.override))return{options:{unrepresentable:`any`,override:pV,...r,...i}}}function _V(e,t,n,r){let i=RB(e,t,n);return Object.defineProperty(i,"name",{value:`validator`,configurable:!0}),Object.assign(i,{[zB]:{target:e,...mV(t,r),options:r}})}function vV(e){let t=async(e,t)=>{await t()};return Object.defineProperty(t,"name",{value:`describeRoute`,configurable:!0}),Object.assign(t,{[zB]:{spec:e}})}var yV={options:{override:e=>{let{jsonSchema:t}=e;delete t.readOnly;let n=t.anyOf?.filter(e=>Object.keys(e).length>0);n&&n.length!==t.anyOf.length&&(n.length===1?(delete t.anyOf,Object.assign(t,n[0])):t.anyOf=n)},unrepresentable:`any`}},bV={integrity:`sha384-U11tb2XnKvmwt8RlTvnwUnYgrN+ur4Xyh9htLhjajWNR/Oyl5AX5DEz00qRmlrmK`,src:`https://cdn.jsdelivr.net/npm/@scalar/api-reference@1.72.1/dist/browser/standalone.js`},xV={description:"Tempo ID signs users in to Tempo apps, authorizes apps for them, and signs key authorizations on their Tempo Accounts. Every refusal is an OAuth error response (RFC 6749 §5.2) whose `reason` determines its `error` and status.",title:`Tempo ID`,version:`0.0.0`};function SV(e){let t=kV.get(e);if(t)return t;let n=AV(e);return kV.set(e,n),n.catch(()=>kV.delete(e)),n}var CV=`<!doctype html>
|
|
484
484
|
<html lang="en">
|
|
485
485
|
<head>
|
|
486
486
|
<meta charset="utf-8" />
|
|
@@ -604,7 +604,7 @@ Most of the features of Better Auth will not work correctly.`);let l=t.secrets??
|
|
|
604
604
|
\r
|
|
605
605
|
`+o.body,c=new TextEncoder().encode(s),l=X6(s);if(l!==void 0)throw new E6(`MIME_ERROR`,`email: header line ${l.index+1} is ${l.octets} octets, over the ${W6}-octet limit in RFC 5322 §2.1.1. A value with no whitespace cannot be folded — shorten it, or move it into the body.`);if(c.byteLength>5242880)throw new E6(`MIME_ERROR`,`email: message size ${c.byteLength} bytes exceeds Cloudflare limit of ${l6} bytes.`);return{raw:c,messageId:n}}var x8=`/__void/inbox/_capture`,S8=`__VOID_EMAIL_DEV_INBOX`,C8=`__VOID_EMAIL_DEV_INBOX_TOKEN`;6*l6;function w8(e){return JSON.stringify({...e,raw:s6(e.raw)})}var T8=`__voidEmailSinks__`,E8=globalThis;function D8(){let e=E8[T8];return e||(e={sinks:new Set},E8[T8]=e),e}function O8(e){for(let t of D8().sinks)try{t(e)}catch(e){console.warn(`[email-dev-inbox] sink error:`,e)}}function k8(){return D8().sinks.size>0}function A8(e,t,n){return{id:Q6(`dev`),capturedAt:Date.now(),raw:t,messageId:n,from:e.from,to:e.to,cc:e.cc,bcc:e.bcc,replyTo:e.replyTo,subject:e.subject,text:e.text,html:e.html,headers:{...e.headers},attachments:e.attachments.map(e=>({filename:e.filename,contentType:e.contentType,size:e.bytes.byteLength,contentId:e.contentId,disposition:e.disposition}))}}new TextEncoder,new TextDecoder(`utf-8`,{fatal:!0});var j8=new TextDecoder(`utf-8`,{fatal:!0,ignoreBOM:!1});async function M8(e,t,n){if(e<=0)throw n();let r;try{return await Promise.race([t(),new Promise((t,i)=>{r=setTimeout(()=>i(n()),e)})])}finally{r!==void 0&&clearTimeout(r)}}async function N8(e,t,n,{rejectEncoding:r=!1}={}){let i=e.headers.get(`content-length`);if(r&&e.headers.has(`content-encoding`)||i!==null&&(!/^\d+$/.test(i)||Number(i)>t))throw e.body?.cancel().catch(()=>{}),Error(`email response refused before reading`);let a=e.body?.getReader();if(!a)throw Error(`email response is empty`);let o=new Uint8Array(t),s=0;try{for(;;){let e=await n(()=>a.read());if(e.done)break;if(s+e.value.byteLength>t)throw Error(`email response too large`);o.set(e.value,s),s+=e.value.byteLength}}finally{a.cancel().catch(()=>{});try{a.releaseLock()}catch{}}if(i!==null&&s!==Number(i))throw Error(`email response length mismatch`);return JSON.parse(j8.decode(o.subarray(0,s)))}new TextEncoder;function P8(){try{return Pv()}catch{return}}function F8(e){let t=P8()?.[e];return typeof t==`string`&&t.length>0?t:void 0}var I8=/^[a-z0-9](?:[a-z0-9-]{0,54}[a-z0-9])?$/;function L8(){let e=F8(`__VOID_PROJECT_SLUG`);return e!==void 0&&I8.test(e)?e:void 0}function R8(e){return new ReadableStream({start(t){t.enqueue(e),t.close()}})}function z8(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function B8(e,t,n){return n===void 0?{code:e,message:t}:{code:e,message:t,cause:n}}var V8=`SEND_EMAIL`,H8=3e4,U8=6e4,W8=class extends Error{constructor(){super(`email binding outcome unknown after timeout`),this.name=`EmailBindingTimeoutError`}};function G8(e){let t=e?.[V8];if(typeof t==`object`&&t)return typeof t.send==`function`?t:void 0}function K8(e){let t=e instanceof Error?e.message:String(e);switch(typeof e?.code==`string`?e.code:``){case`E_RECIPIENT_NOT_ALLOWED`:return B8(`UNVERIFIED_DESTINATION`,t,e);case`E_SENDER_NOT_VERIFIED`:case`E_SENDER_DOMAIN_NOT_AVAILABLE`:return B8(`INVALID_FROM`,t,e);case`E_RATE_LIMIT_EXCEEDED`:case`E_DAILY_LIMIT_EXCEEDED`:return B8(`QUOTA_EXCEEDED`,t,e)}return q8.test(t)?B8(`UNVERIFIED_DESTINATION`,t,e):B8(`OUTCOME_UNKNOWN`,t,e)}var q8=/^[^\n]{0,200}destination address[^\n]{0,200}not (?:yet )?verified/i;async function J8(e,t,n,r,i){let a;try{({EmailMessage:a}=await import(`cloudflare:email`))}catch(e){return Z8(`UPSTREAM_ERROR`,`email: SEND_EMAIL is bound but cloudflare:email could not be loaded: ${e instanceof Error?e.message:String(e)}`,e)}let o=[],s=Date.now()+U8,c=()=>Math.min(H8,s-Date.now());for(let s=0;s<n.length;s++){let l=n[s];if(c()<=0){for(let e of n.slice(s))o.push({recipient:e,ok:!1,state:`cancelled`,error:B8(`UPSTREAM_ERROR`,`email: batch deadline elapsed before provider submission`)});break}try{let n=await M8(c(),()=>e.send(new a(t,l,R8(r))),()=>new W8),s=typeof n?.messageId==`string`?n.messageId:``;o.push({recipient:l,ok:!0,messageId:s||i})}catch(e){let t=e instanceof W8?B8(`OUTCOME_UNKNOWN`,`email: binding submission timed out; inspect provider logs before retrying`,e):K8(e);o.push({recipient:l,ok:!1,...t.code===`OUTCOME_UNKNOWN`?{state:`outcome_unknown`}:{},error:t})}}return o.some(e=>!e.ok)?{ok:!1,deliveries:o}:{ok:!0,ids:o.map(e=>({recipient:e.recipient,messageId:e.messageId}))}}function Y8(e){let t=new Set,n=[];for(let r of[...e.to,...e.cc,...e.bcc]){let e=r.email.toLowerCase();t.has(e)||(t.add(e),n.push(e))}return n}function X8(e){let t=e.from;if(!(t==null||typeof t==`string`&&t.trim()===``||typeof t==`object`&&t&&!(`email`in t)))return e;let n=F8(`__VOID_EMAIL_FROM`);if(n)return{...e,from:n};let r=L8(),i=F8(`__VOID_EMAIL_DOMAIN`);if(!r||!i){if(t===null){let t={...e};return delete t.from,t}return e}return{...e,from:`${r}+noreply@${i}`}}function Z8(e,t,n){return{ok:!1,error:B8(e,t,n)}}function Q8(e){return[`BINDING_MISSING`,`INVALID_FROM`,`INVALID_TO`,`UNVERIFIED_DESTINATION`,`MIME_ERROR`,`QUOTA_EXCEEDED`,`IDEMPOTENCY_CONFLICT`,`OUTCOME_UNKNOWN`,`UPSTREAM_ERROR`].find(t=>t===e)??`UPSTREAM_ERROR`}function $8(e){if(typeof e!=`object`||!e||Array.isArray(e))return null;let{error:t,message:n}=e;return typeof t!=`string`||t===``?null:typeof n==`string`&&n!==``?n:t}function e5(e){if(!z8(e))return null;let t=e.operationId;if(e.ok===!0&&Array.isArray(e.ids))return{ok:!0,ids:e.ids,operationId:t};if(e.ok!==!1)return null;if(Array.isArray(e.deliveries))return{ok:!1,deliveries:e.deliveries,operationId:t};let n=e.error;return typeof n==`object`&&n?{ok:!1,error:{code:`code`in n?n.code:void 0,message:`message`in n?n.message:void 0},operationId:t}:null}function t5(e,t,n,r){if(e.length!==t.length)return{ok:!1,reason:`expected ${t.length} deliveries, got ${e.length}`};let i=new Set(t),a=new Set,o=[];for(let[t,s]of e.entries()){let e=typeof s==`object`&&s?s:null,c=e?.recipient;if(e===null||typeof c!=`string`)return{ok:!1,reason:`entry ${t} is not ${n}`};let l=r(e,c);if(l===void 0)return{ok:!1,reason:`entry ${t} is not ${n}`};if(!i.has(c))return{ok:!1,reason:`entry ${t} names a recipient that was not requested`};if(a.has(c))return{ok:!1,reason:`entry ${t} repeats a recipient`};a.add(c),o.push(l)}return{ok:!0,entries:o}}function n5(e,t,n){return t5(e,t,`{ recipient: string, messageId: string }`,(e,t)=>typeof e.messageId==`string`?{recipient:t,messageId:e.messageId||n,...e.state===`provider_accepted`?{state:`provider_accepted`}:{}}:void 0)}function r5(e,t,n){return t5(e,t,`{ recipient: string, ok: true, messageId: string } | { recipient: string, ok: false, error: { message: string } }`,(e,t)=>{if(e.ok===!0)return typeof e.messageId==`string`?{recipient:t,ok:!0,messageId:e.messageId||n,...e.state===`provider_accepted`?{state:`provider_accepted`}:{}}:void 0;if(e.ok===!1){let n=i5(e.state),r=e.error;return typeof r==`object`&&r&&typeof r.message==`string`?{recipient:t,ok:!1,error:B8(Q8(r.code),r.message),...n?{state:n}:{}}:void 0}})}function i5(e){return[`rejected`,`reserved`,`attempt_started`,`provider_accepted`,`failed`,`outcome_unknown`,`cancelled`].find(t=>t===e)}var a5=65536;async function o5(e,t,n,r){let i;try{i=await N8(e,a5,r)}catch{return Z8(`OUTCOME_UNKNOWN`,`email: could not establish the send outcome (status ${e.status}); check email logs or repeat the same idempotency key`)}let a=e5(i);if(a===null){let t=$8(i);return!e.ok&&t!==null?Z8(`UPSTREAM_ERROR`,`email: proxy returned ${e.status}: ${t}`,i):Z8(`OUTCOME_UNKNOWN`,`email: proxy returned malformed response (status ${e.status})`,i)}let o=e=>Z8(`OUTCOME_UNKNOWN`,`email: proxy returned a malformed delivery list (${e}); do not retry with a new idempotency key`,i),s=typeof a.operationId==`string`&&a.operationId.length<=128?{operationId:a.operationId}:{};if(a.ok===!0){let e=n5(a.ids,t,n);return e.ok?{ok:!0,ids:e.entries,...s}:o(e.reason)}if(`deliveries`in a){let e=r5(a.deliveries,t,n);return e.ok?{ok:!1,deliveries:e.entries,...s}:o(e.reason)}let c=a.error;return{...Z8(Q8(c.code),typeof c.message==`string`?c.message:`email: upstream send failed`),...s}}function s5(e){let t=e?.[S8];if(typeof t!=`string`||t.length===0)return;let n=e?.[t];if(typeof n!=`object`||!n||typeof n.fetch!=`function`)return;let r=e?.[C8];return{fetcher:n,token:typeof r==`string`&&r.length>0?r:void 0}}var c5=5e3,l5=200,u5=1e3;async function d5(e){let t;try{let n=e.body?.getReader();if(!n)return``;let r=await Promise.race([n.read().then(({value:e})=>e),new Promise(e=>{t=setTimeout(()=>e(void 0),u5)})]);return n.cancel().catch(()=>{}),r?new TextDecoder().decode(r).trim().split(`
|
|
606
606
|
`)[0].slice(0,l5):``}catch{return``}finally{t!==void 0&&clearTimeout(t)}}async function f5(e,t){let n;try{let r=Promise.resolve(e.fetcher.fetch(`http://localhost${x8}`,{method:`POST`,headers:{"content-type":`application/json`,...e.token!==void 0&&{"x-void-dev-trigger":e.token}},body:w8(t)})).then(e=>({kind:`response`,res:e}),e=>({kind:`error`,cause:e})),i=await Promise.race([r,new Promise(e=>{n=setTimeout(()=>e({kind:`timeout`}),c5)})]);if(i.kind===`timeout`)return{ok:!1,reason:`no response within ${c5}ms`};if(i.kind===`error`){let e=i.cause;return{ok:!1,reason:e instanceof Error?e.message:String(e)}}let{res:a}=i;if(!a.ok){let e=await d5(a);return{ok:!1,reason:`dev server responded ${a.status}${e?`: ${e}`:``}`}}return a.headers.get(`x-void-email-inbox`)===`captured`?{ok:!0}:{ok:!1,reason:`response did not come from the dev inbox`}}catch(e){return{ok:!1,reason:e instanceof Error?e.message:String(e)}}finally{n!==void 0&&clearTimeout(n)}}function p5(e,t){return{ok:!0,ids:Y8(e).map(e=>({recipient:e,messageId:t}))}}async function m5(e){if(e.idempotencyKey!==void 0&&(typeof e.idempotencyKey!=`string`||!/^[\x21-\x7e]{1,128}$/.test(e.idempotencyKey)))return Z8(`MIME_ERROR`,`email: idempotencyKey must contain 1–128 printable non-space ASCII characters.`);let t=X8(e);if(t.from===void 0)return Z8(`INVALID_FROM`,`email: 'from' is required. Set it explicitly or deploy via Void so the platform-injected __VOID_PROJECT_SLUG and __VOID_EMAIL_DOMAIN can default it to <slug>+noreply@<domain>.`);let n=t,r,i,a;try{r=await L6(n),{raw:i,messageId:a}=b8(r)}catch(e){return e instanceof E6?Z8(e.code,e.message,e):Z8(`MIME_ERROR`,e instanceof Error?e.message:String(e),e)}let o=P8();if(!e.sendInDev&&k8()){let e=A8(r,i,a);return O8(e),p5(r,e.id)}let s=e.sendInDev?void 0:s5(o);if(s){let e=A8(r,i,a),t=await f5(s,e);if(t.ok)return p5(r,e.id);let n=`email: the void dev inbox at ${x8} is unreachable (${t.reason}), so nothing was captured and nothing was sent.`;return console.warn(`[void/email] ${n}`),Z8(`UPSTREAM_ERROR`,n)}let c=Y8(r),l=G8(o);if(l)return e.idempotencyKey===void 0?J8(l,r.from.email,c,i,a):Z8(`MIME_ERROR`,`email: idempotencyKey requires a Void platform; the native Cloudflare binding cannot deduplicate sends.`);let u=o,d=u?.__VOID_PROXY,f=u?.__PROJECT_ID,p=u?.__VOID_PROXY_TOKEN;if(!d||!f||!p)return Z8(`BINDING_MISSING`,"email: neither SEND_EMAIL nor __VOID_PROXY is available, so nothing was sent. Deploy via Void to bind the platform proxy, or set `email.from` in void.config.ts so `void deploy --platform cloudflare` provisions the SEND_EMAIL binding. Under `void dev` messages are captured by the local inbox at /__void/inbox instead — reaching this error there means that path was bypassed by the deprecated `sendInDev: true` (it never delivers) or unavailable (the worker has no assets binding to reach the dev server through).");let m={projectId:f,aiToken:p,from:r.from.email,recipients:c,mimeBase64:s6(i),requestId:Q6(`req`),...e.idempotencyKey===void 0?{}:{idempotencyKey:e.idempotencyKey}},h=JSON.stringify(m),g=new AbortController,_=Date.now()+U8,v=e=>M8(_-Date.now(),e,()=>(g.abort(),Error(`email platform send timed out`))),y;try{y=await v(()=>d.fetch(`https://email-proxy/email/send`,{method:`POST`,headers:{"content-type":`application/json`},body:h,signal:g.signal}))}catch(e){return Z8(`OUTCOME_UNKNOWN`,`email: send outcome is unknown: ${e instanceof Error?e.message:String(e)}. Check email logs or repeat the same idempotency key; do not create a new send.`,e)}return o5(y,c,a,v)}var h5=[`example.com`,`example.net`,`example.org`];function g5(e){let{domain:t,email:n}=e;return!t||!h5.some(e=>e===t)?!1:n.toLowerCase().endsWith(`@${t}`)}var _5=class extends Error{name=`Auth.UndeliverableError`},v5=aB(async(e,t)=>{e.set(`auth`,y5(e)),await t()});function y5(e){return o6(iB({accountStep:t=>e.var.accountChosen?Promise.resolve(!1):Z(e,H2(e,{clientId:t.clientId,cookie:t.headers.get(`cookie`),sessionId:t.sessionId,userId:t.userId}),`AccountStep.due`),baseURL:U.URL,cache:e.var.cache,db:P2,google:b5(),metadataFetch:xF(e.env.CLIENT_METADATA),pendingKey:t=>Z(e,w4($,t),`PendingKey.take`),secret:U.SECRET,sendCode:t=>x5(e,t),sessionCreated:t=>e.set(`newSession`,{session:{id:t.id},user:{id:t.userId}}),waitUntil:t=>e.executionCtx.waitUntil(t)}))}function b5(){let{GOOGLE_CLIENT_ID:e,GOOGLE_CLIENT_SECRET:t}=U;if(e&&t)return{clientId:e,clientSecret:t}}async function x5(e,t){let n=LF({code:t.code}),r=e.env.TEST_INBOX;if(r&&g5({domain:U.TEST_EMAIL_DOMAIN,email:t.email})){await Z(e,r.capture({subject:n.subject,text:n.text,to:[{email:t.email}]}),`inbox.capture`);return}let i=await Z(e,m5({attachments:[n.logo],html:n.html,subject:n.subject,text:n.text,to:t.email}),`email.send`);if(i.ok)return;let a=`error`in i?i.error.code:void 0;throw a===`QUOTA_EXCEEDED`?new aI:a===`UNVERIFIED_DESTINATION`?new _5(`The email service does not deliver to the address.`):Error(`Sending the sign-in code failed: ${a??`delivery`}.`)}(function(e){e.errors=[aI]})(x5||={});async function S5(e,t){let{clientId:n,userId:r}=t;if(!q4(e))try{let[t]=await Z(e,$.select({held:q`exists (${$.select({realmId:CP.realmId}).from(CP).where(Y(CP.userId,r))}) or exists (${$.select({id:wP.id}).from(wP).where(cM(Y(wP.userId,r),vM(wP.address)))})`}).from(q`(values (1)) as one`),`db.account.held`);if(t?.held||!(await Z(e,e.env.ACCOUNT_LIMIT.limit({key:r}),`ratelimit.limit`)).success)return;let i=await Z(e,IH(e,{clientId:n??void 0,db:$,own:new URL(U.URL).origin}),`Realm.forRequest`),a=await Z(e,BH(e,{db:$,origin:U.URL,realms:i}),`Realm.withDefaults`);await Z(e,$1(e,{db:$,env:U,realms:a,userId:r}),`TempoAccount.create`)}catch(t){qF(e,{error:t,fields:{clientId:n??void 0},message:`The sign-in created no first account, since its creation failed.`})}}var C5=`tempo-id-passkey-link`,w5=`host`;async function T5(e,t){let n=TB(e,C5,w5);if(!n)return;let r=await Z(e,Xz(n,{host:new URL(e.req.url).host,secret:U.SECRET}),`Passkey.unseal`);if(!r)return;let[i,a]=await Z(e,Promise.all([r.nonce,t.nonce].map(e=>crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(e)))),`crypto.digest`);return crypto.subtle.timingSafeEqual(i,a)?r:void 0}async function E5(e,t){let n=Ne(crypto.getRandomValues(new Uint8Array(32)),{pad:!1,url:!0});return OB(e,C5,await Z(e,Bz({address:t.credential.address,createdAt:t.credential.createdAt,expiresAt:Math.floor(Date.now()/1e3)+300,host:new URL(e.req.url).host,id:t.id,nonce:n,publicKey:t.credential.publicKey,rpId:t.rpId},{secret:U.SECRET}),`Passkey.seal`),{httpOnly:!0,maxAge:300,path:`/`,prefix:w5,sameSite:`Lax`,secure:!0}),n}async function D5(e){let t=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(e.nonce));return Zt(new Uint8Array(t))}async function O5(e){if(!e.expected)return!1;let t=await D5({nonce:e.nonce});return t.length===e.expected.length&&crypto.subtle.timingSafeEqual(Rt(t).buffer,Rt(e.expected).buffer)}function k5(e){kB(e,C5,{path:`/`,prefix:w5,secure:!0})}var A5=/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/,j5;(function(e){let t;(function(e){e.json=z({email:R().trim().toLowerCase().pipe(kn({abort:!0}).max(254,{abort:!0,error:`Invalid email address`}).refine(e=>{let[t=``,n=``]=e.split(`@`);return t.length<=64&&n.split(`.`).every(e=>A5.test(e))},`Invalid email address`)).meta({description:`The user's email address.`,examples:[`ada@example.com`]})}),e.response=z({sent:xn(!0).meta({description:`The request is accepted. The value is the same for every address.`})})})(t||=e.code||={});let n;(function(e){e.json=z({assertion:Cz.assertion.optional().meta({description:"The assertion of the email step's passkey, over a challenge from `POST /v1/auth/passkey/options` with `link`. Required with `link`, since only the person who holds the passkey can link it."}),code:R().trim().regex(/^\d{6}$/).meta({description:`The six-digit emailed code.`,examples:[`123456`]}),email:t.json.shape.email,link:R().max(64).optional().meta({description:"The email step's `link`, which links the wallet.tempo passkey that asked for it to this user, with that passkey's `assertion`. An expired link refuses the sign-in with `passkey_link_expired`, and the code stays valid.",examples:[`dGhlIG5vbmNlIHRoYXQgdGhlIHN0ZXAgY2Fycmllcw`]}),oauth_query:R().max(8192).optional().meta({description:`The sign-in page's query string when an app's authorization request sent the browser there, which the sign-in continues. Better Auth signs it. At most 8,192 characters.`,examples:[`client_id=client_01JZ8Q6W3N1R5B4V7C2X9K0M3T&response_type=code&exp=1760000000&sig=Gx3kB0`]})}).refine(e=>!e.link||e.assertion,{message:"Required with `link`.",path:[`assertion`]});let n=e.user=z({email:kn().meta({description:`The user's email address.`,examples:[`ada@example.com`]}),id:R().meta({description:"The user's ID, which is the `sub` of every token Tempo ID issues for the user.",examples:[`user_01JZ8Q6W3N1R5B4V7C2X9K0M3T`]})}).meta({description:`The signed-in user.`,id:`User`});e.response=z({authorization:wR.response.optional().meta({description:"The app's headless authorization, for a one-tap sign-in on the app's page whose options carried `authorize`. Absent for any other sign-in."}),redirect:Dn().nullable().meta({description:"Where the browser continues: the app's `redirect_uri` with an authorization code, or `null` for a sign-in that no app waits on.",examples:[`https://app.example.com/callback?code=SplxlOBeZQQYbYS6WxSbIA`]}),user:n}),e.signedIn=_n([z({url:R()}),z({user:z({email:R(),id:R()})})])})(n||=e.verify||={});let r;(function(e){e.json=z({authorize:wR.request.optional().meta({description:"The app's headless authorization request, as `POST /v1/authorize` takes it, from a first-party app's page. The challenge is then the digest of its key, so the passkey's one assertion signs the user in and signs the key, and `POST /v1/auth/passkey/verify` returns the authorization. Requires `client_id`, the same as its own."}),client_id:R().min(1).max(64).optional().meta({description:"The client ID of the first-party app whose page runs the ceremony. It selects the app's realms, and the request's `Origin` must be the origin of one of the app's redirect URIs. Required from an app's page.",examples:[`client_01JZ8Q6W3N1R5B4V7C2X9K0M3T`]}),credentialId:_n([Cz.credentialId,Mn(Cz.credentialId).max(16)]).optional().meta({description:"The credential ID, or up to 16 IDs, that the browser offers as `allowCredentials`, base64url. Defaults to every discoverable passkey of the relying party, as an empty list does.",examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),link:n.json.shape.link.meta({description:"The email step's `link`. The options then name only that step's passkey, at its relying party, in place of `credentialId`. The emailed-code sign-in sends the passkey's assertion with the `link`.",examples:[`dGhlIG5vbmNlIHRoYXQgdGhlIHN0ZXAgY2Fycmllcw`]}),mediation:Sn([`conditional`,`optional`,`required`,`silent`]).optional().meta({description:"Returned in the options for `navigator.credentials.get()`, such as `conditional` for passkey autofill.",examples:[`conditional`]}),oauth_query:n.json.shape.oauth_query,user_code:R().max(32).optional().meta({description:"The user code of the device grant that the sign-in returns to. While the code is pending and bound to no user, it selects the realms of the app that requested it. Any other code selects the `default` realm. Ignored with `oauth_query` or `client_id`.",examples:[`WDJB-MJHT`]})}).refine(e=>!e.authorize||e.authorize.client_id===e.client_id,{message:"Requires the same `client_id`.",path:[`authorize`]}),e.sent=z({authorize:Pn({key_authorization:Pn({}).optional()})}),e.response=z({options:z({mediation:r.json.shape.mediation,publicKey:z({allowCredentials:Mn(z({id:R().meta({description:`A credential ID, base64url.`,examples:[`KEbWNCc7NgaYnUyrNeFGX9_3Y-8`]}),type:xn(`public-key`).meta({description:`The credential type.`})}).meta({description:`A passkey the browser offers.`})).optional().meta({description:"The passkeys the browser offers, from `credentialId`. Absent, it offers every discoverable passkey of the relying party."}),challenge:vn([`0x`,R()]).meta({description:`The single-use challenge, as hex. It expires after 5 minutes.`,examples:[`0xf6310589abb21116acc6e123967ed0a125b5041c43f8e157237093e07eaa354c`]}),rpId:R().meta({description:`The relying party ID of the passkeys.`,examples:[`tempo.xyz`]}),userVerification:xn(`required`).meta({description:`Every passkey sign-in requires user verification.`})}).meta({description:"The `PublicKeyCredentialRequestOptions`, serialized with the challenge as hex."})}).meta({description:"The options for `navigator.credentials.get()`."})})})(r||=e.passkeyOptions||={});let i;(function(e){e.json=z({assertion:Cz.assertion,oauth_query:n.json.shape.oauth_query}),e.response=_n([n.response.meta({description:`The signed-in user.`}),z({step:z({link:R().meta({description:"Send as `link` with the emailed-code sign-in, which links the passkey to that user.",examples:[`dGhlIG5vbmNlIHRoYXQgdGhlIHN0ZXAgY2Fycmllcw`]}),signed:xn(!1).meta({description:`Whether the assertion already signed a key authorization. This route signs none.`}),type:xn(`email`).meta({description:`Sign in with an emailed code, which links the passkey to that user.`})}).meta({description:`The email step, for a wallet.tempo passkey whose account has no email.`})}).meta({description:`A passkey sign-in that continues when the user verifies an email address.`})])})(i||=e.passkeyVerify||={});let a;(function(e){e.response=z({signed_out:xn(!0).meta({description:`The session is over, or there was none.`})})})(a||=e.logout||={});let o;(function(e){e.response=z({user:n.user.extend({name:R().nullable().meta({description:"The user's name, or `null` for a user who signed up without one.",examples:[`Ada Lovelace`]})}).nullable().meta({description:"The signed-in user, or `null` without a session.",id:`SessionUser`})})})(o||=e.session||={});let s;(function(e){e.query=z({oauth_query:n.json.shape.oauth_query,return_to:R().max(2048).optional().meta({description:`The page that sign-in returns to, from the sign-in page's query. Only a path on the device page passes, and any other value reads as absent.`,examples:[`/device?code=WDJB-MJHT`]})}),e.response=z({google:On().meta({description:`Whether Tempo ID offers Google sign-in, which the deployment configures.`,examples:[!0]}),passkeys:On().meta({description:"Whether Tempo ID offers passkey sign-in: one of the realms of the app that `oauth_query` or the device code of `return_to` names, or the `default` realm without one, holds passkeys that sign in at Tempo ID's origin.",examples:[!0]}),app:R().nullable().meta({description:"The display name of the app of the signed authorization request in `oauth_query`, or its client ID without one, or `null` for a forged or expired query, or an unknown app.",examples:[`Tempo Cash`]}),request:z({app:R().meta({description:`The app's display name, or its client ID without one.`,examples:[`Tempo Cash`]}),key:XL.description}).nullable().meta({description:"The app and the key of the signed authorization request in `oauth_query`, which the sign-in grants, or `null` for a forged or expired query, an unknown app, a request without a key, a key with a `challenge`, or a third-party app, whose key the approval page shows instead."}),return_to:R().nullable().meta({description:"The page that sign-in returns to, a path on the device page, or `null` for the account.",examples:[`/device?code=WDJB-MJHT`]}),user_code:R().nullable().meta({description:"The user code of the device page that sign-in returns to, or `null` without one.",examples:[`WDJBMJHT`]}),verified:On().meta({description:"Whether `app` is a registered app, whose name the page marks as verified. `false` for a third-party app, which names itself in its metadata document, and without an app.",examples:[!0]})})})(s||=e.methods||={})})(j5||={});var M5=new Iy().post(`/v1/auth/code`,vV({description:`Emails a sign-in code. The response is the same for every address, so it reveals no account.`,responses:DV({errors:[...yB,...x5.errors,...OV.errors,...LV.errors,rI,cI],success:{description:`The response for every address: the email service accepted the code, or does not deliver to the address.`,schema:j5.code.response}}),tags:[`Authenticate`]}),OV(`json`,j5.code.json),async e=>{let{email:t}=e.req.valid(`json`),n=await Z(e,LV(e,{limits:[{binding:`SIGN_IN_IP_LIMIT`,key:HV(e)},{binding:`SIGN_IN_CODE_LIMIT`,key:BV({email:t})}]}),`RateLimit.check`);if(n)return n;if(!await Z(e,RV($,{email:t}),`RateLimit.countCode`))return zV(e,{policy:FV}),WV(e,{policy:FV,retryAfter:FV.window});let r=await Z(e,e.var.auth.api.createVerificationOTP({body:{email:t,type:`sign-in`}}),`auth.createVerificationOTP`),i=await Z(e,x5(e,{code:r,email:t.toLowerCase()}),`Auth.sendCode`).catch(e=>e);return i&&(qF(e,{error:i,message:`The email service refused a sign-in code.`}),!(i instanceof _5))?X(e,i instanceof aI?i:new cI):e.json({sent:!0},200)}).post(`/v1/auth/code/verify`,vV({description:"Signs in with an emailed code, and sets the session cookie. For a user with no Tempo Account in the realm of the sign-in, the first realm of the app that `oauth_query` names or the `default` realm, it creates one when the realm creates accounts. A failed creation leaves the sign-in signed in, and the next sign-in or `POST /v1/account` creates the account.",responses:DV({errors:[...yB,...X4.errors,...OV.errors,...H4.errors,...LV.errors,$z,eB,fz,hz],success:{description:`The signed-in user.`,schema:j5.verify.response}}),tags:[`Authenticate`]}),OV(`json`,j5.verify.json),async e=>{let{assertion:t,code:n,email:r,link:i,oauth_query:a}=e.req.valid(`json`),o=X4(e,{oauth_query:a});if(o)return X(e,o);let s=await Z(e,LV(e,{limits:[{binding:`SIGN_IN_IP_LIMIT`,key:HV(e)}]}),`RateLimit.check`);if(s)return s;let c=i?await Z(e,T5(e,{nonce:i}),`PasskeyLink.claim`):void 0;if(i&&!c)return X(e,new fz);let l=c&&t?await Z(e,Vz($,{clientDataJSON:t.metadata.clientDataJSON}),`Passkey.take`):void 0;if(c){let n=l&&i?await Z(e,O5({expected:l.link,nonce:i}),`PasskeyLink.matches`):!1;if(!t||!l||!n||l.clientId!==N5({oauth_query:a})||l.origin!==q4(e)||l.rpId!==c.rpId||t.id!==c.id||!Zz(t,{challenge:l.challenge,origin:l.origin??new URL(U.URL).origin,publicKey:c.publicKey,rpId:c.rpId})||!await Z(e,U4(e,{assertion:t,challenge:l}),`Headless.spend`))return X(e,new hz)}let u=await Z(e,e.var.auth.api.signInEmailOTP({asResponse:!1,body:{email:r,otp:n,...a?{oauth_query:a}:{}},headers:new Headers(e.req.raw.headers),request:e.req.raw,returnHeaders:!0}),`auth.signInEmailOTP`).catch(e=>{if(fi(e)&&e.body?.error===`invalid_signature`)return new $z;if(fi(e))return new eB;throw e});if(u instanceof tI)return X(e,u);for(let t of u.headers.getSetCookie())e.header(`set-cookie`,t,{append:!0});e.header(`cache-control`,`private, no-store`);let d=j5.verify.signedIn.parse(u.response),f=(()=>{if(`user`in d)return{email:d.user.email,id:d.user.id};let t=e.var.newSession?.user.id;if(!t)throw Error(`The signed-in user is missing.`);return{email:r,id:t}})();if(c&&await Z(e,Oz($,{credential:c,id:c.id,rpId:c.rpId,userId:f.id}),`Passkey.link`)===f.id&&k5(e),await Z(e,S5(e,{clientId:N5({oauth_query:a}),userId:f.id}),`FirstAccount.create`),l?.authorize!==void 0&&t){e.header(L4,`true`);let n=await Z(e,H4(e,{assertion:t,challenge:l,setCookie:u.headers.getSetCookie()}),`Headless.oneTap`);return n instanceof Response?n:n instanceof tI?X(e,n):e.json({authorization:n,redirect:null,user:f},200)}let p=`user`in d?null:await Z(e,j4(e,{redirect:d.url,setCookie:u.headers.getSetCookie()}),`SignInConsent.afterSignIn`);return e.json({redirect:p,user:f},200)}).post(`/v1/auth/passkey/options`,vV({description:"Issues a single-use challenge, and returns request options for the passkeys of the relying party that the sign-in reaches. Without `oauth_query` or `client_id`, that is the relying party of the `default` realm. With either, it is the first of the app's realms that holds passkeys. From a first-party app's page, with `client_id`, the relying party must cover the page's origin and Tempo ID's, and only that page's assertion spends the challenge. With `link`, the options name only the email step's passkey.",responses:DV({errors:[...yB,...X4.errors,...OV.errors,...TR.errors,...Tz.errors,...LV.errors,fz,pz],success:{description:`The request options.`,schema:j5.passkeyOptions.response}}),tags:[`Authenticate`]}),OV(`json`,j5.passkeyOptions.json),async e=>{let{authorize:t,client_id:n,credentialId:r,link:i,mediation:a,oauth_query:o,user_code:s}=e.req.valid(`json`),c=X4(e,{oauth_query:o});if(c)return X(e,c);let l=HV(e),u=await Z(e,LV(e,{limits:[{binding:`SIGN_IN_IP_LIMIT`,key:l?`passkey-options:${l}`:void 0}]}),`RateLimit.check`);if(u)return u;let d=i?await Z(e,T5(e,{nonce:i}),`PasskeyLink.claim`):void 0;if(i&&!d)return X(e,new fz);let f=q4(e),p=n?await Z(e,B4(e,{clientId:n}),`Headless.app`):void 0;if(f||n){let t=Tz({app:p,clientId:n,origin:e.req.header(`origin`)});if(t)return X(e,t)}let m=N5({oauth_query:o}),h=s?XR(s):void 0,g=!m&&!n&&h?await Z(e,HR($,{userCode:h}),`Device.client`):void 0,_=m??n??g,v=_?await Z(e,CB(e,()=>FH($,{clientId:_}),[`realm.forApp`,_]),`Realm.forApp`):[await Z(e,CB(e,()=>RH($,{id:NH}),[`realm.get`,NH]),`Realm.get`)],y=Fz(await Z(e,BH(e,{db:$,origin:U.URL,realms:v}),`Realm.withDefaults`),{origin:U.URL,page:f}),b=d&&(y?.realmId!=="default"||y.rpId!==d.rpId);if(!y||b)return X(e,new pz({clientId:(m??n)||void 0,origin:f}));let x=i?await Z(e,D5({nonce:i}),`PasskeyLink.digest`):void 0,S=t&&(f?TR(t,{app:p,origin:e.req.header(`origin`)}):new SR({error_description:"Invalid `Origin`: none. A one-tap sign-in with `authorize` runs only on the app's page.",field:`Origin`}));if(S)return X(e,S);let C=await Z(e,wz($,{authorize:await(async()=>{if(!t)return;let n=j5.passkeyOptions.sent.parse(await e.req.json()),r=t.key_authorization;return r?{...n.authorize,key_authorization:{...n.authorize.key_authorization,expiry:r.expiry}}:n.authorize})(),clientId:m,link:x,oneTap:await(async()=>{if(f){let e=t?.key_authorization;if(!e)return;let n=e.witness??Zt(crypto.getRandomValues(new Uint8Array(32)));return{digest:uR({key:e,witness:n}),witness:n}}if(o&&!i)return await Z(e,M4(e,{oauthQuery:o}),`SignInConsent.oneTap`)})(),origin:f,...y}),`Passkey.challenge`);if(!C)return X(e,new hz);let w=d?[d.id]:r===void 0?[]:[r].flat(),E=j5.passkeyOptions.response.shape.options.parse({...wS({challenge:C,...w.length>0?{credentialId:w}:{},rpId:y.rpId,userVerification:`required`}).options,...a?{mediation:a}:{}});return e.header(`cache-control`,`private, no-store`),e.json({options:E},200)}).post(`/v1/auth/passkey/verify`,vV({description:"Signs in with a passkey assertion over a challenge from the options, sent from the page that requested them, and sets the session cookie. For a user with no Tempo Account in the realm of the sign-in, the first realm of the app that `oauth_query` names or the `default` realm, it creates one when the realm creates accounts. A failed creation leaves the sign-in signed in, and the next sign-in or `POST /v1/account` creates the account.",responses:DV({errors:[...yB,...X4.errors,...OV.errors,...dI.errors,...H4.errors,...LV.errors,$z,hz],success:{description:`The signed-in user, with the authorization of a one-tap sign-in on an app's page, or the email step for a wallet.tempo passkey without an email.`,schema:j5.passkeyVerify.response}}),tags:[`Authenticate`]}),OV(`json`,j5.passkeyVerify.json),async e=>{let{assertion:t,oauth_query:n}=e.req.valid(`json`),r=X4(e,{oauth_query:n});if(r)return X(e,r);let i=await Z(e,LV(e,{limits:[{binding:`SIGN_IN_IP_LIMIT`,key:HV(e)}]}),`RateLimit.check`);if(i)return i;let{id:a}=t,o=await Z(e,Uz($,{clientDataJSON:t.metadata.clientDataJSON,id:a}),`Passkey.takeWithKey`),s=o?.challenge;if(!s||s.link!==void 0||s.clientId!==N5({oauth_query:n})||s.origin!==q4(e))return X(e,new hz);let c=o.key,l=await(async()=>{if(!c&&e.env.WALLET&&s.realmId==="default")try{return await Z(e,o0(e.env.WALLET,{id:a}),`Wallet.credential`)}catch(t){return qF(e,{error:t,message:`The wallet service failed a passkey lookup.`}),t instanceof Error&&dI(t)||new cI}})();if(l instanceof tI)return X(e,l);let u=c?.publicKey??l?.publicKey;if(!u||!Zz(t,{challenge:s.challenge,origin:s.origin??new URL(U.URL).origin,publicKey:u,rpId:s.rpId})||!await Z(e,U4(e,{assertion:t,challenge:s}),`Headless.spend`))return X(e,new hz);if(l&&!l.email){let t=await Z(e,E5(e,{credential:l,id:a,rpId:s.rpId}),`PasskeyLink.defer`);return e.header(`cache-control`,`private, no-store`),e.json({step:{link:t,signed:!1,type:`email`}},200)}let d=await(async()=>{if(c)return{user:c.user,userId:c.userId};let t=await Z(e,P5(e,{email:l.email}),`authenticate.emailUser`),n=await Z(e,Oz($,{credential:l,id:a,rpId:s.rpId,userId:t.id}),`Passkey.link`);return n?{user:n===t.id?t:void 0,userId:n}:void 0})();if(!d)return X(e,new hz);let{userId:f}=d,p=await Z(e,e.var.auth.api.signInPasskey({asResponse:!1,body:{userId:f,...c?{user:c.user}:{},...n?{oauth_query:n}:{}},headers:new Headers(e.req.raw.headers),request:e.req.raw,returnHeaders:!0}),`auth.signInPasskey`).catch(e=>{if(fi(e)&&e.body?.error===`invalid_signature`)return new $z;throw e});if(p instanceof tI)return X(e,p);for(let t of p.headers.getSetCookie())e.header(`set-cookie`,t,{append:!0});e.header(`cache-control`,`private, no-store`);let m=j5.verify.signedIn.parse(p.response);if(await Z(e,S5(e,{clientId:N5({oauth_query:n}),userId:f}),`FirstAccount.create`),`user`in m){let n={email:m.user.email,id:m.user.id};if(s.authorize===void 0)return e.json({redirect:null,user:n},200);e.header(L4,`true`);let r=await Z(e,H4(e,{assertion:t,challenge:s,setCookie:p.headers.getSetCookie()}),`Headless.oneTap`);return r instanceof Response?r:r instanceof tI?X(e,r):e.json({authorization:r,redirect:null,user:n},200)}let h=await(async()=>{if(d.user)return{email:d.user.email,id:d.user.id};let[t]=await Z(e,$.select({email:_P.email,id:_P.id}).from(_P).where(Y(_P.id,f)),`db.user.get`);return t})();if(!h)throw Error(`The signed-in user is missing.`);let g=await Z(e,j4(e,{oneTap:s.witness?{assertion:t,witness:s.witness}:void 0,redirect:m.url,setCookie:p.headers.getSetCookie()}),`SignInConsent.afterSignIn`);return e.json({redirect:g,user:h},200)}).post(`/v1/auth/logout`,vV({description:`Signs out: ends the session, revokes the access and refresh tokens that apps received through it, and clears its cookie.`,responses:DV({errors:[...yB,rI],success:{description:`The session is over.`,schema:j5.logout.response}}),tags:[`Authenticate`]}),async e=>{let t=await Z(e,$4(e),`Session.token`);return t&&await Z(e,d3($,{token:t}),`Logout.end`),await Z(e,Z4(e),`Session.clear`),e.header(`set-cookie`,z2(),{append:!0}),e.header(`cache-control`,`private, no-store`),e.json({signed_out:!0},200)}).get(`/v1/auth/session`,vV({description:"Reads the signed-in user, or `null` without a session.",responses:DV({success:{description:`The session.`,schema:j5.session.response}}),tags:[`Authenticate`]}),async e=>{let t=await Z(e,Q4(e),`Session.get`);return e.header(`cache-control`,`private, no-store`),t?e.json({user:{email:t.user.email,id:t.user.id,name:t.user.name||null}},200):e.json({user:null},200)}).get(`/v1/auth/methods`,vV({description:"Reads the sign-in methods that the sign-in page offers, the key that a signed authorization request in `oauth_query` grants, and the page that sign-in returns to. A device code in `return_to` names the app that requested it, while the code is pending and bound to no user. The read binds nothing, and counts against the IP address's sign-in limit. Without `oauth_query`, a client ID reads the `default` realm, as the other sign-in routes do.",responses:DV({errors:[...OV.errors],success:{description:`The sign-in methods.`,schema:j5.methods.response}}),tags:[`Authenticate`]}),OV(`query`,j5.methods.query),async e=>{let t=e.req.valid(`query`),n=QR(t.return_to,{origin:U.URL}),r=(()=>{if(!t.oauth_query)return;let e=new URLSearchParams(t.oauth_query);return e.delete(`error`),e.has(`sig`)?e:void 0})(),i=n?XR(new URL(n,U.URL).searchParams.get(`code`)??``):void 0,a=await(async()=>{if(r)return r.get(`client_id`)??void 0;if(!i)return;let t=HV(e);if(t&&(await Z(e,e.env.SIGN_IN_IP_LIMIT.limit({key:`device-lookup:${t}`}),`ratelimit.limit`)).success)return await Z(e,HR($,{userCode:i}),`Device.client`)})(),o=a?await Z(e,CB(e,()=>FH($,{clientId:a}),[`realm.forApp`,a]),`Realm.forApp`):[await Z(e,CB(e,()=>RH($,{id:NH}),[`realm.get`,NH]),`Realm.get`)],s=await Z(e,BH(e,{db:$,origin:U.URL,realms:o}),`Realm.withDefaults`),c=r?await Z(e,F5(e,{query:r}),`authenticate.granted`):null;return e.json({app:c?.app??null,google:!!b5(),passkeys:!!Fz(s,{origin:U.URL}),request:c?.key?{app:c.app,key:c.key}:null,return_to:n??null,user_code:i||null,verified:c?.verified??!1},200)});function N5(e){return e.oauth_query?new URLSearchParams(e.oauth_query).get(`client_id`):null}async function P5(e,t){let n=t.email.trim().toLowerCase(),r=await Z(e,e.var.auth.$context,`auth.context`),i=await Z(e,r.internalAdapter.findUserByEmail(n),`db.user.findByEmail`);if(i)return{email:i.user.email,id:i.user.id};try{let t=await Z(e,r.internalAdapter.createUser({email:n,emailVerified:!0,name:``},{method:`passkey`}),`db.user.create`);return{email:t.email,id:t.id}}catch(t){let i=await Z(e,r.internalAdapter.findUserByEmail(n),`db.user.findByEmail`);if(i)return{email:i.user.email,id:i.user.id};throw t}}async function F5(e,t){let{query:n}=t,r=await Z(e,e.var.auth.$context,`auth.context`),i=await Z(e,na(n.toString(),r.secret),`auth.verifyOAuthQueryParams`),a=n.get(`client_id`);if(!i||!a)return null;let o=await Z(e,CB(e,async()=>{let e=await CF($,{clientId:a}).catch(e=>{if(!(e instanceof gF))throw e});return e?{name:e.name}:void 0},[`apps.name`,a],{keep:e=>e!==void 0}),`Apps.get`);if(!o)return null;let s=OF(a),c=n.has(`challenge`)||s?void 0:DR(n);return{app:o.name??a,key:c&&!(c instanceof tI)?lR(c):null,verified:!s}}var I5;(function(e){let t;(function(e){e.json=wR.request,e.response=wR.response})(t||=e.authorize||={});let n;(function(e){e.json=z({account:Q1.tempoAccount.shape.address.meta({description:`The address of the account that the user selects, one of the user's accounts in the app's realms.`,examples:[`0x8C3b5d0e2A4f6B1c9D7e3F5a0B2c4D6e8F1a3B5c`]}),oauth_query:R().min(1).max(8192).meta({description:`The account step's query string, which Better Auth signs when it sends the browser there. At most 8,192 characters.`,examples:[`client_id=Qk3vT9xZbLmN2pRw8YcHjF6sDaE4uGtK&response_type=code&exp=1760000000&sig=Gx3kB0`]}),passkey:z({assertion:Cz.assertion}).optional().meta({description:`The passkey's assertion over the options of the passkey step, which the selection of a passkey-owned account returns. The repeated selection signs the key with it.`})}),e.response=_n([z({redirect:R().meta({description:"Where the browser continues: the approval page's path on Tempo ID, or the app's `redirect_uri` with an authorization code and `state`.",examples:[`https://app.example.com/callback?code=Vb7mQ2xLkP9sTzR4&state=af0ifjsldkj`]})}).meta({description:`A selection that continues the authorization.`}),Cz.step]),e.result=z({url:R().min(1)})})(n||=e.account||={});let r;(function(e){e.json=z({accept:On().meta({description:"Whether the user approves the request. `false` denies it, and the app receives `access_denied`.",examples:[!0]}),account:Q1.tempoAccount.shape.address.optional().meta({description:`The Tempo Account that the approval page showed for the request's key authorization, one of the user's accounts in the app's realms. Ignored when the key names its account, and absent for a request without a key.`,examples:[`0x8C3b5d0e2A4f6B1c9D7e3F5a0B2c4D6e8F1a3B5c`]}),oauth_query:R().min(1).max(8192).meta({description:`The approval page's query string, which Better Auth signs when it sends the browser there. At most 8,192 characters.`,examples:[`client_id=Qk3vT9xZbLmN2pRw8YcHjF6sDaE4uGtK&response_type=code&exp=1760000000&sig=Gx3kB0`]}),passkey:z({assertion:Cz.assertion}).optional().meta({description:`The passkey's assertion over the options of the passkey step, which a passkey-owned account's approval returns. The repeated approval signs the key with it.`}),session_id:R().min(1).max(256).meta({description:`The ID of the session that the approval page showed. The decision applies only while that session is the signed-in one.`,examples:[`8nVq3kZ0bT5wXy2mLp7sR4dA`]})});let t=e.step=Cz.step;e.response=_n([z({redirect:Dn().meta({description:"The app's `redirect_uri`, with an authorization code and `state`, or with `error=access_denied` when the user denied the request.",examples:[`https://app.example.com/callback?code=Vb7mQ2xLkP9sTzR4&state=af0ifjsldkj`]})}).meta({description:`A decision that returns to the app.`}),t])})(r||=e.consent||={});let i;(function(e){e.query=z({oauth_query:R().min(1).max(8192).meta({description:`The approval page's query string, which Better Auth signs when it sends the browser there. At most 8,192 characters.`,examples:[`client_id=Qk3vT9xZbLmN2pRw8YcHjF6sDaE4uGtK&response_type=code&exp=1760000000&sig=Gx3kB0`]})}),e.response=_n([z({redirect:Dn().meta({description:"The app's `redirect_uri`, with the refusal of the request's key as `error` and `error_description`, `state`, and `iss`.",examples:[`https://app.example.com/callback?error=invalid_request&state=af0ifjsldkj`]})}).meta({description:`A key that Tempo ID refuses, which returns the browser to the app.`}),z({request:z({account:z({address:Q1.tempoAccount.shape.address.meta({description:`The account address.`,examples:[`0x8C3b5d0e2A4f6B1c9D7e3F5a0B2c4D6e8F1a3B5c`]}),owner:Q1.tempoAccount.shape.config.shape.owners.unwrap().element.shape.type}).optional().meta({description:`The Tempo Account that the approval applies to: the account that the key names, else the app's selected account, else the user's oldest. Present only when the user holds more than one account in the app's realms.`}),app:R().meta({description:`The app's display name, or the host of its redirect URI without one.`,examples:[`Tempo Cash`]}),destination:R().meta({description:`The host of the app's redirect URI, or its scheme for a native app. For a third-party app, the host that serves its metadata document.`,examples:[`cash.tempo.xyz`]}),email:kn().meta({description:`The signed-in user's email address.`,examples:[`ada@example.com`]}),key:XL.description.extend({challenge:R().optional().meta({description:`The message that the key's witness binds, such as a sign-in challenge from the app. Absent when the request carries none.`,examples:[`Sign in to app.example.com
|
|
607
|
-
Nonce: 7f3a9c2e5b1d4f60`]}),refusal:s4.refusal.optional()}).optional().meta({description:`What the key that the request carries may do, and the account that approval signs for. Absent for a request without a key.`}),session:R().meta({description:"The ID of the signed-in session, which `POST /v1/authorize/consent` names.",examples:[`8nVq3kZ0bT5wXy2mLp7sR4dA`]}),verified:On().meta({description:`Whether the app is a registered app, whose name the page marks as verified. A third-party app names itself in its metadata document.`,examples:[!0]})}).nullable().meta({description:"The request that the approval page shows, or `null` for a forged or expired query, or a request without a known app."})}).meta({description:`The request that the approval page shows.`})])})(i||=e.request||={});let a;(function(e){e.query=i.query,e.response=z({request:z({accounts:Mn(z({address:Q1.tempoAccount.shape.address.meta({description:`The account address.`,examples:[`0x8C3b5d0e2A4f6B1c9D7e3F5a0B2c4D6e8F1a3B5c`]}),balance:fB.balance.nullable().meta({description:"The account's holdings of USD tokens on the chain of the request's key, or of Tempo mainnet without one. `null` when the read fails or takes longer than 3 seconds."}),owner:Q1.tempoAccount.shape.config.shape.owners.unwrap().element.shape.type,realm:R().nullable().meta({description:"The name of the account's realm, or `null` for the `default` realm.",examples:[`Tempo Cash`]})})).readonly().meta({description:`The user's accounts in the app's realms, oldest first.`}),app:R().meta({description:`The app's display name.`,examples:[`Tempo Cash`]})}).nullable().meta({description:"The account step, or `null` for a forged or expired query, or a request without a known app."})})})(a||=e.accounts||={})})(I5||={});var L5=new Iy().post(`/v1/authorize`,vV({description:"Authorizes the app for the signed-in user without a redirect. Only a first-party app's page on the redirect URI's origin calls it. A native app authorizes through `/oauth2/authorize` instead. With `code_challenge`, the app's backend receives a code. Without one, a public app receives tokens. A key authorization is signed by the account's owner, and must fit the headless ceiling. The account becomes the app's account for its later requests.",responses:DV({errors:[...TR.errors,...W2.errors,...yB,...OV.errors,...LV.errors,nB,rI,UL,X1],success:{description:`The authorization.`,schema:I5.authorize.response}}),security:[{sessionCookie:[]}],tags:[`Authorization`]}),OV(`json`,I5.authorize.json),async e=>{let t=e.req.valid(`json`),n=t.client_id,r=await Z(e,CF($,{clientId:n}).catch(e=>{if(!(e instanceof gF))throw e}),`Apps.get`),i=TR(t,{app:r,origin:e.req.header(`origin`)});if(i)return X(e,i);let a=await Z(e,Q4(e),`Session.get`);if(!a)return X(e,new nB);let o=await Z(e,V4(e,{headers:new Headers(e.req.raw.headers),request:t,secret:!!r.secret,session:a}),`Headless.authorize`);return o instanceof Response?o:o instanceof tI?X(e,o):e.json(o,200)}).post(`/v1/authorize/account`,vV({description:"Selects the account that the app of `oauth_query` uses, then continues its authorization, and returns the next redirect. The selection holds for the app's later authorizations in the same session, and `GET /v1/account` lists it first. When the sign-in page showed the request's key and a passkey owns the selected account, the selection returns the passkey step, and the repeated selection with `passkey` signs the key without the approval page.",responses:DV({errors:[...yB,...X4.errors,...OV.errors,...R2.errors,...LV.errors,$z,nB,X1],success:{description:`The next redirect, or the passkey step.`,schema:I5.account.response}}),security:[{sessionCookie:[]}],tags:[`Authorization`]}),OV(`json`,I5.account.json),async e=>{let{account:t,oauth_query:n,passkey:r}=e.req.valid(`json`),i=X4(e,{oauth_query:n});if(i)return X(e,i);let a=await Z(e,Q4(e),`Session.get`);if(!a)return X(e,new nB);let o=await Z(e,LV(e,{limits:[{binding:`ACCOUNT_LIMIT`,key:a.user.id}]}),`RateLimit.check`);if(o)return o;let s=await Z(e,e.var.auth.$context,`auth.context`),c=await Z(e,na(n,s.secret),`auth.verifyOAuthQueryParams`),l=new URLSearchParams(n),u=l.get(`client_id`);if(!c||!u)return X(e,new $z);if(O4(l),!U2(await Z(e,R2(e,{clientId:u,userId:a.user.id}),`AccountStep.accounts`),t))return X(e,new X1({account:t}));e.set(`accountChosen`,!0);let d=K2({account:t.toLowerCase(),clientId:u,cookie:e.req.header(`cookie`),sessionId:a.session.id}),f=new Headers(e.req.raw.headers);f.set(`cookie`,d.header);let p=await Z(e,e.var.auth.api.oauth2Continue({asResponse:!1,body:{oauth_query:n,postLogin:!0},headers:f,request:new Request(e.req.url,{headers:f,method:`POST`})}),`auth.oauth2Continue`).catch(e=>{if(fi(e)&&e.body?.error===`invalid_signature`)return new $z;throw e});if(p instanceof tI)return X(e,p);let m=await Z(e,A4(e,{account:t,assertion:r?.assertion,headers:f,redirect:I5.account.result.parse(p).url,session:a}),`SignInConsent.afterAccountStep`);return e.header(`set-cookie`,d.setCookie,{append:!0}),e.header(`cache-control`,`private, no-store`),`options`in m?e.json(Cz.step.parse({step:{options:m.options,type:`passkey`}}),200):e.json({redirect:m.redirect},200)}).post(`/v1/authorize/consent`,vV({description:"Records the signed-in user's decision on the app's authorization request that `oauth_query` carries, and returns the app's redirect. The decision applies only while `session_id` names the signed-in session. An approval stores the consent, so the app's next request with the same scopes skips the approval page. An approval of a request with a key authorization signs the key as the account's owner, and the first redemption of the code returns it from `/oauth2/token`. For a passkey-owned account, the approval first returns the passkey step, and the repeated approval with `passkey` signs the key. A user who holds no account in the app's realms, and whose key names none, first receives a Privy-owned account, as `POST /v1/account` creates it.",responses:DV({errors:[...ER.errors,...yB,...X4.errors,...u4.errors,...d4.errors,...OV.errors,...LV.errors,CR,$z,tB,nB,bR],success:{description:`The app's redirect, or the passkey step.`,schema:I5.consent.response}}),security:[{sessionCookie:[]}],tags:[`Authorization`]}),OV(`json`,I5.consent.json),async e=>{let{accept:t,account:n,oauth_query:r,passkey:i,session_id:a}=e.req.valid(`json`),o=X4(e,{oauth_query:r});if(o)return X(e,o);let s=await Z(e,Q4(e),`Session.get`);if(!s)return X(e,new nB);if(s.session.id!==a)return X(e,new tB);let c=await Z(e,e.var.auth.$context,`auth.context`);if(!await Z(e,na(r,c.secret),`auth.verifyOAuthQueryParams`))return X(e,new $z);let l=new URLSearchParams(r);O4(l);let u=t&&(l.has(`key_authorization`)||l.has(`challenge`))?await Z(e,LV(e,{limits:[{binding:`AUTHORIZE_LIMIT`,key:s.user.id}]}),`RateLimit.check`):void 0;if(u)return u;if(t){let t=await Z(e,E4(e,{account:n,assertion:i?.assertion,headers:new Headers(e.req.raw.headers),oauthQuery:r,session:s}),`Consent.approve`);return t instanceof tI?X(e,t):(e.header(`cache-control`,`private, no-store`),`options`in t?e.json(I5.consent.step.parse({step:{options:t.options,type:`passkey`}}),200):e.json({redirect:t.redirect},200))}let d=await Z(e,e.var.auth.api.oauth2Consent({asResponse:!1,body:{accept:t,oauth_query:r},headers:new Headers(e.req.raw.headers),request:e.req.raw}),`auth.oauth2Consent`).catch(e=>{if(fi(e)&&e.body?.error===`invalid_signature`)return new $z;throw e});return d instanceof tI?X(e,d):(e.header(`cache-control`,`private, no-store`),e.json({redirect:I5.account.result.parse(d).url},200))}).get(`/v1/authorize/request`,vV({description:"Reads the app's authorization request that `oauth_query` carries, as the approval page shows it: the app, where the browser returns, the account that the approval applies to when the user holds several, and any key, with the account that approval signs for and why approval cannot sign it, if it cannot. The account read counts against the user's `ACCOUNT_LIMIT`, as `GET /v1/account` does. A user who holds no account shows no account, and approval creates the first one. Creates no account. Returns the app's redirect with the refusal for a key that Tempo ID refuses.",responses:DV({errors:[...OV.errors,nB,rI],success:{description:`The request, or the app's redirect with a refusal.`,schema:I5.request.response}}),security:[{sessionCookie:[]}],tags:[`Authorization`]}),OV(`query`,I5.request.query),async e=>{if(e.req.header(`sec-fetch-site`)===`cross-site`)return X(e,new rI);let t=await Z(e,Q4(e),`Session.get`);if(!t)return X(e,new nB);e.header(`cache-control`,`private, no-store`);let{oauth_query:n}=e.req.valid(`query`),r=new URLSearchParams(n),i=await Z(e,e.var.auth.$context,`auth.context`);if(!await Z(e,na(n,i.secret),`auth.verifyOAuthQueryParams`))return e.json({request:null},200);let a=r.get(`client_id`),o=r.get(`redirect_uri`),s=URL.parse(o??``);if(!a||!o||!s)return e.json({request:null},200);let c=await Z(e,CF($,{clientId:a}).catch(e=>{if(!(e instanceof gF))throw e}),`Apps.get`);if(!c||!c.redirectUris.includes(o))return e.json({request:null},200);let l=t=>{let n=new URL(o);n.searchParams.append(`error`,t.response.error),n.searchParams.append(`error_description`,t.response.error_description);let i=r.get(`state`);return i&&n.searchParams.append(`state`,i),n.searchParams.append(`iss`,U.URL),e.json({redirect:n.href},200)},u=DR(r);if(u instanceof tI)return l(u);let d=u&&ER({app:c,clientId:a,codeChallenge:r.get(`code_challenge`),key:u,query:r});if(d)return l(d);let f=OF(a)?new URL(a).host:[`http:`,`https:`].includes(s.protocol)?s.host:s.protocol.slice(0,-1),p=await Z(e,l4(e,{account:u?.account,clientId:a,sessionId:t.session.id,userId:t.user.id}),`KeySigner.preview`),m=(()=>{if(p.accounts.length<2)return;let e=U2(p.accounts,p.account),t=e?.config.owners[0];if(e&&t)return{address:e.address,owner:t.type}})(),h=(()=>{if(!u)return;let e=r.get(`challenge`);return{...lR(u),...p.account?{account:p.account}:{},...e?{challenge:e}:{},...p.refusal?{refusal:p.refusal}:{}}})();return e.json({request:{...m?{account:m}:{},app:c.name??f,destination:f,email:t.user.email,...h?{key:h}:{},session:t.session.id,verified:!OF(a)}},200)}).get(`/v1/authorize/accounts`,vV({description:"Reads the account step of the app's authorization request that `oauth_query` carries: the app, and the user's accounts in its realms, oldest first, each with its balance on the chain of the request's key, or of Tempo mainnet without one. The read counts against the user's `ACCOUNT_LIMIT`, as `GET /v1/account` does.",responses:DV({errors:[...R2.errors,...OV.errors,...LV.errors,nB,rI],success:{description:`The account step.`,schema:I5.accounts.response}}),security:[{sessionCookie:[]}],tags:[`Authorization`]}),OV(`query`,I5.accounts.query),async e=>{if(e.req.header(`sec-fetch-site`)===`cross-site`)return X(e,new rI);let t=await Z(e,Q4(e),`Session.get`);if(!t)return X(e,new nB);e.header(`cache-control`,`private, no-store`);let{oauth_query:n}=e.req.valid(`query`),r=new URLSearchParams(n),i=await Z(e,e.var.auth.$context,`auth.context`),a=await Z(e,na(n,i.secret),`auth.verifyOAuthQueryParams`),o=r.get(`client_id`);if(!a||!o)return e.json({request:null},200);let s=await Z(e,CB(e,()=>CF($,{clientId:o}).catch(e=>{if(!(e instanceof gF))throw e}),[`apps.get`,o]),`Apps.get`);if(!s)return e.json({request:null},200);let c=await Z(e,LV(e,{limits:[{binding:`ACCOUNT_LIMIT`,key:t.user.id}]}),`RateLimit.check`);if(c)return c;let l=await Z(e,R2(e,{clientId:o,userId:t.user.id}),`AccountStep.accounts`),u=DR(r),d=u&&!(u instanceof tI)?Number(u.chainId):eR,f=l.flatMap(e=>{let t=e.config.owners[0];return t?[{address:e.address,owner:t.type,realm:e.realm.id==="default"?null:e.realm.name}]:[]}),p=await Z(e,hB(e,{accounts:f,chainId:d,rpcUrl:U.TEMPO_RPC_URL}),`Balance.list`);return e.json({request:{accounts:f.map((e,t)=>({...e,balance:p[t]??null})),app:s.name??`The app`}},200)});async function R5(e,t){let n=e.req.raw.cf,r=[n?.city,n?.country].filter(Boolean).join(`, `);await Z(e,UR($,{challenge:t.challenge??null,device:t.device,deviceCode:t.deviceCode,expiresAt:new Date(Date.now()+t.expiresIn*1e3),ip:e.req.header(`cf-connecting-ip`)??null,key:t.key??null,location:r||null}),`Device.create`)}async function z5(e,t){let n=XR(t.code),r=n?await Z(e,KR($,{userCode:n}),`Device.get`):void 0;if(!n||!r)return new LR;let i=await(async()=>r.status!==`pending`||r.userId?r:await Z(e,VR($,{id:r.id,userId:t.userId}),`Device.bind`)?{...r,userId:t.userId}:await Z(e,KR($,{userCode:n}),`Device.get`))();return!i||i.userId&&i.userId!==t.userId?new LR:{clientId:r.clientId,request:{...r.appName?{app:{name:r.appName}}:{},...r.challenge?{challenge:r.challenge}:{},created_at:Math.floor(r.createdAt.getTime()/1e3),...r.device?{device:r.device}:{},...r.ip?{ip:r.ip}:{},...r.key?{key_authorization:lR(r.key)}:{},...r.location?{location:r.location}:{},status:i.status,user_code:i.userCode}}}(function(e){e.errors=[LR]})(z5||={});async function B5(e,t){let{request:n,session:r}=t,i=n.key,a=await Z(e,CF($,{clientId:n.clientId,enabled:!0}).catch(e=>{if(!(e instanceof gF))throw e}),`Apps.get`);if(!a?.device||a.secret||!a.firstParty)return new CR({description:`Approval refused: \`client_id\` ${n.clientId} names no enabled public first-party device app. Deny the request, and start the sign-in again.`});let o=aR(i)??oR({app:a,clientId:n.clientId,key:i});if(o)return o;let s=await Z(e,u4(e,{account:i.account??t.account,clientId:n.clientId,cookie:e.req.header(`cookie`),create:!0,passkey:!0,sessionId:r.session.id,userId:r.user.id}),`KeySigner.resolve`);if(s instanceof UL){let e=s.response.meta?.account;return new UL({account:e,description:`Passkey required: the passkey of Tempo Account ${e} signs only at its own relying party, which the device page is not part of. Name another account, or deny the request.`})}if(s instanceof tI)return s;if(t.assertion&&s.owner.signer)return new hz;if(!t.assertion&&!s.owner.signer)return{options:await Z(e,c4(e,{account:s.account,clientId:n.clientId,key:i,owner:s.owner,userId:r.user.id}),`KeySigner.challenge`)};let c=await Z(e,d4(e,{account:s.account,assertion:t.assertion,clientId:n.clientId,key:i,owner:s.owner,userId:r.user.id}),`KeySigner.sign`);return c instanceof tI?c:{account:s.account,keyAuthorization:c}}(function(e){e.errors=[...aR.errors,CR,...oR.errors,...u4.errors,...d4.errors,UL,hz]})(B5||={});var V5;(function(e){let t;(function(e){e.json=Fn({challenge:wR.challenge.refine(e=>e===void 0||/^(?:[\t\n]|[^\p{Cc}\p{Cf}])*$/u.test(e),{message:`Remove control and format characters, such as bidi overrides`}),client_id:R().min(1).max(255).optional().meta({description:"The client ID of the device app that the CLI signs in to, whose realms the sign-in and the device page use. Defaults to `tempo-cli`.",examples:[`tempo-cli`]}),device:R().trim().min(1).max(64).regex(/^[^\p{Cc}\p{Cf}]*$/u,{message:`Remove control and format characters, such as bidi overrides`}).meta({description:`The name that the device page shows, such as the machine's hostname. It holds no control or format characters.`,examples:[`ada-macbook`]}),key_authorization:XL.request}).refine(e=>!e.challenge||e.key_authorization,{message:"A challenge requires `key_authorization`, whose witness binds it",path:[`challenge`]}),e.response=z({device_code:R().meta({description:"The secret code that the CLI polls `/v1/device/token` with (RFC 8628 §3.2). The CLI keeps it private.",examples:[`GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS`]}),expires_in:Cn().meta({description:`Seconds until the device code and user code expire.`,examples:[600]}),interval:Cn().meta({description:`Seconds between polls.`,examples:[5]}),user_code:R().meta({description:`The code that the user enters on the device page: eight consonants in two groups of four.`,examples:[`WDJB-MJHT`]}),verification_uri:Dn().meta({description:`The page where the user enters the user code.`,examples:[`https://id.tempo.xyz/device`]}),verification_uri_complete:Dn().meta({description:`The device page with the user code filled in, for a link or QR code.`,examples:[`https://id.tempo.xyz/device?code=WDJB-MJHT`]})})})(t||=e.authorize||={});let n;(function(e){e.json=z({client_id:t.json.shape.client_id.meta({description:"The client ID that `/v1/device/authorize` named. Defaults to `tempo-cli`.",examples:[`tempo-cli`]}),device_code:R().min(1).max(128).meta({description:"The device code that `/v1/device/authorize` returned.",examples:[`GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS`]})}),e.response=wR.tokens.extend({account:XL.account.optional(),key_authorization:XL.rpc.optional().meta({description:`The signed key authorization, in the node's RPC format, when the CLI requested a key. Only the first redemption returns it.`})}).meta({description:`The tokens, with the signed key authorization when the CLI requested a key.`,id:`DeviceTokens`}),e.issued=z({access_token:R(),expires_in:Cn(),id_token:R().optional(),refresh_token:R().optional(),token_type:R()})})(n||=e.token||={});let r;(function(e){e.param=z({code:R().meta({description:`The user code.`,examples:[`WDJB-MJHT`]})}),e.response=z({request:z({app:z({name:R().meta({description:`The app's display name.`,examples:[`Tempo CLI`]})}).optional().meta({description:`The app that requested the code. Absent when the app has no display name.`}),challenge:R().optional().meta({description:`The message whose EIP-191 hash is the key's witness, which approval signs. Absent when the CLI sent none.`,examples:[`Sign in to app.example.com
|
|
607
|
+
Nonce: 7f3a9c2e5b1d4f60`]}),refusal:s4.refusal.optional()}).optional().meta({description:`What the key that the request carries may do, and the account that approval signs for. Absent for a request without a key.`}),session:R().meta({description:"The ID of the signed-in session, which `POST /v1/authorize/consent` names.",examples:[`8nVq3kZ0bT5wXy2mLp7sR4dA`]}),verified:On().meta({description:`Whether the app is a registered app, whose name the page marks as verified. A third-party app names itself in its metadata document.`,examples:[!0]})}).nullable().meta({description:"The request that the approval page shows, or `null` for a forged or expired query, or a request without a known app."})}).meta({description:`The request that the approval page shows.`})])})(i||=e.request||={});let a;(function(e){e.query=i.query,e.response=z({request:z({accounts:Mn(z({address:Q1.tempoAccount.shape.address.meta({description:`The account address.`,examples:[`0x8C3b5d0e2A4f6B1c9D7e3F5a0B2c4D6e8F1a3B5c`]}),balance:fB.balance.nullable().meta({description:"The account's holdings of USD tokens on the chain of the request's key, or of Tempo mainnet without one. `null` when the read fails or takes longer than 3 seconds."}),owner:Q1.tempoAccount.shape.config.shape.owners.unwrap().element.shape.type,realm:R().nullable().meta({description:"The name of the account's realm, or `null` for the `default` realm.",examples:[`Tempo Cash`]})})).readonly().meta({description:`The user's accounts in the app's realms, oldest first.`}),app:R().meta({description:`The app's display name.`,examples:[`Tempo Cash`]})}).nullable().meta({description:"The account step, or `null` for a forged or expired query, or a request without a known app."})})})(a||=e.accounts||={})})(I5||={});var L5=new Iy().post(`/v1/authorize`,vV({description:"Authorizes the app for the signed-in user without a redirect. Only a first-party app's page on the redirect URI's origin calls it. A native app authorizes through `/oauth2/authorize` instead. With `code_challenge`, the app's backend receives a code. Without one, a public app receives tokens. A key authorization is signed by the account's owner, and must fit the headless ceiling. The account becomes the app's account for its later requests.",responses:DV({errors:[...TR.errors,...W2.errors,...yB,...OV.errors,...LV.errors,nB,rI,UL,X1],success:{description:`The authorization.`,schema:I5.authorize.response}}),security:[{sessionCookie:[]}],tags:[`Authorization`]}),OV(`json`,I5.authorize.json),async e=>{let t=e.req.valid(`json`),n=t.client_id,r=await Z(e,CF($,{clientId:n}).catch(e=>{if(!(e instanceof gF))throw e}),`Apps.get`),i=TR(t,{app:r,origin:e.req.header(`origin`)});if(i)return X(e,i);let a=await Z(e,Q4(e),`Session.get`);if(!a)return X(e,new nB);let o=await Z(e,V4(e,{headers:new Headers(e.req.raw.headers),request:t,secret:!!r.secret,session:a}),`Headless.authorize`);return o instanceof Response?o:o instanceof tI?X(e,o):e.json(o,200)}).post(`/v1/authorize/account`,vV({description:"Selects the account that the app of `oauth_query` uses, then continues its authorization, and returns the next redirect. The selection holds for the app's later authorizations in the same session, and `GET /v1/account` lists it first. When the sign-in page showed the request's key and a passkey owns the selected account, the selection returns the passkey step, and the repeated selection with `passkey` signs the key without the approval page.",responses:DV({errors:[...yB,...X4.errors,...OV.errors,...R2.errors,...LV.errors,$z,nB,X1],success:{description:`The next redirect, or the passkey step.`,schema:I5.account.response}}),security:[{sessionCookie:[]}],tags:[`Authorization`]}),OV(`json`,I5.account.json),async e=>{let{account:t,oauth_query:n,passkey:r}=e.req.valid(`json`),i=X4(e,{oauth_query:n});if(i)return X(e,i);let a=await Z(e,Q4(e),`Session.get`);if(!a)return X(e,new nB);let o=await Z(e,LV(e,{limits:[{binding:`ACCOUNT_LIMIT`,key:a.user.id}]}),`RateLimit.check`);if(o)return o;let s=await Z(e,e.var.auth.$context,`auth.context`),c=await Z(e,na(n,s.secret),`auth.verifyOAuthQueryParams`),l=new URLSearchParams(n),u=l.get(`client_id`);if(!c||!u)return X(e,new $z);if(O4(l),!U2(await Z(e,R2(e,{clientId:u,userId:a.user.id}),`AccountStep.accounts`),t))return X(e,new X1({account:t}));e.set(`accountChosen`,!0);let d=K2({account:t.toLowerCase(),clientId:u,cookie:e.req.header(`cookie`),sessionId:a.session.id}),f=new Headers(e.req.raw.headers);f.set(`cookie`,d.header);let p=await Z(e,e.var.auth.api.oauth2Continue({asResponse:!1,body:{oauth_query:n,postLogin:!0},headers:f,request:new Request(e.req.url,{headers:f,method:`POST`})}),`auth.oauth2Continue`).catch(e=>{if(fi(e)&&e.body?.error===`invalid_signature`)return new $z;throw e});if(p instanceof tI)return X(e,p);let m=await Z(e,A4(e,{account:t,assertion:r?.assertion,headers:f,redirect:I5.account.result.parse(p).url,session:a}),`SignInConsent.afterAccountStep`);return e.header(`set-cookie`,d.setCookie,{append:!0}),e.header(`cache-control`,`private, no-store`),`options`in m?e.json(Cz.step.parse({step:{options:m.options,type:`passkey`}}),200):e.json({redirect:m.redirect},200)}).post(`/v1/authorize/consent`,vV({description:"Records the signed-in user's decision on the app's authorization request that `oauth_query` carries, and returns the app's redirect. The decision applies only while `session_id` names the signed-in session. An approval stores the consent, so the app's next request with the same scopes skips the approval page. An approval of a request with a key authorization signs the key as the account's owner, and the first redemption of the code returns it from `/oauth2/token`. For a passkey-owned account, the approval first returns the passkey step, and the repeated approval with `passkey` signs the key. A user who holds no account in the app's realms, and whose key names none, first receives a Privy-owned account, as `POST /v1/account` creates it.",responses:DV({errors:[...ER.errors,...yB,...X4.errors,...u4.errors,...d4.errors,...OV.errors,...LV.errors,CR,$z,tB,nB,bR],success:{description:`The app's redirect, or the passkey step.`,schema:I5.consent.response}}),security:[{sessionCookie:[]}],tags:[`Authorization`]}),OV(`json`,I5.consent.json),async e=>{let{accept:t,account:n,oauth_query:r,passkey:i,session_id:a}=e.req.valid(`json`),o=X4(e,{oauth_query:r});if(o)return X(e,o);let s=await Z(e,Q4(e),`Session.get`);if(!s)return X(e,new nB);if(s.session.id!==a)return X(e,new tB);let c=await Z(e,e.var.auth.$context,`auth.context`);if(!await Z(e,na(r,c.secret),`auth.verifyOAuthQueryParams`))return X(e,new $z);let l=new URLSearchParams(r);O4(l);let u=t&&(l.has(`key_authorization`)||l.has(`challenge`))?await Z(e,LV(e,{limits:[{binding:`AUTHORIZE_LIMIT`,key:s.user.id}]}),`RateLimit.check`):void 0;if(u)return u;if(t){let t=await Z(e,E4(e,{account:n,assertion:i?.assertion,headers:new Headers(e.req.raw.headers),oauthQuery:r,session:s}),`Consent.approve`);return t instanceof tI?X(e,t):(e.header(`cache-control`,`private, no-store`),`options`in t?e.json(I5.consent.step.parse({step:{options:t.options,type:`passkey`}}),200):e.json({redirect:t.redirect},200))}let d=await Z(e,e.var.auth.api.oauth2Consent({asResponse:!1,body:{accept:t,oauth_query:r},headers:new Headers(e.req.raw.headers),request:e.req.raw}),`auth.oauth2Consent`).catch(e=>{if(fi(e)&&e.body?.error===`invalid_signature`)return new $z;throw e});return d instanceof tI?X(e,d):(e.header(`cache-control`,`private, no-store`),e.json({redirect:I5.account.result.parse(d).url},200))}).get(`/v1/authorize/request`,vV({description:"Reads the app's authorization request that `oauth_query` carries, as the approval page shows it: the app, where the browser returns, the account that the approval applies to when the user holds several, and any key, with the account that approval signs for and why approval cannot sign it, if it cannot. The account read counts against the user's `ACCOUNT_LIMIT`, as `GET /v1/account` does. A user who holds no account shows no account, and approval creates the first one. Creates no account. Returns the app's redirect with the refusal for a key that Tempo ID refuses.",responses:DV({errors:[...OV.errors,nB,rI],success:{description:`The request, or the app's redirect with a refusal.`,schema:I5.request.response}}),security:[{sessionCookie:[]}],tags:[`Authorization`]}),OV(`query`,I5.request.query),async e=>{if(e.req.header(`sec-fetch-site`)===`cross-site`)return X(e,new rI);let t=await Z(e,Q4(e),`Session.get`);if(!t)return X(e,new nB);e.header(`cache-control`,`private, no-store`);let{oauth_query:n}=e.req.valid(`query`),r=new URLSearchParams(n),i=await Z(e,e.var.auth.$context,`auth.context`);if(!await Z(e,na(n,i.secret),`auth.verifyOAuthQueryParams`))return e.json({request:null},200);let a=r.get(`client_id`),o=r.get(`redirect_uri`),s=URL.parse(o??``);if(!a||!o||!s)return e.json({request:null},200);let c=await Z(e,CF($,{clientId:a}).catch(e=>{if(!(e instanceof gF))throw e}),`Apps.get`);if(!c||!c.redirectUris.includes(o))return e.json({request:null},200);let l=t=>{let n=new URL(o);n.searchParams.append(`error`,t.response.error),n.searchParams.append(`error_description`,t.response.error_description);let i=r.get(`state`);return i&&n.searchParams.append(`state`,i),n.searchParams.append(`iss`,U.URL),e.json({redirect:n.href},200)},u=DR(r);if(u instanceof tI)return l(u);let d=u&&ER({app:c,clientId:a,codeChallenge:r.get(`code_challenge`),key:u,query:r});if(d)return l(d);let f=OF(a)?new URL(a).host:[`http:`,`https:`].includes(s.protocol)?s.host:s.protocol.slice(0,-1),p=await Z(e,l4(e,{account:u?.account,clientId:a,sessionId:t.session.id,userId:t.user.id}),`KeySigner.preview`),m=(()=>{if(p.accounts.length<2)return;let e=U2(p.accounts,p.account),t=e?.config.owners[0];if(e&&t)return{address:e.address,owner:t.type}})(),h=(()=>{if(!u)return;let e=r.get(`challenge`);return{...lR(u),...p.account?{account:p.account}:{},...e?{challenge:e}:{},...p.refusal?{refusal:p.refusal}:{}}})();return e.json({request:{...m?{account:m}:{},app:c.name??f,destination:f,email:t.user.email,...h?{key:h}:{},session:t.session.id,verified:!OF(a)}},200)}).get(`/v1/authorize/accounts`,vV({description:"Reads the account step of the app's authorization request that `oauth_query` carries: the app, and the user's accounts in its realms, oldest first, each with its balance on the chain of the request's key, or of Tempo mainnet without one. The read counts against the user's `ACCOUNT_LIMIT`, as `GET /v1/account` does.",responses:DV({errors:[...R2.errors,...OV.errors,...LV.errors,nB,rI],success:{description:`The account step.`,schema:I5.accounts.response}}),security:[{sessionCookie:[]}],tags:[`Authorization`]}),OV(`query`,I5.accounts.query),async e=>{if(e.req.header(`sec-fetch-site`)===`cross-site`)return X(e,new rI);let t=await Z(e,Q4(e),`Session.get`);if(!t)return X(e,new nB);e.header(`cache-control`,`private, no-store`);let{oauth_query:n}=e.req.valid(`query`),r=new URLSearchParams(n),i=await Z(e,e.var.auth.$context,`auth.context`),a=await Z(e,na(n,i.secret),`auth.verifyOAuthQueryParams`),o=r.get(`client_id`);if(!a||!o)return e.json({request:null},200);let s=await Z(e,CB(e,()=>CF($,{clientId:o}).catch(e=>{if(!(e instanceof gF))throw e}),[`apps.get`,o]),`Apps.get`);if(!s)return e.json({request:null},200);let c=await Z(e,LV(e,{limits:[{binding:`ACCOUNT_LIMIT`,key:t.user.id}]}),`RateLimit.check`);if(c)return c;let l=await Z(e,R2(e,{clientId:o,userId:t.user.id}),`AccountStep.accounts`),u=DR(r),d=u&&!(u instanceof tI)&&u.chainId?Number(u.chainId):eR,f=l.flatMap(e=>{let t=e.config.owners[0];return t?[{address:e.address,owner:t.type,realm:e.realm.id==="default"?null:e.realm.name}]:[]}),p=await Z(e,hB(e,{accounts:f,chainId:d,rpcUrl:U.TEMPO_RPC_URL}),`Balance.list`);return e.json({request:{accounts:f.map((e,t)=>({...e,balance:p[t]??null})),app:s.name??`The app`}},200)});async function R5(e,t){let n=e.req.raw.cf,r=[n?.city,n?.country].filter(Boolean).join(`, `);await Z(e,UR($,{challenge:t.challenge??null,device:t.device,deviceCode:t.deviceCode,expiresAt:new Date(Date.now()+t.expiresIn*1e3),ip:e.req.header(`cf-connecting-ip`)??null,key:t.key??null,location:r||null}),`Device.create`)}async function z5(e,t){let n=XR(t.code),r=n?await Z(e,KR($,{userCode:n}),`Device.get`):void 0;if(!n||!r)return new LR;let i=await(async()=>r.status!==`pending`||r.userId?r:await Z(e,VR($,{id:r.id,userId:t.userId}),`Device.bind`)?{...r,userId:t.userId}:await Z(e,KR($,{userCode:n}),`Device.get`))();return!i||i.userId&&i.userId!==t.userId?new LR:{clientId:r.clientId,request:{...r.appName?{app:{name:r.appName}}:{},...r.challenge?{challenge:r.challenge}:{},created_at:Math.floor(r.createdAt.getTime()/1e3),...r.device?{device:r.device}:{},...r.ip?{ip:r.ip}:{},...r.key?{key_authorization:lR(r.key)}:{},...r.location?{location:r.location}:{},status:i.status,user_code:i.userCode}}}(function(e){e.errors=[LR]})(z5||={});async function B5(e,t){let{request:n,session:r}=t,i=n.key,a=await Z(e,CF($,{clientId:n.clientId,enabled:!0}).catch(e=>{if(!(e instanceof gF))throw e}),`Apps.get`);if(!a?.device||a.secret||!a.firstParty)return new CR({description:`Approval refused: \`client_id\` ${n.clientId} names no enabled public first-party device app. Deny the request, and start the sign-in again.`});let o=aR(i)??oR({app:a,clientId:n.clientId,key:i});if(o)return o;let s=await Z(e,u4(e,{account:i.account??t.account,clientId:n.clientId,cookie:e.req.header(`cookie`),create:!0,passkey:!0,sessionId:r.session.id,userId:r.user.id}),`KeySigner.resolve`);if(s instanceof UL){let e=s.response.meta?.account;return new UL({account:e,description:`Passkey required: the passkey of Tempo Account ${e} signs only at its own relying party, which the device page is not part of. Name another account, or deny the request.`})}if(s instanceof tI)return s;if(t.assertion&&s.owner.signer)return new hz;if(!t.assertion&&!s.owner.signer)return{options:await Z(e,c4(e,{account:s.account,clientId:n.clientId,key:i,owner:s.owner,userId:r.user.id}),`KeySigner.challenge`)};let c=await Z(e,d4(e,{account:s.account,assertion:t.assertion,clientId:n.clientId,key:i,owner:s.owner,userId:r.user.id}),`KeySigner.sign`);return c instanceof tI?c:{account:s.account,keyAuthorization:c}}(function(e){e.errors=[...aR.errors,CR,...oR.errors,...u4.errors,...d4.errors,UL,hz]})(B5||={});var V5;(function(e){let t;(function(e){e.json=Fn({challenge:wR.challenge.refine(e=>e===void 0||/^(?:[\t\n]|[^\p{Cc}\p{Cf}])*$/u.test(e),{message:`Remove control and format characters, such as bidi overrides`}),client_id:R().min(1).max(255).optional().meta({description:"The client ID of the device app that the CLI signs in to, whose realms the sign-in and the device page use. Defaults to `tempo-cli`.",examples:[`tempo-cli`]}),device:R().trim().min(1).max(64).regex(/^[^\p{Cc}\p{Cf}]*$/u,{message:`Remove control and format characters, such as bidi overrides`}).meta({description:`The name that the device page shows, such as the machine's hostname. It holds no control or format characters.`,examples:[`ada-macbook`]}),key_authorization:XL.request}).refine(e=>!e.challenge||e.key_authorization,{message:"A challenge requires `key_authorization`, whose witness binds it",path:[`challenge`]}),e.response=z({device_code:R().meta({description:"The secret code that the CLI polls `/v1/device/token` with (RFC 8628 §3.2). The CLI keeps it private.",examples:[`GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS`]}),expires_in:Cn().meta({description:`Seconds until the device code and user code expire.`,examples:[600]}),interval:Cn().meta({description:`Seconds between polls.`,examples:[5]}),user_code:R().meta({description:`The code that the user enters on the device page: eight consonants in two groups of four.`,examples:[`WDJB-MJHT`]}),verification_uri:Dn().meta({description:`The page where the user enters the user code.`,examples:[`https://id.tempo.xyz/device`]}),verification_uri_complete:Dn().meta({description:`The device page with the user code filled in, for a link or QR code.`,examples:[`https://id.tempo.xyz/device?code=WDJB-MJHT`]})})})(t||=e.authorize||={});let n;(function(e){e.json=z({client_id:t.json.shape.client_id.meta({description:"The client ID that `/v1/device/authorize` named. Defaults to `tempo-cli`.",examples:[`tempo-cli`]}),device_code:R().min(1).max(128).meta({description:"The device code that `/v1/device/authorize` returned.",examples:[`GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS`]})}),e.response=wR.tokens.extend({account:XL.account.optional(),key_authorization:XL.rpc.optional().meta({description:`The signed key authorization, in the node's RPC format, when the CLI requested a key. Only the first redemption returns it.`})}).meta({description:`The tokens, with the signed key authorization when the CLI requested a key.`,id:`DeviceTokens`}),e.issued=z({access_token:R(),expires_in:Cn(),id_token:R().optional(),refresh_token:R().optional(),token_type:R()})})(n||=e.token||={});let r;(function(e){e.param=z({code:R().meta({description:`The user code.`,examples:[`WDJB-MJHT`]})}),e.response=z({request:z({app:z({name:R().meta({description:`The app's display name.`,examples:[`Tempo CLI`]})}).optional().meta({description:`The app that requested the code. Absent when the app has no display name.`}),challenge:R().optional().meta({description:`The message whose EIP-191 hash is the key's witness, which approval signs. Absent when the CLI sent none.`,examples:[`Sign in to app.example.com
|
|
608
608
|
Nonce: 7f3a9c2e5b1d4f60`]}),created_at:Cn().meta({description:`When the CLI requested the code, in Unix seconds.`,examples:[1792075800]}),device:R().optional().meta({description:"The name that the CLI reported, such as its hostname. Absent for a code from `POST /device/code`.",examples:[`ada-macbook`]}),ip:R().optional().meta({description:`The CLI's IP address. Absent when it is unknown.`,examples:[`203.0.113.7`]}),key_authorization:XL.description.extend({account:XL.description.shape.account.meta({description:`The Tempo Account that approval signs for: the one the request names, else the one the user selected for the app, else the oldest. Absent when the request names none and the accounts cannot be read, or the user holds none.`,examples:[`0x9a073914db0d149375ac2b7fbb72c68c0780fb5f`]}),refusal:s4.refusal.optional()}).optional().meta({description:`What the key that the CLI requested may do. Absent when the CLI requested no key.`}),location:R().optional().meta({description:`The CLI's city and country, from its IP address. Absent when they are unknown.`,examples:[`Berlin, DE`]}),status:Sn([`approved`,`denied`,`pending`]).meta({description:"Whether the user approved or denied the code. `pending` until the user decides.",examples:[`pending`]}),user_code:R().meta({description:`The user code.`,examples:[`WDJB-MJHT`]})}).meta({description:`The request that the CLI made with the code.`})})})(r||=e.requests||={});let i;(function(e){e.json=z({account:Q1.tempoAccount.shape.address.optional().meta({description:`The Tempo Account that the device page showed for the request's key authorization, one of the user's accounts in the app's realms. Ignored when the key names its account, and absent for a request without a key.`,examples:[`0x8C3b5d0e2A4f6B1c9D7e3F5a0B2c4D6e8F1a3B5c`]}),code:R().max(32).meta({description:`The user code.`,examples:[`WDJB-MJHT`]}),passkey:z({assertion:Cz.assertion}).optional().meta({description:`The passkey's assertion over the options of the passkey step, which a passkey-owned account's approval returns. The repeated approval signs the key with it.`})});let t=e.step=Cz.step;e.response=_n([z({status:xn(`approved`).meta({description:`The user approved the code. The CLI receives its tokens, and any signed key, on its next poll.`})}).meta({description:`A stored approval.`}),t])})(i||=e.approve||={});let a;(function(e){e.json=z({code:i.json.shape.code}),e.response=z({status:xn(`denied`).meta({description:"The user denied the code. The next poll returns `access_denied`."})})})(a||=e.deny||={})})(V5||={});async function H5(e,t){if(q4(e))return new rI;let n=await Z(e,Q4(e),`Session.get`);if(!n)return new nB;let r=await Z(e,LV(e,{limits:[{binding:`AUTHORIZE_LIMIT`,key:n.user.id}]}),`RateLimit.check`);if(r)return r;let i=XR(t.code),a=i?await Z(e,KR($,{userCode:i}),`Device.get`):void 0;if(!i||!a||a.userId&&a.userId!==n.user.id)return new LR;if(a.status!==`pending`)return new MR;let o=await(async()=>a.userId?a:await Z(e,VR($,{id:a.id,userId:n.user.id}),`Device.bind`)?{...a,userId:n.user.id}:await Z(e,KR($,{userCode:i}),`Device.get`))();if(!o||o.userId!==n.user.id)return new LR;if(o.status!==`pending`)return new MR;let s=await(async()=>{if(t.decision!==`approve`||!o.key)return;let r=await Z(e,B5(e,{account:t.account,assertion:t.assertion,request:o,session:n}),`DeviceRequest.sign`);if(r instanceof tI)return r;if(r.options)return{options:r.options};let i={account:r.account,keyAuthorization:r.keyAuthorization};return await Z(e,qR($,{id:o.id,key:i,userId:n.user.id}),`Device.hold`)?{key:i}:await l()})();if(s instanceof tI)return s;if(s&&`options`in s)return{options:s.options};let c=async()=>{s&&await Z(e,JR($,{id:o.id,key:s.key}),`Device.release`)};return await Z(e,WR($,{id:o.id,status:t.decision===`approve`?`approved`:`denied`,userId:n.user.id}).catch(async e=>{throw await c(),e}),`Device.decide`)?void 0:(await c(),await l());async function l(){return await Z(e,KR($,{userCode:i}),`Device.get`)?new MR:new LR}}(function(e){e.errors=[...B5.errors,nB,MR,LR,rI]})(H5||={});async function U5(e,t){let n=await Z(e,e.var.auth.handler(new Request(new URL(`/oauth2/token`,U.URL),{body:new URLSearchParams({client_id:t.clientId,device_code:t.deviceCode,grant_type:_F,resource:U.URL}),headers:{"content-type":`application/x-www-form-urlencoded`},method:`POST`})),`auth.handler`),r=await Z(e,n.json(),`response.json`);if(n.ok)return V5.token.issued.parse(r);let i=z({error:R()}).safeParse(r).data?.error;if(i===`authorization_pending`)return new NR;if(i===`slow_down`)return new FR;if(i===`access_denied`)return new IR;if(i===`expired_token`||i===`invalid_grant`)return new PR;throw Error(`The token endpoint refused a device code with ${i??n.status}.`)}(function(e){e.errors=[NR,PR,FR,IR]})(U5||={});var W5=new Iy().post(`/v1/device/authorize`,vV({description:"Starts the device grant (RFC 8628) for a CLI, as the device app that `client_id` names, or `tempo-cli`. The user approves the user code on the device page, and the CLI polls `/v1/device/token`. A request with `key_authorization` asks for a key, which the device page shows and approval signs. The key follows the rules of the redirect's approval page, without the headless ceiling, and a `challenge` requires the app's `tempo-id:sign` scope.",responses:DV({errors:[...yB,...aR.errors,...oR.errors,...OV.errors,...LV.errors,CR,rI],success:{description:`The device code.`,schema:V5.authorize.response}}),tags:[`Device grant`]}),OV(`json`,V5.authorize.json),async e=>{let t=await Z(e,LV(e,{limits:[{binding:`DEVICE_LIMIT`,key:HV(e)}]}),`RateLimit.check`);if(t)return t;let{challenge:n,client_id:r=RR,device:i,key_authorization:a}=e.req.valid(`json`),o=await Z(e,CF($,{clientId:r,enabled:!0}).catch(e=>{if(!(e instanceof gF))throw e}),`Apps.get`);if(!o?.device||o.secret||!o.firstParty)return X(e,new CR({description:`Device grant refused: \`client_id\` ${r} names no enabled public first-party device app. Send the client ID of a registered device app, or leave out \`client_id\`.`}));if(a){let t=iR(a,{challenge:n}),i=aR(t)??oR({app:o,clientId:r,key:t});if(i)return X(e,i)}let s=await Z(e,e.var.auth.api.deviceCode({body:{client_id:r,resource:U.URL,scope:zR}}),`auth.deviceCode`);await Z(e,R5(e,{challenge:n,device:i,deviceCode:s.device_code,expiresIn:s.expires_in,key:a}),`DeviceRequest.create`);let c=GR(s.user_code),l=new URL(ZR,U.URL);return e.header(`cache-control`,`no-store`),e.json({device_code:s.device_code,expires_in:s.expires_in,interval:s.interval,user_code:c,verification_uri:l.href,verification_uri_complete:`${l.href}?${new URLSearchParams({code:c})}`},200)}).post(`/v1/device/token`,vV({description:`Polls for the device grant's tokens (RFC 8628 §3.4). The tokens of an approved code, and the key authorization that approval signed, are returned once.`,responses:DV({errors:[...yB,...OV.errors,...LV.errors,...U5.errors,rI],success:{description:`The tokens.`,schema:V5.token.response}}),tags:[`Device grant`]}),OV(`json`,V5.token.json),async e=>{let t=await Z(e,LV(e,{limits:[{binding:`TOKEN_LIMIT`,key:HV(e)}]}),`RateLimit.check`);if(t)return t;let n=e.req.valid(`json`).device_code,r=await Z(e,YR($,{deviceCode:n}),`Device.id`),i=await Z(e,U5(e,{clientId:e.req.valid(`json`).client_id??`tempo-cli`,deviceCode:n}),`device.poll`);if(e.header(`cache-control`,`no-store`),i instanceof tI)return X(e,i);let a=r?await Z(e,$R($,{id:r}),`Device.take`).catch(t=>{WF(e,{error:t,message:`The device token poll failed to take the held key.`})}):void 0,{access_token:o,expires_in:s,id_token:c,refresh_token:l,token_type:u}=i;return e.json({access_token:o,...a?{account:a.account,key_authorization:a.keyAuthorization}:{},expires_in:s,...c?{id_token:c}:{},...l?{refresh_token:l}:{},token_type:u},200)}).get(`/v1/device/requests/:code`,vV({description:"Reads a device code's request for the device page, by its user code. The first signed-in user to read a pending code binds it, so no other user decides it. A pending request's key carries the account that approval signs for, and why approval cannot sign it, if it cannot. That lookup counts against the user's `ACCOUNT_LIMIT`, as `GET /v1/account` does. Creates no account.",responses:DV({errors:[...OV.errors,...z5.errors,...LV.errors,nB,rI],success:{description:`What the CLI requested.`,schema:V5.requests.response}}),security:[{sessionCookie:[]}],tags:[`Device grant`]}),OV(`param`,V5.requests.param),async e=>{if(e.req.header(`sec-fetch-site`)===`cross-site`)return X(e,new rI);let t=await Z(e,Q4(e),`Session.get`);if(!t)return X(e,new nB);let n=await Z(e,LV(e,{limits:[{binding:`AUTHORIZE_LIMIT`,key:`${t.user.id}:device`}]}),`RateLimit.check`);if(n)return n;let r=await Z(e,z5(e,{code:e.req.valid(`param`).code,userId:t.user.id}),`DeviceRequest.read`);if(e.header(`cache-control`,`private, no-store`),r instanceof tI)return X(e,r);let{clientId:i,request:a}=r,{key_authorization:o,...s}=a;if(!o||a.status!==`pending`)return e.json({request:a},200);let c=await Z(e,l4(e,{account:o.account,clientId:i,sessionId:t.session.id,userId:t.user.id}),`KeySigner.preview`);return e.json({request:{...s,key_authorization:{...o,...c.account?{account:c.account}:{},...c.refusal?{refusal:c.refusal}:{}}}},200)}).post(`/v1/device/approve`,vV({description:"Approves a device code for the signed-in user. Only Tempo ID's device page may call it. The CLI receives its tokens on its next poll. An approval of a request with a key authorization signs the key as the account's owner, and the poll returns it beside the tokens. For a passkey-owned account, the approval first returns the passkey step, and the repeated approval with `passkey` signs the key. A user who holds no account in the app's realms, and whose key names none, first receives a Privy-owned account, as `POST /v1/account` creates it.",responses:DV({errors:[...yB,...OV.errors,...LV.errors,...H5.errors],success:{description:`The code is approved, or the passkey step.`,schema:V5.approve.response}}),security:[{sessionCookie:[]}],tags:[`Device grant`]}),OV(`json`,V5.approve.json),async e=>{let{account:t,code:n,passkey:r}=e.req.valid(`json`),i=await Z(e,H5(e,{account:t,assertion:r?.assertion,code:n,decision:`approve`}),`device.decide`);return i instanceof Response?i:i instanceof tI?X(e,i):i?(e.header(`cache-control`,`private, no-store`),e.json(V5.approve.step.parse({step:{options:i.options,type:`passkey`}}),200)):e.json({status:`approved`},200)}).post(`/v1/device/deny`,vV({description:"Denies a device code for the signed-in user. Only Tempo ID's device page may call it. The CLI's next poll returns `access_denied`.",responses:DV({errors:[...yB,...OV.errors,...LV.errors,...H5.errors],success:{description:`The code is denied.`,schema:V5.deny.response}}),security:[{sessionCookie:[]}],tags:[`Device grant`]}),OV(`json`,V5.deny.json),async e=>{let t=await Z(e,H5(e,{code:e.req.valid(`json`).code,decision:`deny`}),`device.decide`);return t instanceof Response?t:t instanceof tI?X(e,t):e.json({status:`denied`},200)}),G5;(function(e){let t;(function(e){e.response=z({ok:xn(!0).meta({description:"Always `true`."}),version:z({id:R().meta({description:"The version's ID, as `wrangler deploy` prints it.",examples:[`a5f3c2e1-7b4d-4e8a-9c6f-2d1b0e3a4c5f`]}),tag:R().meta({description:`The version's tag, or empty when it has none.`,examples:[`v1.4.0`]})}).meta({description:`The deployed Worker version that served the request.`})})})(t||=e.health||={})})(G5||={});var K5=new Iy().get(`/health`,vV({description:`Responds while the Worker is up, with the version that served the request.`,responses:DV({success:{description:`The Worker is up.`,schema:G5.health.response}}),tags:[`Health`]}),e=>{let{id:t,tag:n}=e.env.CF_VERSION_METADATA;return e.header(`cache-control`,`no-store`),e.json({ok:!0,version:{id:t,tag:n}},200)}),q5,J5=aB(async(e,t)=>{e.set(`cache`,e.env.CACHE??(q5??=SB({ttl:(U.CONFIG_CACHE_TTL??30)*1e3}))),await t()}),Y5;(function(e){let t;(function(e){e.response=Pn({authorization_endpoint:Dn().meta({description:`The authorization endpoint.`,examples:[`https://id.tempo.xyz/oauth2/authorize`]}),issuer:Dn().meta({description:"The issuer's identifier, every token's `iss`.",examples:[`https://id.tempo.xyz`]}),jwks_uri:Dn().meta({description:`The issuer's signing keys.`,examples:[`https://id.tempo.xyz/oauth2/jwks`]}),token_endpoint:Dn().meta({description:`The token endpoint.`,examples:[`https://id.tempo.xyz/oauth2/token`]})}).meta({description:`The issuer's metadata (RFC 8414 §2, OpenID Connect Discovery §3), with the members that RFC 8414 defines.`,id:`AuthorizationServerMetadata`})})(t||=e.openidConfiguration||={});let n;(function(e){e.response=t.response})(n||=e.oauthAuthorizationServer||={});let r;(function(e){e.query=z({challenge:R().optional().meta({description:"A message, such as a sign-in challenge from the app's backend, whose EIP-191 hash becomes the key authorization's `witness` (TIP-1053). Requires `key_authorization`, and the app's `tempo-id:sign` scope.",examples:[`Sign in to app.example.com
|
|
609
609
|
Nonce: 7f3a9c2e5b1d4f60`]}),client_id:R().meta({description:`The app's client ID.`,examples:[`tempo-cli`]}),code_challenge:R().meta({description:`The PKCE challenge: the base64url SHA-256 hash of the code verifier (RFC 7636 §4.2).`,examples:[`E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM`]}),code_challenge_method:xn(`S256`).meta({description:`The PKCE challenge method.`}),key_authorization:R().optional().meta({description:"A key authorization for the app's own key, as base64url JSON in the shape of `KeyAuthorizationRequest`. The request always shows the approval page, which signs the key, and `/oauth2/token` returns it beside the tokens. A key that breaks a rule returns to the redirect URI with the refusal.",examples:[`eyJhZGRyZXNzIjoiMHg4MWMwZjIyYmQxNzNjMTE1ZDE4ZWVlYTBmNmEzOGU5MzVlY2Y1MmZiIn0`]}),prompt:Sn([`consent`,`login`,`none`,`select_account`]).optional().meta({description:`Whether the user signs in or consents again (OIDC Core §3.1.2.1). Absent to reuse the session and stored consent.`,examples:[`consent`]}),redirect_uri:Dn().meta({description:`One of the app's registered redirect URIs.`,examples:[`https://app.example/callback`]}),resource:Dn().optional().meta({description:`The API the access token is for (RFC 8707). Absent for Tempo ID's own origin.`,examples:[`https://id.tempo.xyz`]}),response_type:xn(`code`).meta({description:`The authorization code flow.`}),scope:R().meta({description:`Space-separated OAuth scopes.`,examples:[`openid profile email`]}),state:R().optional().meta({description:`An opaque value that the redirect returns to the app unchanged.`,examples:[`af0ifjsldkj`]})}),e.response=z({redirect:On().meta({description:"Whether the app sends the browser to `url`.",examples:[!0]}),url:R().meta({description:`Where the browser goes next: the sign-in page, the consent page, or the redirect URI with a code.`,examples:[`https://app.example/callback?code=SplxlOBeZQQYbYS6WxSbIA`]})}).meta({description:`The next step of the authorization, for a request that a script sends.`})})(r||=e.authorize||={});let i;(function(e){e.error=z({error:R().meta({description:"The RFC 6749 error code, such as `invalid_grant` or `invalid_client`.",examples:[`invalid_grant`]}),error_description:R().optional().meta({description:`The issuer's description of the error. Absent when the issuer sends none.`,examples:[`invalid code`]}),error_uri:Dn().optional().meta({description:`A page about the error. Absent when the issuer sends none.`,examples:[`https://example.com/docs/errors#invalid_grant`]}),request_id:R().optional().meta({description:"The request ID, which Tempo ID adds and `X-Request-Id` also carries.",examples:[`5b3e1f2a-8c4d-4e6f-9a0b-7c2d1e3f4a5b`]})}).meta({description:`The issuer's OAuth error response (RFC 6749 §5.2), passed through.`,id:`OAuthErrorResponse`}),e.form=z({client_id:R().optional().meta({description:"The app's client ID. Absent when the app authenticates with HTTP Basic `Authorization`.",examples:[`tempo-cli`]}),client_secret:R().optional().meta({description:`A confidential app's secret.`,examples:[`3bTm9qXc2Lr7WvN5kYp8Hs4Df6Ga1Je0`]}),code:R().optional().meta({description:"The authorization code to redeem, for the `authorization_code` grant.",examples:[`SplxlOBeZQQYbYS6WxSbIA`]}),code_verifier:R().optional().meta({description:"The PKCE verifier whose S256 hash is the authorization request's `code_challenge` (RFC 7636 §4.5).",examples:[`dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk`]}),device_code:R().optional().meta({description:`The device code, for the device code grant (RFC 8628 §3.4).`,examples:[`GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS`]}),grant_type:Sn([`authorization_code`,`client_credentials`,`refresh_token`,`urn:ietf:params:oauth:grant-type:device_code`]).meta({description:`The OAuth grant that the request redeems.`,examples:[`authorization_code`]}),redirect_uri:R().optional().meta({description:"The redirect URI of the authorization request, for the `authorization_code` grant.",examples:[`https://app.example/callback`]}),refresh_token:R().optional().meta({description:"The refresh token to redeem, for the `refresh_token` grant.",examples:[`yAjhKk7QnRZ3vD9pLm2Xc8Ws5Tf1Ub4N`]}),resource:Dn().optional().meta({description:`The API the access token is for (RFC 8707). Absent for Tempo ID's own origin.`,examples:[`https://id.tempo.xyz`]}),scope:R().optional().meta({description:`Space-separated OAuth scopes to request. Absent to keep the scopes of the grant.`,examples:[`openid profile email`]})}),e.response=Pn({access_token:R().meta({description:`The access token, an RS256 JWT for the requested resource.`,examples:[`eyJhbGciOiJSUzI1NiIsInR5cCI6ImF0K2p3dCJ9.e30.c2lnbmF0dXJl`]}),account:XL.account.optional().meta({description:"The Tempo Account that the key acts for. Present beside `key_authorization`.",examples:[`0x9a073914db0d149375ac2b7fbb72c68c0780fb5f`]}),expires_in:Cn().meta({description:`How long the access token lasts, in seconds.`,examples:[300]}),id_token:R().optional().meta({description:"The ID token, an RS256 JWT. Absent without the `openid` scope.",examples:[`eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.e30.c2lnbmF0dXJl`]}),key_authorization:XL.rpc.optional().meta({description:"The key authorization that the approval page signed, for the first redemption of a code whose request carried `key_authorization`. Absent for every other code, a refresh, and a key that expired."}),refresh_token:R().optional().meta({description:"The refresh token. Absent without the `offline_access` scope.",examples:[`yAjhKk7QnRZ3vD9pLm2Xc8Ws5Tf1Ub4N`]}),scope:R().optional().meta({description:`Space-separated OAuth scopes of the tokens.`,examples:[`openid profile email`]}),token_type:R().meta({description:`The type of the access token (RFC 6749 §7.1).`,examples:[`Bearer`]})}).meta({description:`The issuer's token response (RFC 6749 §5.1).`,id:`TokenResponse`})})(i||=e.token||={});let a;(function(e){e.form=z({client_id:R().optional().meta({description:"The app's client ID. The app holds the device grant. Absent when the app authenticates with HTTP Basic `Authorization`.",examples:[`tempo-cli`]}),client_secret:R().optional().meta({description:`A confidential app's secret.`,examples:[`3bTm9qXc2Lr7WvN5kYp8Hs4Df6Ga1Je0`]}),resource:Dn().optional().meta({description:`The API the access token is for (RFC 8707). Absent for Tempo ID's own origin.`,examples:[`https://id.tempo.xyz`]}),scope:R().optional().meta({description:`Space-separated OAuth scopes.`,examples:[`openid email offline_access`]})}),e.response=z({device_code:R().meta({description:"The secret code that the device polls `/oauth2/token` with (RFC 8628 §3.2). The device keeps it private.",examples:[`GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS`]}),expires_in:Cn().meta({description:`Seconds until the device code and user code expire.`,examples:[600]}),interval:Cn().meta({description:`Seconds between polls.`,examples:[5]}),user_code:R().meta({description:`The code that the user enters on the verification page: eight consonants.`,examples:[`WDJBMJHT`]}),verification_uri:Dn().meta({description:`The page where the user enters the user code.`,examples:[`https://id.tempo.xyz/device`]}),verification_uri_complete:Dn().meta({description:`The verification page with the user code filled in, for a link or QR code.`,examples:[`https://id.tempo.xyz/device?user_code=WDJBMJHT`]})}).meta({description:`The issuer's device authorization response (RFC 8628 §3.2).`}),e.issued=z({device_code:R(),expires_in:Cn()})})(a||=e.deviceCode||={});let o;(function(e){e.form=z({client_id:i.form.shape.client_id,client_secret:i.form.shape.client_secret,token:R().meta({description:`The token to introspect.`,examples:[`yAjhKk7QnRZ3vD9pLm2Xc8Ws5Tf1Ub4N`]}),token_type_hint:Sn([`access_token`,`refresh_token`]).optional().meta({description:"The type of `token`, which helps the issuer find it (RFC 7662 §2.1).",examples:[`refresh_token`]})}),e.response=Pn({active:On().meta({description:`Whether the token is active. An inactive token has no other members.`,examples:[!0]}),client_id:R().optional().meta({description:`The client ID of the app that the token belongs to.`,examples:[`tempo-cli`]}),exp:Cn().optional().meta({description:`When the token expires, in Unix seconds.`,examples:[1792076100]}),iat:Cn().optional().meta({description:`When the issuer issued the token, in Unix seconds.`,examples:[1792075800]}),iss:R().optional().meta({description:`The issuer's identifier.`,examples:[`https://id.tempo.xyz`]}),scope:R().optional().meta({description:`Space-separated OAuth scopes of the token.`,examples:[`openid profile email`]}),sub:R().optional().meta({description:`The user ID of the token's subject.`,examples:[`user_01JZ8Q6W3N1R5B4V7C2X9K0M3T`]})}).meta({description:`The issuer's introspection response (RFC 7662 §2.2).`,id:`IntrospectionResponse`})})(o||=e.introspect||={});let s;(function(e){e.form=z({client_id:i.form.shape.client_id,client_secret:i.form.shape.client_secret,token:R().meta({description:`The access or refresh token to revoke.`,examples:[`yAjhKk7QnRZ3vD9pLm2Xc8Ws5Tf1Ub4N`]}),token_type_hint:o.form.shape.token_type_hint})})(s||=e.revoke||={});let c;(function(e){e.response=Pn({email:R().optional().meta({description:"The user's email address. Absent without the `email` scope.",examples:[`ada@example.com`]}),email_verified:On().optional().meta({description:"Whether the issuer verified the email address. Absent without the `email` scope.",examples:[!0]}),sub:R().meta({description:`The user ID.`,examples:[`user_01JZ8Q6W3N1R5B4V7C2X9K0M3T`]})}).meta({description:`The issuer's UserInfo response (OIDC Core §5.3.2).`,id:`UserInfoResponse`})})(c||=e.userinfo||={});let l;(function(e){e.form=(e.query=z({client_id:R().optional().meta({description:"The app's client ID. Absent when `id_token_hint` names the app.",examples:[`tempo-cli`]}),continuation:R().optional().meta({description:`The sealed parameters of a form POST that carried no session cookie, which its 303 sends here. Absent otherwise.`,examples:[`a3f1c2…`]}),id_token_hint:R().optional().meta({description:"An ID token that Tempo ID issued to the app, which names the session to end. It may be expired. Required without `continuation`.",examples:[`eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.e30.c2lnbmF0dXJl`]}),post_logout_redirect_uri:Dn().optional().meta({description:`Where the browser goes after sign-out: one of the app's registered post-logout redirect URIs.`,examples:[`https://app.example/signed-out`]}),state:r.query.shape.state})).omit({continuation:!0}).extend({id_token_hint:R().meta({description:`An ID token that Tempo ID issued to the app, which names the session to end. It may be expired.`,examples:[`eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.e30.c2lnbmF0dXJl`]})}),e.response=z({signed_out:xn(!0).meta({description:`The browser holds no session that the hint names, since it ended or never held one.`})})})(l||=e.endSession||={});let u;(function(e){e.response=z({keys:Mn(Pn({alg:R().optional().meta({description:`The algorithm that the key signs with.`,examples:[`RS256`]}),kid:R().optional().meta({description:"The key ID, which matches the `kid` header of a token that the key signs.",examples:[`Qq0BN2lPx8VzTRsaGgMjc5HbEFKY4Wty`]}),kty:R().meta({description:`The key family (RFC 7518 §6.1).`,examples:[`RSA`]})})).meta({description:`The issuer's public signing keys, with the members of each key that RFC 7517 defines.`})}).meta({description:`The issuer's JSON Web Key Set (RFC 7517 §5).`,id:`JsonWebKeySet`})})(u||=e.jwks||={})})(Y5||={});var X5={...TV([]),400:{content:{"application/json":{schema:mV(Y5.token.error)}},description:`The issuer's refusal, passed through.`},401:{content:{"application/json":{schema:mV(Y5.token.error)}},description:`The issuer's refusal of the client or token, passed through.`}},Z5={responses:{200:{content:{"application/json":{schema:mV(Y5.introspect.response)}},description:`The issuer's introspection response.`},...X5,...TV([...yB,...LV.errors])},security:[{},{clientBasic:[]}],tags:[`OAuth`]},Q5={description:`Signs the browser out (OpenID Connect RP-Initiated Logout) when it holds the session that the app's ID token names: revokes the access and refresh tokens that apps received through that session, ends it, and clears its cookie and the account step's selections. Any other session stays signed in. Redirects the browser to the app's post-logout redirect URI.`,responses:{302:{description:"Redirects the browser to the app's post-logout redirect URI, with `state`."},...DV({errors:[...OV.errors,...c3.errors],success:{description:"The browser is signed out of the session that the hint names, for a request without `post_logout_redirect_uri`.",schema:Y5.endSession.response}})},tags:[`OAuth`]},$5=[`/.well-known/oauth-authorization-server`,`/.well-known/openid-configuration`,`/oauth2/authorize`,`/oauth2/introspect`,`/oauth2/jwks`,`/oauth2/revoke`,`/oauth2/token`,`/oauth2/userinfo`],e7=new Set([`/device/code`,`/oauth2/authorize`,`/oauth2/introspect`,`/oauth2/revoke`,`/oauth2/token`]),t7=new Iy().get(`/.well-known/openid-configuration`,vV({description:`Reads the issuer's OpenID Connect discovery document.`,responses:DV({success:{description:`The discovery document.`,schema:Y5.openidConfiguration.response}}),tags:[`OAuth`]}),e=>i7(e)).get(`/.well-known/oauth-authorization-server`,vV({description:`Reads the issuer's authorization server metadata.`,responses:DV({success:{description:`The metadata.`,schema:Y5.oauthAuthorizationServer.response}}),tags:[`OAuth`]}),e=>i7(e)).get(`/oauth2/authorize`,vV({description:`Starts an authorization. A signed-out browser goes to the sign-in page, and a signed-in one to the consent page or to the redirect URI with a code.`,responses:{200:{content:{"application/json":{schema:mV(Y5.authorize.response)}},description:`The next step, for a request that a script sends.`},302:{description:"Redirects the browser to the sign-in page, the consent page, or the redirect URI. A refused `key_authorization` returns to the redirect URI with `error` and `error_description`. An unknown or disabled app, or an unregistered redirect URI, redirects to the error page."},...X5,...TV(LV.errors)},tags:[`OAuth`]}),EV(`query`,Y5.authorize.query),e=>i7(e)).post(`/oauth2/token`,vV({description:`Redeems an authorization code, a refresh token, a device code, or client credentials for tokens.`,responses:{200:{content:{"application/json":{schema:mV(Y5.token.response)}},description:`The tokens.`},...X5,...TV([...yB,...LV.errors])},security:[{},{clientBasic:[]}],tags:[`OAuth`]}),EV(`form`,Y5.token.form),async e=>{let t=await Z(e,LV(e,{limits:[{binding:`TOKEN_LIMIT`,key:HV(e)}]}),`RateLimit.check`);if(t)return t;let n=new URLSearchParams(await Z(e,e.req.text(),`request.text`)),r=n7({authorization:e.req.header(`authorization`),form:n}),i=r?await Z(e,bF($,r),`Apps.authenticate`):!1;return await Z(e,LV(e,{limits:[{binding:`TOKEN_APP_LIMIT`,key:i?r?.clientId:void 0}]}),`RateLimit.check`)||i7(e)}).post(`/device/code`,vV({description:"Starts the device grant (RFC 8628 §3.1) for an app that holds it. The user approves the user code on the verification page, and the device redeems the device code at `/oauth2/token`. The device code binds to the user who approves it.",responses:{200:{content:{"application/json":{schema:mV(Y5.deviceCode.response)}},description:`The device code.`},...X5,...TV([...yB,...LV.errors])},security:[{},{clientBasic:[]}],tags:[`OAuth`]}),EV(`form`,Y5.deviceCode.form),async e=>{let t=HV(e),n=await Z(e,LV(e,{limits:[{binding:`DEVICE_LIMIT`,key:t===void 0?void 0:`${t}:form`}]}),`RateLimit.check`);if(n)return n;let r=await Z(e,i7(e),`oauth2.forward`);if(!r.ok)return r;let i=Y5.deviceCode.issued.parse(await Z(e,r.clone().json(),`response.json`));return await Z(e,R5(e,{device:null,deviceCode:i.device_code,expiresIn:i.expires_in}),`DeviceRequest.create`),r}).post(`/oauth2/introspect`,vV({description:"Introspects a token (RFC 7662). The app authenticates with its client credentials, in the body or as HTTP Basic `Authorization`.",...Z5}),EV(`form`,Y5.introspect.form),e=>i7(e)).post(`/oauth2/introspection`,vV({deprecated:!0,description:"Introspects a token, as `POST /oauth2/introspect` does. Clients of the older package call this path.",...Z5}),EV(`form`,Y5.introspect.form),async e=>{let t=new URL(e.req.url);t.pathname=`/oauth2/introspect`;let n=new Request(t,e.req.raw);return await Z(e,a7(e,{body:await Z(e,n.clone().text(),`request.text`),request:n}),`oauth2.limitDiscovery`)||Z(e,e.var.auth.handler(n),`auth.handler`)}).post(`/oauth2/revoke`,vV({description:"Revokes an access or refresh token (RFC 7009). The app authenticates with its client credentials, in the body or as HTTP Basic `Authorization`.",responses:{200:{content:{"application/json":{schema:{description:`Empty: the token is revoked, or was already invalid (RFC 7009 §2.2).`}}},description:`The token is revoked.`},...X5,...TV([...yB,...LV.errors])},security:[{},{clientBasic:[]}],tags:[`OAuth`]}),EV(`form`,Y5.revoke.form),e=>i7(e)).get(`/oauth2/userinfo`,vV({description:`Reads the token subject's claims (OIDC Core §5.3).`,responses:{200:{content:{"application/json":{schema:mV(Y5.userinfo.response)}},description:`The issuer's UserInfo response.`},...X5},security:[{accessToken:[]}],tags:[`OAuth`]}),e=>i7(e)).get(`/oauth2/end-session`,vV(Q5),OV(`query`,Y5.endSession.query),async e=>r7(e,e.req.valid(`query`))).post(`/oauth2/end-session`,vV({...Q5,responses:{...Q5.responses,...TV(yB),303:{description:"Continues a form POST without the session cookie as `GET /oauth2/end-session` with the sealed parameters in `continuation`, which the browser sends with the cookie."}}}),OV(`form`,Y5.endSession.form),async e=>r7(e,e.req.valid(`form`))).get(`/oauth2/jwks`,vV({description:`Reads the issuer's signing keys. A verifier may cache the response for 60 seconds, since a new key signs 5 minutes after its rotation.`,responses:DV({success:{description:`The JSON Web Key Set.`,schema:Y5.jwks.response}}),tags:[`OAuth`]}),async e=>{let t=await Z(e,i7(e),`oauth2.forward`);if(!t.ok)return t;let n=Y5.jwks.response.safeParse(await Z(e,t.clone().json(),`response.json`));return n.success&&n.data.keys.length>0&&t.headers.set(`cache-control`,`public, max-age=60`),t}).on([`GET`,`POST`],[...$5],e=>i7(e));function n7(e){let{authorization:t,form:n}=e;if(t&&/^Basic +/i.test(t))try{return Er(t)}catch{return}let[r,...i]=n.getAll(`client_id`).filter(e=>e.length>0),[a,...o]=n.getAll(`client_secret`).filter(e=>e.length>0);if(r&&a&&!i.length&&!o.length)return{clientId:r,clientSecret:a}}async function r7(e,t){let n=t.continuation===void 0?t:await Z(e,u3(t.continuation,{secret:U.SECRET}),`Logout.unseal`);if(!n)return X(e,new bR({issues:[{message:`Expired or invalid continuation. Send the logout request again`,path:[`continuation`]}]}));let r=n.id_token_hint;if(!r)return X(e,new bR({issues:[{message:`Required`,path:[`id_token_hint`]}]}));let i=await Z(e,mF($,{hint:r}),`SigningKey.hintKeys`),a=await Z(e,c3($,{clientId:n.client_id,hint:r,issuer:U.URL,jwks:i,postLogoutRedirectUri:n.post_logout_redirect_uri,state:n.state}),`Logout.check`);if(a instanceof tI)return X(e,a);let o=await Z(e,$4(e),`Session.token`),s=(o?await Z(e,d3($,{sessionId:a.sessionId,token:o}),`Logout.end`):void 0)!==void 0;if(!s&&e.req.method===`POST`){let t=await Z(e,l3({client_id:n.client_id,id_token_hint:r,post_logout_redirect_uri:n.post_logout_redirect_uri,state:n.state},{secret:U.SECRET}),`Logout.seal`),i=new URL(`/oauth2/end-session`,U.URL);return i.searchParams.set(`continuation`,t),e.header(`cache-control`,`no-store`),e.redirect(i.href,303)}return s&&(await Z(e,Z4(e),`Session.clear`),e.header(`set-cookie`,z2(),{append:!0})),e.header(`cache-control`,`no-store`),a.redirect?e.redirect(a.redirect,302):e.json({signed_out:!0},200)}async function i7(e){let t=await Z(e,l7(e),`oauth2.withResource`),n=t.method===`POST`?await Z(e,t.clone().text(),`request.text`):void 0,r=n!==void 0&&t.headers.get(`content-type`)?.toLowerCase().includes(`application/x-www-form-urlencoded`)?new URLSearchParams(n):new URL(t.url).searchParams;return await Z(e,a7(e,{body:n,request:t}),`oauth2.limitDiscovery`)||(e.req.path===`/oauth2/authorize`&&r.getAll(`client_id`).length>1?X(e,new bR({issues:[{message:`Repeated parameter. Send it once`,path:[`client_id`]}]})):e.req.path===`/oauth2/authorize`&&await Z(e,c7(e,{query:r}),`oauth2.refuseKey`)||Z(e,e.var.auth.handler(t),`auth.handler`))}async function a7(e,t){let{body:n,request:r}=t,i=new URL(r.url);if(!e7.has(i.pathname))return;let a=[...i.searchParams.getAll(`client_id`),...o7(n),s7(r)].filter(e=>e!==void 0);if(a.some(OF)&&(await Z(e,kF($,{clientIds:a}),`Apps.stale`)).length!==0)return Z(e,LV(e,{limits:[{binding:`APP_DISCOVERY_LIMIT`,key:HV(e)}]}),`RateLimit.check`)}function o7(e){if(!e)return[];let t=new URLSearchParams(e),n=(()=>{try{let t=JSON.parse(e);if(typeof t!=`object`||!t)return[];let n=t.client_id;return typeof n==`string`?[n]:[]}catch{return[]}})(),r=t.getAll(`client_assertion`).flatMap(e=>{try{let[,t]=e.split(`.`),n=JSON.parse(new TextDecoder().decode(ye(t??``)));if(typeof n!=`object`||!n)return[];let{iss:r,sub:i}=n;return[r,i].filter(e=>typeof e==`string`)}catch{return[]}});return[...t.getAll(`client_id`),...n,...r]}function s7(e){let t=e.headers.get(`authorization`);if(t&&/^Basic +/i.test(t))try{return Er(t).clientId}catch{return}}async function c7(e,t){let{query:n}=t;if(!n.has(`key_authorization`)&&!n.has(`challenge`))return;let r=n.get(`client_id`),i=n.get(`redirect_uri`);if(!r||!i||OF(r)&&!(await Z(e,e.var.auth.api.resolveOAuthClient({body:{client_id:r}}).catch(e=>{if(fi(e))return{resolved:!1};throw e}),`auth.resolveOAuthClient`)).resolved)return;let a=await Z(e,CF($,{clientId:r}).catch(e=>{if(!(e instanceof gF))throw e}),`Apps.get`);if(!a||!a.redirectUris.includes(i))return;let o=DR(n),s=o instanceof tI?o:o&&ER({app:a,clientId:r,codeChallenge:n.get(`code_challenge`),key:o,query:n});if(!s)return;let c=new URL(i);c.searchParams.append(`error`,s.response.error),c.searchParams.append(`error_description`,s.response.error_description);let l=n.get(`state`);return l&&c.searchParams.append(`state`,l),c.searchParams.append(`iss`,U.URL),e.header(`cache-control`,`no-store`),e.redirect(c.href,302)}async function l7(e){let t=e.req.raw;if(e.req.path===`/oauth2/authorize`&&e.req.method===`GET`){let e=new URL(t.url);return e.searchParams.has(`resource`)||e.searchParams.set(`resource`,U.URL),e.search=OR(e.searchParams).toString(),new Request(e,t)}if(e.req.path===`/oauth2/authorize`&&e.req.method===`POST`&&e.req.header(`content-type`)?.split(`;`)[0]?.toLowerCase().includes(`application/x-www-form-urlencoded`)){let n=new URLSearchParams(await Z(e,e.req.text(),`request.text`));n.has(`resource`)||n.set(`resource`,U.URL);let r=new Headers(t.headers);return r.delete(`content-length`),r.set(`content-type`,`application/x-www-form-urlencoded`),new Request(t.url,{body:OR(n),headers:r,method:`POST`})}if(e.req.path===`/oauth2/token`&&e.req.method===`POST`){let n=new URLSearchParams(await Z(e,e.req.text(),`request.text`));n.has(`resource`)||n.set(`resource`,U.URL);let r=new Headers(t.headers);return r.delete(`content-length`),new Request(t.url,{body:n,headers:r,method:`POST`})}if(e.req.path===`/device/code`&&e.req.method===`POST`){let n=new URLSearchParams(await Z(e,e.req.text(),`request.text`));n.has(`resource`)||n.set(`resource`,U.URL),n.delete(`user_id`);let r=new Headers(t.headers);return r.delete(`content-length`),r.set(`content-type`,`application/x-www-form-urlencoded`),new Request(t.url,{body:n,headers:r,method:`POST`})}return t}var u7=class extends nI(`return_to_not_permitted`){name=`Provider.ReturnToNotPermittedError`;constructor(e){super({error_description:`Invalid return_to: ${e.origin} is not an origin of the app's redirect URIs. Return to a page on one of them, and pass the app's client_id.`,field:`return_to`,meta:{origin:e.origin}})}},d7=class extends nI(`unknown_provider`){name=`Provider.UnknownError`;constructor(e){super({error_description:`Unknown provider: ${e.provider} is not offered. Request GET /v1/auth/providers for the providers offered.`,field:`provider`,meta:{provider:e.provider}})}},f7={google:`Google`};function p7(e){return e.google?[{id:`google`,name:f7.google}]:[]}async function m7(e,t){let{clientId:n,own:r}=t,i=new URL(t.returnTo,r);if(i.protocol!==`https:`&&i.protocol!==`http:`)return new u7({origin:i.origin});if(i.origin===r)return i.href;let[a]=n?await e.select({redirectUris:iP.redirectUris}).from(iP).where(cM(Y(iP.clientId,n),_M(iP.clientDiscoveryId))):[];return(a?.redirectUris??[]).flatMap(e=>{let t=URL.parse(e);return t&&(t.protocol===`https:`||t.protocol===`http:`)?[t.origin]:[]}).includes(i.origin)?i.href:new u7({origin:i.origin})}(function(e){e.errors=[u7]})(m7||={});var h7=`tempo-id-grant`,g7=`tempo-id-sign-in-app`,_7=600,v7;(function(e){let t;(function(e){e.response=z({providers:Mn(z({id:Sn([`google`]).meta({description:"The provider's ID, which `GET /v1/auth/oauth/{provider}` takes.",examples:[`google`]}),name:R().meta({description:"The name to show, such as `Google`.",examples:[`Google`]})}).meta({description:`One provider Tempo ID offers.`})).readonly().meta({description:`The providers Tempo ID offers, in the order a page shows them. Empty when the deployment configures none.`})})})(t||=e.providers||={});let n;(function(e){e.param=z({provider:R().min(1).max(64).meta({description:"The ID of the provider, from `GET /v1/auth/providers`.",examples:[`google`]})}),e.query=z({client_id:R().min(1).max(255).optional().meta({description:"The app's client ID. A `return_to` on an origin of the app's redirect URIs requires it.",examples:[`client_01JZ8Q6W3N1R5B4V7C2X9K0M3T`]}),oauth_query:R().min(1).max(8192).optional().meta({description:`The signed authorization request in the sign-in page's query. The callback continues it, and redirects to the app.`,examples:[`client_id=tempo-cli&response_type=code&exp=1767225600&sig=4mLx2Wq9cH8t`]}),return_to:R().min(1).max(8448).refine(e=>URL.canParse(e,`https://id.invalid`),{message:`Set an absolute URL, or a path on Tempo ID`}).optional().meta({description:"The page that the browser returns to, signed in, on Tempo ID's origin or an origin of the app's redirect URIs. Defaults to the account page. A failed sign-in returns there with `error=access_denied`.",examples:[`https://app.example.com/welcome`]})})})(n||=e.signIn||={});let r;(function(e){e.param=n.param,e.query=n.query.pick({client_id:!0,return_to:!0})})(r||=e.failed||={});let i;(function(e){e.param=n.param,e.query=z({code:R().optional().meta({description:`The provider's authorization code.`,examples:[`4/0AVMBsJh7c2X9K0M3T`]}),error:R().optional().meta({description:`The provider's error code, for a refused sign-in.`,examples:[`access_denied`]}),state:R().optional().meta({description:`The state that the redirect to the provider sent.`,examples:[`Qm7rXcJ2bWv9Tk4LsN8pHd3F`]})})})(i||=e.callback||={})})(v7||={});var y7=new Iy().get(`/v1/auth/providers`,vV({description:`Lists the OAuth providers Tempo ID offers, for an app that shows its own sign-in buttons.`,responses:DV({success:{description:`The providers.`,schema:v7.providers.response}}),tags:[`Authenticate`]}),e=>e.json({providers:p7({google:b5()})},200)).get(`/v1/auth/oauth/:provider`,vV({description:"Redirects the browser to the provider. The provider returns it to `/callback/{provider}`, which sets the session cookie, then continues `oauth_query` or redirects to `return_to`. The callback grants the key of `oauth_query` only when Tempo ID's own sign-in page sent the browser here.",responses:{302:{description:`Redirects the browser to the provider.`},...TV([...OV.errors,...m7.errors,...LV.errors,$z,d7])},tags:[`Authenticate`]}),OV(`param`,v7.signIn.param),OV(`query`,v7.signIn.query),async e=>{let t=e.req.valid(`query`),n=p7({google:b5()}).find(t=>t.id===e.req.valid(`param`).provider);if(!n)return X(e,new d7({provider:e.req.valid(`param`).provider}));let r=HV(e),i=await Z(e,LV(e,{limits:[{binding:`SIGN_IN_IP_LIMIT`,key:r?`provider:${r}`:void 0}]}),`RateLimit.check`);if(i)return i;let a=await Z(e,m7($,{clientId:t.client_id,own:new URL(U.URL).origin,returnTo:t.return_to??`/`}),`Provider.returnTo`);if(a instanceof tI)return X(e,a);let o=new URL(`/v1/auth/oauth/${n.id}/failed`,U.URL);o.searchParams.set(`return_to`,t.return_to??`/`),t.client_id&&o.searchParams.set(`client_id`,t.client_id);let s=await Z(e,e.var.auth.api.signInSocial({body:{callbackURL:a,disableRedirect:!0,errorCallbackURL:o.href,provider:n.id,...t.oauth_query?{oauth_query:t.oauth_query}:{}},headers:new Headers(e.req.raw.headers),returnHeaders:!0}),`auth.signInSocial`).catch(e=>{if(fi(e)&&e.body?.error===`invalid_signature`)return new $z;throw e});if(s instanceof tI)return X(e,s);for(let t of s.headers.getSetCookie())e.header(`set-cookie`,t,{append:!0});t.oauth_query&&e.req.header(`sec-fetch-site`)===`same-origin`?OB(e,h7,y4(new URLSearchParams(t.oauth_query)),{httpOnly:!0,maxAge:_7,path:`/`,prefix:`host`,sameSite:`Lax`,secure:!0}):kB(e,h7,{path:`/`,prefix:`host`,secure:!0});let c=t.oauth_query?new URLSearchParams(t.oauth_query).get(`client_id`):null;return c?OB(e,g7,c,{httpOnly:!0,maxAge:_7,path:`/`,prefix:`host`,sameSite:`Lax`,secure:!0}):kB(e,g7,{path:`/`,prefix:`host`,secure:!0}),e.header(`cache-control`,`private, no-store`),e.redirect(s.response.url??`/`,302)}).get(`/v1/auth/oauth/:provider/failed`,vV({description:"Redirects the browser from a failed provider sign-in to `return_to`, with `error=access_denied`. The code is the same for every cause, so it reveals neither the cause nor whether an account exists.",responses:{302:{description:"Redirects the browser to `return_to`."},...TV([...OV.errors,...m7.errors])},tags:[`Authenticate`]}),OV(`param`,v7.failed.param),OV(`query`,v7.failed.query),async e=>{let t=e.req.valid(`query`),n=await Z(e,m7($,{clientId:t.client_id,own:new URL(U.URL).origin,returnTo:t.return_to??`/login`}),`Provider.returnTo`);if(n instanceof tI)return X(e,n);let r=new URL(n);return r.searchParams.set(`error`,`access_denied`),e.redirect(r.href,302)}).get(`/callback/:provider`,vV({description:"Receives the provider's redirect, sets the session cookie, and redirects the browser to `return_to`, or continues the app's authorization. For a user with no Tempo Account in the realm of the sign-in, it creates one, as `POST /v1/auth/code/verify` does. A failure redirects to the failed route, or to the error page with `error=invalid_callback_request` if the browser holds no state for the callback.",responses:{302:{description:"Redirects the browser to `return_to`, to the app's redirect URI, to the failed route, or to the error page."},...TV([])},tags:[`Authenticate`]}),EV(`param`,v7.callback.param),EV(`query`,v7.callback.query),async e=>{let t=await Z(e,e.var.auth.handler(e.req.raw),`auth.handler`),n=t.headers.get(`location`);if(t.status!==302||!n)return t;let r=new URL(`/error`,U.URL),i=URL.parse(n,U.URL);if(i?.origin===r.origin&&i.pathname===r.pathname){r.searchParams.set(`error`,`invalid_callback_request`);let e=new Headers(t.headers);return e.set(`location`,r.href),new Response(null,{headers:e,status:302})}let a=e.var.newSession;a&&await Z(e,S5(e,{clientId:TB(e,g7,`host`)??null,userId:a.user.id}),`FirstAccount.create`);let o=TB(e,h7,`host`),s=URL.parse(n,U.URL),c=o&&s&&y4(s.searchParams)===o?await Z(e,j4(e,{redirect:n,setCookie:t.headers.getSetCookie()}),`SignInConsent.afterSignIn`):n;if(!o&&c===n)return t;let l=new Headers(t.headers);return l.set(`location`,c),o&&l.append(`set-cookie`,oe(`__Host-${h7}`,``,{httpOnly:!0,maxAge:0,path:`/`,sameSite:`Lax`,secure:!0})),new Response(null,{headers:l,status:302})}),b7=new Iy().route(`/`,K5).route(`/`,t3).route(`/`,M5).route(`/`,L5).route(`/`,W5).route(`/`,t7).route(`/`,y7),x7=new Iy().use(oB).use(e4()).use(J5).use(N1).use(qy({referrerPolicy:`same-origin`})).use(tb()).use(`/.well-known/oauth-authorization-server`,Y4).use(`/.well-known/openid-configuration`,Y4).use(`/oauth2/introspect`,Y4).use(`/oauth2/introspection`,Y4).use(`/oauth2/jwks`,Y4).use(`/oauth2/revoke`,Y4).use(`/oauth2/token`,Y4).use(`/oauth2/userinfo`,Y4).use(`/v1/*`,J4).use(zy([`/device/code`,`/oauth2/*`],Wy())).use(`/device/code`,xB).use(`/oauth2/*`,xB).use(`/v1/*`,xB).use(v5).route(`/`,b7).get(`/openapi.json`,vV({description:`Returns this OpenAPI document.`,responses:{200:{content:{"application/json":{schema:{type:`object`}}},description:`The OpenAPI 3.1 document.`},...TV([])},tags:[`Reference`]}),async e=>e.json(await Z(e,SV(x7),`OpenApi.document`),200)).get(`/docs`,vV({description:`Renders this OpenAPI document as an API reference.`,responses:{200:{content:{"text/html":{schema:{type:`string`}}},description:`The API reference page.`},...TV([])},tags:[`Reference`]}),e=>(e.header(`content-security-policy`,wV),e.html(CV))).all(`/:version{v\\d+}/*`,e=>X(e,new sI)).notFound(async e=>S7(e.req.path)?X(e,new sI):Z(e,e.env.pages(e),`page.render`)).onError(fI);function S7(e){if(C7.has(e))return!1;let t=e.split(`/`)[1]??``;return w7.has(t)||/^v\d+$/.test(t)}var C7=new Set([`/device`]),w7=new Set(x7.routes.flatMap(e=>{let t=e.path.split(`/`)[1]??``;return t&&t!==`*`&&!t.startsWith(`:`)?[t]:[]})),T7=new WeakSet;function E7(e){if(e instanceof Response)return e;let t;return t=e==null?new Response(null,{status:204}):typeof e==`string`?new Response(e,{headers:{"Content-Type":`text/html; charset=utf-8`}}):Response.json(e),T7.add(t),t}function D7(e){return Array.from(e,e=>({message:e.message,path:e.path?.map(e=>typeof e==`object`?e.key:e).join(`.`)}))}async function O7(e,t){let n=await e[`~standard`].validate(t);return n.issues?{ok:!1,issues:n.issues}:{ok:!0,value:n.value}}async function k7(e,t){let n={},r=[];if(e.params){let i=t.req.param(),a=await O7(e.params,i);a.ok?n.params=a.value:r.push({slot:`params`,issues:D7(a.issues)})}if(e.query){let i=new URL(t.req.url),a={};for(let[e,t]of i.searchParams)a[e]=t;let o=await O7(e.query,a);o.ok?n.query=o.value:r.push({slot:`query`,issues:D7(o.issues)})}if(e.body){let i;try{i=await t.req.json()}catch{return{ok:!1,response:Response.json({error:`Invalid JSON body`},{status:400})}}let a=await O7(e.body,i);a.ok?n.body=a.value:r.push({slot:`body`,issues:D7(a.issues)})}return r.length>0?{ok:!1,response:Response.json({error:`Validation failed`,issues:r},{status:400})}:{ok:!0,input:n}}function A7(...e){if(e.length===1)return e[0];let t=e.slice(0,-1),n=e[e.length-1];return(async e=>{let r=0,i=async()=>{if(r<t.length){let n=t[r++],a=await n(e,i);a instanceof Response&&(e.res=a)}else e.res=E7(await n(e))};return await i(),e.res})}(function(e){function t(e){return t=>(async n=>{let r=await k7(e,n);return r.ok?E7(await t(n,r.input)):r.response})}e.withValidator=t})(A7||={}),new TextEncoder,new TextDecoder(`utf-8`,{fatal:!0});function j7(e){return e}var M7=864e5,N7=j7(async e=>{let t=new Date;try{await P2.delete(yP).where(pM(yP.expiresAt,t)),await P2.delete(eP).where(pM(eP.expiresAt,t)),await P2.delete(SP).where(pM(SP.expiresAt,t)),await P2.delete(TP).where(pM(TP.expiresAt,t)),await P2.delete(iP).where(cM(vM(iP.clientDiscoveryId),pM(iP.updatedAt,new Date(t.getTime()-M7)),q`not exists (select 1 from ${lP} where ${lP.clientId} = ${iP.clientId})`,q`not exists (select 1 from ${xP} where ${xP.clientId} = ${iP.clientId})`)),await P2.delete(aP).where(pM(aP.expiresAt,t)),await P2.delete(nP).where(pM(nP.expiresAt,t)),await P2.delete(dP).where(cM(pM(dP.expiresAt,t),bM(P2.select({one:q`1`}).from(nP).where(Y(nP.refreshId,dP.id))))),await P2.delete(hP).where(cM(pM(hP.expiresAt,t),bM(P2.select({one:q`1`}).from(nP).where(Y(nP.sessionId,hP.id))),bM(P2.select({one:q`1`}).from(dP).where(Y(dP.sessionId,hP.id)))))}catch(t){throw WF({error:t,fields:{cron:e.cron},message:`The cleanup cron failed.`}),t}}),P7=[`ratelimit`,`ratelimit-policy`,`retry-after`],F7=[`cf-connecting-ip`,`cf-ray`,`cf-worker`,`user-agent`],I7=bv(kh),L7={fetch:(e,t,n)=>x7.fetch(e,{...t,pages:e=>R7(e,{env:t,ctx:n})},n),scheduled:(...e)=>zv(e[1],()=>N7(...e))};async function R7(e,t){let{ctx:n,env:r}=t,i=V7(e.req.header(`cookie`)),a=new URL(e.req.url).origin,o,s,c=!1,l=async(t,o)=>{let l=new Request(t,o),u=new URL(l.url);if(u.origin!==a||!u.pathname.startsWith(`/v1/`))throw Error(`A page called a path outside the JSON API.`);i.size>0&&l.headers.set(`cookie`,H7(i));for(let t of F7){let n=e.req.header(t);n&&l.headers.set(t,n)}let d=await Z(e,Promise.resolve(x7.fetch(l,{...r,pages:()=>B7()},n)),`api`,`${l.method} ${new URL(l.url).pathname}`);for(let t of d.headers.getSetCookie())z7(i,{setCookie:t}),c?qF(e,{message:`A page set a cookie after its headers were sent.`}):e.header(`set-cookie`,t,{append:!0});return d.status===429&&(s??=d),d},u=await I7(e.req.raw,{context:{fetch:async(t,n)=>{o&&await Z(e,o.catch(()=>void 0),`api.wait`);let r=l(t,n);return o??=r,r},origin:a}});if(c=!0,e.header(`cache-control`,`private, no-store`),s&&u.status===200){for(let t of P7){let n=s.headers.get(t);n&&e.header(t,n)}return e.newResponse(u.body,{headers:u.headers,status:429})}return e.newResponse(u.body,u)}function z7(e,t){let[n,...r]=t.setCookie.split(`;`),i=n.indexOf(`=`),a=n.slice(0,i).trim(),o=n.slice(i+1).trim();r.some(e=>/^max-age=0$/i.test(e.trim()))||!o?e.delete(a):e.set(a,o)}function B7(){return Promise.resolve(new Response(null,{status:404}))}function V7(e){let t=new Map;for(let n of e?.split(`;`)??[]){let e=n.indexOf(`=`);e>0&&t.set(n.slice(0,e).trim(),n.slice(e+1).trim())}return t}function H7(e){return[...e].map(([e,t])=>`${e}=${t}`).join(`; `)}function U7(){let e=null;return async(t,n)=>{if(e)return e;let r=globalThis.__VITE_MANIFEST__;if(typeof r==`object`&&r)return e=r,e;let i=n?.ASSETS;if(!i||typeof i.fetch!=`function`)return null;let a=await i.fetch(new Request(new URL(`/.vite/manifest.json`,t.url).toString()));return a.ok?(e=await a.json(),e):null}}var W7={".avif":`image/avif`,".css":`text/css; charset=utf-8`,".gif":`image/gif`,".html":`text/html; charset=utf-8`,".ico":`image/x-icon`,".jpeg":`image/jpeg`,".jpg":`image/jpeg`,".js":`text/javascript; charset=utf-8`,".json":`application/json; charset=utf-8`,".mjs":`text/javascript; charset=utf-8`,".png":`image/png`,".svg":`image/svg+xml`,".txt":`text/plain; charset=utf-8`,".wasm":`application/wasm`,".webp":`image/webp`,".woff":`font/woff`,".woff2":`font/woff2`};function G7(e,t,n=`assets`,r=!1){if(![`GET`,`HEAD`].includes(e.method)||![200,206,304].includes(t.status))return t;let i=new URL(e.url).pathname,a=i.slice(i.lastIndexOf(`/`)+1),o=a.slice(a.lastIndexOf(`.`)).toLowerCase(),s=new Headers(t.headers);!s.has(`Content-Type`)&&W7[o]&&s.set(`Content-Type`,W7[o]);let c=s.get(`Cache-Control`),l=(c??``).toLowerCase().split(`,`).map(e=>e.trim()).sort().join(`,`)===`max-age=0,must-revalidate,public`,u=r&&i.startsWith(`/`+n.replace(/^\/+|\/+$/g,``)+`/`)&&o!==`.html`&&!(s.get(`Content-Type`)??``).toLowerCase().includes(`text/html`);return!s.has(`Set-Cookie`)&&u&&(!c||l)?s.set(`Cache-Control`,`public, max-age=31536000, immutable`):c||s.set(`Cache-Control`,`no-store`),new Response(t.body,{status:t.status,statusText:t.statusText,headers:s})}function K7(e,t=U7()){let n;return async(r,i,a)=>{let o=new URL(r.url).pathname;return![`GET`,`HEAD`].includes(r.method)||![200,206,304].includes(a.status)||!o.startsWith(`/`+(e??`assets`).replace(/^\/+|\/+$/g,``)+`/`)?G7(r,a,e):(n||=t(r,i).then(e=>new Set(Object.values(e??{}).flatMap(e=>Array.isArray(e?.immutableFiles)?e.immutableFiles:[])),()=>new Set),G7(r,a,e,(await n).has(o.slice(1))))}}function q7(e={}){let t=K7(e.assetsDir);return async(n,r,i)=>{if(i.status!==404||!r.ASSETS||n.method!==`GET`&&n.method!==`HEAD`)return i;let a=await r.ASSETS.fetch(new Request(n.url,{method:n.method,headers:n.headers}));if(a.status!==404)return t(n,r,a);let o=n.headers.get(`accept`)??``;if(e.serveSpaFallback&&o.includes(`text/html`)){let e=new URL(`/index.html`,n.url),t=await r.ASSETS.fetch(new Request(e,{method:n.method}));if(t.status===200){let e=new Response(t.body,{status:200,headers:t.headers});return e.headers.set(`Cache-Control`,`no-store`),e.headers.set(`Content-Type`,`text/html; charset=utf-8`),e}}else if(!e.serveSpaFallback&&e.notFound===`404-page`&&o.includes(`text/html`)&&(a.headers.get(`content-type`)??``).includes(`text/html`)){let e=new Response(a.body,a);return e.headers.set(`Cache-Control`,`no-store`),e}return i}}var J7={...L7,fetch(e,t,n){return zv(t,async()=>Y7(e,t,await L7.fetch(e,t,n)))}},Y7=q7({assetsDir:`assets`,serveSpaFallback:!1,notFound:`none`}),X7=J7??{};export{X7 as default};
|
|
610
610
|
//# sourceMappingURL=index.js.map
|