@botanary/agent 0.1.0-alpha.11 → 0.1.0-alpha.12
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/README.md +1 -1
- package/dist/exact-action.d.ts +15 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/runtime.d.ts +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @botanary/agent
|
|
2
2
|
|
|
3
|
-
Version 0.1.0-alpha.
|
|
3
|
+
Version 0.1.0-alpha.12, canonical API contract 2026-09-12. MIT licensed. Node 22 or later.
|
|
4
4
|
|
|
5
5
|
The runtime is extracted from `botanary-mcp`. MCP keeps desktop keychain adapters, profile selection,
|
|
6
6
|
owner sessions and approval handles. The CLI consumes that desktop adapter through MCP. The shared
|
package/dist/exact-action.d.ts
CHANGED
|
@@ -69,9 +69,23 @@ export interface MandateTransferInput {
|
|
|
69
69
|
readonly amountRaw: string;
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
|
+
export interface MandateSwapInput {
|
|
73
|
+
readonly mandate: AgentMandateProjection;
|
|
74
|
+
readonly action: {
|
|
75
|
+
readonly type: 'swap';
|
|
76
|
+
readonly tokenAddress: Hex;
|
|
77
|
+
readonly tokenOutAddress: Hex;
|
|
78
|
+
readonly amountRaw: string;
|
|
79
|
+
readonly routerAddress: Hex;
|
|
80
|
+
readonly minAmountOutRaw: string;
|
|
81
|
+
readonly maxSlippageBps?: number;
|
|
82
|
+
readonly verifyRoute?: (facts: SwapRouteFacts) => Promise<boolean> | boolean;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export type MandateActionInput = MandateTransferInput | MandateSwapInput;
|
|
72
86
|
export interface AgentPolicyRefusal {
|
|
73
87
|
readonly status: 'refused';
|
|
74
|
-
readonly reason: 'over_per_action_max' | 'wrong_recipient' | 'mandate_inactive' | 'mandate_revoked' | 'mandate_expired';
|
|
88
|
+
readonly reason: 'over_per_action_max' | 'wrong_recipient' | 'unbudgeted_swap_leg' | 'mandate_inactive' | 'mandate_revoked' | 'mandate_expired';
|
|
75
89
|
readonly transactionSubmitted: false;
|
|
76
90
|
readonly requestedAmountRaw: string;
|
|
77
91
|
readonly perActionMaxRaw: string | null;
|
package/dist/index.d.ts
CHANGED
|
@@ -7,4 +7,4 @@ export { registerAgent, type AgentRegistrationClient } from './registration.js';
|
|
|
7
7
|
export type * from './views.js';
|
|
8
8
|
export { PairingCodeManager, DEFAULT_PAIRING_CODE_TTL_MS, type PairingCode } from './pairing-code.js';
|
|
9
9
|
export { crockfordBase32, deriveFingerprint, generatePairingNonce, FINGERPRINT_BYTES, NONCE_BYTES } from './fingerprint.js';
|
|
10
|
-
export type { ExactAgentAction, ExactAgentExecution, AgentActionBinding, AgentSwapBinding, SwapRouteFacts, PreparedAgentAction, AgentMandateProjection, MandateTransferInput, AgentPolicyRefusal } from './exact-action.js';
|
|
10
|
+
export type { ExactAgentAction, ExactAgentExecution, AgentActionBinding, AgentSwapBinding, SwapRouteFacts, PreparedAgentAction, AgentMandateProjection, MandateTransferInput, MandateSwapInput, MandateActionInput, AgentPolicyRefusal } from './exact-action.js';
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var h=class extends Error{constructor(t,n,i=null,d=null){super(t);this.status=n;this.details=i;this.retryAfterSeconds=d;this.name="BotanaryApiError"}requestId;code;operationId;userOpHash;requirementId;ambiguous=!1};import{encodeFunctionData as O,encodePacked as Oe,decodeFunctionData as j,parseAbi as D,getAddress as v,zeroAddress as Be,zeroHash as Te}from"viem";import{entryPoint07Address as oe,getUserOperationHash as He}from"viem/account-abstraction";import{publicKeyToAddress as _e}from"viem/accounts";function a(){let r=new h("Botanary returned an invalid response. Nothing was signed.",0);throw r.code="invalid_response",r}function m(r){return typeof r!="object"||r===null||Array.isArray(r)?a():r}function c(r,e){(typeof r!="string"||!/^0x(?:[0-9a-fA-F]{2})*$/.test(r)||e!==void 0&&r.length!==2+2*e)&&a()}function A(r){(typeof r!="string"||!/^[A-Za-z0-9_-]{1,128}$/.test(r)||/^(?:bsk|deo|ags|dcs|dca|dcr|dcc|dcq|din)_/.test(r))&&a()}function k(r){if(typeof r!="string")return!1;let e=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.exec(r);if(!e)return!1;let t=Number(e[1]),n=Number(e[2]),i=Number(e[3]),s=[31,t%4===0&&(t%100!==0||t%400===0)?29:28,31,30,31,30,31,31,30,31,30,31];return t>=1&&n>=1&&n<=12&&i>=1&&i<=s[n-1]&&Number(e[4])<=23&&Number(e[5])<=59&&Number(e[6])<=59&&Number.isFinite(Date.parse(r))}function N(r){(typeof r!="string"||!/^(0|[1-9][0-9]{0,77})$/.test(r)||BigInt(r)>=2n**256n)&&a()}function U(r){let e=m(r);return c(e.address,20),c(e.publicKey,65),(!e.publicKey.startsWith("0x04")||_e(e.publicKey).toLowerCase()!==e.address.toLowerCase()||typeof e.fingerprint!="string"||!/^[A-Za-z0-9]{1,32}$/.test(e.fingerprint)||typeof e.backend!="string"||!/^[A-Za-z0-9_-]{1,64}$/.test(e.backend)||!k(e.createdAt))&&a(),Object.freeze({address:e.address,publicKey:e.publicKey,fingerprint:e.fingerprint,backend:e.backend,createdAt:e.createdAt})}function M(r){let e=m(r);return(typeof e.intentType!="string"||!e.intentType||typeof e.userOpHash!="string")&&a(),c(e.userOpHash,32),E(e.userOp),e}function Ee(r){let e=m(r);return c(e.to,20),c(e.data),N(e.value),(!Number.isSafeInteger(e.chainId)||Number(e.chainId)<1)&&a(),{to:e.to,data:e.data,value:e.value,chainId:Number(e.chainId)}}function ie(r){let e=m(r);return(!["id","agentId","accountId","declineReason","reason"].every(t=>typeof e[t]=="string"&&e[t].length>0)||!Array.isArray(e.calls)||!k(e.raisedAt)||!k(e.expiresAt)||Date.parse(e.expiresAt)<=Date.parse(e.raisedAt)||!["open","approved","expired","withdrawn"].includes(String(e.status)))&&a(),{...e,calls:e.calls.map(Ee)}}function se(r){let e=m(r);if(c(e.address,20),(!["id","name","fingerprint","accountId"].every(t=>typeof e[t]=="string"&&e[t].length>0)||!k(e.connectedAt)||!(e.accountAddress==null||typeof e.accountAddress=="string")||e.accountAddress!=null&&!/^0x[0-9a-fA-F]{40}$/.test(e.accountAddress))&&a(),e.grant!==null){let t=m(e.grant);c(t.permissionId,32),(typeof t.id!="string"||!t.id||typeof t.status!="string"||!t.status||typeof t.humanSummary!="string"||typeof t.chain!="string"||!Number.isSafeInteger(t.chainId)||!m(t.policySet)||!Array.isArray(t.spentToDate))&&a()}if(e.accountSetup!=null){let t=m(e.accountSetup);(typeof t.ready!="boolean"||!Array.isArray(t.missing)||!t.missing.every(n=>typeof n=="string")||t.ready!==(t.missing.length===0)||!Number.isSafeInteger(t.chainId)||Number(t.chainId)<1)&&a()}return e}function x(r,e=256){if(typeof r!="string"||!/^(0|[1-9][0-9]{0,77}|0x[0-9a-fA-F]{1,64})$/.test(r))return a();let t=BigInt(r);return t>=2n**BigInt(e)?a():t}function E(r){let e=m(r);for(let t of["sender","entryPoint"])c(e[t],20);for(let t of["nonce","callGasLimit","verificationGasLimit","preVerificationGas","maxFeePerGas","maxPriorityFeePerGas"])x(e[t]);for(let t of["callData","signature"])c(e[t]);for(let t of["paymasterVerificationGasLimit","paymasterPostOpGasLimit"])e[t]!=null&&x(e[t],128);(!Number.isSafeInteger(e.chainId)||Number(e.chainId)<=0)&&a();for(let t of["factory","paymaster"])e[t]!=null&&c(e[t],20);for(let t of["factoryData","paymasterData"])e[t]!=null&&c(e[t]);return r}function $(r){let e=m(r);c(e.payload,32),c(e.validator,20),(!Number.isSafeInteger(e.index)||Number(e.index)<0||Number(e.index)>=2**32)&&a();let t=m(e.authorization);return c(t.from,20),c(t.to,20),c(t.nonce,32),N(t.value),N(t.validAfter),N(t.validBefore),BigInt(t.validBefore)<=BigInt(t.validAfter)&&a(),{payload:e.payload,validator:e.validator,index:Number(e.index),authorization:{from:t.from,to:t.to,nonce:t.nonce,value:t.value,validAfter:t.validAfter,validBefore:t.validBefore}}}function F(r,e){let t=m(r);(t.requirementId!==e||typeof t.simulated!="boolean")&&a();let n={ready:["not_submitted"],pending_approval:["not_submitted"],submitted:["pending"],settled:["settled"],declined:["not_submitted","not_settled"]};return(typeof t.status!="string"||!Object.hasOwn(n,t.status)||!n[t.status].includes(String(t.paymentStatus)))&&a(),t.providerStatus!==void 0&&(!Number.isSafeInteger(t.providerStatus)||Number(t.providerStatus)<100||Number(t.providerStatus)>599)&&a(),t.txHash!==void 0&&c(t.txHash,32),t.status==="settled"&&c(t.txHash,32),t.status==="ready"?$(t.ready):t.ready!==void 0&&a(),t}var ae=D(["function execute(bytes32 mode, bytes executionCalldata) payable"]),W=D(["function executeUnderGrant(bytes32 permissionId, address target, uint256 value, bytes callData)","function executeUnderGrantWithAllowance(bytes32 permissionId, address target, uint256 value, address token, uint256 allowance, bytes callData)"]),Ce=D(["function transfer(address to, uint256 amount) returns (bool)"]),de=D(["function swapExactIn(address tokenIn, address tokenOut, uint256 amountIn, uint256 minOut, address to) returns (uint256 amountOut)"]),Ne=BigInt("0x000100000000008bdaba73cd9815d79069c247eb4bda0000");function y(r,e){return typeof r=="string"&&r.toLowerCase()===e.toLowerCase()}function b(r,e=!0){if(typeof r!="string"||!/^(0|[1-9][0-9]{0,77})$/.test(r))return a();let t=BigInt(r);return t>=2n**256n||e&&t===0n?a():t}function ce(r){let e=m(r),t=["accountId","accountAddress","chainId","action","tokenAddress","amount","recipient","tokenOutAddress","maxSlippageBps"];return Object.keys(e).some(n=>!t.includes(n))&&a(),A(e.accountId),c(e.accountAddress,20),c(e.tokenAddress,20),b(e.amount),(!Number.isSafeInteger(e.chainId)||Number(e.chainId)<=0)&&a(),e.action==="transfer"?(c(e.recipient,20),(e.tokenOutAddress!==void 0||e.maxSlippageBps!==void 0)&&a()):e.action==="swap"?(c(e.tokenOutAddress,20),(e.recipient!==void 0||e.maxSlippageBps!==void 0&&(!Number.isInteger(e.maxSlippageBps)||Number(e.maxSlippageBps)<1||Number(e.maxSlippageBps)>1e3))&&a()):a(),Object.freeze({...r,accountAddress:v(r.accountAddress),tokenAddress:v(r.tokenAddress),...r.recipient!==void 0?{recipient:v(r.recipient)}:{},...r.tokenOutAddress!==void 0?{tokenOutAddress:v(r.tokenOutAddress)}:{}})}function ue(r,e){if(A(r.delegationId),c(r.permissionId,32),c(r.executorAddress,20),b(r.maxGasCostWei),e.action==="swap"){let t=r;c(t.routerAddress,20),b(t.minAmountOut),t.verifyRoute!==void 0&&typeof t.verifyRoute!="function"&&a()}return Object.freeze({...r,executorAddress:v(r.executorAddress),...e.action==="swap"?{routerAddress:v(r.routerAddress)}:{}})}async function pe(r,e,t){try{let n=m(r),i=m(n.execution),d=E(n.userOp),s=Object.freeze({...d,sender:v(d.sender),entryPoint:v(d.entryPoint)});c(n.userOpHash,32),(n.intentType!=="delegated_action"||m(n.simulation).willSucceed!==!0||i.accountId!==e.accountId||!y(i.accountAddress,e.accountAddress)||i.chainId!==e.chainId||i.action!==e.action||i.amount!==e.amount||!y(i.tokenAddress,e.tokenAddress)||i.delegationId!==t.delegationId||!y(i.permissionId,t.permissionId)||i.gasMethod!=="native"||!y(s.sender,e.accountAddress)||s.chainId!==e.chainId||!y(s.entryPoint,oe)||s.factory!=null||s.factoryData!=null||s.paymaster!=null||s.paymasterData!=null||s.paymasterVerificationGasLimit!=null||s.paymasterPostOpGasLimit!=null)&&a();let o=x(s.nonce);o>>64n!==Ne&&a();let u=x(s.callGasLimit,128),p=x(s.verificationGasLimit,128),l=x(s.preVerificationGas),I=x(s.maxFeePerGas,128),f=x(s.maxPriorityFeePerGas,128);(f>I||(u+p+l)*I>b(t.maxGasCostWei))&&a();let g=s.callData,R;if(e.action==="transfer"){(!y(i.recipient,e.recipient)||i.tokenOutAddress!==void 0||i.maxSlippageBps!==void 0)&&a();let w=y(e.tokenAddress,Be);R=O({abi:W,functionName:"executeUnderGrant",args:[t.permissionId,w?e.recipient:e.tokenAddress,w?b(e.amount):0n,w?"0x":O({abi:Ce,functionName:"transfer",args:[e.recipient,b(e.amount)]})]})}else{let w=t;(!y(i.tokenOutAddress,e.tokenOutAddress)||i.recipient!==void 0||i.maxSlippageBps!==(e.maxSlippageBps??50))&&a();let z=j({abi:ae,data:g}).args[1],P=j({abi:W,data:`0x${z.slice(106)}`});P.functionName!=="executeUnderGrantWithAllowance"&&a();let _=P.args[5],C=Object.freeze({chainId:e.chainId,accountAddress:e.accountAddress,routerAddress:w.routerAddress,tokenAddress:e.tokenAddress,tokenOutAddress:e.tokenOutAddress,amount:e.amount,minAmountOut:w.minAmountOut,callData:_});if(w.verifyRoute)await w.verifyRoute(C)!==!0&&a();else{let re=j({abi:de,data:_}),[ke,ve,Re,Pe,Se]=re.args;(!y(ke,e.tokenAddress)||!y(ve,e.tokenOutAddress)||Re!==b(e.amount)||Pe<b(w.minAmountOut)||!y(Se,e.accountAddress)||!y(O({abi:de,functionName:"swapExactIn",args:re.args}),_))&&a()}R=O({abi:W,functionName:"executeUnderGrantWithAllowance",args:[t.permissionId,w.routerAddress,0n,e.tokenAddress,b(e.amount),_]})}let S=O({abi:ae,functionName:"execute",args:[Te,Oe(["address","uint256","bytes"],[t.executorAddress,0n,R])]});y(g,S)||a();let T=He({entryPointAddress:oe,entryPointVersion:"0.7",chainId:e.chainId,userOperation:{sender:s.sender,nonce:o,callData:s.callData,callGasLimit:u,verificationGasLimit:p,preVerificationGas:l,maxFeePerGas:I,maxPriorityFeePerGas:f,signature:"0x"}});y(T,n.userOpHash)||a();let G=Object.freeze({...e,delegationId:t.delegationId,permissionId:t.permissionId,gasMethod:"native",...e.action==="swap"?{maxSlippageBps:e.maxSlippageBps??50}:{}});return{userOp:Object.freeze({sender:s.sender,chainId:s.chainId,entryPoint:s.entryPoint,nonce:s.nonce,callData:s.callData,callGasLimit:s.callGasLimit,verificationGasLimit:s.verificationGasLimit,preVerificationGas:s.preVerificationGas,maxFeePerGas:s.maxFeePerGas,maxPriorityFeePerGas:s.maxPriorityFeePerGas,signature:"0x"}),userOpHash:T,execution:G}}catch{return a()}}function V(r,e){try{let t=m(r);if(A(t.id),!y(t.userOpHash,e)||!["pending","included","failed"].includes(String(t.status)))throw new Error;return t.txHash!=null&&c(t.txHash,32),t}catch{let t=new h("Botanary returned an invalid receipt. Reconcile using the original operation hash.",0);throw t.code="invalid_response",t.userOpHash=e,t.ambiguous=!0,t}}import{keccak256 as Ye,toHex as Je,encodePacked as xe,encodeAbiParameters as Qe}from"viem";import{randomBytes as Ue}from"node:crypto";import{hexToBytes as $e}from"viem";var le="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function K(r){let e=0,t=0,n="";for(let i of r)for(e=e<<8|i,t+=8;t>=5;)n+=le[e>>>t-5&31],t-=5;return t>0&&(n+=le[e<<5-t&31]),n}var ge=3,me=5;function Z(r){let e=$e(r);return K(e.slice(0,ge))}function X(){return K(Ue(me))}var fe=600*1e3,B=class{#r;#e;#d;#o;#i=null;constructor(e,t){if(!/^[0-9A-HJKMNP-TV-Z]{5}$/.test(e))throw new TypeError("Invalid agent fingerprint.");if(t?.ttlMs!==void 0&&(!Number.isSafeInteger(t.ttlMs)||t.ttlMs<1e3||t.ttlMs>36e5))throw new TypeError("Invalid pairing code lifetime.");this.#r=e,this.#e=t?.ttlMs??fe,this.#d=t?.now??Date.now,this.#o=t?.nonce??X}current(){let e=this.#d();return(!this.#i||this.#i.expiresAt<=e)&&this.#c(e),this.#s()}regenerate(){return this.#c(this.#d()),this.#s()}#c(e){if(!Number.isSafeInteger(e)||e<0||e>864e13)throw new TypeError("Invalid pairing clock.");let t=this.#o();if(!/^[0-9A-HJKMNP-TV-Z]{8}$/.test(t))throw new TypeError("Invalid pairing nonce.");this.#i={nonce:t,issuedAt:e,expiresAt:e+this.#e}}#s(){let e=this.#i;if(!e)throw new Error("unreachable: no pairing code minted");return{code:`${this.#r}-${e.nonce}`,fingerprint:this.#r,nonce:e.nonce,issuedAt:new Date(e.issuedAt).toISOString(),expiresAt:new Date(e.expiresAt).toISOString()}}};import je from"openapi-fetch";var he=[{method:"post",path:"/agents/pair"},{method:"post",path:"/agents/session/nonce"},{method:"post",path:"/agents/session"},{method:"get",path:"/agents/me"},{method:"get",path:"/agents/requests"},{method:"post",path:"/agents/requests"},{method:"get",path:"/balance"},{method:"get",path:"/chains"},{method:"get",path:"/gas/methods"},{method:"get",path:"/account"},{method:"post",path:"/delegations/{delegationId}/actions"},{method:"post",path:"/delegations/{delegationId}/actions/exact"},{method:"post",path:"/userops"},{method:"get",path:"/userops/{userOpId}"},{method:"get",path:"/userops/by-hash/{chainId}/{userOpHash}"},{method:"get",path:"/apis/providers"},{method:"get",path:"/apis/providers/{providerId}"},{method:"get",path:"/apis/budget"},{method:"post",path:"/apis/calls/requirements"},{method:"get",path:"/apis/calls/requirements/{id}"},{method:"post",path:"/apis/calls/relay"},{method:"get",path:"/apis/calls/relay/{id}"}];var ye="https://botanary-canonical-path.invalid",Ae="(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})",xt=`${Ae}+`,De=new RegExp(`^${Ae}+$`),qe=new RegExp("^(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})*$"),Ge=/^\.{1,2}$/,Le=/[/\\#?]/,ze=/[\u0000-\u001f\u007f]/,Me=6;function Fe(r){let e=r;for(let t=0;t<Me;t+=1){if(Ge.test(e)||Le.test(e)||ze.test(e))return!0;if(!e.includes("%"))return!1;let n;try{n=decodeURIComponent(e)}catch{return!0}if(n===e)return!1;e=n}return!0}function we(r){if(typeof r!="string"||r.length===0||!r.startsWith("/")||r.startsWith("//"))return null;let e=r.indexOf("?"),t=e===-1?r:r.slice(0,e),n=e===-1?"":r.slice(e),i=t.split("/");for(let s=1;s<i.length;s+=1){let o=i[s];if(!De.test(o)||Fe(o))return null}if(n!==""&&!qe.test(n.slice(1)))return null;let d;try{d=new URL(t+n,ye)}catch{return null}return d.origin!==ye||d.hash!==""||d.pathname!==t||d.search!==n?null:{path:t,query:n,full:t+n}}var q=class{#r;constructor(e,t=fetch){let n=new URL(e);if(n.username||n.password||n.search||n.hash||n.pathname!=="/"||n.protocol!=="https:"&&!(n.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(n.hostname)))throw new Error("Agent API origin must be HTTPS, or HTTP on loopback.");this.#r=je({baseUrl:n.origin+"/v1",fetch:Xe(t)})}get(e,t){return this.#e("get",e,void 0,t)}post(e,t,n){return this.#e("post",e,t,n)}async#e(e,t,n,i){let d=we(t);if(!d?.path.startsWith("/v1/"))throw new Error("Invalid agent API path.");if(i!==void 0&&!/^ags_[a-f0-9]{64}$/.test(i))throw new Error("Expected an agent session credential.");let s=d.path.slice(3),o=he.find(f=>f.method===e&&new RegExp("^"+f.path.replace(/\{[^}]+\}/g,"[A-Za-z0-9_-]+")+"$").test(s));if(!o)throw new Error("This route is outside the reviewed agent API.");let u={};o.path.split("/").forEach((f,g)=>{f.startsWith("{")&&(u[f.slice(1,-1)]=s.split("/")[g])});let p=Object.fromEntries(new URLSearchParams(d.query)),l=new AbortController,I=setTimeout(()=>l.abort(),3e4);try{let f=await this.#r.request(e,o.path,{params:{path:u,query:p},...n===void 0?{}:{body:n},headers:i?{authorization:`Bearer ${i}`}:{},credentials:"omit",redirect:"error",cache:"no-store",signal:l.signal,parseAs:"text"}),g=f.response,R=f.error;if(g.ok)try{R=f.data?JSON.parse(f.data):{}}catch{throw new Error("Invalid JSON response.")}if(!g.ok){let S=Y(Y(R)?.error),T=typeof S?.message=="string"?S.message:`Agent request failed with ${g.status}.`,G=We(T).replace(/0x[a-fA-F0-9]{64,}/g,"[redacted]"),H=g.headers.get("retry-after"),w=H&&/^\d+(?:\.\d+)?$/.test(H)?Number(H):null,L=Y(S?.details),z=L&&Object.fromEntries(Object.entries(L).filter(([_,C])=>["missingModule","declineReason","chainId"].includes(_)&&(typeof C=="number"||Ze(C)))),P=new h(G.slice(0,1e3),g.status,z,w);throw P.requestId=Ve(g.headers.get("x-request-id")),P.code=Ke(S?.code)??"http_error",P.ambiguous=e==="post"&&g.status>=500,P}return R}catch(f){if(f instanceof h)throw f;let g=new h("The agent request did not complete. Check the existing operation before retrying.",0);throw g.code=l.signal.aborted?"timeout":"transport_error",g.ambiguous=e==="post",g}finally{clearTimeout(I)}}};function Y(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)?r:null}var J=/(?:bsk_(?:test|live)|deo_(?:test|live)|dcs|dca|dcr|dcc|dcq|ags|din|whsec)_[A-Za-z0-9_+/=-]+/g;function Q(r){return J.lastIndex=0,!J.test(r)}function We(r){return r.replace(J,"[redacted]")}function Ve(r){return typeof r=="string"&&/^req_[A-Za-z0-9_-]{1,124}$/.test(r)&&Q(r)?r:void 0}function Ke(r){return typeof r=="string"&&/^[a-z][a-z0-9_]{0,63}$/.test(r)&&Q(r)?r:void 0}function Ze(r){return typeof r=="string"&&/^[a-zA-Z0-9_-]{1,100}$/.test(r)&&Q(r)}function Xe(r){return async(e,t)=>{let n=e instanceof Request?e:new Request(e,t),i=n.signal,d=()=>{},s=new Promise((u,p)=>{d=()=>p(new Error("Request aborted.")),i.aborted?d():i.addEventListener("abort",d,{once:!0})}),o;try{let u=await Promise.race([r(n),s]);if(!u.body)return u;o=u.body.getReader();let p=[],l=0;for(;;){let g=await Promise.race([o.read(),s]);if(g.done)break;if(l+=g.value.byteLength,l>4*1024*1024)throw new Error("Response too large.");p.push(g.value)}let I=new Uint8Array(l),f=0;for(let g of p)I.set(g,f),f+=g.byteLength;return new Response(I,{status:u.status,statusText:u.statusText,headers:u.headers})}finally{i.removeEventListener("abort",d),o&&o.cancel().catch(()=>{})}}}import{recoverAddress as et}from"viem";async function ee(r,e,t,n,i){if(!Number.isFinite(t)||t<0||t>36e5)throw new Error("Invalid wait budget.");let d=n(),s=await r(e);for(;["pending","pending_approval","submitted","queued"].includes(String(s.status))&&n()-d<t;)await i(1500),s=await r(e);return s}var tt=3e4,be=300*1e3,Ie="https://api.app.botanary.xyz",te=class{#r;#e;#d;#o;#i=null;#c=null;#s=null;#u=null;#p=null;#n=0;#g;constructor(e,t={}){if(this.#r=e,this.#d=t.baseUrl??Ie,this.#e=t.transport??new q(this.#d,t.fetch),this.#o=t.provenance??{},t.maxGasCostWei!==void 0&&(!/^[1-9][0-9]{0,77}$/.test(t.maxGasCostWei)||BigInt(t.maxGasCostWei)>=2n**256n))throw new Error("Use a positive integer agent gas ceiling in wei.");this.#g=t.maxGasCostWei??null}get apiBaseUrl(){return this.#d}get identityMaterialized(){return this.#i!==null||this.#u!==null}setProvenance(e){this.#o=e}replaceSigner(e){if(this.identityMaterialized)throw new Error("Cannot replace a materialized agent signer.");this.#r=e,this.reset()}async identity(){if(this.#i)return this.#i;if(this.#u)return this.#u;let e=this.#n,t=(async()=>{let n;try{n=await this.#r.ensure()}catch{throw this.#a()}if(e!==this.#n)throw this.#a();let i=U(n);return this.#i=i,i})();this.#u=t;try{return await t}finally{this.#u===t&&(this.#u=null)}}#a(){let e=new h("The agent signer could not complete the request.",0);return e.code="signer_error",e}async#l(e){c(e,32);let t=this.#n,n=await this.identity();if(t!==this.#n)throw this.#a();try{let i=await this.#r.signHash(e);c(i,65);let d=await et({hash:e,signature:i});if(t!==this.#n||d.toLowerCase()!==n.address.toLowerCase())throw this.#a();return i}catch{throw this.#a()}}async pairingCode(){return(await this.#f()).current()}async regeneratePairingCode(){return(await this.#f()).regenerate()}async pair(){let e=await this.pairingCode(),t=Math.floor(Date.now()/1e3),n=await this.identity(),i=`${e.code}|${t}`,d=Ye(Je(i));return await this.#e.post("/v1/agents/pair",{code:e.code,publicKey:n.publicKey,timestamp:t,signature:await this.#l(d),...this.#o.client?{client:this.#o.client}:{},...this.#o.profile?{profile:this.#o.profile}:{}}),e}async mintSession(){if(this.#p)return this.#p;let e=this.#n,t=(async()=>{let n=await this.identity(),i=m(await this.#e.post("/v1/agents/session/nonce",{address:n.address}));if(c(i.nonce,32),e!==this.#n)throw this.#a();let d=await this.#l(i.nonce),s=m(await this.#e.post("/v1/agents/session",{address:n.address,nonce:i.nonce,signature:d}));if((typeof s.token!="string"||!/^ags_[a-f0-9]{64}$/.test(s.token)||!k(s.expiresAt)||Date.parse(s.expiresAt)<=Date.now()||Date.parse(s.expiresAt)>Date.now()+366e4)&&a(),e!==this.#n)throw this.#a();return this.#s={token:s.token,safeUntil:Date.parse(s.expiresAt)-tt},s.token})();this.#p=t;try{return await t}finally{this.#p===t&&(this.#p=null)}}async ensureSession(){return this.#s&&this.#s.safeUntil>Date.now()?this.#s.token:this.mintSession()}async me(){return se(await this.#t(e=>this.#e.get("/v1/agents/me",e)))}async getBalance(){return this.#t(e=>this.#e.get("/v1/balance",e))}async listRequests(){return this.#t(e=>this.#e.get("/v1/agents/requests",e))}async listChains(){return this.#t(e=>this.#e.get("/v1/chains",e))}async getGasMethods(e){let t=new URLSearchParams;e.chainId!==void 0&&t.set("chainId",String(e.chainId)),e.accountId&&t.set("accountId",e.accountId),e.key&&t.set("key",e.key);let n=t.toString();return this.#t(i=>this.#e.get(`/v1/gas/methods${n?`?${n}`:""}`,i))}async getAccount(e){let t=new URLSearchParams;e.chainId!==void 0&&t.set("chainId",String(e.chainId));let n=t.toString();return this.#t(i=>this.#e.get(`/v1/account${n?`?${n}`:""}`,i))}async prepareExactAction(e,t){let n=ce(e),i=ue(t,n),d=this.#n,s=await this.#t(p=>this.#e.post(`/v1/delegations/${i.delegationId}/actions/exact`,n,p),!1),o=await pe(s,n,i),u;return Object.freeze({status:"prepared",userOpHash:o.userOpHash,execution:o.execution,submit:()=>(u||(u=(async()=>{if(d!==this.#n)throw this.#a();let p=await this.ensureSession();if(d!==this.#n)throw this.#a();return V(await this.spendUnderGrant(o.userOp,o.userOpHash,i.permissionId,p,"delegated_action"),o.userOpHash)})()),u),reconcile:()=>this.getUserOpByHash(n.chainId,o.userOpHash)})}async prepareAction(e){let{mandate:t,action:n}=structuredClone(e),i=/^[1-9][0-9]{0,77}$/.test(n.amountRaw)?BigInt(n.amountRaw):0n,d=t.policy.perActionMaxRaw&&/^[1-9][0-9]{0,77}$/.test(t.policy.perActionMaxRaw)?BigInt(t.policy.perActionMaxRaw):null,s=t.chainState.remaining?.find(p=>p.token.toLowerCase()===n.tokenAddress.toLowerCase())?.remainingRaw??null,o=p=>Object.freeze({status:"refused",reason:p,transactionSubmitted:!1,requestedAmountRaw:n.amountRaw,perActionMaxRaw:t.policy.perActionMaxRaw,remainingRaw:s});if(t.chainId!==84532||!["submitted","unresolved","confirmed"].includes(t.createStatus)||t.chainState.status!=="active"||t.apiAccess!=="active")return o(t.revokeStatus==="confirmed"||t.chainState.status==="revoked"?"mandate_revoked":Date.parse(t.policy.expiresAt)<=Date.now()?"mandate_expired":"mandate_inactive");if(i===0n||!t.policy.budgets.some(p=>p.token.toLowerCase()===n.tokenAddress.toLowerCase()))return o("mandate_inactive");if(d!==null&&i>d)return o("over_per_action_max");if(t.policy.recipients.length>0&&!t.policy.recipients.some(p=>p.toLowerCase()===n.recipient.toLowerCase()))return o("wrong_recipient");if((await this.identity()).address.toLowerCase()!==t.agentAddress.toLowerCase())return o("mandate_inactive");if(!this.#g)throw new Error("Configure maxGasCostWei before preparing mandate actions.");return this.prepareExactAction({accountId:t.accountId,accountAddress:t.accountAddress,chainId:84532,action:"transfer",tokenAddress:n.tokenAddress,recipient:n.recipient,amount:n.amountRaw},{delegationId:t.id,permissionId:t.permissionId,executorAddress:t.grantExecutor,maxGasCostWei:this.#g})}async buildDelegatedAction(e){A(e.delegationId),c(e.recipient,20),(!Number.isFinite(e.amount)||e.amount<=0||e.amount>Number.MAX_SAFE_INTEGER)&&a(),e.token!==void 0&&(typeof e.token!="string"||!e.token||e.token.length>256)&&a();let t={recipient:e.recipient,amount:e.amount,...e.token?{token:e.token}:{}};return M(await this.#t(n=>this.#e.post(`/v1/delegations/${e.delegationId}/actions`,t,n),!1))}async buildDelegatedSwap(e){A(e.delegationId),(![e.tokenIn,e.tokenOut].every(n=>typeof n=="string"&&n.length>0&&n.length<=64)||!Number.isFinite(e.amountIn)||e.amountIn<=0||e.amountIn>Number.MAX_SAFE_INTEGER||e.maxSlippageBps!==void 0&&(!Number.isSafeInteger(e.maxSlippageBps)||e.maxSlippageBps<0||e.maxSlippageBps>1e4))&&a();let t={action:"swap",tokenIn:e.tokenIn,tokenOut:e.tokenOut,amountIn:e.amountIn,...e.maxSlippageBps!=null?{maxSlippageBps:e.maxSlippageBps}:{}};return M(await this.#t(n=>this.#e.post(`/v1/delegations/${e.delegationId}/actions`,t,n),!1))}async raiseRequest(e,t){return(!Array.isArray(e)||!e.length||e.length>100||typeof t!="string"||!t.trim()||t.length>2e3)&&a(),ie(await this.#t(n=>this.#e.post("/v1/agents/requests",{calls:e,reason:t},n),!1))}async spendUnderGrant(e,t,n,i,d){E(e),c(t,32),c(n,32);let s=await this.#l(t),o=xe(["bytes1","bytes32","bytes"],["0x00",n,s]);try{return await this.#e.post("/v1/userops",{userOp:{...e,signature:o},userOpHash:t,intentType:d},i)}catch(u){throw u instanceof h&&(u.userOpHash=t),u}}async getUserOp(e){return A(e),this.#t(t=>this.#e.get(`/v1/userops/${e}`,t))}async getUserOpByHash(e,t){return(!Number.isSafeInteger(e)||e<1)&&a(),c(t,32),V(await this.#t(n=>this.#e.get(`/v1/userops/by-hash/${e}/${t}`,n)),t)}async awaitTerminal(e,t){return ee(n=>this.getUserOp(n),e,t,()=>Date.now(),n=>new Promise(i=>setTimeout(i,n)))}async listApis(e){return this.#t(t=>this.#e.get(`/v1/apis/providers?chainId=${e}`,t))}async getApiProvider(e,t){let n=t!==void 0?`?chainId=${t}`:"";return this.#t(i=>this.#e.get(`/v1/apis/providers/${e}${n}`,i))}async callApi(e){let t=await this.#t(n=>this.#e.post("/v1/apis/calls/requirements",e,n),!1);return A(t?.requirementId),["ready","pending_approval"].includes(t.status)||a(),this.#m(t)}async resumeApi(e,t=be){A(e);let n=F(await this.#t(i=>this.#e.get(`/v1/apis/calls/relay/${e}`,i)),e);return n.status==="ready"?this.#m({requirementId:e,status:"ready",...$(n.ready)},t):n.status!=="pending_approval"?n:this.#m({requirementId:e,status:"pending_approval",approvalId:e,expiresAt:""},t)}async#m(e,t=be){let n;if(e.status==="pending_approval"){let o=await ee(u=>this.#t(p=>this.#e.get(`/v1/apis/calls/requirements/${u}`,p)),e.requirementId,t,()=>Date.now(),u=>new Promise(p=>setTimeout(p,u)));if(o.status==="approved"&&o.payload&&o.authorization&&o.index!==void 0&&o.validator)n={payload:o.payload,authorization:o.authorization,index:o.index,validator:o.validator};else{let u=o.status==="declined"?"owner_declined":o.status==="expired"?"approval_timed_out":"approval_still_pending",p=u==="owner_declined"?"The owner declined this call. Nothing was signed and nothing was charged.":u==="approval_timed_out"?"The owner did not respond before the approval window closed. Nothing was signed and nothing was charged.":"The owner has not answered yet. Nothing was signed or charged. Resume this requirement or ask the owner to check their pending approvals.";return["pending","declined","expired"].includes(o.status)||a(),{status:o.status==="pending"?"pending_approval":"declined",declineReason:u,message:p,requirementId:e.requirementId,approvalId:e.status==="pending_approval"?e.approvalId:void 0}}}else n=e;n=$(n);let i=await this.identity(),d=await this.#l(n.payload),s=xe(["bytes1","address","bytes"],["0x01",n.validator,Qe([{type:"address"},{type:"tuple",components:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]},{type:"uint32"},{type:"bytes"}],[i.address,{from:n.authorization.from,to:n.authorization.to,value:BigInt(n.authorization.value),validAfter:BigInt(n.authorization.validAfter),validBefore:BigInt(n.authorization.validBefore),nonce:n.authorization.nonce},n.index,d])]);try{return F(await this.#t(o=>this.#e.post("/v1/apis/calls/relay",{requirementId:e.requirementId,signature:s},o),!1),e.requirementId)}catch(o){throw o instanceof h&&(o.requirementId=e.requirementId),o}}async getApiBudget(e){return this.#t(t=>this.#e.get(`/v1/apis/budget?chainId=${e}`,t))}reset(){this.#n+=1,this.#u=null,this.#p=null,this.#i=null,this.#c=null,this.#s=null}async#f(){if(!this.#c){let e=await this.identity();this.#c??=new B(e.fingerprint)}return this.#c}async#t(e,t=!0){let n=await this.ensureSession();try{return await e(n)}catch(i){if(t&&i instanceof h&&i.status===401){let d=this.#s&&this.#s.token!==n?await this.ensureSession():await this.mintSession();return await e(d)}throw i}}};function nt(r,e={}){let t={address:r.address,publicKey:r.publicKey,fingerprint:Z(r.address),backend:e.backend??"injected",createdAt:e.createdAt??new Date().toISOString()};return{ensure:async()=>({...t}),sign:n=>r.signMessage({message:n}),signHash:n=>r.sign({hash:n})}}import{recoverMessageAddress as rt}from"viem";async function it(r,e,t){if(typeof t!="string"||t.trim().length<1||t.trim().length>80)throw new Error("Agent name must contain 1 to 80 characters.");let n;try{n=U(await r.ensure())}catch{throw ne()}let i=await e.app.context();A(i.appId),A(i.keyId),["test","live"].includes(i.environment)||a();let d=n.publicKey.toLowerCase(),s=n.address.toLowerCase(),o=await e.agents.challenge({publicKey:d,name:t.trim()});(!o||o.appId!==i.appId||o.environment!==i.environment||o.publicKey!==d||o.address!==s||!/^dach_[A-Za-z0-9_-]{43}$/.test(o.id)||!k(o.expiresAt)||Date.parse(o.expiresAt)<=Date.now()||Date.parse(o.expiresAt)>Date.now()+36e4)&&a();let u=["Botanary agent registration","Purpose: register-agent-key","Audience: botanary:developer-platform:2026-09-07",`Application: ${i.appId}`,`Environment: ${i.environment}`,`API key: ${i.keyId}`,`Public key: ${d}`,`Address: ${s}`,`Nonce: ${o.id}`,`Expires: ${o.expiresAt}`,"This proof does not authorize an account connection or an on-chain grant."].join(`
|
|
2
|
-
`);
|
|
1
|
+
var h=class extends Error{constructor(t,n,i=null,d=null){super(t);this.status=n;this.details=i;this.retryAfterSeconds=d;this.name="BotanaryApiError"}requestId;code;operationId;userOpHash;requirementId;ambiguous=!1};import{encodeFunctionData as O,encodePacked as Oe,decodeFunctionData as j,parseAbi as D,getAddress as v,zeroAddress as Be,zeroHash as He}from"viem";import{entryPoint07Address as ae,getUserOperationHash as Te}from"viem/account-abstraction";import{publicKeyToAddress as _e}from"viem/accounts";function o(){let r=new h("Botanary returned an invalid response. Nothing was signed.",0);throw r.code="invalid_response",r}function f(r){return typeof r!="object"||r===null||Array.isArray(r)?o():r}function u(r,e){(typeof r!="string"||!/^0x(?:[0-9a-fA-F]{2})*$/.test(r)||e!==void 0&&r.length!==2+2*e)&&o()}function A(r){(typeof r!="string"||!/^[A-Za-z0-9_-]{1,128}$/.test(r)||/^(?:bsk|deo|ags|dcs|dca|dcr|dcc|dcq|din)_/.test(r))&&o()}function k(r){if(typeof r!="string")return!1;let e=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.exec(r);if(!e)return!1;let t=Number(e[1]),n=Number(e[2]),i=Number(e[3]),s=[31,t%4===0&&(t%100!==0||t%400===0)?29:28,31,30,31,30,31,31,30,31,30,31];return t>=1&&n>=1&&n<=12&&i>=1&&i<=s[n-1]&&Number(e[4])<=23&&Number(e[5])<=59&&Number(e[6])<=59&&Number.isFinite(Date.parse(r))}function N(r){(typeof r!="string"||!/^(0|[1-9][0-9]{0,77})$/.test(r)||BigInt(r)>=2n**256n)&&o()}function U(r){let e=f(r);return u(e.address,20),u(e.publicKey,65),(!e.publicKey.startsWith("0x04")||_e(e.publicKey).toLowerCase()!==e.address.toLowerCase()||typeof e.fingerprint!="string"||!/^[A-Za-z0-9]{1,32}$/.test(e.fingerprint)||typeof e.backend!="string"||!/^[A-Za-z0-9_-]{1,64}$/.test(e.backend)||!k(e.createdAt))&&o(),Object.freeze({address:e.address,publicKey:e.publicKey,fingerprint:e.fingerprint,backend:e.backend,createdAt:e.createdAt})}function z(r){let e=f(r);return(typeof e.intentType!="string"||!e.intentType||typeof e.userOpHash!="string")&&o(),u(e.userOpHash,32),E(e.userOp),e}function Ee(r){let e=f(r);return u(e.to,20),u(e.data),N(e.value),(!Number.isSafeInteger(e.chainId)||Number(e.chainId)<1)&&o(),{to:e.to,data:e.data,value:e.value,chainId:Number(e.chainId)}}function ie(r){let e=f(r);return(!["id","agentId","accountId","declineReason","reason"].every(t=>typeof e[t]=="string"&&e[t].length>0)||!Array.isArray(e.calls)||!k(e.raisedAt)||!k(e.expiresAt)||Date.parse(e.expiresAt)<=Date.parse(e.raisedAt)||!["open","approved","expired","withdrawn"].includes(String(e.status)))&&o(),{...e,calls:e.calls.map(Ee)}}function se(r){let e=f(r);if(u(e.address,20),(!["id","name","fingerprint","accountId"].every(t=>typeof e[t]=="string"&&e[t].length>0)||!k(e.connectedAt)||!(e.accountAddress==null||typeof e.accountAddress=="string")||e.accountAddress!=null&&!/^0x[0-9a-fA-F]{40}$/.test(e.accountAddress))&&o(),e.grant!==null){let t=f(e.grant);u(t.permissionId,32),(typeof t.id!="string"||!t.id||typeof t.status!="string"||!t.status||typeof t.humanSummary!="string"||typeof t.chain!="string"||!Number.isSafeInteger(t.chainId)||!f(t.policySet)||!Array.isArray(t.spentToDate))&&o()}if(e.accountSetup!=null){let t=f(e.accountSetup);(typeof t.ready!="boolean"||!Array.isArray(t.missing)||!t.missing.every(n=>typeof n=="string")||t.ready!==(t.missing.length===0)||!Number.isSafeInteger(t.chainId)||Number(t.chainId)<1)&&o()}return e}function b(r,e=256){if(typeof r!="string"||!/^(0|[1-9][0-9]{0,77}|0x[0-9a-fA-F]{1,64})$/.test(r))return o();let t=BigInt(r);return t>=2n**BigInt(e)?o():t}function E(r){let e=f(r);for(let t of["sender","entryPoint"])u(e[t],20);for(let t of["nonce","callGasLimit","verificationGasLimit","preVerificationGas","maxFeePerGas","maxPriorityFeePerGas"])b(e[t]);for(let t of["callData","signature"])u(e[t]);for(let t of["paymasterVerificationGasLimit","paymasterPostOpGasLimit"])e[t]!=null&&b(e[t],128);(!Number.isSafeInteger(e.chainId)||Number(e.chainId)<=0)&&o();for(let t of["factory","paymaster"])e[t]!=null&&u(e[t],20);for(let t of["factoryData","paymasterData"])e[t]!=null&&u(e[t]);return r}function $(r){let e=f(r);u(e.payload,32),u(e.validator,20),(!Number.isSafeInteger(e.index)||Number(e.index)<0||Number(e.index)>=2**32)&&o();let t=f(e.authorization);return u(t.from,20),u(t.to,20),u(t.nonce,32),N(t.value),N(t.validAfter),N(t.validBefore),BigInt(t.validBefore)<=BigInt(t.validAfter)&&o(),{payload:e.payload,validator:e.validator,index:Number(e.index),authorization:{from:t.from,to:t.to,nonce:t.nonce,value:t.value,validAfter:t.validAfter,validBefore:t.validBefore}}}function F(r,e){let t=f(r);(t.requirementId!==e||typeof t.simulated!="boolean")&&o();let n={ready:["not_submitted"],pending_approval:["not_submitted"],submitted:["pending"],settled:["settled"],declined:["not_submitted","not_settled"]};return(typeof t.status!="string"||!Object.hasOwn(n,t.status)||!n[t.status].includes(String(t.paymentStatus)))&&o(),t.providerStatus!==void 0&&(!Number.isSafeInteger(t.providerStatus)||Number(t.providerStatus)<100||Number(t.providerStatus)>599)&&o(),t.txHash!==void 0&&u(t.txHash,32),t.status==="settled"&&u(t.txHash,32),t.status==="ready"?$(t.ready):t.ready!==void 0&&o(),t}var oe=D(["function execute(bytes32 mode, bytes executionCalldata) payable"]),W=D(["function executeUnderGrant(bytes32 permissionId, address target, uint256 value, bytes callData)","function executeUnderGrantWithAllowance(bytes32 permissionId, address target, uint256 value, address token, uint256 allowance, bytes callData)"]),Ce=D(["function transfer(address to, uint256 amount) returns (bool)"]),de=D(["function swapExactIn(address tokenIn, address tokenOut, uint256 amountIn, uint256 minOut, address to) returns (uint256 amountOut)"]),Ne=BigInt("0x000100000000008bdaba73cd9815d79069c247eb4bda0000");function y(r,e){return typeof r=="string"&&r.toLowerCase()===e.toLowerCase()}function I(r,e=!0){if(typeof r!="string"||!/^(0|[1-9][0-9]{0,77})$/.test(r))return o();let t=BigInt(r);return t>=2n**256n||e&&t===0n?o():t}function ce(r){let e=f(r),t=["accountId","accountAddress","chainId","action","tokenAddress","amount","recipient","tokenOutAddress","maxSlippageBps"];return Object.keys(e).some(n=>!t.includes(n))&&o(),A(e.accountId),u(e.accountAddress,20),u(e.tokenAddress,20),I(e.amount),(!Number.isSafeInteger(e.chainId)||Number(e.chainId)<=0)&&o(),e.action==="transfer"?(u(e.recipient,20),(e.tokenOutAddress!==void 0||e.maxSlippageBps!==void 0)&&o()):e.action==="swap"?(u(e.tokenOutAddress,20),(e.recipient!==void 0||e.maxSlippageBps!==void 0&&(!Number.isInteger(e.maxSlippageBps)||Number(e.maxSlippageBps)<1||Number(e.maxSlippageBps)>1e3))&&o()):o(),Object.freeze({...r,accountAddress:v(r.accountAddress),tokenAddress:v(r.tokenAddress),...r.recipient!==void 0?{recipient:v(r.recipient)}:{},...r.tokenOutAddress!==void 0?{tokenOutAddress:v(r.tokenOutAddress)}:{}})}function ue(r,e){if(A(r.delegationId),u(r.permissionId,32),u(r.executorAddress,20),I(r.maxGasCostWei),e.action==="swap"){let t=r;u(t.routerAddress,20),I(t.minAmountOut),t.verifyRoute!==void 0&&typeof t.verifyRoute!="function"&&o()}return Object.freeze({...r,executorAddress:v(r.executorAddress),...e.action==="swap"?{routerAddress:v(r.routerAddress)}:{}})}async function pe(r,e,t){try{let n=f(r),i=f(n.execution),d=E(n.userOp),s=Object.freeze({...d,sender:v(d.sender),entryPoint:v(d.entryPoint)});u(n.userOpHash,32),(n.intentType!=="delegated_action"||f(n.simulation).willSucceed!==!0||i.accountId!==e.accountId||!y(i.accountAddress,e.accountAddress)||i.chainId!==e.chainId||i.action!==e.action||i.amount!==e.amount||!y(i.tokenAddress,e.tokenAddress)||i.delegationId!==t.delegationId||!y(i.permissionId,t.permissionId)||i.gasMethod!=="native"||!y(s.sender,e.accountAddress)||s.chainId!==e.chainId||!y(s.entryPoint,ae)||s.factory!=null||s.factoryData!=null||s.paymaster!=null||s.paymasterData!=null||s.paymasterVerificationGasLimit!=null||s.paymasterPostOpGasLimit!=null)&&o();let a=b(s.nonce);a>>64n!==Ne&&o();let c=b(s.callGasLimit,128),g=b(s.verificationGasLimit,128),p=b(s.preVerificationGas),x=b(s.maxFeePerGas,128),l=b(s.maxPriorityFeePerGas,128);(l>x||(c+g+p)*x>I(t.maxGasCostWei))&&o();let m=s.callData,R;if(e.action==="transfer"){(!y(i.recipient,e.recipient)||i.tokenOutAddress!==void 0||i.maxSlippageBps!==void 0)&&o();let w=y(e.tokenAddress,Be);R=O({abi:W,functionName:"executeUnderGrant",args:[t.permissionId,w?e.recipient:e.tokenAddress,w?I(e.amount):0n,w?"0x":O({abi:Ce,functionName:"transfer",args:[e.recipient,I(e.amount)]})]})}else{let w=t;(!y(i.tokenOutAddress,e.tokenOutAddress)||i.recipient!==void 0||i.maxSlippageBps!==(e.maxSlippageBps??50))&&o();let M=j({abi:oe,data:m}).args[1],S=j({abi:W,data:`0x${M.slice(106)}`});S.functionName!=="executeUnderGrantWithAllowance"&&o();let _=S.args[5],C=Object.freeze({chainId:e.chainId,accountAddress:e.accountAddress,routerAddress:w.routerAddress,tokenAddress:e.tokenAddress,tokenOutAddress:e.tokenOutAddress,amount:e.amount,minAmountOut:w.minAmountOut,callData:_});if(w.verifyRoute)await w.verifyRoute(C)!==!0&&o();else{let re=j({abi:de,data:_}),[ke,ve,Re,Se,Pe]=re.args;(!y(ke,e.tokenAddress)||!y(ve,e.tokenOutAddress)||Re!==I(e.amount)||Se<I(w.minAmountOut)||!y(Pe,e.accountAddress)||!y(O({abi:de,functionName:"swapExactIn",args:re.args}),_))&&o()}R=O({abi:W,functionName:"executeUnderGrantWithAllowance",args:[t.permissionId,w.routerAddress,0n,e.tokenAddress,I(e.amount),_]})}let P=O({abi:oe,functionName:"execute",args:[He,Oe(["address","uint256","bytes"],[t.executorAddress,0n,R])]});y(m,P)||o();let H=Te({entryPointAddress:ae,entryPointVersion:"0.7",chainId:e.chainId,userOperation:{sender:s.sender,nonce:a,callData:s.callData,callGasLimit:c,verificationGasLimit:g,preVerificationGas:p,maxFeePerGas:x,maxPriorityFeePerGas:l,signature:"0x"}});y(H,n.userOpHash)||o();let G=Object.freeze({...e,delegationId:t.delegationId,permissionId:t.permissionId,gasMethod:"native",...e.action==="swap"?{maxSlippageBps:e.maxSlippageBps??50}:{}});return{userOp:Object.freeze({sender:s.sender,chainId:s.chainId,entryPoint:s.entryPoint,nonce:s.nonce,callData:s.callData,callGasLimit:s.callGasLimit,verificationGasLimit:s.verificationGasLimit,preVerificationGas:s.preVerificationGas,maxFeePerGas:s.maxFeePerGas,maxPriorityFeePerGas:s.maxPriorityFeePerGas,signature:"0x"}),userOpHash:H,execution:G}}catch{return o()}}function V(r,e){try{let t=f(r);if(A(t.id),!y(t.userOpHash,e)||!["pending","included","failed"].includes(String(t.status)))throw new Error;return t.txHash!=null&&u(t.txHash,32),t}catch{let t=new h("Botanary returned an invalid receipt. Reconcile using the original operation hash.",0);throw t.code="invalid_response",t.userOpHash=e,t.ambiguous=!0,t}}import{keccak256 as Ye,toHex as Je,encodePacked as xe,encodeAbiParameters as Qe}from"viem";import{randomBytes as Ue}from"node:crypto";import{hexToBytes as $e}from"viem";var le="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function K(r){let e=0,t=0,n="";for(let i of r)for(e=e<<8|i,t+=8;t>=5;)n+=le[e>>>t-5&31],t-=5;return t>0&&(n+=le[e<<5-t&31]),n}var ge=3,me=5;function Z(r){let e=$e(r);return K(e.slice(0,ge))}function X(){return K(Ue(me))}var fe=600*1e3,B=class{#r;#e;#d;#a;#i=null;constructor(e,t){if(!/^[0-9A-HJKMNP-TV-Z]{5}$/.test(e))throw new TypeError("Invalid agent fingerprint.");if(t?.ttlMs!==void 0&&(!Number.isSafeInteger(t.ttlMs)||t.ttlMs<1e3||t.ttlMs>36e5))throw new TypeError("Invalid pairing code lifetime.");this.#r=e,this.#e=t?.ttlMs??fe,this.#d=t?.now??Date.now,this.#a=t?.nonce??X}current(){let e=this.#d();return(!this.#i||this.#i.expiresAt<=e)&&this.#c(e),this.#s()}regenerate(){return this.#c(this.#d()),this.#s()}#c(e){if(!Number.isSafeInteger(e)||e<0||e>864e13)throw new TypeError("Invalid pairing clock.");let t=this.#a();if(!/^[0-9A-HJKMNP-TV-Z]{8}$/.test(t))throw new TypeError("Invalid pairing nonce.");this.#i={nonce:t,issuedAt:e,expiresAt:e+this.#e}}#s(){let e=this.#i;if(!e)throw new Error("unreachable: no pairing code minted");return{code:`${this.#r}-${e.nonce}`,fingerprint:this.#r,nonce:e.nonce,issuedAt:new Date(e.issuedAt).toISOString(),expiresAt:new Date(e.expiresAt).toISOString()}}};import je from"openapi-fetch";var he=[{method:"post",path:"/agents/pair"},{method:"post",path:"/agents/session/nonce"},{method:"post",path:"/agents/session"},{method:"get",path:"/agents/me"},{method:"get",path:"/agents/requests"},{method:"post",path:"/agents/requests"},{method:"get",path:"/balance"},{method:"get",path:"/chains"},{method:"get",path:"/gas/methods"},{method:"get",path:"/account"},{method:"post",path:"/delegations/{delegationId}/actions"},{method:"post",path:"/delegations/{delegationId}/actions/exact"},{method:"post",path:"/userops"},{method:"get",path:"/userops/{userOpId}"},{method:"get",path:"/userops/by-hash/{chainId}/{userOpHash}"},{method:"get",path:"/apis/providers"},{method:"get",path:"/apis/providers/{providerId}"},{method:"get",path:"/apis/budget"},{method:"post",path:"/apis/calls/requirements"},{method:"get",path:"/apis/calls/requirements/{id}"},{method:"post",path:"/apis/calls/relay"},{method:"get",path:"/apis/calls/relay/{id}"}];var ye="https://botanary-canonical-path.invalid",Ae="(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})",xt=`${Ae}+`,De=new RegExp(`^${Ae}+$`),qe=new RegExp("^(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})*$"),Ge=/^\.{1,2}$/,Le=/[/\\#?]/,Me=/[\u0000-\u001f\u007f]/,ze=6;function Fe(r){let e=r;for(let t=0;t<ze;t+=1){if(Ge.test(e)||Le.test(e)||Me.test(e))return!0;if(!e.includes("%"))return!1;let n;try{n=decodeURIComponent(e)}catch{return!0}if(n===e)return!1;e=n}return!0}function we(r){if(typeof r!="string"||r.length===0||!r.startsWith("/")||r.startsWith("//"))return null;let e=r.indexOf("?"),t=e===-1?r:r.slice(0,e),n=e===-1?"":r.slice(e),i=t.split("/");for(let s=1;s<i.length;s+=1){let a=i[s];if(!De.test(a)||Fe(a))return null}if(n!==""&&!qe.test(n.slice(1)))return null;let d;try{d=new URL(t+n,ye)}catch{return null}return d.origin!==ye||d.hash!==""||d.pathname!==t||d.search!==n?null:{path:t,query:n,full:t+n}}var q=class{#r;constructor(e,t=fetch){let n=new URL(e);if(n.username||n.password||n.search||n.hash||n.pathname!=="/"||n.protocol!=="https:"&&!(n.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(n.hostname)))throw new Error("Agent API origin must be HTTPS, or HTTP on loopback.");this.#r=je({baseUrl:n.origin+"/v1",fetch:Xe(t)})}get(e,t){return this.#e("get",e,void 0,t)}post(e,t,n){return this.#e("post",e,t,n)}async#e(e,t,n,i){let d=we(t);if(!d?.path.startsWith("/v1/"))throw new Error("Invalid agent API path.");if(i!==void 0&&!/^ags_[a-f0-9]{64}$/.test(i))throw new Error("Expected an agent session credential.");let s=d.path.slice(3),a=he.find(l=>l.method===e&&new RegExp("^"+l.path.replace(/\{[^}]+\}/g,"[A-Za-z0-9_-]+")+"$").test(s));if(!a)throw new Error("This route is outside the reviewed agent API.");let c={};a.path.split("/").forEach((l,m)=>{l.startsWith("{")&&(c[l.slice(1,-1)]=s.split("/")[m])});let g=Object.fromEntries(new URLSearchParams(d.query)),p=new AbortController,x=setTimeout(()=>p.abort(),3e4);try{let l=await this.#r.request(e,a.path,{params:{path:c,query:g},...n===void 0?{}:{body:n},headers:i?{authorization:`Bearer ${i}`}:{},credentials:"omit",redirect:"error",cache:"no-store",signal:p.signal,parseAs:"text"}),m=l.response,R=l.error;if(m.ok)try{R=l.data?JSON.parse(l.data):{}}catch{throw new Error("Invalid JSON response.")}if(!m.ok){let P=Y(Y(R)?.error),H=typeof P?.message=="string"?P.message:`Agent request failed with ${m.status}.`,G=We(H).replace(/0x[a-fA-F0-9]{64,}/g,"[redacted]"),T=m.headers.get("retry-after"),w=T&&/^\d+(?:\.\d+)?$/.test(T)?Number(T):null,L=Y(P?.details),M=L&&Object.fromEntries(Object.entries(L).filter(([_,C])=>["missingModule","declineReason","chainId"].includes(_)&&(typeof C=="number"||Ze(C)))),S=new h(G.slice(0,1e3),m.status,M,w);throw S.requestId=Ve(m.headers.get("x-request-id")),S.code=Ke(P?.code)??"http_error",S.ambiguous=e==="post"&&m.status>=500,S}return R}catch(l){if(l instanceof h)throw l;let m=new h("The agent request did not complete. Check the existing operation before retrying.",0);throw m.code=p.signal.aborted?"timeout":"transport_error",m.ambiguous=e==="post",m}finally{clearTimeout(x)}}};function Y(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)?r:null}var J=/(?:bsk_(?:test|live)|deo_(?:test|live)|dcs|dca|dcr|dcc|dcq|ags|din|whsec)_[A-Za-z0-9_+/=-]+/g;function Q(r){return J.lastIndex=0,!J.test(r)}function We(r){return r.replace(J,"[redacted]")}function Ve(r){return typeof r=="string"&&/^req_[A-Za-z0-9_-]{1,124}$/.test(r)&&Q(r)?r:void 0}function Ke(r){return typeof r=="string"&&/^[a-z][a-z0-9_]{0,63}$/.test(r)&&Q(r)?r:void 0}function Ze(r){return typeof r=="string"&&/^[a-zA-Z0-9_-]{1,100}$/.test(r)&&Q(r)}function Xe(r){return async(e,t)=>{let n=e instanceof Request?e:new Request(e,t),i=n.signal,d=()=>{},s=new Promise((c,g)=>{d=()=>g(new Error("Request aborted.")),i.aborted?d():i.addEventListener("abort",d,{once:!0})}),a;try{let c=await Promise.race([r(n),s]);if(!c.body)return c;a=c.body.getReader();let g=[],p=0;for(;;){let m=await Promise.race([a.read(),s]);if(m.done)break;if(p+=m.value.byteLength,p>4*1024*1024)throw new Error("Response too large.");g.push(m.value)}let x=new Uint8Array(p),l=0;for(let m of g)x.set(m,l),l+=m.byteLength;return new Response(x,{status:c.status,statusText:c.statusText,headers:c.headers})}finally{i.removeEventListener("abort",d),a&&a.cancel().catch(()=>{})}}}import{recoverAddress as et}from"viem";async function ee(r,e,t,n,i){if(!Number.isFinite(t)||t<0||t>36e5)throw new Error("Invalid wait budget.");let d=n(),s=await r(e);for(;["pending","pending_approval","submitted","queued"].includes(String(s.status))&&n()-d<t;)await i(1500),s=await r(e);return s}var tt=3e4,be=300*1e3,Ie="https://api.app.botanary.xyz",te=class{#r;#e;#d;#a;#i=null;#c=null;#s=null;#u=null;#p=null;#n=0;#g;constructor(e,t={}){if(this.#r=e,this.#d=t.baseUrl??Ie,this.#e=t.transport??new q(this.#d,t.fetch),this.#a=t.provenance??{},t.maxGasCostWei!==void 0&&(!/^[1-9][0-9]{0,77}$/.test(t.maxGasCostWei)||BigInt(t.maxGasCostWei)>=2n**256n))throw new Error("Use a positive integer agent gas ceiling in wei.");this.#g=t.maxGasCostWei??null}get apiBaseUrl(){return this.#d}get identityMaterialized(){return this.#i!==null||this.#u!==null}setProvenance(e){this.#a=e}replaceSigner(e){if(this.identityMaterialized)throw new Error("Cannot replace a materialized agent signer.");this.#r=e,this.reset()}async identity(){if(this.#i)return this.#i;if(this.#u)return this.#u;let e=this.#n,t=(async()=>{let n;try{n=await this.#r.ensure()}catch{throw this.#o()}if(e!==this.#n)throw this.#o();let i=U(n);return this.#i=i,i})();this.#u=t;try{return await t}finally{this.#u===t&&(this.#u=null)}}#o(){let e=new h("The agent signer could not complete the request.",0);return e.code="signer_error",e}async#l(e){u(e,32);let t=this.#n,n=await this.identity();if(t!==this.#n)throw this.#o();try{let i=await this.#r.signHash(e);u(i,65);let d=await et({hash:e,signature:i});if(t!==this.#n||d.toLowerCase()!==n.address.toLowerCase())throw this.#o();return i}catch{throw this.#o()}}async pairingCode(){return(await this.#f()).current()}async regeneratePairingCode(){return(await this.#f()).regenerate()}async pair(){let e=await this.pairingCode(),t=Math.floor(Date.now()/1e3),n=await this.identity(),i=`${e.code}|${t}`,d=Ye(Je(i));return await this.#e.post("/v1/agents/pair",{code:e.code,publicKey:n.publicKey,timestamp:t,signature:await this.#l(d),...this.#a.client?{client:this.#a.client}:{},...this.#a.profile?{profile:this.#a.profile}:{}}),e}async mintSession(){if(this.#p)return this.#p;let e=this.#n,t=(async()=>{let n=await this.identity(),i=f(await this.#e.post("/v1/agents/session/nonce",{address:n.address}));if(u(i.nonce,32),e!==this.#n)throw this.#o();let d=await this.#l(i.nonce),s=f(await this.#e.post("/v1/agents/session",{address:n.address,nonce:i.nonce,signature:d}));if((typeof s.token!="string"||!/^ags_[a-f0-9]{64}$/.test(s.token)||!k(s.expiresAt)||Date.parse(s.expiresAt)<=Date.now()||Date.parse(s.expiresAt)>Date.now()+366e4)&&o(),e!==this.#n)throw this.#o();return this.#s={token:s.token,safeUntil:Date.parse(s.expiresAt)-tt},s.token})();this.#p=t;try{return await t}finally{this.#p===t&&(this.#p=null)}}async ensureSession(){return this.#s&&this.#s.safeUntil>Date.now()?this.#s.token:this.mintSession()}async me(){return se(await this.#t(e=>this.#e.get("/v1/agents/me",e)))}async getBalance(){return this.#t(e=>this.#e.get("/v1/balance",e))}async listRequests(){return this.#t(e=>this.#e.get("/v1/agents/requests",e))}async listChains(){return this.#t(e=>this.#e.get("/v1/chains",e))}async getGasMethods(e){let t=new URLSearchParams;e.chainId!==void 0&&t.set("chainId",String(e.chainId)),e.accountId&&t.set("accountId",e.accountId),e.key&&t.set("key",e.key);let n=t.toString();return this.#t(i=>this.#e.get(`/v1/gas/methods${n?`?${n}`:""}`,i))}async getAccount(e){let t=new URLSearchParams;e.chainId!==void 0&&t.set("chainId",String(e.chainId));let n=t.toString();return this.#t(i=>this.#e.get(`/v1/account${n?`?${n}`:""}`,i))}async prepareExactAction(e,t){let n=ce(e),i=ue(t,n),d=this.#n,s=await this.#t(g=>this.#e.post(`/v1/delegations/${i.delegationId}/actions/exact`,n,g),!1),a=await pe(s,n,i),c;return Object.freeze({status:"prepared",userOpHash:a.userOpHash,execution:a.execution,submit:()=>(c||(c=(async()=>{if(d!==this.#n)throw this.#o();let g=await this.ensureSession();if(d!==this.#n)throw this.#o();return V(await this.spendUnderGrant(a.userOp,a.userOpHash,i.permissionId,g,"delegated_action"),a.userOpHash)})()),c),reconcile:()=>this.getUserOpByHash(n.chainId,a.userOpHash)})}async prepareAction(e){let t=e.action.type==="swap"?e.action.verifyRoute:void 0,{mandate:n,action:i}=structuredClone({mandate:e.mandate,action:{...e.action,verifyRoute:void 0}}),d=/^[1-9][0-9]{0,77}$/.test(i.amountRaw)?BigInt(i.amountRaw):0n,s=n.policy.perActionMaxRaw&&/^[1-9][0-9]{0,77}$/.test(n.policy.perActionMaxRaw)?BigInt(n.policy.perActionMaxRaw):null,a=n.chainState.remaining?.find(l=>l.token.toLowerCase()===i.tokenAddress.toLowerCase())?.remainingRaw??null,c=l=>Object.freeze({status:"refused",reason:l,transactionSubmitted:!1,requestedAmountRaw:i.amountRaw,perActionMaxRaw:n.policy.perActionMaxRaw,remainingRaw:a});if(n.chainId!==84532||!["submitted","unresolved","confirmed"].includes(n.createStatus)||n.chainState.status!=="active"||n.apiAccess!=="active")return c(n.revokeStatus==="confirmed"||n.chainState.status==="revoked"?"mandate_revoked":Date.parse(n.policy.expiresAt)<=Date.now()?"mandate_expired":"mandate_inactive");if(d===0n)return c("mandate_inactive");if(!n.policy.budgets.some(l=>l.token.toLowerCase()===i.tokenAddress.toLowerCase()))return c(i.type==="swap"?"unbudgeted_swap_leg":"mandate_inactive");if(s!==null&&d>s)return c("over_per_action_max");if(i.type==="transfer"&&n.policy.recipients.length>0&&!n.policy.recipients.some(l=>l.toLowerCase()===i.recipient.toLowerCase()))return c("wrong_recipient");if((await this.identity()).address.toLowerCase()!==n.agentAddress.toLowerCase())return c("mandate_inactive");if(!this.#g)throw new Error("Configure maxGasCostWei before preparing mandate actions.");let p={accountId:n.accountId,accountAddress:n.accountAddress,chainId:84532,tokenAddress:i.tokenAddress,amount:i.amountRaw},x={delegationId:n.id,permissionId:n.permissionId,executorAddress:n.grantExecutor,maxGasCostWei:this.#g};return i.type==="swap"?this.prepareExactAction({...p,action:"swap",tokenOutAddress:i.tokenOutAddress,...i.maxSlippageBps!=null?{maxSlippageBps:i.maxSlippageBps}:{}},{...x,routerAddress:i.routerAddress,minAmountOut:i.minAmountOutRaw,...t?{verifyRoute:t}:{}}):this.prepareExactAction({...p,action:"transfer",recipient:i.recipient},x)}async buildDelegatedAction(e){A(e.delegationId),u(e.recipient,20),(!Number.isFinite(e.amount)||e.amount<=0||e.amount>Number.MAX_SAFE_INTEGER)&&o(),e.token!==void 0&&(typeof e.token!="string"||!e.token||e.token.length>256)&&o();let t={recipient:e.recipient,amount:e.amount,...e.token?{token:e.token}:{}};return z(await this.#t(n=>this.#e.post(`/v1/delegations/${e.delegationId}/actions`,t,n),!1))}async buildDelegatedSwap(e){A(e.delegationId),(![e.tokenIn,e.tokenOut].every(n=>typeof n=="string"&&n.length>0&&n.length<=64)||!Number.isFinite(e.amountIn)||e.amountIn<=0||e.amountIn>Number.MAX_SAFE_INTEGER||e.maxSlippageBps!==void 0&&(!Number.isSafeInteger(e.maxSlippageBps)||e.maxSlippageBps<0||e.maxSlippageBps>1e4))&&o();let t={action:"swap",tokenIn:e.tokenIn,tokenOut:e.tokenOut,amountIn:e.amountIn,...e.maxSlippageBps!=null?{maxSlippageBps:e.maxSlippageBps}:{}};return z(await this.#t(n=>this.#e.post(`/v1/delegations/${e.delegationId}/actions`,t,n),!1))}async raiseRequest(e,t){return(!Array.isArray(e)||!e.length||e.length>100||typeof t!="string"||!t.trim()||t.length>2e3)&&o(),ie(await this.#t(n=>this.#e.post("/v1/agents/requests",{calls:e,reason:t},n),!1))}async spendUnderGrant(e,t,n,i,d){E(e),u(t,32),u(n,32);let s=await this.#l(t),a=xe(["bytes1","bytes32","bytes"],["0x00",n,s]);try{return await this.#e.post("/v1/userops",{userOp:{...e,signature:a},userOpHash:t,intentType:d},i)}catch(c){throw c instanceof h&&(c.userOpHash=t),c}}async getUserOp(e){return A(e),this.#t(t=>this.#e.get(`/v1/userops/${e}`,t))}async getUserOpByHash(e,t){return(!Number.isSafeInteger(e)||e<1)&&o(),u(t,32),V(await this.#t(n=>this.#e.get(`/v1/userops/by-hash/${e}/${t}`,n)),t)}async awaitTerminal(e,t){return ee(n=>this.getUserOp(n),e,t,()=>Date.now(),n=>new Promise(i=>setTimeout(i,n)))}async listApis(e){return this.#t(t=>this.#e.get(`/v1/apis/providers?chainId=${e}`,t))}async getApiProvider(e,t){let n=t!==void 0?`?chainId=${t}`:"";return this.#t(i=>this.#e.get(`/v1/apis/providers/${e}${n}`,i))}async callApi(e){let t=await this.#t(n=>this.#e.post("/v1/apis/calls/requirements",e,n),!1);return A(t?.requirementId),["ready","pending_approval"].includes(t.status)||o(),this.#m(t)}async resumeApi(e,t=be){A(e);let n=F(await this.#t(i=>this.#e.get(`/v1/apis/calls/relay/${e}`,i)),e);return n.status==="ready"?this.#m({requirementId:e,status:"ready",...$(n.ready)},t):n.status!=="pending_approval"?n:this.#m({requirementId:e,status:"pending_approval",approvalId:e,expiresAt:""},t)}async#m(e,t=be){let n;if(e.status==="pending_approval"){let a=await ee(c=>this.#t(g=>this.#e.get(`/v1/apis/calls/requirements/${c}`,g)),e.requirementId,t,()=>Date.now(),c=>new Promise(g=>setTimeout(g,c)));if(a.status==="approved"&&a.payload&&a.authorization&&a.index!==void 0&&a.validator)n={payload:a.payload,authorization:a.authorization,index:a.index,validator:a.validator};else{let c=a.status==="declined"?"owner_declined":a.status==="expired"?"approval_timed_out":"approval_still_pending",g=c==="owner_declined"?"The owner declined this call. Nothing was signed and nothing was charged.":c==="approval_timed_out"?"The owner did not respond before the approval window closed. Nothing was signed and nothing was charged.":"The owner has not answered yet. Nothing was signed or charged. Resume this requirement or ask the owner to check their pending approvals.";return["pending","declined","expired"].includes(a.status)||o(),{status:a.status==="pending"?"pending_approval":"declined",declineReason:c,message:g,requirementId:e.requirementId,approvalId:e.status==="pending_approval"?e.approvalId:void 0}}}else n=e;n=$(n);let i=await this.identity(),d=await this.#l(n.payload),s=xe(["bytes1","address","bytes"],["0x01",n.validator,Qe([{type:"address"},{type:"tuple",components:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]},{type:"uint32"},{type:"bytes"}],[i.address,{from:n.authorization.from,to:n.authorization.to,value:BigInt(n.authorization.value),validAfter:BigInt(n.authorization.validAfter),validBefore:BigInt(n.authorization.validBefore),nonce:n.authorization.nonce},n.index,d])]);try{return F(await this.#t(a=>this.#e.post("/v1/apis/calls/relay",{requirementId:e.requirementId,signature:s},a),!1),e.requirementId)}catch(a){throw a instanceof h&&(a.requirementId=e.requirementId),a}}async getApiBudget(e){return this.#t(t=>this.#e.get(`/v1/apis/budget?chainId=${e}`,t))}reset(){this.#n+=1,this.#u=null,this.#p=null,this.#i=null,this.#c=null,this.#s=null}async#f(){if(!this.#c){let e=await this.identity();this.#c??=new B(e.fingerprint)}return this.#c}async#t(e,t=!0){let n=await this.ensureSession();try{return await e(n)}catch(i){if(t&&i instanceof h&&i.status===401){let d=this.#s&&this.#s.token!==n?await this.ensureSession():await this.mintSession();return await e(d)}throw i}}};function nt(r,e={}){let t={address:r.address,publicKey:r.publicKey,fingerprint:Z(r.address),backend:e.backend??"injected",createdAt:e.createdAt??new Date().toISOString()};return{ensure:async()=>({...t}),sign:n=>r.signMessage({message:n}),signHash:n=>r.sign({hash:n})}}import{recoverMessageAddress as rt}from"viem";async function it(r,e,t){if(typeof t!="string"||t.trim().length<1||t.trim().length>80)throw new Error("Agent name must contain 1 to 80 characters.");let n;try{n=U(await r.ensure())}catch{throw ne()}let i=await e.app.context();A(i.appId),A(i.keyId),["test","live"].includes(i.environment)||o();let d=n.publicKey.toLowerCase(),s=n.address.toLowerCase(),a=await e.agents.challenge({publicKey:d,name:t.trim()});(!a||a.appId!==i.appId||a.environment!==i.environment||a.publicKey!==d||a.address!==s||!/^dach_[A-Za-z0-9_-]{43}$/.test(a.id)||!k(a.expiresAt)||Date.parse(a.expiresAt)<=Date.now()||Date.parse(a.expiresAt)>Date.now()+36e4)&&o();let c=["Botanary agent registration","Purpose: register-agent-key","Audience: botanary:developer-platform:2026-09-07",`Application: ${i.appId}`,`Environment: ${i.environment}`,`API key: ${i.keyId}`,`Public key: ${d}`,`Address: ${s}`,`Nonce: ${a.id}`,`Expires: ${a.expiresAt}`,"This proof does not authorize an account connection or an on-chain grant."].join(`
|
|
2
|
+
`);a.message!==c&&o();let g;try{if(g=await r.sign(c),u(g,65),(await rt({message:c,signature:g})).toLowerCase()!==s)throw ne()}catch{throw ne()}let p=await e.agents.complete({challengeId:a.id,signature:g});return(!p||p.appId!==i.appId||p.environment!==i.environment||p.publicKey!==d||p.address!==s||p.grantStatus!=="unknown"||!["awaiting_connection","active","disabled","app_disabled","key_revoked","connection_revoked","unavailable"].includes(p.apiAccess)||p.apiAccess==="active"&&p.connectionId===null||p.apiAccess==="awaiting_connection"&&p.connectionId!==null)&&o(),p.connectionId!==null&&A(p.connectionId),p}function ne(){let r=new h("The agent signer could not complete registration.",0);return r.code="signer_error",r}export{te as AgentRuntime,h as BotanaryApiError,Ie as DEFAULT_API_BASE_URL,fe as DEFAULT_PAIRING_CODE_TTL_MS,ge as FINGERPRINT_BYTES,me as NONCE_BYTES,B as PairingCodeManager,ee as awaitTerminalWith,nt as createViemAgentSigner,K as crockfordBase32,Z as deriveFingerprint,X as generatePairingNonce,it as registerAgent};
|
package/dist/runtime.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ExactAgentAction, type AgentActionBinding, type AgentSwapBinding, type PreparedAgentAction, type
|
|
1
|
+
import { type ExactAgentAction, type AgentActionBinding, type AgentSwapBinding, type PreparedAgentAction, type MandateActionInput, type AgentPolicyRefusal } from './exact-action.js';
|
|
2
2
|
import { type Hex } from 'viem';
|
|
3
3
|
import { type PairingCode } from './pairing-code.js';
|
|
4
4
|
import { type AgentTransport } from './transport.js';
|
|
@@ -44,7 +44,7 @@ export declare class AgentRuntime {
|
|
|
44
44
|
chainId?: number;
|
|
45
45
|
}): Promise<unknown>;
|
|
46
46
|
prepareExactAction(input: ExactAgentAction, binding: AgentActionBinding | AgentSwapBinding): Promise<PreparedAgentAction>;
|
|
47
|
-
prepareAction(input:
|
|
47
|
+
prepareAction(input: MandateActionInput): Promise<PreparedAgentAction | AgentPolicyRefusal>;
|
|
48
48
|
buildDelegatedAction(params: {
|
|
49
49
|
delegationId: string;
|
|
50
50
|
recipient: string;
|