@oakagentkit/addon 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +12 -2
  3. package/build/dist/bridge.d.ts +61 -0
  4. package/build/dist/bridge.js +1 -0
  5. package/build/dist/chunks/4B2GMIK7.js +1 -0
  6. package/build/dist/chunks/4LWKW7PM.js +2 -0
  7. package/build/dist/chunks/4X7FLHGQ.js +1 -0
  8. package/build/dist/chunks/5HTX664S.js +1 -0
  9. package/build/dist/chunks/62PM22KQ.js +7 -0
  10. package/build/dist/chunks/GONTF7K4.js +1 -0
  11. package/build/dist/chunks/HGFLLHB6.js +1 -0
  12. package/build/dist/chunks/HLAZAI2Q.js +4 -0
  13. package/build/dist/chunks/ILJVXWGD.js +1 -0
  14. package/build/dist/chunks/QIDB35RS.js +1 -0
  15. package/build/dist/chunks/U4YOG57X.js +1 -0
  16. package/build/dist/chunks/VZCMAMZL.js +2 -0
  17. package/build/dist/chunks/YVAFJM4Y.js +1 -0
  18. package/build/dist/cli.d.ts +63 -0
  19. package/build/dist/cli.js +6 -0
  20. package/build/dist/identity.d.ts +48 -0
  21. package/build/dist/identity.js +1 -0
  22. package/build/dist/journal.d.ts +53 -0
  23. package/build/dist/journal.js +1 -0
  24. package/build/dist/onboarding.d.ts +38 -0
  25. package/build/dist/onboarding.js +1 -0
  26. package/build/dist/private-files.d.ts +5 -0
  27. package/build/dist/private-files.js +1 -0
  28. package/build/dist/recipes.d.ts +26 -0
  29. package/build/dist/recipes.js +1 -0
  30. package/build/dist/redact.d.ts +4 -0
  31. package/build/dist/redact.js +1 -0
  32. package/build/dist/renew.d.ts +2 -0
  33. package/build/dist/renew.js +1 -0
  34. package/build/dist/schema/recipe.schema.json +1 -0
  35. package/build/dist/sender.d.ts +116 -0
  36. package/build/dist/sender.js +1 -0
  37. package/build/dist/session.d.ts +45 -0
  38. package/build/dist/session.js +1 -0
  39. package/build/dist/setup.d.ts +24 -0
  40. package/build/dist/setup.js +1 -0
  41. package/build/dist/subscribe.d.ts +347 -0
  42. package/build/dist/subscribe.js +1 -0
  43. package/build/dist/version.d.ts +1 -0
  44. package/build/dist/version.js +1 -0
  45. package/build/dist/wallet.d.ts +11 -0
  46. package/build/dist/wallet.js +12 -0
  47. package/package.json +54 -4
package/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Oak — Free to use, no copying
2
+ Copyright (c) 2026 Oak. All rights reserved.
3
+
4
+ Anyone may install and use this package, including in their own agents and
5
+ commercial products, free of charge. You may make the copies technically
6
+ necessary to install, run and back up the package for that use.
7
+
8
+ You may not otherwise copy, modify, distribute, resell, sublicense or rehost
9
+ the package code, whether in original, minified or derived form. Products
10
+ may depend on the official package; this does not permit redistributing its
11
+ code inside another package, bundle, service download or hosted mirror.
12
+
13
+ Keep this license with permitted copies. Third-party dependencies are
14
+ separate works governed by their own licenses; these restrictions do not
15
+ replace their terms. This license grants no trademark rights.
16
+
17
+ The package is provided as is, without warranty. To the extent permitted
18
+ by law, Oak is not liable for claims or damages arising from its use.
package/README.md CHANGED
@@ -1,3 +1,13 @@
1
- # Temporary Holding Version
1
+ # @oakagentkit/addon
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The local Oak CLI and MCP bridge. It keeps wallet signing on your computer and connects AI agents to Oak on Robinhood Chain.
4
+
5
+ Install:
6
+
7
+ ```sh
8
+ npm install -g @oakagentkit/addon
9
+ ```
10
+
11
+ See [setup](https://oakagentkit.org/setup.html) and [documentation](https://oakagentkit.org/docs.html). Oak is not affiliated with Robinhood. Not financial advice. Onchain actions involve risk; Oak never promises returns. Run `oak init` and `oak export` yourself in your own terminal, never through an agent. Never share recovery words or private keys.
12
+
13
+ On first use, `oak mcp` or `oak address` creates the local wallet automatically without prompts. `account` returns its address, network, ETH/USDG funding message and optional backup guidance. The agent re-checks balances after funding, then uses `oak_setup` and `oak_subscribe` with user authorization. Mainnet defaults include service/RPC URLs and public contract discovery. Run `oak backup` for guidance; export/recovery remain owner-terminal operations.
@@ -0,0 +1,61 @@
1
+ import { createModule as kyberswap } from '@oakagentkit/core/modules/kyberswap/index';
2
+ import { createModule as velora } from '@oakagentkit/core/modules/velora/index';
3
+ import { createModule as spark } from '@oakagentkit/core/modules/spark/index';
4
+ import { createModule as netnet } from '@oakagentkit/core/modules/netnet/index';
5
+ import { createModule as longbow } from '@oakagentkit/core/modules/longbow/index';
6
+ import { createModule as beefy } from '@oakagentkit/core/modules/beefy/index';
7
+ import { createModule as orbio } from '@oakagentkit/core/modules/orbio/index';
8
+ import { createModule as hoodlock } from '@oakagentkit/core/modules/hoodlock/index';
9
+ import { createModule as uniswap } from '@oakagentkit/core/modules/uniswap/index';
10
+ import { createModule as hookr } from '@oakagentkit/core/modules/hookr/index';
11
+ import { createModule as poolstrade } from '@oakagentkit/core/modules/poolstrade/index';
12
+ export declare const MODULE_FACTORIES: readonly [typeof kyberswap, typeof velora, import("@oakagentkit/core/types").CreateModule, typeof spark, typeof netnet, typeof longbow, import("@oakagentkit/core/types").CreateModule, typeof beefy, import("@oakagentkit/core/types").CreateModule, typeof orbio, typeof hoodlock, import("@oakagentkit/core/types").CreateModule, import("@oakagentkit/core/types").CreateModule, import("@oakagentkit/core/types").CreateModule, import("@oakagentkit/core/types").CreateModule, import("@oakagentkit/core/types").CreateModule, import("@oakagentkit/core/types").CreateModule, import("@oakagentkit/core/types").CreateModule, import("@oakagentkit/core/types").CreateModule, typeof uniswap, typeof hookr, import("@oakagentkit/core/types").CreateModule, import("@oakagentkit/core/types").CreateModule, import("@oakagentkit/core/types").CreateModule, typeof poolstrade];
13
+ import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
14
+ import { type OakNetwork } from '@oakagentkit/core/addresses';
15
+ import type { Recipe, ToolArgs } from '@oakagentkit/core/types';
16
+ import { type RecipeReadClient } from './recipes.js';
17
+ import { createSender } from './sender.js';
18
+ import { type IdentityClient } from './identity.js';
19
+ import type { SetupRequest } from './setup.js';
20
+ import type { LifecycleResult } from './subscribe.js';
21
+ import type { WalletSigner } from './wallet.js';
22
+ export interface ListedTool {
23
+ name: string;
24
+ description: string;
25
+ inputSchema: {
26
+ type: 'object';
27
+ [key: string]: unknown;
28
+ };
29
+ }
30
+ export declare const READ_TOOLS: ReadonlySet<string>;
31
+ export declare function toolManifest(network?: OakNetwork): ListedTool[];
32
+ export declare function jsonArgs(value: unknown): ToolArgs;
33
+ export declare function serverAddress(value: string): URL;
34
+ export declare const PREVIEW_TTL_SECONDS = 12;
35
+ export interface BridgeOptions {
36
+ startupInstructions?: () => Promise<string>;
37
+ launchOnly?: boolean;
38
+ privateTestMode?: boolean;
39
+ identity?: Pick<IdentityClient, 'sessions' | 'requireVerified'> & Partial<Pick<IdentityClient, 'unlink'>>;
40
+ signOwner?: import('./identity.js').OwnerSign;
41
+ setup?: (request: SetupRequest) => Promise<unknown>;
42
+ subscribe?: (plan: 'holder' | 'nohold') => Promise<unknown>;
43
+ network?: OakNetwork;
44
+ serverUrl: string;
45
+ signer: WalletSigner;
46
+ sender?: Pick<ReturnType<typeof createSender>, 'send' | 'signTypedData'> & Partial<Pick<ReturnType<typeof createSender>, 'blockNumber' | 'withAction'>>;
47
+ display(text: string): void | Promise<void>;
48
+ ensureSubscribed(): Promise<LifecycleResult>;
49
+ fetch?: typeof fetch;
50
+ recipes?: () => Promise<Recipe[]>;
51
+ recipeClient?: RecipeReadClient;
52
+ now?: () => number;
53
+ previewTtlSeconds?: number;
54
+ }
55
+ export declare function createBridge(options: BridgeOptions): {
56
+ listTools: () => Promise<ListedTool[]>;
57
+ postTool: (name: string, args: ToolArgs) => Promise<unknown>;
58
+ callTool: (name: string, original: ToolArgs) => Promise<unknown>;
59
+ start: (transport?: Transport) => Promise<void>;
60
+ stop: () => Promise<void>;
61
+ };
@@ -0,0 +1 @@
1
+ import{a,b,c,d,e,f,g}from"./chunks/62PM22KQ.js";import"./chunks/HLAZAI2Q.js";import"./chunks/4X7FLHGQ.js";import"./chunks/5HTX664S.js";import"./chunks/4B2GMIK7.js";import"./chunks/QIDB35RS.js";import"./chunks/VZCMAMZL.js";import"./chunks/4LWKW7PM.js";import"./chunks/GONTF7K4.js";import"./chunks/YVAFJM4Y.js";export{a as MODULE_FACTORIES,f as PREVIEW_TTL_SECONDS,b as READ_TOOLS,g as createBridge,d as jsonArgs,e as serverAddress,c as toolManifest};
@@ -0,0 +1 @@
1
+ import{createHash as p,randomBytes as x}from"node:crypto";import{canonicalSessionIdentity as w}from"@oakagentkit/core/identity-link";import{generatePrivateKey as b,privateKeyToAccount as N}from"viem/accounts";import{getAddress as h,recoverMessageAddress as K}from"viem";import{loadSigner as P}from"#oak-wallet";var a=()=>new Error("Invalid or expired Oak session."),l=()=>Math.floor(Date.now()/1e3);function k(e,t){let n={expires:e.expires,wallet:h(e.wallet)};if(e.identity!==void 0){if(n.identity=w(e.identity,t),typeof e.nonce!="string"||!/^0x[0-9a-f]{64}$/.test(e.nonce))throw a();n.nonce=e.nonce}return e.sessionKey!==void 0&&(n.sessionKey=h(e.sessionKey)),JSON.stringify(n)}async function v(e={}){let t=(e.now??l)(),n=e.lifetime??900;if(!Number.isSafeInteger(t)||t<0||!Number.isSafeInteger(n)||n<1||n>900||!Number.isSafeInteger(t+n))throw a();try{let r=e.signer??await P(),o=k({expires:t+n,wallet:r.address,...e.sessionKey?{sessionKey:e.sessionKey}:{},...e.identity?{identity:e.identity,nonce:`0x${x(32).toString("hex")}`}:{}},e.network??"mainnet"),s=await r.signMessage({message:o}),i=`${Buffer.from(o,"utf8").toString("base64url")}.${s}`;return await O(i,t,e.network??"mainnet"),i}catch{throw new Error("Local session signing failed.")}}async function O(e,t=l(),n="mainnet"){try{if(!Number.isSafeInteger(t)||t<0||typeof e!="string"||e.length>1024)throw a();let r=/^([A-Za-z0-9_-]+)\.(0x[0-9a-fA-F]{130})$/.exec(e);if(!r)throw a();let o=r[1],s=Buffer.from(o,"base64url").toString("utf8");if(Buffer.from(s,"utf8").toString("base64url")!==o)throw a();let i=JSON.parse(s);if(!i||!Number.isSafeInteger(i.expires)||i.expires<=t||i.expires-t>900||typeof i.wallet!="string"||k(i,n)!==s)throw a();let u=await K({message:s,signature:r[2]});if(h(u)!==i.wallet)throw a();return i}catch{throw a()}}function R(e){let t=e.network??"mainnet",n=e.now??l,r=e.identity&&w(e.identity,t),o,s,i=0;function u(){i++,o=void 0,s=void 0}let S={get identity(){return r&&{...r}},setIdentity(c){r=c&&w(c,t),u()},clear:u,async get(){if(o&&o.expires-n()>60)return o.token;if(!s){let c=i,m=n(),y=r&&{...r},f=N(b()),d=Promise.resolve().then(async()=>{let g=y&&e.refreshIdentity?await e.refreshIdentity(y):y;if(i!==c)throw new Error("Identity changed while signing; retry the action.");return r=g,v({...e,network:t,identity:g,sessionKey:f.address,now:()=>m})}).then(g=>{if(i!==c)throw new Error("Identity changed while signing; retry the action.");return o={token:g,expires:m+900,key:f},g}).finally(()=>{s===d&&(s=void 0)});s=d}return s},async headers(c,m,y){let f=await S.get(),d=o;if(!d||d.token!==f)throw a();let g=i,I=await $({token:f,signer:d.key,method:c,path:m,body:y,expires:Math.min(n()+60,d.expires)});if(i!==g)throw new Error("Identity changed while signing; retry the action.");return{"X-Oak-Session":f,"X-Oak-Request":I}}};return S}async function $(e){let t=r=>p("sha256").update(r).digest("hex"),n=JSON.stringify({session:t(e.token),method:e.method,path:e.path,bodyHash:t(e.body),nonce:e.nonce??`0x${x(32).toString("hex")}`,expires:e.expires});return`${Buffer.from(n).toString("base64url")}.${await e.signer.signMessage({message:n})}`}export{v as a,O as b,R as c,$ as d};
@@ -0,0 +1,2 @@
1
+ import{a as w,b as C,d as R}from"./GONTF7K4.js";import{c as U}from"./YVAFJM4Y.js";import ne from"ajv";import{constants as l}from"node:fs";import{lstat as I,mkdir as ie,open as Z,readdir as N,rmdir as oe,unlink as ae}from"node:fs/promises";import{homedir as se}from"node:os";import{basename as J,dirname as q,isAbsolute as W,join as E,parse as ce,relative as pe,resolve as A,sep as Y}from"node:path";import{Readable as fe,Transform as de}from"node:stream";import{pipeline as le}from"node:stream/promises";import{createGunzip as ue}from"node:zlib";import me from"tar-stream";import{createPublicClient as we,decodeFunctionResult as he,encodeFunctionData as O,getAddress as V,http as ye,isAddress as z}from"viem";var F={$schema:"http://json-schema.org/draft-07/schema#",$id:"https://oakagentkit.org/schema/recipe.schema.json",title:"Oak declarative recipe v1",type:"object",additionalProperties:!1,required:["schema","project","name","description","chainId","contract","function","inputs","kind"],properties:{schema:{const:"oak-recipe/v1"},project:{$ref:"#/definitions/slug"},name:{$ref:"#/definitions/slug"},description:{type:"string"},chainId:{const:4663},contract:{type:"string",format:"eip55"},function:{type:"object",additionalProperties:!1,required:["type","name","stateMutability","inputs","outputs"],properties:{type:{const:"function"},name:{type:"string",pattern:"^[A-Za-z_][A-Za-z0-9_]*$"},stateMutability:{enum:["view","pure","nonpayable","payable"]},inputs:{type:"array",maxItems:128,items:{$ref:"#/definitions/parameter"}},outputs:{type:"array",maxItems:128,items:{$ref:"#/definitions/parameter"}}}},inputs:{type:"array",maxItems:128,items:{type:"object",additionalProperties:!1,required:["name","type","description"],properties:{name:{type:"string",pattern:"^[A-Za-z_][A-Za-z0-9_]*$"},type:{type:"string",pattern:"^(address|bool|string|bytes([1-9]|[12][0-9]|3[0-2])?|u?int(8|16|24|32|40|48|56|64|72|80|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256)?|tuple)(\\[([1-9][0-9]*)?\\])*$"},description:{type:"string"},default:{}}}},kind:{enum:["read","tx"]},value:{type:"object",additionalProperties:!1,required:["fromInput"],properties:{fromInput:{type:"string",pattern:"^[A-Za-z_][A-Za-z0-9_]*$"}}},approve:{type:"object",additionalProperties:!1,required:["token","amountFromInput"],properties:{token:{type:"string",format:"eip55"},amountFromInput:{type:"string",pattern:"^[A-Za-z_][A-Za-z0-9_]*$"}}}},definitions:{slug:{type:"string",pattern:"^[a-z0-9-]{1,40}$"},parameter:{type:"object",additionalProperties:!1,required:["type"],properties:{name:{type:"string",pattern:"^([A-Za-z_][A-Za-z0-9_]*)?$"},type:{type:"string",pattern:"^(address|bool|string|bytes([1-9]|[12][0-9]|3[0-2])?|u?int(8|16|24|32|40|48|56|64|72|80|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256)?|tuple)(\\[([1-9][0-9]*)?\\])*$"},internalType:{type:"string"},components:{type:"array",minItems:1,maxItems:128,items:{$ref:"#/definitions/parameter"}}}}}};var d=64*1024,S=4*1024*1024,H=100,v=/^[a-z0-9-]{1,40}$/,X=/^package\/recipes\/[a-z0-9-]{1,40}\.recipe\.json$/,ge="as-is, not reviewed by Oak",L=new ne({strict:!0,allErrors:!0});L.addFormat("eip55",{type:"string",validate:e=>z(e,{strict:!1})&&V(e)===e});var M=L.compile(F),T=(e,t)=>Object.hasOwn(e,t);function B(e,t=0){if(t>16)throw new Error("Recipe ABI nesting exceeds 16 levels.");let r=/^tuple(?:\[|$)/.test(e.type),o="components"in e?e.components:void 0;if(r!==!!o)throw new Error("Recipe tuple components must match its ABI type.");for(let n of o??[])B(n,t+1);for(let n of e.type.matchAll(/\[(\d+)\]/g))if(!Number.isSafeInteger(Number(n[1])))throw new Error("Invalid ABI array length.")}function G(e,t=256){if(typeof e!="string"||!/^(0|[1-9][0-9]*)$/.test(e))throw new Error("Expected an unsigned decimal base-unit string.");let r=BigInt(e);if(r>=1n<<BigInt(t))throw new Error("Unsigned integer exceeds its ABI type.");return r}function g(e,t){let r=/^(.*)\[([0-9]*)\]$/.exec(e.type);if(r){if(!Array.isArray(t)||r[2]!==""&&t.length!==Number(r[2]))throw new Error("Expected an ABI array of the declared length.");return t.map(n=>g({...e,type:r[1]},n))}if(e.type==="tuple"&&"components"in e){if(Array.isArray(t)){if(t.length!==e.components.length)throw new Error("Tuple input length mismatch.");return e.components.map((i,a)=>g(i,t[a]))}if(t===null||typeof t!="object")throw new Error("Expected a tuple input.");let n=e.components.map(i=>i.name);if(n.some(i=>!i)||new Set(n).size!==n.length||Object.keys(t).length!==n.length)throw new Error("Use positional values for this tuple.");return e.components.map(i=>{if(!T(t,i.name))throw new Error("Missing tuple input.");return g(i,t[i.name])})}let o=/^(u?int)(\d*)$/.exec(e.type);if(o){let n=Number(o[2]||256);if(o[1]==="uint")return G(t,n);if(typeof t!="string"||!/^(0|-?[1-9][0-9]*)$/.test(t))throw new Error("Expected a signed decimal string.");let i=BigInt(t),a=1n<<BigInt(n-1);if(i<-a||i>=a)throw new Error("Signed integer exceeds its ABI type.");return i}if(e.type==="address"){if(typeof t!="string"||!z(t))throw new Error("Expected an address input.");return V(t)}if(e.type==="bool"&&typeof t=="boolean"||e.type==="string"&&typeof t=="string")return t;if(/^bytes\d*$/.test(e.type)&&typeof t=="string"&&/^0x(?:[0-9a-fA-F]{2})*$/.test(t)){let n=e.type.slice(5);if(!n||(t.length-2)/2===Number(n))return t}throw new Error(`Invalid typed input for ${e.type}.`)}function b(e){let t=typeof e=="string"?e:e instanceof Uint8Array?Buffer.from(e).toString("utf8"):JSON.stringify(e);if(t===void 0||Buffer.byteLength(t)>d)throw new Error("Recipe exceeds 64 KiB or is not JSON.");let r=JSON.parse(t);if(!M(r))throw new Error(`Invalid recipe schema: ${L.errorsText(M.errors)}.`);let o=r;if(o.function.inputs.length!==o.inputs.length)throw new Error("Recipe inputs must match ABI inputs by position and type.");let n=new Set;o.inputs.forEach((a,c)=>{if(n.has(a.name))throw new Error("Duplicate recipe input name.");n.add(a.name);let s=o.function.inputs[c];if(s.type!==a.type)throw new Error("Recipe inputs must match ABI inputs by position and type.");B(s),T(a,"default")&&g(s,a.default)}),o.function.outputs.forEach(a=>B(a));let i=o.function.stateMutability;if(o.kind==="read"?!["view","pure"].includes(i):!["nonpayable","payable"].includes(i))throw new Error("Recipe kind does not match function stateMutability.");if(o.approve&&o.kind!=="tx")throw new Error("Recipe approve requires kind tx.");for(let a of[o.value?.fromInput,o.approve?.amountFromInput])if(a!==void 0&&!o.inputs.some(c=>c.name===a&&/^uint(\d*)$/.test(c.type)))throw new Error("Recipe value/approve must reference an unsigned integer input.");if(o.value&&i!=="payable")throw new Error("Recipe value requires a payable function.");return o}function Q(e,t){if(t===null||typeof t!="object"||Array.isArray(t)||Object.keys(t).some(r=>!e.inputs.some(o=>o.name===r)))throw new Error("Unexpected recipe inputs.");return e.inputs.map((r,o)=>{let n=T(t,r.name)?t[r.name]:r.default;if(n===void 0)throw new Error(`Missing recipe input: ${r.name}.`);return g(e.function.inputs[o],n)})}function $(e){if(typeof e=="bigint"||typeof e=="number")return String(e);if(e==null)return null;if(typeof e=="string"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map($);if(typeof e=="object")return Object.fromEntries(Object.entries(e).map(([t,r])=>[t,$(r)]));throw new Error("Unexpected decoded recipe result.")}async function ze(e,t,r={}){try{if(e=b(e),e.kind!=="read")throw new Error("Expected a read recipe.");let o=O({abi:[e.function],functionName:e.function.name,args:Q(e,t)});if(!r.client&&!process.env.OAK_RPC_URL)throw new Error("Set OAK_RPC_URL before reading a recipe.");let n=r.client??we({transport:ye(process.env.OAK_RPC_URL),cacheTime:0});if(await n.getChainId()!==e.chainId)throw new Error("RPC chain does not match recipe chain.");let i=await n.call({to:e.contract,data:o});if(!i.data)throw new Error("Recipe read returned no data.");return $(he({abi:[e.function],functionName:e.function.name,data:i.data}))}catch(o){throw U(o)}}function Le(e,t,r){if(e=b(e),e.kind!=="tx")throw new Error("Expected a tx recipe.");if(!z(r))throw new Error("Invalid wallet address.");let o=Q(e,t),n=s=>String(o[e.inputs.findIndex(f=>f.name===s)]),i=`${e.project}/${e.name} \u2014 ${ge}`,a={to:e.contract,data:O({abi:[e.function],functionName:e.function.name,args:o}),value:e.value?n(e.value.fromInput):"0",chainId:e.chainId,description:i};return e.approve?[{to:e.approve.token,data:O({abi:[{type:"function",name:"approve",stateMutability:"nonpayable",inputs:[{type:"address"},{type:"uint256"}],outputs:[{type:"bool"}]}],functionName:"approve",args:[e.contract,G(n(e.approve.amountFromInput))]}),value:"0",chainId:e.chainId,description:`Approve exact amount for ${i}`},a]:[a]}function j(e){if(!e||e.startsWith("/")||/^[A-Za-z]:/.test(e)||e.includes("\\")||[...e].some(t=>t.charCodeAt(0)<32||t.charCodeAt(0)===127)||e.split("/").some(t=>t===".."||t==="."))throw new Error("Unsafe archive path.")}var P=class extends de{total=0;entries=0;header=Buffer.alloc(512);filled=0;remaining=0;zeroBlocks=0;_transform(t,r,o){try{if(this.total+=t.length,this.total>S)throw new Error("Archive exceeds 4 MiB decompressed limit.");let n=0;for(;n<t.length;){if(this.remaining){let m=Math.min(this.remaining,t.length-n);this.remaining-=m,n+=m;continue}let i=Math.min(512-this.filled,t.length-n);if(t.copy(this.header,this.filled,n,n+i),this.filled+=i,n+=i,this.filled!==512)continue;if(this.filled=0,this.header.every(m=>m===0)){this.zeroBlocks++;continue}if(this.zeroBlocks)throw new Error("Archive contains trailing entries after its terminator.");if(++this.entries>H)throw new Error("Archive exceeds 100 entries.");let a=(m,te)=>this.header.subarray(m,m+te).toString("utf8").split("\0")[0],c=this.header.subarray(257,263).equals(Buffer.from("ustar\0"))?a(345,155):"",s=`${c?`${c}/`:""}${a(0,100)}`;j(s);let f=this.header[156];if(f!==0&&f!==48&&f!==53)throw new Error("Unsupported archive entry type (links and extensions forbidden).");if(a(157,100))throw new Error("Unsupported archive link type.");let p=a(124,12).trim();if(!/^[0-7]+$/.test(p))throw new Error("Invalid archive size.");let y=Number.parseInt(p,8);if(!Number.isSafeInteger(y)||y>S)throw new Error("Archive exceeds 4 MiB decompressed limit.");if(f===53&&y!==0)throw new Error("Archive directory must have no payload.");if((X.test(s)||s==="package/package.json")&&y>d)throw new Error("Selected recipe or metadata exceeds 64 KiB.");this.remaining=Math.ceil(y/512)*512}o(null,t)}catch(n){o(n)}}_flush(t){t(this.filled||this.remaining||this.zeroBlocks<2?new Error("Truncated archive or missing terminator."):null)}};async function D(e){let t=[],r,o=me.extract();if(o.on("entry",(i,a,c)=>{let s=X.test(i.name)||i.name==="package/package.json";try{if(j(i.name),i.type!=="file"&&i.type!=="directory")throw new Error("Unsupported archive entry type.");if(s&&(i.size??0)>d)throw new Error("Selected recipe or metadata exceeds 64 KiB.")}catch(p){c(p);return}let f=[];a.on("data",p=>{s&&Buffer.isBuffer(p)&&f.push(p)}),a.on("end",()=>{try{if(j(i.name),i.type!=="file"&&i.type!=="directory")throw new Error("Unsupported archive entry type.");if(i.type==="file"&&s){let p=Buffer.concat(f);if(p.length>d)throw new Error("Selected recipe or metadata exceeds 64 KiB.");if(i.name==="package/package.json"){if(r)throw new Error("Duplicate package metadata.");r=p}else t.push({name:J(i.name),data:p})}c()}catch(p){c(p)}}),a.on("error",p=>o.destroy(p))}),await le(e,ue(),new P,o),!r)throw new Error("Missing package metadata.");let n=JSON.parse(r.toString("utf8"));if(!n||typeof n!="object"||!("oakProject"in n)||typeof n.oakProject!="string"||!v.test(n.oakProject))throw new Error("Invalid package oakProject metadata.");for(let i of t)if(b(i.data).project!==n.oakProject)throw new Error("Recipe project differs from package oakProject.");return t}async function h(e){try{return await I(e)}catch(t){if(t.code==="ENOENT")return;throw t}}async function u(e){let t=A(e),r=ce(t).root;for(let o of t.slice(r.length).split(Y).filter(Boolean)){r=E(r,o);let n=await h(r);if(!n)return;if(n.isSymbolicLink())throw new Error("Recipe paths must not contain links.");if(r!==t&&!n.isDirectory())throw new Error("Recipe ancestor is not a directory.")}}async function Ee(e,t=!1){let r=t?await R(e,l.O_RDONLY,d):await Z(e,l.O_RDONLY|l.O_NOFOLLOW|l.O_NONBLOCK);try{let o=await r.stat();if(!o.isFile())throw new Error("Recipe source must be a regular file.");if(o.size>d)throw new Error("Recipe exceeds 64 KiB.");let n=Buffer.alloc(d+1),i=0;for(;i<n.length;){let{bytesRead:a}=await r.read(n,i,n.length-i,null);if(!a)break;i+=a}if(i>d)throw new Error("Recipe exceeds 64 KiB.");return n.subarray(0,i)}finally{await r.close()}}async function ee(e,t=!1){let r=[],o=0,n=0,i=async a=>{if(++o>H)throw new Error("Local import exceeds 100 entries.");let c=await I(a);if(c.isSymbolicLink())throw new Error("Local imports must not follow links.");if(c.isDirectory()){t&&await w(a);for(let s of(await N(a)).sort())await i(E(a,s))}else if(c.isFile()){if(a.endsWith(".recipe.json")){let s=await Ee(a,t);if(n+=s.length,n>S)throw new Error("Local import exceeds 4 MiB.");r.push({name:J(a),data:s})}}else throw new Error("Unsupported local file type.")};return await i(e),r}var x=e=>A(e.directory??E(se(),".oak/recipes"));function k(e,t,r){if(!v.test(t))throw new Error("Invalid recipe project.");if(r!==void 0&&!v.test(r))throw new Error("Invalid recipe name.");let o=A(e,t,...r===void 0?[]:[`${r}.recipe.json`]),n=pe(e,o);if(!n||n.startsWith(`..${Y}`)||n===".."||W(n))throw new Error("Recipe destination escapes store.");return o}async function _(e){await u(e);let t=await h(e);if(t){if(!t.isDirectory())throw new Error("Recipe store path is not a directory.");return}await _(q(e));try{await ie(e,{mode:448})}catch(r){if(r.code!=="EEXIST")throw r}if(await u(e),!(await I(e)).isDirectory())throw new Error("Recipe store path is not a directory.")}async function K(e,t){let r=await t(e,{headers:{"User-Agent":"Oak-Recipe-Importer/1"},signal:AbortSignal.timeout(3e4)});if(!r.ok||!r.body)throw await r.body?.cancel(),new Error(`Recipe fetch failed (${r.status}).`);return fe.fromWeb(r.body)}async function be(e,t){let r=/^(@[a-z0-9-]+\/[a-z0-9._-]+|[a-z0-9][a-z0-9._-]*)(?:@([a-zA-Z0-9._-]+))?$/.exec(e);if(!r)throw new Error("Invalid npm recipe source.");let o=r[1].replace("/","%2F"),n=await K(`https://registry.npmjs.org/${o}/${r[2]??"latest"}`,t),i=[],a=0;for await(let f of n){if(a+=f.length,a>d)throw new Error("Registry metadata exceeds 64 KiB.");i.push(f)}let c=JSON.parse(Buffer.concat(i).toString("utf8"));if(typeof c?.dist?.tarball!="string")throw new Error("Missing npm tarball metadata.");let s=new URL(c.dist.tarball);if(s.protocol!=="https:"||s.username||s.password)throw new Error("Invalid npm tarball URL.");return K(s.href,t)}async function Te(e,t={}){let r=A(e);await u(r);let o=await h(r),n;if(o)if(o.isFile()&&/\.(tgz|tar\.gz)$/.test(r)){let s=await Z(r,l.O_RDONLY|l.O_NOFOLLOW|l.O_NONBLOCK);try{n=await D(s.createReadStream())}finally{await s.close()}}else n=await ee(r);else{if(W(e)||e.startsWith("."))throw new Error("Local recipe source does not exist.");n=await D(await be(e,t.fetch??fetch))}let i=x(t),a=new Set,c=n.map(s=>{let f=b(s.data);if(`${f.name}.recipe.json`!==s.name)throw new Error("Recipe filename must match its name.");let p=k(i,f.project,f.name);if(a.has(p))throw new Error("Recipe has a duplicate destination.");return a.add(p),f});if(!c.length)throw new Error("No recipe files selected.");for(let s of a)if(await u(s),await h(s))throw new Error("Recipe destination already exists.");await _(i),await w(i);for(let s of c){let f=k(i,s.project,s.name);await _(q(f)),await u(f);let p=await R(f,l.O_WRONLY|l.O_CREAT|l.O_EXCL,d);try{await p.writeFile(`${JSON.stringify(s,null,2)}
2
+ `),await C(p,d),await p.sync()}finally{await p.close()}}return c}async function Ue(e={}){let t=x(e);if(await u(t),!await h(t))return[];await w(t);let r=[];for(let o of(await N(t)).sort()){let n=k(t,o);await u(n);for(let i of await ee(n,!0)){let a=b(i.data);if(a.project!==o||i.name!==`${a.name}.recipe.json`)throw new Error("Stored recipe namespace/filename mismatch.");r.push(a)}}return r}async function Ce(e,t={}){let r=k(x(t),e);if(await u(r),!await h(r))return;await w(x(t)),await w(r);let o=await N(r);for(let n of o){let i=E(r,n);if(await u(i),!/^[a-z0-9-]{1,40}\.recipe\.json$/.test(n)||!(await I(i)).isFile())throw new Error("Recipe project contains an unexpected file.");await(await R(i,l.O_RDONLY,d)).close()}for(let n of o)await ae(E(r,n));await oe(r)}export{b as a,ze as b,Le as c,Te as d,Ue as e,Ce as f};
@@ -0,0 +1 @@
1
+ var o="0.1.0";export{o as a};
@@ -0,0 +1 @@
1
+ import{a as E,c as S}from"./4B2GMIK7.js";import{getAddress as R}from"viem";import{buildIdentityLinkTypedData as x,canonicalSessionIdentity as g}from"@oakagentkit/core/identity-link";var w="Identity changed, expired or link revoked. Run oak setup link <agentId> with the current owner to verify or link it again. Reads remain available; actions are paused.",f="Identity status is unavailable. Please try again. Reads remain available; actions are paused.",y=class extends Error{constructor(){super(w)}};function b(e){return e.verified===!1&&typeof e.status=="string"&&["revoked","unlinked","transferred","burned"].includes(e.status)}var h="This wallet does not own that agent ID. Ask the current owner to sign the link in oak setup link <agentId>.",l="The identity challenge expired. Run oak setup link <agentId> again for a fresh owner signature.",I="Wrong identity network or registry. Set OAK_NETWORK and OAK_CHAIN_ID to match the owner\u2019s agent, then run oak setup again.",O="Owner signing cancelled. Run the identity command again when ready.",v="Owner signing requires your terminal. Run oak setup link <agentId> or oak identity unlink --owner <linkId> there.";function k(e){if(e instanceof y)return e;let i=e instanceof Error?e.message:typeof e=="string"?e:"";return/cancelled|canceled/i.test(i)?new Error(O):[w,f,h,l,I,v].includes(i)?new Error(i):/identity changed|link revoked|reads remain available/i.test(i)?new Error(w):/challenge.*expir/i.test(i)?new Error(l):/network|registry|chain/i.test(i)?new Error(I):/owner|signature|proof/i.test(i)?new Error(h):new Error(w)}function N(e){let i=S({...e,refreshIdentity:async a=>{let t=await E({signer:e.signer,network:e.network,now:e.now});try{let r=await m(new URL("/v1/identity/status",e.base),{method:"POST",redirect:"error",headers:{"content-type":"application/json","X-Oak-Session":t},body:JSON.stringify({identity:a}),signal:AbortSignal.timeout(3e4)}),n=await r.json();if(r.ok&&n?.ok===!0&&n.data&&b(n.data)){await e.clearIdentity?.();return}}catch{}return a}}),m=e.fetch??fetch,c=e.now??(()=>Math.floor(Date.now()/1e3));async function u(a,t){try{let r=`/v1/identity/${a}`,n=JSON.stringify(t),d=await m(new URL(r,e.base),{method:"POST",redirect:"error",headers:{"content-type":"application/json",...await i.headers("POST",r,n)},body:n,signal:AbortSignal.timeout(3e4)}),o=await d.json();if(!d.ok||!o||o.ok!==!0||!o.data||typeof o.data!="object")throw a==="status"?new Error(f):k(o?.error);return o.data}catch(r){throw a==="status"?new Error(f):k(r)}}async function p(a){let t=await u("status",{identity:a});if(b(t))throw new y;if(t.verified!==!0)throw new Error(f);return t}return{sessions:i,async requireVerified(){if(e.loadIdentity){let t=await e.loadIdentity();JSON.stringify(t)!==JSON.stringify(i.identity)&&i.setIdentity(t)}let a=i.identity;if(!a)throw new Error("Run oak setup to register or link an ERC-8004 identity first. Reads remain available; actions are paused.");try{await p(a)}catch(t){throw t instanceof y&&(i.setIdentity(void 0),await e.clearIdentity?.()),t}},async unlink(a={actor:"agent"},t){let r=a.linkId??i.identity?.linkId;if(!r||!/^0x[0-9a-f]{64}$/.test(r))throw new Error("Provide the linkId to unlink, or link an identity first.");if(!["agent","owner"].includes(a.actor))throw new Error("Choose agent or owner to unlink.");let n;if(a.actor==="owner"){if(!t)throw new Error("Owner signing is unavailable. Run oak identity unlink --owner <linkId> in your terminal.");let o=await u("challenge",{linkId:r});try{if(x(o),g({chainId:o.chainId,registry:o.registry,agentId:o.agentId},e.network),o.audience!==JSON.stringify([e.base.origin,"unlink",r]))throw new Error(I);if(BigInt(o.issuedAt)>BigInt(c())||BigInt(o.expiresAt)<=BigInt(c()))throw new Error(l);let s=await t({...o});if(BigInt(o.expiresAt)<=BigInt(c()))throw new Error(l);if(!/^0x(?:[0-9a-fA-F]{2})+$/.test(s))throw new Error(h);n={link:o,signature:s}}catch(s){throw k(s)}}if((await u("unlink",{linkId:r,...n?{proof:n}:{}})).unlinked!==!0)throw new Error(w);return i.identity?.linkId===r&&(i.setIdentity(void 0),await e.clearIdentity?.()),{unlinked:!0,summary:"Identity link removed. Reads remain available; linked actions are paused."}},async accept(a){let t=g(a,e.network);return await p(t),i.setIdentity(t),t},async link(a,t){let r=g(a,e.network);if(r.linkId)throw new Error("Request a fresh identity link without an old linkId.");let n=await u("challenge",{identity:r});try{if(x(n),n.chainId!==r.chainId||n.registry!==r.registry||n.agentId!==r.agentId||R(n.agentWallet)!==e.signer.address||n.audience!==e.base.origin)throw new Error(I);if(BigInt(n.issuedAt)>BigInt(c())||BigInt(n.expiresAt)<=BigInt(c()))throw new Error(l);let d=await t({...n});if(BigInt(n.expiresAt)<=BigInt(c()))throw new Error(l);if(typeof d!="string"||!/^0x(?:[0-9a-fA-F]{2})+$/.test(d))throw new Error(h);let o=await u("link",{proof:{link:n,signature:d}}),s=g(o.identity,e.network);if(!s.linkId||s.agentId!==r.agentId)throw new Error(w);return await p(s),i.setIdentity(s),s}catch(d){throw k(d)}}}}export{w as a,f as b,h as c,l as d,I as e,O as f,v as g,k as h,N as i};
@@ -0,0 +1,7 @@
1
+ import{c as ge}from"./HLAZAI2Q.js";import{a as pe}from"./4X7FLHGQ.js";import{i as be}from"./5HTX664S.js";import{a as ke,c as ve}from"./VZCMAMZL.js";import{b as we,c as he,e as ye}from"./4LWKW7PM.js";import{a as G,b as me,c as K}from"./YVAFJM4Y.js";import{isReadDiscovery as Q}from"@oakagentkit/core/tool-policy";import{LAUNCH_ACTION as Me,LAUNCH_TOOLS as xe}from"@oakagentkit/core/launch";import{rejectWalletSecrets as Ne}from"@oakagentkit/core/secret-fields";import{untrustedText as Te}from"@oakagentkit/core/untrusted";import{createModule as Ce}from"@oakagentkit/core/modules/kyberswap/index";import{createModule as $e}from"@oakagentkit/core/modules/velora/index";import{createModule as Ue}from"@oakagentkit/core/modules/steakhouse/index";import{createModule as Be}from"@oakagentkit/core/modules/spark/index";import{createModule as He}from"@oakagentkit/core/modules/netnet/index";import{createModule as Le}from"@oakagentkit/core/modules/longbow/index";import{createModule as De}from"@oakagentkit/core/modules/grove/index";import{createModule as Je}from"@oakagentkit/core/modules/beefy/index";import{createModule as Fe}from"@oakagentkit/core/modules/pons/index";import{createModule as Ve}from"@oakagentkit/core/modules/orbio/index";import{createModule as We}from"@oakagentkit/core/modules/hoodlock/index";import{createModule as ze}from"@oakagentkit/core/modules/merkl/index";import{createModule as Ge}from"@oakagentkit/core/modules/relay/index";import{createModule as Ke}from"@oakagentkit/core/modules/lighter/index";import{createModule as Ae}from"@oakagentkit/core/modules/erc8004/index";import{createModule as Qe}from"@oakagentkit/core/modules/hoodag/index";import{createModule as Xe}from"@oakagentkit/core/modules/heyresearch/index";import{createModule as Ye}from"@oakagentkit/core/modules/priors/index";import{createModule as Ze}from"@oakagentkit/core/modules/morpho/index";import{createModule as er}from"@oakagentkit/core/modules/uniswap/index";import{createModule as rr}from"@oakagentkit/core/modules/hookr/index";import{createModule as tr}from"@oakagentkit/core/modules/meridian/index";import{createModule as nr}from"@oakagentkit/core/modules/tickerspring/index";import{createModule as ir}from"@oakagentkit/core/modules/clanker/index";import{createModule as or}from"@oakagentkit/core/modules/poolstrade/index";import{isDeepStrictEqual as X}from"node:util";import{createPublicClient as ar,custom as cr,encodeAbiParameters as Y,keccak256 as Z,parseAbiParameters as ee,zeroAddress as _e}from"viem";import{Server as dr}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as ur}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as lr,ListToolsRequestSchema as fr}from"@modelcontextprotocol/sdk/types.js";import{ADDRESSES as pr,CHAIN_ID as ae,NETWORKS as mr,resolveNetwork as wr}from"@oakagentkit/core/addresses";import{createModuleContext as hr,createModuleRegistry as yr}from"@oakagentkit/core/module";import{unsignedTx as Pe}from"@oakagentkit/core/tx";var sr=[Ce,$e,Ue,Be,He,Le,De,Je,Fe,Ve,We,ze,Ge,Ke,Ae,Qe,Xe,Ye,Ze,er,rr,tr,nr,ir,or],re="as-is, not reviewed by Oak",te=new Set(["balances","find_token","price","quote","preview","history","positions","account","kyberswap_quote","velora_quote","steakhouse_list","spark_list","netnet_list","longbow_list","grove_list","beefy_list","pons_browse","pons_status","pons_launch_options","orbio_credit_status","hoodlock_list_locks","merkl_rewards","relay_status","lighter_funding","erc8004_identity","hoodag_resolve","hoodag_name_info","heyresearch_research_project","heyresearch_chain_activity","priors_status","morpho_status","uniswap_list_positions","meridian_browse","meridian_positions","tickerspring_orders","clanker_browse"]),ne="Action tools and recipe transactions are paused. Run oak status, top up the required funds, then run oak renew; if you have no subscription, run oak subscribe --plan holder or oak subscribe --plan nohold.",H=()=>{throw new Error("Manifest construction must not execute a tool.")};function gr(e="mainnet"){let s=ar({transport:cr({request:H})}),f=hr({network:e,clientFor:()=>s,http:H,preview:H,quoteSwap:H,buildSwap:H}),m=(p,g={},I=[])=>({name:p,description:`Oak ${p}`,inputSchema:{type:"object",additionalProperties:!1,properties:g,required:I}}),a=[m("find_token",{query:{type:"string",minLength:1,description:"Token name, symbol or address on Robinhood Chain. Pons and pools.trade require an address."}},["query"]),m("balances"),m("price",{token:{type:"string"}},["token"]),m("quote",{from:{type:"string",description:"Token address or verified symbol; use find_token for discovery."},to:{type:"string",description:"Token address or verified symbol; use find_token for discovery."},amountIn:{type:"string",description:"Positive decimal integer in input token base units, not a human amount."},slippageBps:{type:"integer"}},["from","to","amountIn"]),m("swap",{quoteId:{type:"string"}},["quoteId"]),m("preview",{txs:{type:"array"}},["txs"]),m("history",{limit:{type:"integer",minimum:1}}),m("positions"),m("account")],h=yr(f,e==="testnet"?[Ae]:sr);if(h.errors.length)throw new Error("Oak module manifest could not be loaded.");return[...a,...h.tools.map(p=>({name:p.name,description:`Oak ${p.name}`,inputSchema:p.inputSchema}))]}function b(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function q(e,s){return typeof e=="string"&&typeof s=="string"&&e.toLowerCase()===s.toLowerCase()}function R(e){if(typeof e!="string"||!/^[0-9]+$/.test(e)||e.length>78||BigInt(e)>=2n**256n)throw new Error("Invalid project integer.");return BigInt(e)}function V(e){if(!b(e))throw new Error("Provide a JSON object.");return Ne(e),e}function br(e){let s=new URL(e);if(s.protocol!=="https:"&&!(s.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(s.hostname))||s.username||s.password||s.search||s.hash)throw new Error("Use an HTTPS Oak server URL, or HTTP on loopback for local testing.");return s}var ie=pr[ae].meridian,kr=[{name:"predictionHash",type:"bytes32"},{name:"signer",type:"address"},{name:"collateral",type:"uint256"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"}],vr=[{name:"tradeHash",type:"bytes32"},{name:"signer",type:"address"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"}];function oe(e,s,f,m,a,h,p){let g=e==="meridian_buy";if(!g&&e!=="meridian_sell")throw new Error("Unexpected project continuation.");let I=(g?ie.PredictionMarketEscrow:ie.SecondaryMarketEscrow).address;if(a.chainId!==ae||!q(a.wallet,f)||!q(a.escrowContract,I)||typeof a.requestId!="string"||!a.requestId)throw new Error("Project chain, domain or wallet mismatch.");if(h&&a.requestId!==h.requestId)throw new Error("Project exchange changed during continuation.");let O=h?.stage;if(a.stage==="prerequisites"){if(O!==void 0&&O!=="prerequisites"||!m.length||m.some(S=>S.kind!=="tx"))throw new Error("Unexpected prerequisite step order.");return}if(m.length!==1||m[0]?.kind!=="typedData"||!b(a.request)||!X(a.request,m[0].request))throw new Error("Project must return exactly its current typed-data step.");if(g?a.stage!=="primary_accept"||O!==void 0&&O!=="prerequisites":a.stage==="secondary_start"?O!==void 0&&O!=="prerequisites":a.stage!=="secondary_accept"||O!=="secondary_start")throw new Error("Unexpected project step order.");let A=m[0].request,D=g?"MintApproval":"TradeApproval";if(!X(A.domain,{name:g?"PredictionMarketEscrow":"SecondaryMarketEscrow",version:"1",chainId:ae,verifyingContract:I})||A.primaryType!==D||!X(A.types,{[D]:g?kr:vr})||!q(A.message.signer,f))throw new Error("Project typed-data domain, type or wallet mismatch.");let j=[R(A.message.deadline)];if(R(A.message.nonce),a.stage!=="secondary_start"){if(!b(a.winningBid)||typeof a.auctionId!="string"||!a.auctionId||a.winningBid.auctionId!==a.auctionId)throw new Error("Project winning bid or auction mismatch.");j.push(R(a.acceptDeadline)),g?j.push(R(a.winningBid.counterpartyDeadline)):a.winningBid.buyerDeadline!==void 0&&j.push(R(a.winningBid.buyerDeadline))}if(j.some(S=>BigInt(p)>=S))throw new Error("Meridian exchange expired. Start a fresh auction.");let _=a.winningBid,P;if(g){let S=s.picks,C=Z(Y(ee("(address conditionResolver,bytes conditionId,uint8 predictedOutcome)[]"),[S]));if(P=Z(Y(ee("bytes32,uint256,uint256,address,address,address,bytes"),[C,R(s.stake),R(_?.counterpartyCollateral),f,_?.counterparty,_e,"0x"])),A.message.collateral!==s.stake)throw new Error("Project collateral differs from the requested stake.")}else if(P=Z(Y(ee("address,address,address,address,uint256,uint256"),[s.token,ie.CollateralToken_USDe.address,f,a.stage==="secondary_start"?_e:_?.buyer,R(s.amount),a.stage==="secondary_start"?0n:R(_?.price)])),h?.stage==="secondary_start"){let S=h.request;if(S.message.nonce!==A.message.nonce||S.message.deadline!==A.message.deadline)throw new Error("Project changed its signing nonce or deadline.")}if(A.message[g?"predictionHash":"tradeHash"]!==P)throw new Error("Project hash does not match the current winning terms.")}var xr=12;function T(e){return e>1e11?Math.floor(e/1e3):Math.floor(e)}function L(e){if(typeof e=="number"&&Number.isFinite(e)&&e>=0)return T(e);if(typeof e=="bigint"&&e>=0n)return T(Number(e));if(typeof e=="string"&&e.trim()){if(/^[0-9]+$/.test(e.trim()))return T(Number(e.trim()));let s=Date.parse(e);if(Number.isFinite(s)&&s>=0)return T(s)}}function W(e){if(typeof e=="bigint"&&e>=0n)return e;if(typeof e=="number"&&Number.isSafeInteger(e)&&e>=0)return BigInt(e);if(typeof e=="string"&&/^(?:0|[1-9][0-9]*|0x[0-9a-fA-F]+)$/.test(e.trim()))return BigInt(e.trim())}function N(e,s){for(let f of s?["sender","wallet","from","account"]:["sender","wallet","account"])if(typeof e[f]=="string")return e[f]}function se(e){if(!(!Array.isArray(e)||!e.length))try{return e.map(s=>{if(!b(s))throw new Error("Invalid preview transaction.");let f=typeof s.description=="string"&&s.description.trim()?s.description:"preview";return Pe({...s,description:f})})}catch{return}}function Se(e,s){return e.length===s.length&&e.every((f,m)=>{let a=s[m];return q(f.to,a.to)&&q(f.data,a.data)&&f.value===a.value&&f.chainId===a.chainId})}function ft(e){let s=br(e.serverUrl),f=wr(e.network),{chainId:m}=mr[f];if(f==="testnet"&&!e.sender)throw new Error("Configure a testnet sender before starting the bridge.");let a=e.fetch??fetch,h=e.identity??be({base:s,signer:e.signer,network:f,fetch:a,now:e.now}),p=e.now??(()=>Math.floor(Date.now()/1e3)),g=e.previewTtlSeconds??xr,I=e.sender??ge({signer:e.signer,preview:M,now:e.now,notAfterSeconds:g});if((e.launchOnly||e.privateTestMode)&&f!=="mainnet")throw new Error("Launch bootstrap requires mainnet chain 4663.");let O=gr(f).filter(r=>!e.launchOnly||xe.has(r.name)),A=new Set(O.map(r=>r.name)),D=e.recipes??(()=>ye()),j=async()=>e.launchOnly?[]:(await D()).filter(r=>r.chainId===m),_,P,S,C=!1,J;async function ce(r){try{if(typeof I.blockNumber=="function")return await I.blockNumber(r);let o=e.recipeClient;if(typeof o?.getBlockNumber=="function")return await o.getBlockNumber();if(typeof o?.getBlock=="function")return(await o.getBlock({blockTag:"latest"})).number}catch{return}}async function U(r,o){if(r==="account"){if(V(o),Object.keys(o).length)throw new Error("Provide an empty JSON object.");let n=ve(e.signer.address,f);try{let{data:t}=await $(r,o);if(!b(t))throw new Error("Invalid account status.");return{...t,...n}}catch{return{...n,statusUnavailable:!0,summary:"Subscription status is unavailable. Retry account when the Oak service is reachable; do not assume action access."}}}return(await $(r,V(o))).data}async function $(r,o){if(!A.has(r))throw new Error("Unknown Oak tool.");let n=JSON.stringify(o);if(Buffer.byteLength(n)>(r==="pons_launch"?8388608:1048576))throw new Error("Tool arguments are too large.");!te.has(r)&&!Q(r,o)&&r!=="erc8004_register"&&await B(r);let t=r==="preview"||!te.has(r)&&!Q(r,o),y=r==="relay_bridge_in"&&typeof o.originChainId=="number"?o.originChainId:r==="preview"&&Array.isArray(o.txs)&&b(o.txs[0])&&typeof o.txs[0].chainId=="number"?o.txs[0].chainId:m,k=T(p()),x=t?await ce(y):void 0,w=`/v1/tools/${r}`,l=await h.sessions.headers("POST",w,n),d;try{d=await a(new URL(w,s),{method:"POST",redirect:"error",headers:{"content-type":"application/json",...l},body:n,signal:AbortSignal.timeout(18e4)})}catch{throw new Error("Oak server request failed. Check connectivity; any project exchange may need a fresh auction.")}let i;try{i=await d.json()}catch{throw new Error("Oak server returned invalid JSON.")}if(!b(i)||typeof i.ok!="boolean")throw new Error("Oak server returned an invalid tool envelope.");if(!i.ok)throw new Error(typeof i.error=="string"?G(i.error):"Oak tool failed.");if(!d.ok||!Object.hasOwn(i,"data"))throw new Error("Oak server returned an invalid tool response.");if(r==="preview"&&b(i.data)&&typeof i.data.summary=="string"&&(!("changes"in i.data)||Array.isArray(i.data.changes))){let c=se(o.txs),u=i.data.txs!==void 0?se(i.data.txs):c,v=Array.isArray(i.data.txs)?i.data.txs:Array.isArray(o.txs)?o.txs:[];c&&u&&Se(c,u)&&(J={preview:i.data,txs:u,rawTxs:v,sender:N(i.data,!0)??e.signer.address,at:L(i.data.timestamp??i.data.createdAt??i.data.simulatedAt)??k,blockNumber:W(i.data.blockNumber??i.data.block)??x})}return{data:i.data,meta:{at:k,blockNumber:x}}}async function M(r){r=G(r),await e.display(r),_?.getClientCapabilities()&&await _.sendLoggingMessage({level:"info",logger:"oak-preview",data:r}).catch(()=>{})}async function de(){try{return await Ie()}catch(r){throw K(r)}}async function Ie(){return e.launchOnly?O:[...O,...h.unlink?[{name:"oak_identity_unlink",description:"Remove an identity link as the linked agent or with a current-owner signature. No transaction.",inputSchema:{type:"object",additionalProperties:!1,properties:{actor:{enum:["agent","owner"]},linkId:{type:"string"}}}}]:[],...e.subscribe?[{name:"oak_subscribe",description:"Start a recurring USDG subscription after the user approves the plan and price. Requires verified identity; previews and signs locally.",inputSchema:{type:"object",additionalProperties:!1,required:["plan"],properties:{plan:{enum:["holder","nohold"]}}}},{name:"oak_renew",description:"Reconcile or renew the current subscription using local signing.",inputSchema:{type:"object",additionalProperties:!1,properties:{}}}]:[],...e.setup?[{name:"oak_setup",description:"Register a public identity with a default profile (costs gas), or link an existing ID. An external owner signs in their terminal.",inputSchema:{type:"object",additionalProperties:!1,required:["mode"],properties:{mode:{enum:["register","link"]},agentId:{type:"string"},profile:{type:"object"},tag:{type:"boolean"}}}}]:[],...(await j()).map(r=>({name:`${r.project}.${r.name}`,description:`Third-party recipe; ${re}. Description: ${Te(r.description)}`,inputSchema:{type:"object",additionalProperties:!1,properties:Object.fromEntries(r.inputs.map(o=>[o.name,{description:`${o.type}; ${Te(o.description)}`}])),required:r.inputs.filter(o=>o.default===void 0).map(o=>o.name)}}))]}async function Oe(r,o,n,t,y){let k=J;J=void 0;let x=e.signer.address;if(t){let i=N(t,!1);if(i!==void 0&&!q(i,x))return}for(let i of r)if(b(i)){let c=N(i,!0);if(c!==void 0&&!q(c,x))return}let w=[];if(t&&b(t.preview)&&typeof t.preview.summary=="string"&&(!("changes"in t.preview)||Array.isArray(t.preview.changes))){let i=se(t.preview.txs);if(i){let c=W(t.preview.blockNumber??t.preview.block),u=W(t.blockNumber??t.block);(c===void 0||u===void 0||c===u)&&w.push({preview:t.preview,txs:i,rawTxs:t.preview.txs,sender:N(t.preview,!0)??N(t,!1)??x,at:L(t.preview.timestamp??t.preview.createdAt??t.preview.simulatedAt??t.timestamp??t.createdAt)??y?.at,blockNumber:c??u??y?.blockNumber})}}if(k&&(!t||t.preview===void 0)&&w.push(k),!w.length)return;let l=T(p()),d=t?W(t.blockNumber??t.block):void 0;for(let i of w){if(i.preview.stale===!0||t?.stale===!0||!q(i.sender,x)||i.preview.chainId!==void 0&&i.preview.chainId!==n||i.rawTxs.some(v=>b(v)&&N(v,!0)!==void 0&&!q(N(v,!0),x))||!Se(i.txs,o)||i.at===void 0||!Number.isFinite(i.at)||l<i.at||l-i.at>g)continue;let c=L(i.preview.expiresAt??t?.expiresAt);if(c!==void 0&&l>=c||i.blockNumber===void 0)continue;let u=d??await ce(n);if(!(u===void 0||i.blockNumber!==u))return i.preview}}async function F(r,o,n,t,y,k){let x=n.map(d=>b(d)?{...d}:d),w=n.map(d=>Pe(d)),l=r==="relay_bridge_in"?o.originChainId:m;if(w.some(d=>d.chainId!==l)||r==="relay_bridge_in"&&y?.originChainId!==void 0&&y.originChainId!==l)throw new Error("Transaction chain differs from the requested project or Relay origin chain.");if(w.length){let d=await Oe(x,w,l,y,k),i=d?k?.at??T(p()):T(p());d||(d=await U("preview",{txs:w}),i=T(p())),J=void 0;let c=(E,qe)=>{let fe=[L(E?.expiresAt),L(y?.expiresAt),qe].filter(je=>je!==void 0);return fe.length?Math.min(...fe):void 0},u=c(d),v=u!==void 0?Math.min(i+g,u):i+g;if(await M(`${t}
2
+ ${JSON.stringify(d)}
3
+ ${JSON.stringify(w)}`),r!=="erc8004_register"&&await B(r),T(p())>v||u!==void 0&&T(p())>=u){if(u!==void 0&&T(p())>=u)throw new Error("Prepared transaction expired before signing; request a fresh quote and preview.");if(d=await U("preview",{txs:w}),i=T(p()),u=c(d,u),v=u!==void 0?Math.min(i+g,u):i+g,await M(`${t}
4
+ ${JSON.stringify(d)}
5
+ ${JSON.stringify(w)}`),r!=="erc8004_register"&&await B(r),T(p())>v||u!==void 0&&T(p())>=u)throw new Error("Prepared transaction expired before signing; request a fresh quote and preview.")}for(let E of w)Object.defineProperty(E,"notAfter",{value:v,configurable:!0});return I.send(w)}return{hashes:[],summary:""}}async function ue(r,o){try{return await Ee(r,o)}catch(n){throw K(n)}}async function Ee(r,o){if(e.launchOnly&&!xe.has(r))throw new Error("Only Pons launch tools are available before deployment.");let n=V(JSON.parse(JSON.stringify(V(o))));if(n.continuation!==void 0||n.signature!==void 0)throw new Error("Start a fresh tool call; the local bridge owns project continuations.");if(r==="oak_identity_unlink"&&h.unlink){if(Object.keys(n).some(l=>!["actor","linkId"].includes(l))||n.actor!==void 0&&n.actor!=="agent"&&n.actor!=="owner"||n.linkId!==void 0&&typeof n.linkId!="string")throw new Error("Provide actor (agent or owner) and an optional linkId.");return h.unlink({actor:n.actor==="owner"?"owner":"agent",linkId:n.linkId},e.signOwner)}if(r==="oak_subscribe"&&e.subscribe){if(Object.keys(n).length!==1||n.plan!=="holder"&&n.plan!=="nohold")throw new Error("Choose plan holder or nohold.");return await h.requireVerified(),e.subscribe(n.plan)}if(r==="oak_renew"&&e.subscribe){if(Object.keys(n).length)throw new Error("Provide an empty JSON object.");return await h.requireVerified(),e.ensureSubscribed()}if(r==="oak_setup"&&e.setup){if(Object.keys(n).some(l=>!["mode","agentId","profile","tag"].includes(l)))throw new Error("Provide only documented setup arguments.");if(n.mode==="link"&&typeof n.agentId=="string"&&n.profile===void 0&&n.tag===void 0)return e.setup({mode:"link",agentId:n.agentId});if(n.mode==="register"&&(n.profile===void 0||b(n.profile))&&n.agentId===void 0&&(n.tag===void 0||typeof n.tag=="boolean"))return e.setup({mode:"register",profile:n.profile,tag:n.tag});throw new Error("Choose register (profile optional), or link with an agentId.")}if(r.includes(".")){let l=(await j()).find(c=>`${c.project}.${c.name}`===r);if(!l)throw new Error("Unknown or disabled recipe.");if(l.kind==="read")return we(l,n,{client:e.recipeClient});await B();let d=he(l,n,e.signer.address),i=await F(r,n,d,re);return{...i,summary:`${re}. ${i.summary}`}}if(r==="account")return U(r,n);let{data:t,meta:y}=await $(r,n);if(te.has(r)||Q(r,n))return t;let k=[],x,w;for(;;){if(!b(t)||!Array.isArray(t.txs)&&!Array.isArray(t.steps))return t;if(typeof t.summary!="string"||Array.isArray(t.txs)&&Array.isArray(t.steps))throw new Error("Invalid project action result.");if(Array.isArray(t.txs)){if(t.continuation!==void 0)throw new Error("Continuation requires project steps.");let c=await F(r,n,t.txs,t.summary,t,y);if(k.push(...c.hashes),r==="pons_launch"&&c.hashes.length){let v=c.hashes.at(-1);try{let E=await U(r,{transactionHash:v});if(!b(E)||E.txs!==void 0||E.steps!==void 0)throw new Error("Invalid Pons launch confirmation.");return{...E,hashes:k,summary:[t.summary,E.summary,c.summary].filter(Boolean).join(" ")}}catch{return{hashes:k,transactionHash:v,confirmationPending:!0,summary:`Pons launch transaction mined: ${v}. Token lookup is unavailable. Call pons_launch with only transactionHash to read it; do not launch again.`}}}if(r==="erc8004_register"&&c.hashes.length){if(c.hashes.length!==1)throw new Error("Unexpected ERC-8004 registration sequence.");if(!w)w=c.hashes[0],{data:t,meta:y}=await $(r,{...n,transactionHash:w});else if({data:t,meta:y}=await $(r,{...n,transactionHash:w,metadataTransactionHash:c.hashes[0]}),b(t)&&(Array.isArray(t.txs)||Array.isArray(t.steps)))throw new Error("Unexpected ERC-8004 confirmation response.");if(b(t)&&!Array.isArray(t.txs))return{...t,hashes:k};continue}return{...Object.fromEntries(Object.entries(t).filter(([v])=>v!=="txs")),hashes:k,summary:[t.summary,c.summary].filter(Boolean).join(" ")}}let l=t.steps;if(!b(t.continuation)){if(l.some(u=>u.kind!=="tx"))throw new Error("Typed signing requires a project continuation.");let c=await F(r,n,l.map(u=>u.tx),t.summary,t,y);return{hashes:[...k,...c.hashes],summary:`${t.summary} ${c.summary}`.trim()}}let d=t.continuation;oe(r,n,e.signer.address,l,d,x,p());let i;if(l[0]?.kind==="typedData")await M(`${t.summary}
6
+ ${JSON.stringify(l[0].request)}
7
+ Signature only; external settlement remains pending.`),await B(),oe(r,n,e.signer.address,l,d,x,p()),i=await I.signTypedData(l[0].request),oe(r,n,e.signer.address,l,d,x,p());else{let c=await F(r,n,l.map(u=>u.tx),t.summary,t,y);k.push(...c.hashes)}x=d,{data:t,meta:y}=await $(r,{...n,continuation:d,...i?{signature:i}:{}})}}function z(){let r="Wallet reconciliation failed. Wait for the pending transaction or check local wallet and RPC availability.";return S||(S=Promise.resolve().then(async()=>(typeof I.withAction=="function"&&await I.withAction(async()=>{}),r="Subscription check failed.",e.ensureSubscribed())).then(async o=>{let n=o.ok===!0&&o.access===!0;return await M(n?o.summary:`${o.summary} ${ne}`),n}).catch(async()=>(await M(`${r} ${ne}`).catch(()=>{}),!1)).finally(()=>{S=void 0})),S}async function B(r){if(e.privateTestMode||e.launchOnly&&r===Me){let o=e.privateTestMode?"/v1/private-access":"/v1/launch-access",n="{}",t=await a(new URL(o,s),{method:"POST",redirect:"error",headers:{"content-type":"application/json",...await h.sessions.headers("POST",o,n)},body:n,signal:AbortSignal.timeout(3e4)}),y=await t.json();if(!t.ok||y?.ok!==!0||y.data?.allowed!==!0)throw new Error(e.privateTestMode?"This wallet is not on the server private test allow-list. Ask the operator to configure private test access or use the normal paid setup.":"This wallet is not on the server launch allow-list. Ask the operator to configure launch access or use the normal paid setup.");return}if(await h.requireVerified(),!await z())throw new Error(ne)}async function le(){C=!0,P&&globalThis.clearInterval(P),P=void 0,await _?.close(),await S,h.sessions.clear()}async function Re(r=new ur){if(_||C)throw new Error("MCP bridge has already started or closed.");!e.launchOnly&&!e.privateTestMode&&await h.requireVerified().then(()=>z()).catch(async()=>{await M("Run oak setup to register or link your identity first. Reads remain available.")}),_=new dr({name:"oak",version:pe},{capabilities:{tools:{},logging:{}},instructions:e.startupInstructions?await e.startupInstructions():ke(e.signer.address,f)}),_.setRequestHandler(fr,async()=>({tools:await de()})),_.setRequestHandler(lr,async o=>{try{return{content:[{type:"text",text:JSON.stringify(await ue(o.params.name,o.params.arguments??{}))}]}}catch(n){return{isError:!0,content:[{type:"text",text:me(n,"Oak tool failed.")}]}}}),_.onclose=()=>{C=!0,P&&globalThis.clearInterval(P),P=void 0};try{await _.connect(r)}catch(o){throw await le(),o}!C&&!e.launchOnly&&!e.privateTestMode&&(P=globalThis.setInterval(()=>{h.requireVerified().then(()=>z()).catch(()=>{})},36e5),P.unref())}return{listTools:de,postTool:U,callTool:ue,start:Re,stop:le}}export{sr as a,te as b,gr as c,V as d,br as e,xr as f,ft as g};
@@ -0,0 +1 @@
1
+ import{constants as o}from"node:fs";import{lstat as w,mkdir as m,open as a}from"node:fs/promises";import{platform as n}from"node:os";import{dirname as d}from"node:path";async function s(e,r=!1){r&&await m(e,{recursive:!0,mode:448});let i=await w(e);if(!i.isDirectory()||i.isSymbolicLink()||n()!=="win32"&&((i.mode&63)!==0||i.uid!==process.getuid?.()))throw new Error("Unsafe local Oak directory. Use an owner-only directory without links.")}async function f(e,r){let i=await e.stat();if(!i.isFile()||i.nlink!==1||i.size>r||n()!=="win32"&&((i.mode&511)!==384||i.uid!==process.getuid?.()))throw new Error("Unsafe local Oak file. Use an owner-owned 0600 file without links.")}async function v(e){if(n()==="win32")return;await s(e);let r=await a(e,o.O_RDONLY|o.O_NOFOLLOW);try{await r.sync()}finally{await r.close()}}async function F(e,r,i,c=!1){await s(d(e),c);let t=await a(e,r|o.O_NOFOLLOW|o.O_NONBLOCK,384);try{return await f(t,i),t}catch(l){throw await t.close(),l}}export{s as a,f as b,v as c,F as d};
@@ -0,0 +1 @@
1
+ import{b as P}from"./HLAZAI2Q.js";import{randomBytes as D}from"node:crypto";import{encodeFunctionData as f,erc20Abi as O,getAddress as C,parseAbi as v,parseSignature as I,zeroAddress as y,zeroHash as L}from"viem";import{ADDRESSES as $,ETH_USDG_POOL as G,NETWORKS as H,assertNetworkUsdg as z}from"@oakagentkit/core/addresses";import{approval as A,unsignedTx as B}from"@oakagentkit/core/tx";import{verifyNoteOffchain as _}from"@oakagentkit/core/pricenote";import{grandfatherProofFor as W,verifyGrandfatherProof as q}from"@oakagentkit/core/grandfather";var u=v(["struct PriceNote { address wallet; uint256 oakPerEthE18; uint64 timestamp; bytes32 nonce; }","function subscribe(uint8 plan,uint256 maxCount,uint256 maxPrice,PriceNote n,bytes sig)","function subscribeWithAuthorization(uint256 maxCount,PriceNote n,bytes sig,bytes usdgAuth)","function subscribeGrandfatheredWithAuthorization(uint256 count,bytes32[] proof,bytes usdgAuth)","function renewWithAuthorization(bytes usdgAuth)","function renewNoHold(uint256 maxPrice,PriceNote n,bytes sig)","function cancel()","function hasRecord(address) view returns (bool)","function previous() view returns (address)","function retired() view returns (bool)","function plan(address) view returns (uint8)","function paidUntil(address) view returns (uint64)","function signupOakCount(address) view returns (uint256)","function grandfatherRoot() view returns (bytes32)","function grandfatherDeadline() view returns (uint64)","function quoteHolder(PriceNote n,bytes sig) view returns (uint256 count,uint256 burn)","function quoteNoHold(PriceNote n,bytes sig) view returns (uint256 price)","error NoteOutsideGuard(uint256 spot,uint256 note)","error OracleUnreadable(address source)","error NoteExpired()","error NoteUsed()","error NoteBadSignature()"]),k=v(["function phase() view returns (uint8)","function priceSigner() view returns (address)","function spotOakPerEthE18() view returns (uint256)"]),S=v(["function authorizationState(address,bytes32) view returns (bool)","function receiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce,uint8 v,bytes32 r,bytes32 s)"]),K={ReceiveWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]},j=new Set(Object.values($[4663]).flatMap(s=>Object.values(s).map(e=>e.address.toLowerCase()))),F={wallet:y,oakPerEthE18:0n,timestamp:0n,nonce:L},b=9000000n,ne=3n*86400n,R=s=>(s*101n+99n)/100n,m=(s,e)=>s.toLowerCase()===e.toLowerCase(),i=class extends Error{constructor(n,t=!1){super(n);this.retryNote=t}retryNote};function E(s){if(s.network!=="mainnet"&&s.network!=="testnet")throw new i("Set the subscription deployment network to mainnet or testnet.");let e=H[s.network];if(s.chainId!==e.chainId)throw new i("Network does not match the subscription deployment chain.");return z(s.network,s.usdg),{...e.usdgDomain}}function M(s){E(s);for(let e of["subscription","usdg","oak","oracle","ethUsdgPool"]){let n=C(s[e]);if(n===y)throw new i(`Configure a non-zero ${e} in the deployment config.`);if(s.network==="testnet"&&j.has(n.toLowerCase()))throw new i(`${e} cannot use a mainnet pin in the testnet deployment config.`)}if(s.network==="mainnet"&&!m(s.ethUsdgPool,G))throw new i("ETH/USDG pool must match the pinned mainnet pool.")}function J(s){let e=s;for(let n=0;e&&typeof e=="object"&&n<12;n++){let t=e;if(t.data?.errorName)return t.data.errorName;e=t.cause}}var l=(s,e=!1,n=!1,t=[])=>({ok:e,access:n,summary:s,hashes:t}),x=class{constructor(e){this.options=e;M(e.deployment),C(e.wallet)}options;get deployment(){return this.options.deployment}get wallet(){return this.options.wallet}async now(){return(await this.options.client.getBlock({blockTag:"latest"})).timestamp}async authoritative(){let e=new Set,n=this.deployment.subscription;for(let t=0;n!==y&&t<256;t++){if(e.has(n.toLowerCase()))throw new i("Invalid subscription lineage.");e.add(n.toLowerCase());let o=r=>this.options.client.readContract({address:n,abi:u,functionName:r,args:[this.wallet]});if(await o("hasRecord")){let[r,a,c,d]=await Promise.all([o("plan"),o("paidUntil"),o("signupOakCount"),this.options.client.readContract({address:n,abi:u,functionName:"retired"})]);return{contract:n,plan:Number(r),paidUntil:BigInt(a),count:BigInt(c),retired:d}}n=await this.options.client.readContract({address:n,abi:u,functionName:"previous"})}if(n!==y)throw new i("Subscription lineage is too deep.");return null}async proof(e){let n=await this.options.grandfatherList?.();if(!n)return null;let t=W(n,this.wallet);if(!t||!m(t.source,e.contract)||BigInt(t.count)!==e.count)return null;let o=await this.options.client.readContract({address:this.deployment.subscription,abi:u,functionName:"grandfatherRoot"});if(!q(o,t.entry,t.proof))throw new i("Grandfather proof does not match the successor root.");return t}async balance(e){return this.options.client.readContract({address:e,abi:O,functionName:"balanceOf",args:[this.wallet]})}async access(e){return!e||e.plan===0||e.paidUntil<await this.now()?!1:e.plan===2||e.plan===1&&await this.balance(this.deployment.oak)>=e.count}plain(e){if(e instanceof i)return e;if(e instanceof P)return new i(e.message);let n=J(e);return n==="OracleUnreadable"?new i(`Price unavailable: check the ETH/USDG pool ${this.deployment.ethUsdgPool}; try again when the oracle recovers.`):n?.startsWith("Note")?new i(`Price note rejected (${n}); retry with a fresh note.`,!0):new i("Subscription action failed; check funds and RPC availability, then retry with oak renew or oak subscribe.")}async action(e,n=!1){for(let t=0;t<(n?2:1);t++){let o;try{let r=await this.options.sender.withAction(async a=>{try{if(await this.options.client.getChainId()!==this.deployment.chainId)throw new i("RPC chain does not match the subscription deployment; nothing was signed.");return await e(a)}catch(c){o=this.plain(c);let d=await a.approvalStatus?.();return l(`${o.message}${d?` ${d}`:""}`)}});if(o?.retryNote&&t===0&&n)continue;return r}catch(r){return r instanceof P?l(r.message):l("Payment failed or remains pending; tools are paused. Run oak renew to reconcile the wallet journal before another payment.")}}return l("Price note unavailable; retry with a fresh note.")}tx(e,n,t){return B({to:e,data:n,value:"0",chainId:this.deployment.chainId,description:t})}async funds(e,n=0n){if(await this.options.client.getBalance({address:this.wallet,blockTag:"pending"})===0n)throw new i(`Needs ETH for network fees: send ETH to ${this.wallet} on chain ${this.deployment.chainId}.`);if(await this.balance(this.deployment.usdg)<e)throw new i(`Renewal/payment needs ${e} USDG base units (token ${this.deployment.usdg}, decimals 6). Top up and run oak renew; tools are paused until payment succeeds.`);if(n>0n&&await this.balance(this.deployment.oak)<n)throw new i(`Needs ${n} OAK base units (token ${this.deployment.oak}, decimals 18). Buy back OAK and retry.`)}async authorization(e,n){let t=`0x${D(32).toString("hex")}`;if(await this.options.client.readContract({address:this.deployment.usdg,abi:S,functionName:"authorizationState",args:[this.wallet,t]}))throw new i("USDG authorization nonce is used or cancelled; retry with a new nonce.");let o=await this.now()+300n,r={domain:E(this.deployment),types:K,primaryType:"ReceiveWithAuthorization",message:{from:this.wallet,to:n,value:b.toString(),validAfter:"0",validBefore:o.toString(),nonce:t}},a=I(await e.signTypedData(r));return f({abi:S,functionName:"receiveWithAuthorization",args:[this.wallet,n,b,0n,o,t,Number(a.v??BigInt(a.yParity??0)+27n),a.r,a.s]})}async note(e){for(let n=0;n<2;n++){let t=await this.options.issueNote({for:"subscription",wallet:this.wallet});if("reason"in t)throw t.reason==="eth_usd_unreadable"&&/price source is stale|freshness is unavailable/.test(t.error)?new i(`Price unavailable: ETH/USDG pool ${this.deployment.ethUsdgPool} needs a readable observation within 30 minutes. Retry after the pool updates.`):t.reason==="history_too_thin"&&/OAK price source is stale/.test(t.error)?new i("Price unavailable: refresh the stale OAK 30-minute trade history before retrying."):t.reason==="eth_usd_unreadable"?new i(`Price unavailable: ETH/USDG pool ${this.deployment.ethUsdgPool} is unreadable.`):t.reason==="history_too_thin"?new i("Price warmup: wait until the pool has 30 minutes of history, then retry."):new i(`Price unavailable (${t.reason}); retry in a minute.`);if(!m(t.consumer,e)||!m(t.note.wallet,this.wallet))throw new i("Price note consumer or wallet does not match this subscription.");let o=await this.now();if(BigInt(t.note.timestamp)+300n-o<60n)continue;let[r,a]=await Promise.all([this.options.client.readContract({address:this.deployment.oracle,abi:k,functionName:"priceSigner"}),this.options.client.readContract({address:this.deployment.oracle,abi:k,functionName:"spotOakPerEthE18"})]),c=await _({note:t.note,signature:t.signature,consumer:e,wallet:this.wallet,signer:r,spotOakPerEthE18:a,now:o,expiresAt:t.expiresAt,chainId:this.deployment.chainId});if(!c.ok)throw new i(`Price note rejected (${c.reason}); retry with a fresh note.`,c.reason==="outside_guard"||c.reason==="expired");return t}throw new i("Price note has less than 60 seconds remaining; retry with a fresh note.")}async fresh(e){if(e&&BigInt(e.note.timestamp)+300n-await this.now()<60n)throw new i("Price note is too close to expiry; retry with a fresh note.",!0)}async pricedPayment(e,n,t,o=!1){let r=await this.options.client.readContract({address:this.deployment.oracle,abi:k,functionName:"phase"});if(r!==0&&r!==1)throw new i("Unknown subscription phase; nothing was signed.");if(r===0&&t==="holder")throw new i("Holder plan is closed during the curve; use oak subscribe --plan nohold.");let a=r===1?await this.note(n):null,c=a?{...a.note,timestamp:BigInt(a.note.timestamp),oakPerEthE18:BigInt(a.note.oakPerEthE18)}:F,d=a?.signature??"0x",h=[];if(t==="holder"){let[w,p]=await this.options.client.readContract({address:n,abi:u,functionName:"quoteHolder",args:[c,d],account:this.wallet}),g=R(w);await this.funds(b,w),await this.fresh(a);let U=await this.authorization(e,n);h.push(A(this.deployment.oak,n,p.toString(),this.deployment.chainId)),h.push(this.tx(n,f({abi:u,functionName:"subscribeWithAuthorization",args:[g,c,d,U]}),`Subscribe holder: 9000000 USDG base units (decimals 6); exact OAK burn ${p} (decimals 18).`))}else{let w=r===0?12333333n:await this.options.client.readContract({address:n,abi:u,functionName:"quoteNoHold",args:[c,d],account:this.wallet}),p=r===0?w:R(w);await this.funds(w),h.push(A(this.deployment.usdg,n,p.toString(),this.deployment.chainId));let g=o?f({abi:u,functionName:"renewNoHold",args:[p,c,d]}):f({abi:u,functionName:"subscribe",args:[2,0n,p,c,d]});h.push(this.tx(n,g,`${o?"Renew":"Subscribe"} nohold: at most ${p} USDG base units (token ${this.deployment.usdg}, decimals 6).`))}await this.fresh(a),await e.assertCanPayGas(h);let T=await e.send(h.slice(0,-1));await this.fresh(a),a&&(t==="holder"?await this.options.client.readContract({address:n,abi:u,functionName:"quoteHolder",args:[c,d],account:this.wallet}):await this.options.client.readContract({address:n,abi:u,functionName:"quoteNoHold",args:[c,d],account:this.wallet}));let N=await e.send(h.slice(-1));return l(N.summary,!0,await this.access(await this.authoritative()),[...T.hashes,...N.hashes])}async holderPayment(e,n,t){let o=t?this.deployment.subscription:n.contract;if(t&&await this.options.client.readContract({address:o,abi:u,functionName:"grandfatherDeadline"})<await this.now())return l("Grandfather deadline has passed; once the old paid days expire, use oak subscribe for a fresh subscription.",!1,await this.access(n));await this.funds(b,t?n.count:0n);let r=await this.authorization(e,o),a=t?f({abi:u,functionName:"subscribeGrandfatheredWithAuthorization",args:[BigInt(t.count),t.proof,r]}):f({abi:u,functionName:"renewWithAuthorization",args:[r]}),c=await e.send([this.tx(o,a,`Renew holder: 9000000 USDG base units (token ${this.deployment.usdg}, decimals 6); no OAK burn.`)]);return l(c.summary,!0,await this.access(await this.authoritative()),c.hashes)}subscribe(e){return this.action(async n=>{if(e!=="holder"&&e!=="nohold")throw new i("Choose oak subscribe --plan holder or --plan nohold.");let t=await this.authoritative();if(t?.plan===1&&!m(t.contract,this.deployment.subscription)&&t.paidUntil>=await this.now()&&await this.proof(t))throw new i("your paid days carry over with `oak renew` when it is due");if(t&&m(t.contract,this.deployment.subscription)&&t.plan!==0)throw new i("Already subscribed; use oak renew, or oak cancel before switching plans.");if(await this.options.client.readContract({address:this.deployment.subscription,abi:u,functionName:"retired"}))throw new i("Subscription deployment is retired; configure its successor before signing up.");return this.pricedPayment(n,this.deployment.subscription,e)},!0)}cancel(){return this.action(async e=>{let n=await this.authoritative();if(!n||n.plan===0)return l("No active subscription to cancel.",!0);let t=await e.send([this.tx(n.contract,f({abi:u,functionName:"cancel"}),"Cancel subscription; all remaining paid days are forfeited immediately.")]);return l("Subscription cancelled; remaining paid days forfeited.",!0,!1,t.hashes)})}async register(e=!1){return this.options.callTool?this.options.callTool("erc8004_register",{noTag:e}):{ok:!1,error:"Configure the authenticated ERC-8004 tool bridge before oak register."}}};export{u as a,b,ne as c,E as d,M as e,x as f};
@@ -0,0 +1,4 @@
1
+ import{b as J,c as te,d as ne}from"./QIDB35RS.js";import{a as ae}from"./YVAFJM4Y.js";import{createPublicClient as fe,decodeFunctionData as me,encodeFunctionData as pe,erc20Abi as O,getAddress as re,http as ge,keccak256 as be,parseTransaction as R,recoverTypedDataAddress as ye,TransactionNotFoundError as xe,TransactionReceiptNotFoundError as Pe}from"viem";import{CHAIN_ID as M,OAK_FINALITY as Te}from"@oakagentkit/core/addresses";import{hasErrorCode as ke}from"@oakagentkit/core/errors";import{unsignedTx as ve}from"@oakagentkit/core/tx";import{loadSigner as Ce}from"#oak-wallet";var Ie=12,w=class extends Error{},f=()=>new w("Wallet journal is unresolved; wait for the pending transaction before a new action."),C=()=>new w("Local signing failed."),ie=()=>new w("Transaction reverted; the remaining sequence was stopped."),G=(s,h)=>new w(`needs ETH for network fees: send ETH to ${s} on chain ${h}.`),se=(s,h,m)=>new w(`Transaction ${s+1} of ${h} cannot be estimated on chain ${m}; it was not signed.`),W=()=>new w("Prepared transaction expired before signing; preview and retry with a fresh quote."),q=s=>s instanceof w?s:new w("Wallet action failed; check local custody and RPC availability. Any pending journal remains unresolved."),z=s=>s+s/4n,U=s=>s+s/10n+1n,I=(s,h)=>s>h?s:h;function Se(){let s=process.env.OAK_FINALITY??Te;if(s==="safe"||s==="finalized")return s;if(/^[1-9]\d*$/.test(s)&&Number.isSafeInteger(Number(s)))return Number(s);throw new w("Invalid OAK_FINALITY setting.")}function Fe(s){if(s!==M)throw new w("Configure an RPC for the transaction chain.");let h=process.env.OAK_RPC_URL;if(!h)throw new w("Set OAK_RPC_URL before sending a transaction.");return fe({transport:ge(h),cacheTime:0})}function Ne(s,h){let m=`${s} transaction${s===1?"":"s"}`;return h===s?`${m} mined and final.`:h===0?`${m} mined, awaiting finality.`:`${m} mined; ${h} final, ${s-h} awaiting finality.`}function K(s={}){let h=new Set(s.allowedChainIds??[M]),m=s.finality??Se();if(typeof m=="number"&&(!Number.isSafeInteger(m)||m<1))throw new w("Invalid finality block count.");let N=s.notAfterSeconds??Ie;if(!Number.isSafeInteger(N)||N<1)throw new w("Invalid transaction not-after window.");let k=()=>{let t=(s.now??(()=>Math.floor(Date.now()/1e3)))(),e=t>1e11?Math.floor(t/1e3):Math.floor(t);if(!Number.isSafeInteger(e)||e<0)throw new w("Invalid local timestamp; check the system clock.");return e},$=s.preview?t=>s.preview(ae(t)):void 0;async function S(t){if(!Number.isSafeInteger(t)||!h.has(t))throw new w("Unsupported transaction chain.");let e=(s.clientFor??Fe)(t);if(await e.getChainId()!==t)throw new w("RPC chain does not match the requested chain; nothing was signed.");return e}async function v(t,e){let a=await t.getBlock(e);if(a.number===null)throw new w("RPC returned a block without a height; retry when the node is synchronized.");return{...a,number:a.number}}async function H(t){let[e,a]=await Promise.all([v(t,{blockTag:"latest"}),t.estimateMaxPriorityFeePerGas()]),n=e.baseFeePerGas;if(typeof n!="bigint"||n<0n||a<0n||n*2n+a<=0n)throw new w("Network fee data is unavailable; nothing was signed.");return{baseFee:n,maxFeePerGas:n*2n+a,maxPriorityFeePerGas:a,blockNumber:e.number}}async function oe(t,e,a,n){let r=a.map(i=>({account:e,to:i.to,data:i.data,value:BigInt(i.value)})),d;try{d=(await t.simulateBlocks({blocks:[{calls:r}],validation:!1,traceTransfers:!0}))[0]?.calls??[]}catch(i){if(!ke(i,-32601,-32004))throw i;return Promise.all(r.map((o,u)=>t.estimateGas(o).catch(()=>{throw se(u,r.length,n)})))}if(d.length!==r.length)throw new w(`Simulation on chain ${n} returned an unexpected result; nothing was signed.`);return d.map((i,o)=>{if(i.status!=="success")throw new w(`Transaction ${o+1} of ${r.length} would revert on chain ${n}; nothing was signed.`);let u=I(i.gasUsed,i.maxUsedGas??0n);if(u<=0n)throw new w("Gas estimate is unavailable.");return u})}async function Y(t,e){let a=k(),n=t.map(i=>{let o=ve(i),u=i.notAfter;if(u!==void 0&&(typeof u!="number"||!Number.isSafeInteger(u)||u<0))throw new w("Invalid transaction not-after timestamp.");let l=u??a+N;if(a>l)throw W();return{tx:o,notAfter:l}}),r=new Map;for(let{tx:i}of n){let o=r.get(i.chainId)??{client:await S(i.chainId),txs:[]};o.txs.push(i),r.set(i.chainId,o)}let d=new Map;for(let[i,o]of r){let[u,l]=await Promise.all([o.client.getBalance({address:e.address,blockTag:"pending"}),H(o.client)]),c=o.txs.reduce((g,b)=>g+BigInt(b.value),0n);if(u<c)throw G(e.address,i);let p=await oe(o.client,e.address,o.txs,i);if(o.txs.forEach((g,b)=>{d.set(g,p[b]),c+=z(p[b])*l.maxFeePerGas}),u<c)throw G(e.address,i)}return n.map(({tx:i,notAfter:o})=>({tx:i,notAfter:o,client:r.get(i.chainId).client,value:BigInt(i.value),simulated:d.get(i)}))}async function X(t,e){let{blockNumber:a}=e;try{return e.blockHash&&(await v(t,{blockNumber:a})).hash!==e.blockHash?!1:typeof m=="number"?(await v(t,{blockTag:"latest"})).number-a+1n>=BigInt(m):(await v(t,{blockTag:m})).number>=a}catch{return!1}}async function L(t,e,a,n=t.hash){let r=await e.waitForTransactionReceipt({hash:n,confirmations:1,timeout:s.receiptTimeoutMs??12e4});if(!J(t).some(i=>i.toLowerCase()===r.transactionHash.toLowerCase()))throw f();let d=await X(e,r);if(d&&await a.clear(t.hash),r.status!=="success")throw ie();return d}async function ce(t,e){for(let a of e)try{let n=await t.getTransactionReceipt({hash:a});if(n.transactionHash.toLowerCase()!==a.toLowerCase())throw f();return n}catch(n){if(!(n instanceof Pe))throw n}}async function Q(t,e){for(let a of e)try{if((await t.getTransaction({hash:a})).hash.toLowerCase()===a.toLowerCase())return a}catch(n){if(!(n instanceof xe))throw n}}async function de(t,e,a,n){let r=R(t.rawTx),d=r.maxFeePerGas??r.gasPrice??0n,i=await H(e),o=t;if(d<i.baseFee){if(!r.to||r.gas===void 0)throw f();let l=r.value??0n,c=I(i.maxPriorityFeePerGas,U(r.maxPriorityFeePerGas??0n)),p=I(i.baseFee*2n+c,U(d));if(await e.getBalance({address:a.address,blockTag:"pending"})<l+r.gas*p)throw G(a.address,t.chainId);let g;try{g=await a.signTransaction({chainId:t.chainId,nonce:t.nonce,to:r.to,data:r.data??"0x",value:l,gas:r.gas,maxFeePerGas:p,maxPriorityFeePerGas:c})}catch{throw C()}o=await n.replace(t.hash,g,i.blockNumber.toString(),k())}if((await e.sendRawTransaction({serializedTransaction:o.rawTx})).toLowerCase()!==o.hash.toLowerCase())throw f();return o}async function le(t,e,a,n){let r=R(t.rawTx),d=r.maxFeePerGas??r.gasPrice??0n,i=await H(e),o=await e.estimateGas({account:a.address,to:a.address,data:"0x",value:0n}),u=I(21000n,o),l=I(i.maxPriorityFeePerGas,U(r.maxPriorityFeePerGas??r.gasPrice??0n)),c=I(i.baseFee*2n+l,U(d));if(await e.getBalance({address:a.address,blockTag:"pending"})<u*c){let y=await Q(e,J(t));if(!y)throw G(a.address,t.chainId);if(!await L(t,e,n,y))throw f();return}let g=c,b=l,T;try{T=await a.signTransaction({chainId:t.chainId,nonce:t.nonce,to:a.address,data:"0x",value:0n,gas:u,maxFeePerGas:g,maxPriorityFeePerGas:b});let y=R(T);if(!y.to||y.to.toLowerCase()!==a.address.toLowerCase()||(y.data??"0x")!=="0x"||(y.value??0n)!==0n||y.chainId!==t.chainId||y.nonce!==t.nonce||y.gas!==u)throw C()}catch{throw C()}let x=k(),A=await n.burn(t.hash,T,i.blockNumber.toString(),x,x+N);if((await e.sendRawTransaction({serializedTransaction:A.rawTx})).toLowerCase()!==A.hash.toLowerCase())throw f();return A}async function ue(t,e){for(let a of await e.read()){let n=E(a);n&&n.amount>0n&&await e.retainApproval(a);let r=await S(a.chainId),d=J(a),[i,o]=await Promise.all([r.getTransactionCount({address:t.address,blockTag:"latest"}),r.getTransactionCount({address:t.address,blockTag:"pending"})]),u=await ce(r,d);if(u){if(!await X(r,u))throw f();if(await e.clear(a.hash),u.status!=="success")throw ie();continue}let l=a.notAfter??a.sentAt+N,c=await v(r,{blockTag:"latest"});if(c.timestamp<0n||c.timestamp>BigInt(Number.MAX_SAFE_INTEGER))throw new w("Invalid block timestamp; check RPC availability.");let p=k()>l||c.timestamp>BigInt(l);if(!p||a.kind==="burn"){let x=await Q(r,d);if(x){if(!await L(a,r,e,x))throw f();continue}}let g=typeof m=="number"?c:await v(r,{blockTag:m}),b=BigInt(a.blockNumber)+BigInt(typeof m=="number"?m:1);if(!p&&g.number<b)throw f();if(i>a.nonce){if(g.number<b)throw f();let x=typeof m=="number"?c.number-BigInt(m)+1n:g.number;if(x<0n||await r.getTransactionCount({address:t.address,blockNumber:x})<=a.nonce)throw f();await e.clear(a.hash,"nonce_consumed");continue}if(i!==a.nonce||o<a.nonce||!p&&o!==a.nonce)throw f();let T=p&&a.kind!=="burn"?await le(a,r,t,e):await de(a,r,t,e);if(T&&!await L(T,r,e))throw f()}}function E(t){let e=R(t.rawTx);if(!(!e.to||(e.value??0n)!==0n))try{let a=me({abi:O,data:e.data??"0x"});return a.functionName!=="approve"?void 0:{token:re(e.to),spender:re(a.args[0]),amount:a.args[1]}}catch{return}}async function _(t){let e=[];for(let a of await t.approvals()){let n=E(a);if(!n)throw f();e.push(`Submitted approval: token ${n.token}, spender ${n.spender}, amount ${n.amount} base units, chain ${a.chainId}. It may remain active. Retry an Oak action to reconcile and revoke it before new work, or clear it in your wallet by calling approve(${n.spender}, 0) on ${n.token} on chain ${a.chainId}.`)}return e.join(" ")}async function V(t,e,a){let n=await Y(t,e),r=[],d=0;for(let[i,{tx:o,notAfter:u,client:l,value:c,simulated:p}]of n.entries()){if(k()>u)throw W();await S(o.chainId);let[g,b,T]=await Promise.all([l.estimateGas({account:e.address,to:o.to,data:o.data,value:c}).catch(()=>{throw se(i,n.length,o.chainId)}),H(l),l.getTransactionCount({address:e.address,blockTag:"pending"})]);if(k()>u)throw W();let x=z(I(g,p)),A=n.slice(i+1).filter(P=>P.tx.chainId===o.chainId).reduce((P,ee)=>P+ee.value+z(ee.simulated)*b.maxFeePerGas,0n);if(await l.getBalance({address:e.address,blockTag:"pending"})<c+x*b.maxFeePerGas+A)throw G(e.address,o.chainId);let F;try{F=await e.signTransaction({chainId:o.chainId,to:o.to,data:o.data,value:c,gas:x,nonce:T,maxFeePerGas:b.maxFeePerGas,maxPriorityFeePerGas:b.maxPriorityFeePerGas});let P=R(F);if(!P.to||P.to.toLowerCase()!==o.to.toLowerCase()||(P.data??"0x").toLowerCase()!==o.data.toLowerCase()||(P.value??0n)!==c||P.chainId!==o.chainId||P.nonce!==T||P.gas!==x)throw C()}catch{throw C()}let y=be(F),Z=k(),he=Z<=u?Z:u,D={nonce:T,hash:y,rawTx:F,kind:o.data.startsWith("0x095ea7b3")?"approval":"main",sentAt:he,notAfter:u,chainId:o.chainId,blockNumber:b.blockNumber.toString()},j=E(D);if(j&&j.amount>0n&&await a.retainApproval(D),await a.append(D),(await l.sendRawTransaction({serializedTransaction:F})).toLowerCase()!==y.toLowerCase())throw f();await L(D,l,a)&&d++,r.push(y)}return{hashes:r,summary:Ne(r.length,d)}}async function we(t,e){for(let a of await e.approvals()){let n=E(a);if(!n)throw f();let r=await S(a.chainId),d=await r.readContract({address:n.token,abi:O,functionName:"allowance",args:[t.address,n.spender]});if(typeof d!="bigint"||d<0n)throw f();if(d>0n){let i={to:n.token,data:pe({abi:O,functionName:"approve",args:[n.spender,0n]}),value:"0",chainId:a.chainId,description:`Revoke remaining ${d} base-unit approval to ${n.spender}`};if(!$)throw new w("Approval cleanup requires a preview display. Clear the recorded approval in your wallet before retrying.");let o=await r.simulateBlocks({blocks:[{calls:[{account:t.address,to:i.to,data:i.data,value:0n}]}],validation:!1,traceTransfers:!0});if(await $(`Remaining approval: token ${n.token}, spender ${n.spender}, amount ${d} base units, chain ${a.chainId}. Revoke to zero. Simulation: ${JSON.stringify(o,(l,c)=>typeof c=="bigint"?c.toString():c)}`),await V([i],t,e),(await e.read()).length||await r.readContract({address:n.token,abi:O,functionName:"allowance",args:[t.address,n.spender]})!==0n)throw f()}await e.forgetApproval(a.hash)}}async function B(t){try{let e=s.signer??await Ce();return await te(e.address,async()=>{let a=new ne(e.address,s.directory);try{await ue(e,a),await we(e,a)}catch(l){let c=await _(a);throw new w(`${q(l).message}${c?` ${c}`:""}`)}let n=!0,r=!1,d,i;function o(l){if(!n||r||d)return Promise.reject(new w("Wallet action must be awaited inside its lock."));r=!0;let c=l().catch(async p=>{d=q(p);let g=await _(a);throw g&&(d=new w(`${d.message} ${g}`)),d}).finally(()=>{r=!1});return i=c.then(()=>{},()=>{}),c}let u={approvalStatus:()=>_(a),assertCanPayGas:l=>o(async()=>{await Y(l,e)}),send:l=>o(()=>V(l,e,a)),signTypedData:l=>o(async()=>{if(!$)throw new w("No preview display is configured; nothing was signed.");let c=JSON.parse(JSON.stringify(l));await S(c.domain.chainId??0),await $(`Project: ${c.domain.name??c.primaryType}
2
+ Domain, deadline and exact typed request:
3
+ ${JSON.stringify(c,null,2)}
4
+ Signature only; external settlement remains pending.`);try{let p=await e.signTypedData(c);if((await ye({...c,signature:p})).toLowerCase()!==e.address.toLowerCase())throw C();return p}catch{throw C()}})};try{let l=await t(u);if(n=!1,await i,d)throw d;return l}finally{n=!1,await i}},{directory:s.directory})}catch(e){throw q(e)}}return{withAction:B,send:t=>B(e=>e.send(t)),signTypedData:t=>B(e=>e.signTypedData(t)),assertCanPayGas:t=>B(e=>e.assertCanPayGas(t)),blockNumber:async(t=M)=>(await v(await S(t),{blockTag:"latest"})).number}}var De=(s,h)=>K(h).send(s),Je=(s,h)=>K(h).signTypedData(s),Oe=(s,h)=>K(h).assertCanPayGas(s);export{Ie as a,w as b,K as c,De as d,Je as e,Oe as f};
@@ -0,0 +1 @@
1
+ import{c as o,e as a}from"./5HTX664S.js";import{e as s}from"./VZCMAMZL.js";import{getAddress as d}from"viem";import{buildIdentityLinkTypedData as w,buildIdentityTuple as g,canonicalSessionIdentity as c}from"@oakagentkit/core/identity-link";function k(e){return async n=>{let r;if(n.mode==="register"){let t=await e.callTool("erc8004_register",{profile:n.profile??s,tag:n.tag??!0});if(!t||typeof t.agentId!="string"||!Array.isArray(t.hashes)||!t.hashes.length)throw new Error("Registration is not confirmed. Wait for the mined receipt before running oak setup again.");if(r=g(t.agentId,e.network),t.chainId!==r.chainId||t.registry!==r.registry)throw new Error(a);if(typeof t.owner!="string"||d(t.owner)!==e.signer.address)throw new Error(o);await e.identity.accept(r)}else{let t=g(n.agentId,e.network),i=await e.callTool("erc8004_identity",{agentId:n.agentId});if(i.chainId!==t.chainId||i.registry!==t.registry)throw new Error(a);let l=typeof i.owner=="string"&&d(i.owner)===e.signer.address?y=>e.signer.signTypedData(w(y)):e.signOwner??(async()=>{throw new Error(o)});r=await e.identity.link(t,l)}r=c(r,e.network);try{await e.save(r)}catch{throw e.identity.sessions.setIdentity(),new Error("Could not save identity. Run oak setup again after fixing local configuration.")}return{identity:r,summary:`Agent ${r.agentId} verified on chain ${r.chainId}. Identity setup is complete; run oak subscribe --plan holder or oak subscribe --plan nohold next.`}}}export{k as a};
@@ -0,0 +1 @@
1
+ import{randomUUID as $}from"node:crypto";import{constants as P}from"node:fs";import{lstat as S,mkdir as D,open as k,readdir as M,rename as L,rmdir as O,unlink as A}from"node:fs/promises";import{homedir as R}from"node:os";import{join as u}from"node:path";import{getAddress as g,keccak256 as b,parseTransaction as _,recoverTransactionAddress as F}from"viem";var j=()=>u(R(),".oak"),h=i=>i?.code,W=i=>new Promise(t=>setTimeout(t,i)),l=()=>new Error("Wallet journal is unreadable or invalid; resolve it before a new action."),v=i=>new Error(i),N=i=>typeof i=="string"&&/^0x(?:[0-9a-fA-F]{2})+$/.test(i),H=i=>typeof i=="string"&&/^(0|[1-9]\d*)$/.test(i),m=(i,t)=>Number.isSafeInteger(i)&&i>=t,K=i=>[i.hash,...(i.previous??[]).map(t=>b(t))];async function I(i){await D(i,{recursive:!0,mode:448});let t=await S(i);if(!t.isDirectory()||t.isSymbolicLink()||process.platform!=="win32"&&((t.mode&63)!==0||t.uid!==process.getuid?.()))throw new Error("Unsafe wallet state directory.")}async function Y(i){if(process.platform==="win32")return;let t=await k(i,P.O_RDONLY);try{await t.sync()}finally{await t.close()}}async function Q(i,t,a={}){let e=a.directory??j();await I(e);let r=g(i).toLowerCase(),n=u(e,`${r}.lock`),o=`${process.pid}-${$()}`,s=u(e,`${r}.lock-${o}`);await D(s,{mode:448}),await(await k(u(s,o),"wx",384)).close();let c=!1,f=Date.now();try{for(;!c;)try{await L(s,n),c=!0}catch(E){if(!["EEXIST","ENOTEMPTY"].includes(h(E)??""))throw v("Wallet lock cannot be acquired.");let w=await S(n).catch(p=>{if(h(p)!=="ENOENT")throw p});if(!w)continue;if(!w.isDirectory()||w.isSymbolicLink())throw v("Invalid wallet lock.");let x=await M(n).catch(p=>{if(h(p)==="ENOENT")return[];throw p});if(x.length===1){let p=x[0],T=/^(\d+)-[0-9a-f-]{36}$/.exec(p)?.[1];if(!T||Number(T)<1)throw v("Invalid wallet lock owner.");let C=!0;try{process.kill(Number(T),0)}catch(y){h(y)==="ESRCH"&&(C=!1)}if(!C){await A(u(n,p)).catch(y=>{if(h(y)!=="ENOENT")throw y}),await O(n).catch(y=>{if(!["ENOENT","ENOTEMPTY","EEXIST"].includes(h(y)??""))throw y});continue}}else if(x.length>1)throw v("Invalid wallet lock owner.");if(Date.now()-f>=(a.timeoutMs??3e4))throw v("Wallet is busy; retry after the current action finishes.");await W(a.pollMs??25)}return await t()}finally{let E=c?n:s;await A(u(E,o)).catch(w=>{if(h(w)!=="ENOENT")throw w}),await O(E).catch(w=>{if(!["ENOENT","ENOTEMPTY","EEXIST"].includes(h(w)??""))throw w})}}var J=class{constructor(t,a=j()){this.address=t;this.directory=a;let e=g(t).toLowerCase();this.path=u(a,`${e}.pending.json`),this.approvalsPath=u(a,`${e}.approvals.json`),this.clearedPath=u(a,`${e}.cleared.json`)}address;directory;path;clearedPath;approvalsPath;async signedCall(t){let a=_(t);if(g(await F({serializedTransaction:t}))!==g(this.address))throw l();return{chainId:a.chainId,nonce:a.nonce,gas:a.gas,call:[a.to?.toLowerCase(),a.data??"0x",a.value??0n,a.gas].join(":")}}async validate(t){if(!Array.isArray(t))throw l();let a=new Set;for(let e of t){if(!e||!m(e.nonce,0)||!m(e.chainId,1)||!m(e.sentAt,0)||e.notAfter!==void 0&&(!m(e.notAfter,0)||e.notAfter<e.sentAt)||!H(e.blockNumber)||!["approval","main","burn"].includes(e.kind)||!N(e.rawTx)||b(e.rawTx)!==e.hash||e.previous!==void 0&&(!Array.isArray(e.previous)||!e.previous.every(N)))throw l();let r=await this.signedCall(e.rawTx);if(r.chainId!==e.chainId||r.nonce!==e.nonce||e.kind==="burn"&&(r.gas===void 0||r.gas<21000n||r.call!==[this.address.toLowerCase(),"0x",0n,r.gas].join(":")))throw l();let n=new Set([e.hash]),o=e.kind==="burn"?void 0:r.call;for(let d of e.previous??[]){let c=await this.signedCall(d),f=b(d);if(c.chainId!==r.chainId||c.nonce!==r.nonce||n.has(f))throw l();if(o===void 0)o=c.call;else if(c.call!==o&&c.call!==r.call)throw l();n.add(f)}let s=`${e.chainId}:${e.nonce}`;if(a.has(s))throw l();a.add(s)}return t}validateCleared(t){if(!Array.isArray(t))throw l();for(let a of t)if(!a||!N(a.hash)||a.hash.length!==66||!m(a.nonce,0)||!m(a.chainId,1)||!["approval","main","burn"].includes(a.kind)||!m(a.sentAt,0)||!H(a.blockNumber)||a.reason!=="nonce_consumed"||!m(a.clearedAt,0))throw l();return t}async load(t,a){try{await I(this.directory);let e=await k(t,P.O_RDONLY|(P.O_NOFOLLOW??0));try{let r=await e.stat();if(!r.isFile()||r.nlink!==1||r.size>16*1024*1024||process.platform!=="win32"&&((r.mode&63)!==0||r.uid!==process.getuid?.()))throw l();return await a(JSON.parse(await e.readFile("utf8")))}finally{await e.close()}}catch(e){if(h(e)==="ENOENT")return;throw l()}}async store(t,a,e){let r=`${t}.${$()}.tmp`;await I(this.directory);try{await e(a);let n=await k(r,"wx",384);try{await n.writeFile(JSON.stringify(a)),await n.sync()}finally{await n.close()}await L(r,t),await Y(this.directory)}catch{throw l()}finally{await A(r).catch(n=>{if(h(n)!=="ENOENT")throw l()})}}async approvals(){return await this.load(this.approvalsPath,t=>this.validate(t))??[]}async retainApproval(t){let a=await this.approvals();a.some(e=>e.hash===t.hash)||await this.store(this.approvalsPath,[...a,t],e=>this.validate(e))}async forgetApproval(t){await this.store(this.approvalsPath,(await this.approvals()).filter(a=>a.hash!==t),a=>this.validate(a))}async read(){return await this.load(this.path,t=>this.validate(t))??[]}async cleared(){return await this.load(this.clearedPath,t=>this.validateCleared(t))??[]}async write(t){await this.store(this.path,t,a=>this.validate(a))}async append(t){await this.write([...await this.read(),t])}async replace(t,a,e,r){let n=await this.read(),o=n.findIndex(c=>c.hash===t);if(o<0)throw l();let s=n[o],d={...s,rawTx:a,hash:b(a),blockNumber:e,sentAt:r,previous:[...s.previous??[],s.rawTx]};return n[o]=d,await this.write(n),d}async burn(t,a,e,r,n){let o=await this.read(),s=o.findIndex(f=>f.hash===t);if(s<0)throw l();let d=o[s],c={...d,kind:"burn",rawTx:a,hash:b(a),blockNumber:e,sentAt:r,...n!==void 0?{notAfter:n}:{},previous:[...d.previous??[],d.rawTx]};return o[s]=c,await this.write(o),c}async clear(t,a){let e=await this.read(),r=e.find(n=>n.hash===t);if(r&&a){let n=await this.cleared();if(!n.some(o=>o.hash===t)){let{nonce:o,chainId:s,kind:d,sentAt:c,blockNumber:f}=r;await this.store(this.clearedPath,[...n,{hash:t,nonce:o,chainId:s,kind:d,sentAt:c,blockNumber:f,reason:a,clearedAt:Math.floor(Date.now()/1e3)}],E=>this.validateCleared(E))}}await this.write(e.filter(n=>n.hash!==t))}};export{j as a,K as b,Q as c,J as d};
@@ -0,0 +1 @@
1
+ import{c as o}from"./HGFLLHB6.js";async function i(r){return r.action(async e=>{let s=await r.authoritative();if(!s||s.plan===0)return{ok:!1,access:!1,hashes:[],summary:"No subscription. Use oak subscribe --plan holder or oak subscribe --plan nohold."};if(s.paidUntil-await r.now()>o){let a=await r.access(s);return{ok:a,access:a,hashes:[],summary:a?"Subscription is paid; renewal is not due.":`Buy back ${s.count} OAK base units (token ${r.deployment.oak}, decimals 18) to restore access.`}}if(s.retired){let a=s.plan===1?await r.proof(s):null;return a?r.holderPayment(e,s,a):{ok:!1,access:await r.access(s),hashes:[],summary:"Retired subscription has no eligible grandfather proof; once the old paid days expire, use oak subscribe for a fresh subscription on the successor."}}return s.plan===1?r.holderPayment(e,s):r.pricedPayment(e,s.contract,"nohold",!0)},!0)}export{i as a};
@@ -0,0 +1,2 @@
1
+ import{c as s,d as c}from"./GONTF7K4.js";import{getAddress as p}from"viem";import{NETWORKS as u}from"@oakagentkit/core/addresses";import{constants as i}from"node:fs";import{homedir as d}from"node:os";import{join as l}from"node:path";function h(t,e){return`Wallet ${t} on Robinhood Chain ${e} (chain ${u[e].chainId}); ask for balances anytime.`}async function b(t,e,a=l(d(),".oak")){let r;try{r=await c(l(a,"first-start-shown"),i.O_WRONLY|i.O_CREAT|i.O_EXCL,2,!0)}catch(n){if(n.code==="EEXIST")return h(t,e);throw new Error("Could not save the first-start notice marker. Check local Oak directory permissions and restart MCP.",{cause:n})}try{await r.writeFile(`1
2
+ `),await r.sync()}finally{await r.close()}await s(a);let o=m(t,e);return`Tell the user: ${o.message} ${o.backup} ${o.notice} Never run oak init or oak export through an agent, read wallet files, or ask for keys, recovery words or passphrases. After funding, explain that ERC-8004 registration publishes a profile and costs gas; get user authorization before oak_setup registration. External identity owners sign in their own terminal. Read account for phase and price and get approval for the recurring subscription before oak_subscribe. Both plans wait during warmup. Never subscribe automatically just because funds arrived. Read tools stay available without paid access.`}function m(t,e){let{chainId:a,usdg:r}=u[e];return{wallet:t,address:t,network:e,chainId:a,funding:{gas:{address:"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",symbol:"ETH",decimals:18,chainId:a},payment:{address:p(r),symbol:"USDG",decimals:6,chainId:a}},message:`Fund this address ${t} with a little ETH for gas and USDG on Robinhood Chain ${e} (chain ${a}). Re-check balances after funding.`,backup:"When you hold more than pocket change, run oak export in your own terminal. Run oak backup for guidance. Oak cannot recover a lost key.",notice:"Availability varies by region; check the terms of each service. Oak is independent and is not affiliated with Robinhood."}}var O="Backups are optional. When you hold more than pocket change, run oak export in your own terminal, never through an agent. Keep the exported private key offline and private. Restore it with oak init --recover in your own terminal. Automatic wallets have no recovery phrase. Oak cannot recover a lost key.",x={type:"https://eips.ethereum.org/EIPS/eip-8004#registration-v1",name:"Oak agent",description:"A local Oak agent wallet.",image:"https://oakagentkit.org/favicon.svg",services:[],x402Support:!1,active:!0,registrations:[]};export{h as a,b,m as c,O as d,x as e};
@@ -0,0 +1 @@
1
+ import{BaseError as i}from"viem";function a(e){return e.replace(/\b(?:https?|wss?):(?:\/\/|\\\/\\\/)[^\s<>"'`]+/gi,"[redacted URL]").replace(/((?:^|[\r\n])[ \t]*(?:set-)?cookie\s*[:=][ \t]*)[^\r\n]+/gi,"$1[redacted]").replace(/((?:^|[^a-z0-9_-])["']?(?:proxy[-_])?authorization["']?\s*[:=]\s*)([a-z]+[ \t]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\r\n,;}"']+))/gi,"$1[redacted]").replace(/\?[^\s<>"'`]+/g,"[redacted query]").replace(/((?:^|[^a-z0-9_-])["']?(?:(?:x[-_])?api[-_ ]?key|(?:access|auth|refresh)[-_ ]?token|(?:proxy[-_])?authorization|password|(?:client[-_])?secret|(?:set[-_])?cookie|token)["']?\s*[:=]\s*)("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|(?![\s{[])(?:(?![ \t]+["']?[a-z][\w-]*["']?\s*[:=])[^\r\n,;}[\]<>"'{])+)/gi,(r,t,n)=>{let s=n.trim().replace(/^["']|["']$/g,""),o=/^\$?[A-Z][A-Za-z0-9.]{0,11}$/.test(s)||/^0x[0-9a-f]{40}$/i.test(s);return/(?:^|[^a-z0-9_-])["']?token["']?\s*[:=]\s*$/i.test(t)&&o?r:`${t}[redacted]`}).replace(/\b(?:Bearer|Basic)\s+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\s,"'}]+)/gi,"[redacted authorization]").replace(/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g,"[redacted token]")}function c(e,r="Oak request failed. Check connectivity and retry."){return e instanceof i?a(e.shortMessage):a(e instanceof Error?e.message:r)}var d=e=>new Error(c(e)),g=()=>new Error("Cannot read local Oak configuration. Check file ownership, links and 0600 permissions.");export{a,c as b,d as c,g as d};
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ import { type OwnerSign } from './identity.js';
3
+ import { type SetupRequest } from './setup.js';
4
+ import type { Address } from 'viem';
5
+ import { createBridge } from './bridge.js';
6
+ import { SubscriptionLifecycle } from './subscribe.js';
7
+ import { createWallet, exportKey } from './wallet.js';
8
+ type Config = Record<string, string>;
9
+ export declare function readConfig(path?: string): Promise<Config>;
10
+ export declare function createRuntime(config: Config, writeDisplay: (text: string) => void | Promise<void>, recipeDirectory?: string, setupOptions?: {
11
+ configPath?: string;
12
+ signOwner?: OwnerSign;
13
+ }): Promise<{
14
+ wallet: `0x${string}`;
15
+ bridge: {
16
+ listTools: () => Promise<import("./bridge.js").ListedTool[]>;
17
+ postTool: (name: string, args: import("@oakagentkit/core/types").ToolArgs) => Promise<unknown>;
18
+ callTool: (name: string, original: import("@oakagentkit/core/types").ToolArgs) => Promise<unknown>;
19
+ start: (transport?: import("@modelcontextprotocol/sdk/shared/transport").Transport) => Promise<void>;
20
+ stop: () => Promise<void>;
21
+ };
22
+ readonly lifecycle: SubscriptionLifecycle;
23
+ subscribe: (plan: "holder" | "nohold") => Promise<import("./subscribe.js").LifecycleResult>;
24
+ cancel: () => Promise<import("./subscribe.js").LifecycleResult>;
25
+ renew: () => Promise<import("./subscribe.js").LifecycleResult>;
26
+ setup: (request: SetupRequest) => Promise<{
27
+ identity: import("@oakagentkit/core/identity-link").SessionIdentity;
28
+ summary: string;
29
+ }>;
30
+ profile: {
31
+ type: string;
32
+ name: string;
33
+ description: string;
34
+ image: string;
35
+ services: never[];
36
+ x402Support: boolean;
37
+ active: boolean;
38
+ registrations: never[];
39
+ } | import("@oakagentkit/core/types").ToolArgs;
40
+ }>;
41
+ type Runtime = Pick<Awaited<ReturnType<typeof createRuntime>>, 'wallet' | 'profile' | 'renew'> & {
42
+ bridge: Pick<ReturnType<typeof createBridge>, 'postTool' | 'callTool' | 'start'>;
43
+ lifecycle: Pick<SubscriptionLifecycle, 'subscribe' | 'cancel'>;
44
+ setup?: (request: SetupRequest) => Promise<unknown>;
45
+ subscribe?: (plan: 'holder' | 'nohold') => Promise<unknown>;
46
+ cancel?: () => Promise<unknown>;
47
+ };
48
+ export interface CliOptions {
49
+ output?: (text: string) => void;
50
+ error?: (text: string) => void;
51
+ isTTY?: boolean;
52
+ initialize?: typeof createWallet;
53
+ exportWallet?: typeof exportKey;
54
+ address?: () => Promise<Address>;
55
+ runtime?: () => Promise<Runtime>;
56
+ configPath?: string;
57
+ recipeDirectory?: string;
58
+ signOwner?: OwnerSign;
59
+ chooseSetup?: () => Promise<string>;
60
+ }
61
+ export declare function runCli(argv: string[], options?: CliOptions): Promise<number>;
62
+ export declare function terminalOwnerSign(display: (text: string) => void): OwnerSign;
63
+ export {};
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import{a as he}from"./chunks/U4YOG57X.js";import{a as pe}from"./chunks/ILJVXWGD.js";import{e as B,f as ge}from"./chunks/HGFLLHB6.js";import{d as S,e as j,g as we}from"./chunks/62PM22KQ.js";import{c as oe}from"./chunks/HLAZAI2Q.js";import{a as Q}from"./chunks/4X7FLHGQ.js";import{c as J,f as se,g as ae,i as ce}from"./chunks/5HTX664S.js";import"./chunks/4B2GMIK7.js";import"./chunks/QIDB35RS.js";import{b as le,c as de,d as fe,e as ue}from"./chunks/VZCMAMZL.js";import{d as ne,e as $,f as ie}from"./chunks/4LWKW7PM.js";import{a as te,c as re,d as v}from"./chunks/GONTF7K4.js";import{a as W,b as Z,d as ee}from"./chunks/YVAFJM4Y.js";import{buildIdentityLinkTypedData as De,canonicalSessionIdentity as Ae,identityNetwork as Ee}from"@oakagentkit/core/identity-link";import{constants as I}from"node:fs";import{realpath as Ke,rename as Ie,unlink as Ne}from"node:fs/promises";import{randomUUID as ke}from"node:crypto";import{homedir as Pe}from"node:os";import{dirname as _e,join as Ce}from"node:path";import{pathToFileURL as ve}from"node:url";import{createPublicClient as Le,getAddress as y,http as Ue}from"viem";import{ETH_USDG_POOL as He,NETWORKS as N,assertNetworkRpc as xe,assertNetworkUsdg as Oe,resolveNetwork as k}from"@oakagentkit/core/addresses";import{DEFAULT_RPC_URL as We}from"@oakagentkit/core/chain";import{createWallet as $e,exportKey as Je,loadSigner as ye}from"#oak-wallet";var je="oak identity unlink [--owner <linkId>]|setup [register [--no-tag]|link <agentId>]|init [--recover [--replace]]|address|status|backup|export|subscribe --plan <holder|nohold>|renew|cancel|register [--no-tag]|recipes add|remove|list <pkg-or-path>|config set <k> <v>|mcp|call <tool> <json>",Se="The command or its arguments are not valid. Run oak --help and retry with the listed arguments.",me="as-is, not reviewed by Oak",L=()=>Ce(Pe(),".oak","config.json"),Be=new Set(["OAK_PRIVATE_TEST_MODE","OAK_LAUNCH_BOOTSTRAP","OAK_NETWORK","OAK_CHAIN_ID","OAK_SERVER_URL","OAK_RPC_URL","OAK_SUBSCRIPTION_ADDRESS","OAK_RETIRED_SUBSCRIPTION_ADDRESSES","OAK_TOKEN_ADDRESS","OAK_USDG_ADDRESS","OAK_ORACLE_ADDRESS","OAK_ETH_USDG_POOL_ADDRESS","OAK_FINALITY","profile","grandfather","identity"]);function Y(n,i){if(!Be.has(n)&&!/^OAK_RPC_URL_[1-9][0-9]*$/.test(n))throw new Error("Unknown setting. Wallet keys cannot be stored in config.");if(!i.trim()||i.length>1048576)throw new Error("Invalid configuration value.");if(["OAK_LAUNCH_BOOTSTRAP","OAK_PRIVATE_TEST_MODE"].includes(n)&&!["true","false"].includes(i))throw new Error("Set the mode to true or false.");if(n==="OAK_NETWORK")k(i);else{if(n==="OAK_CHAIN_ID"&&!["4663","46630"].includes(i))throw new Error("Set OAK_CHAIN_ID to 4663 or 46630.");if(n==="OAK_SERVER_URL")j(i);else if(n.startsWith("OAK_RPC_URL")){let o=new URL(i);if(!["https:","http:"].includes(o.protocol))throw new Error("RPC URL must use HTTP or HTTPS.")}else if(n.endsWith("_ADDRESS"))y(i);else if(n==="OAK_RETIRED_SUBSCRIPTION_ADDRESSES")i.split(",").forEach(o=>y(o.trim()));else{if(n==="OAK_FINALITY"&&i!=="safe"&&i!=="finalized"&&(!/^[1-9][0-9]*$/.test(i)||!Number.isSafeInteger(Number(i))))throw new Error("Invalid finality setting.");if(n==="identity"){let o=S(JSON.parse(i));Ae(o,Ee(o.chainId))}else(n==="profile"||n==="grandfather")&&S(JSON.parse(i))}}}async function U(n=L()){let i;try{i=await v(n,I.O_RDONLY,2097152)}catch(o){if(o.code==="ENOENT")return{};throw ee()}try{let o=await i.stat();if(!o.isFile()||o.size>2097152)throw new Error("Invalid local Oak configuration.");let f=S(JSON.parse(await i.readFile("utf8")));for(let[w,s]of Object.entries(f)){if(typeof s!="string")throw new Error("Configuration values must be strings.");Y(w,s)}return f}finally{await i.close()}}async function F(n,i,o){if(o!==void 0)Y(i,o);else if(i!=="identity")throw new Error("Only the public identity setting can be cleared.");let f={...await U(n)};o===void 0?delete f[i]:f[i]=o;let w=`${JSON.stringify(f,null,2)}
3
+ `;if(Buffer.byteLength(w)>2097152)throw new Error("Local Oak configuration exceeds 2 MiB. Remove unused settings before retrying.");await te(_e(n),!0);let s=`${n}.${ke()}.tmp`,p=await v(s,I.O_WRONLY|I.O_CREAT|I.O_EXCL,2097152);try{try{await p.writeFile(w),await p.sync()}finally{await p.close()}try{await(await v(n,I.O_RDONLY,2097152)).close()}catch(r){if(r.code!=="ENOENT")throw r}await Ie(s,n),await re(_e(n))}finally{await Ne(s).catch(r=>{if(r.code!=="ENOENT")throw r})}}async function Fe(n,i,o,f={}){n={...n};let w=t=>i(W(t)),s=t=>process.env[t]??n[t],p=t=>{let c=s(t);if(!c)throw new Error(`Set ${t} with oak config set before this command.`);return c},r=k(n.OAK_NETWORK);if(process.env.OAK_NETWORK!==void 0&&k(process.env.OAK_NETWORK)!==r)throw new Error("OAK_NETWORK disagrees with the local config; set the network in the config explicitly.");let{chainId:e,usdg:m}=N[r];if((n.OAK_CHAIN_ID??String(N.mainnet.chainId))!==String(e)||process.env.OAK_CHAIN_ID!==void 0&&process.env.OAK_CHAIN_ID!==String(e))throw new Error(`Set OAK_CHAIN_ID to ${e} in the local deployment config.`);let g=(t,c)=>{let d=n[t]??c;if(!d)throw new Error(`Set ${t} in the local deployment config.`);let O=y(d);if(process.env[t]!==void 0&&y(process.env[t])!==O)throw new Error(`${t} disagrees with the local deployment config.`);return O},A=n.OAK_PRIVATE_TEST_MODE==="true",E=n.OAK_LAUNCH_BOOTSTRAP==="true";if(E&&A)throw new Error("Choose private test mode or launch-only bootstrap, then restart Oak.");if((E||A)&&r!=="mainnet")throw new Error("Launch bootstrap requires mainnet chain 4663.");let b=()=>{let t={network:r,chainId:e,subscription:g("OAK_SUBSCRIPTION_ADDRESS"),usdg:g("OAK_USDG_ADDRESS",m),oak:g("OAK_TOKEN_ADDRESS"),oracle:g("OAK_ORACLE_ADDRESS"),ethUsdgPool:g("OAK_ETH_USDG_POOL_ADDRESS")};return Oe(r,t.usdg),B(t),t},T=["OAK_SUBSCRIPTION_ADDRESS","OAK_TOKEN_ADDRESS","OAK_ORACLE_ADDRESS","OAK_ETH_USDG_POOL_ADDRESS"];for(let t of T)if(process.env[t]!==void 0&&n[t]===void 0)throw new Error(`Set ${t} in the local deployment config; environment-only addresses are not accepted.`);!E&&!A&&T.every(t=>n[t])&&b();let D=j(s("OAK_SERVER_URL")??(r==="mainnet"?"https://api.oakagentkit.org":p("OAK_SERVER_URL"))),l=async()=>{if(T.every(O=>n[O])){b();return}let t;try{let O=await fetch(new URL("/v1/config",D),{redirect:"error",signal:AbortSignal.timeout(5e3)}),K=S(await O.json());if(!O.ok||K.ok!==!0)throw new Error;t=S(K.data)}catch{throw new Error("Oak deployment configuration is unavailable. Ask the operator to enable /v1/config or configure the published Oak contract addresses. Your wallet address and read tools remain available.")}if(t.network!==r||t.chainId!==e||typeof t.usdg!="string")throw new Error("The Oak service configuration does not match the selected network.");Oe(r,y(t.usdg));let c={OAK_SUBSCRIPTION_ADDRESS:t.subscription,OAK_TOKEN_ADDRESS:t.oak,OAK_ORACLE_ADDRESS:t.oracle,OAK_ETH_USDG_POOL_ADDRESS:t.ethUsdgPool},d={};for(let[O,K]of Object.entries(c)){if(typeof K!="string")throw new Error("The Oak service deployment configuration is invalid.");let X=y(K);if(n[O]&&y(n[O])!==X)throw new Error(`${O} disagrees with the local deployment config.`);d[O]=X}if(B({network:r,chainId:e,subscription:d.OAK_SUBSCRIPTION_ADDRESS,oak:d.OAK_TOKEN_ADDRESS,oracle:d.OAK_ORACLE_ADDRESS,ethUsdgPool:d.OAK_ETH_USDG_POOL_ADDRESS,usdg:y(t.usdg)}),r==="mainnet"&&d.OAK_ETH_USDG_POOL_ADDRESS!==He)throw new Error("ETH/USDG pool must match the pinned mainnet pool.");Object.assign(n,d),b()},u=new Map,a=t=>{let c=u.get(t);if(!c){let d=t===e?s("OAK_RPC_URL")??(r==="mainnet"?We:p("OAK_RPC_URL")):p(`OAK_RPC_URL_${t}`);c=Le({transport:Ue(d,{timeout:1e4,retryCount:0}),cacheTime:0}),u.set(t,c)}return c},h=[e,...Object.keys({...n,...process.env}).filter(t=>/^OAK_RPC_URL_[1-9][0-9]*$/.test(t)).map(t=>Number(t.slice(12)))];if(h.includes(r==="testnet"?N.mainnet.chainId:N.testnet.chainId))throw new Error("Do not configure the other Robinhood network as an additional RPC. Set OAK_NETWORK and OAK_RPC_URL together.");await Promise.all([...new Set(h)].filter(t=>t!==e||s("OAK_RPC_URL")).map(async t=>{let c=a(t);if(t===e)await xe(r,c);else if(await c.getChainId()!==t)throw new Error(`RPC chain does not match configured chain ${t}.`)}));let _=s("OAK_FINALITY");_&&Y("OAK_FINALITY",_);let P=_===void 0?void 0:_==="safe"||_==="finalized"?_:Number(_),R=await ye(),G=t=>{if(!t)return;let c=JSON.parse(t),d=Ae(c,Ee(c.chainId));return d.chainId===e?d:void 0},H=ce({base:D,signer:R,network:r,identity:E||A?void 0:G(n.identity),clearIdentity:()=>F(f.configPath??L(),"identity"),loadIdentity:async()=>E||A?void 0:G((await U(f.configPath)).identity)}),M=oe({signer:R,clientFor:a,allowedChainIds:h,finality:P,preview:w}),Re={withAction:t=>M.withAction(c=>t({...c,send:async d=>(d.length&&await w(JSON.stringify(await x.postTool("preview",{txs:d}))),c.send(d))}))},be,C=()=>be??=new ge({wallet:R.address,deployment:b(),client:a(e),sender:Re,issueNote:async t=>{try{let c=await fetch(new URL("/v1/price-note",D),{method:"POST",redirect:"error",headers:{"content-type":"application/json"},body:JSON.stringify(t),signal:AbortSignal.timeout(3e4)}),d=await c.json();if(!c.ok&&!("reason"in d))throw new Error;return d}catch{throw new Error("Price note is unavailable. Retry when the server is reachable.")}},...n.grandfather?{grandfatherList:async()=>JSON.parse(n.grandfather)}:{}}),V=async()=>(await l(),he(C())),q=async t=>(await H.requireVerified(),await l(),C().subscribe(t)),Te=async()=>(await l(),C().cancel()),x=we({network:r,launchOnly:E,privateTestMode:A,identity:H,signOwner:f.signOwner,setup:t=>z(t),serverUrl:D.href,signer:R,sender:M,display:w,ensureSubscribed:V,startupInstructions:()=>le(R.address,r),subscribe:q,recipes:()=>$({directory:o}),recipeClient:a(e)}),z=pe({network:r,signer:R,identity:H,callTool:x.callTool,signOwner:f.signOwner,save:t=>F(f.configPath??L(),"identity",JSON.stringify(t))});return{wallet:R.address,bridge:x,get lifecycle(){return C()},subscribe:q,cancel:Te,renew:V,setup:z,profile:n.profile?S(JSON.parse(n.profile)):ue}}async function Ye(n,i={}){let o=i.output??(r=>{process.stdout.write(`${r}
4
+ `)}),f=i.error??i.output??(r=>{process.stderr.write(`${r}
5
+ `)}),w=r=>f(W(r)),s=r=>o(JSON.stringify(r)),p=()=>{if(!(i.isTTY??(process.stdin.isTTY===!0&&process.stdout.isTTY===!0)))throw new Error("run this in your own terminal, not through the agent")};try{let[r,...e]=n;if(r==="--version"||r==="-v")return o(Q),0;if(r==="--help"||r==="-h")return o(je),0;if(r==="init"&&(!e.length||e[0]==="--recover"&&(e.length===1||e.length===2&&e[1]==="--replace"))){p();let a=i.initialize??$e;return s(await(e.length?a({recover:!0,replace:e[1]==="--replace"}):a())),0}if(r==="export"&&!e.length)return p(),await(i.exportWallet??Je)(),0;if(r==="backup"&&!e.length)return o(fe),0;if(r==="address"&&!e.length){let a=await U(i.configPath),h=k(a.OAK_NETWORK);if(process.env.OAK_NETWORK!==void 0&&k(process.env.OAK_NETWORK)!==h)throw new Error("OAK_NETWORK disagrees with the local config; set the network in the config explicitly.");let _=N[h].chainId;if(a.OAK_CHAIN_ID!==void 0&&a.OAK_CHAIN_ID!==String(_)||process.env.OAK_CHAIN_ID!==void 0&&process.env.OAK_CHAIN_ID!==String(_))throw new Error(`Set OAK_CHAIN_ID to ${_} for the selected network.`);return s(de(await(i.address??(async()=>(await ye()).address))(),h)),0}if(r==="config"&&e.length===3&&e[0]==="set")return await F(i.configPath??L(),e[1],e[2]),o(`Saved ${e[1]}.`),0;if(r==="recipes"){let a={directory:i.recipeDirectory};if(e[0]==="add"&&e.length===2)s({recipes:await ne(e[1],a),label:me});else if(e[0]==="remove"&&e.length===2)await ie(e[1],a),o("Recipe project removed.");else if(e[0]==="list"&&e.length<=2)s({recipes:(await $(a)).filter(h=>!e[1]||h.project===e[1]),label:me});else throw new Error(Se);return 0}let m=r==="identity"&&e[0]==="unlink"&&(e.length===1||e.length===3&&e[1]==="--owner"&&/^0x[0-9a-f]{64}$/.test(e[2])),g=r==="setup"&&(!e.length||e[0]==="register"&&(e.length===1||e.length===2&&e[1]==="--no-tag")||e[0]==="link"&&e.length===2),A=["status","renew","cancel","mcp"].includes(r??"")&&!e.length,E=r==="subscribe"&&e.length===2&&e[0]==="--plan"&&["holder","nohold"].includes(e[1]),b=r==="register"&&(!e.length||e.length===1&&e[0]==="--no-tag"),T=r==="call"&&e.length===2;if(!m&&!g&&!A&&!E&&!b&&!T)throw new Error(Se);let D=T?S(JSON.parse(e[1])):void 0,l=await(i.runtime??(async()=>Fe(await U(i.configPath),w,i.recipeDirectory,{configPath:i.configPath,signOwner:i.signOwner??(["setup","identity","mcp","call"].includes(r??"")?Ge(w):void 0)})))(),u;switch(r){case"identity":u=await l.bridge.callTool("oak_identity_unlink",e[1]==="--owner"?{actor:"owner",linkId:e[2]}:{actor:"agent"});break;case"setup":{if(!l.setup)throw new Error("Identity setup is unavailable in this runtime.");let a=e[0],h=e[1];if(!a){let P=(i.chooseSetup?await i.chooseSetup():"register").trim().split(/\s+/);a=P[0],h=P[1]}if(a==="link"&&h)u=await l.setup({mode:a,agentId:h});else if(a==="register"){if(!l.profile)throw new Error("Set a registration-v1 profile with oak config set profile <json>, then run oak setup register.");u=await l.setup({mode:a,profile:l.profile,tag:h!=="--no-tag"})}else throw new Error("Choose register or link <agentId> with oak setup.");break}case"status":u={wallet:l.wallet,...S(await l.bridge.postTool("account",{}))};break;case"subscribe":u=await(l.subscribe??(a=>l.lifecycle.subscribe(a)))(e[1]);break;case"renew":u=await l.renew();break;case"cancel":u=await(l.cancel??(()=>l.lifecycle.cancel()))();break;case"register":if(!l.profile)throw new Error("Set a registration-v1 profile with oak config set profile <json>, then run oak register.");u=await l.bridge.callTool("erc8004_register",{profile:l.profile,tag:e[0]!=="--no-tag"});break;case"call":u=await l.bridge.callTool(e[0],D);break;case"mcp":return await l.bridge.start(),0}return s(u),u&&typeof u=="object"&&"ok"in u&&u.ok===!1?1:0}catch(r){return w(r instanceof SyntaxError?"The JSON is not valid. Use a JSON object with double-quoted field names and strings, then retry.":Z(r,"Oak command failed. Run oak status and retry when the server is reachable.")),1}}function Ge(n){return async i=>{if(!process.stdin.isTTY||!process.stderr.isTTY)throw new Error(ae);return n("In the current owner\u2019s wallet, sign this EIP-712 identity request (the audience identifies link or unlink). Paste only the signature below; input is hidden. Never paste a key or recovery words."),n(JSON.stringify(De(i),(o,f)=>typeof f=="bigint"?f.toString():f)),new Promise((o,f)=>{let w=process.stdin.isRaw,s="",p=m=>{process.stdin.off("data",e),process.stdin.off("end",r),process.stdin.setRawMode(w===!0),process.stdin.pause(),m?f(m):/^0x(?:[0-9a-fA-F]{2})+$/.test(s)?o(s):f(new Error(J))},r=()=>p(new Error(se)),e=m=>{for(let g of m.toString("utf8")){if(g===""||g===""){r();return}if(g==="\r"||g===`
6
+ `){p();return}if(g==="\x7F"?s=s.slice(0,-1):s+=g,s.length>131072){p(new Error(J));return}}};process.stdin.setRawMode(!0),process.stdin.on("data",e),process.stdin.once("end",r),process.stdin.resume()})}}process.argv[1]&&import.meta.url===ve(await Ke(process.argv[1])).href&&(process.exitCode=await Ye(process.argv.slice(2)));export{Fe as createRuntime,U as readConfig,Ye as runCli,Ge as terminalOwnerSign};
@@ -0,0 +1,48 @@
1
+ import { type SessionIdentity } from '@oakagentkit/core/identity-link';
2
+ import type { IdentityLink, SignedIdentityLink } from '@oakagentkit/core/types';
3
+ import type { OakNetwork } from '@oakagentkit/core/addresses';
4
+ import type { WalletSigner } from './wallet.js';
5
+ export declare const identityPaused = "Identity changed, expired or link revoked. Run oak setup link <agentId> with the current owner to verify or link it again. Reads remain available; actions are paused.";
6
+ export declare const identityUnknown = "Identity status is unavailable. Please try again. Reads remain available; actions are paused.";
7
+ export declare const ownerMismatch = "This wallet does not own that agent ID. Ask the current owner to sign the link in oak setup link <agentId>.";
8
+ export declare const challengeExpired = "The identity challenge expired. Run oak setup link <agentId> again for a fresh owner signature.";
9
+ export declare const wrongNetwork = "Wrong identity network or registry. Set OAK_NETWORK and OAK_CHAIN_ID to match the owner\u2019s agent, then run oak setup again.";
10
+ export declare const signingCancelled = "Owner signing cancelled. Run the identity command again when ready.";
11
+ export declare const signingUnavailable = "Owner signing requires your terminal. Run oak setup link <agentId> or oak identity unlink --owner <linkId> there.";
12
+ export type UnlinkRequest = {
13
+ actor: 'agent' | 'owner';
14
+ linkId?: `0x${string}`;
15
+ };
16
+ export type OwnerSign = (link: IdentityLink) => Promise<SignedIdentityLink['signature']>;
17
+ export declare function identityError(value: unknown): Error;
18
+ export declare function createIdentityClient(options: {
19
+ base: URL;
20
+ signer: WalletSigner;
21
+ network: OakNetwork;
22
+ identity?: SessionIdentity;
23
+ fetch?: typeof fetch;
24
+ now?: () => number;
25
+ loadIdentity?: () => Promise<SessionIdentity | undefined>;
26
+ clearIdentity?: () => Promise<void>;
27
+ }): {
28
+ sessions: {
29
+ readonly identity: {
30
+ chainId: number;
31
+ registry: import("viem").Address;
32
+ agentId: import("@oakagentkit/core/types").DecimalString;
33
+ linkId?: import("viem").Hex;
34
+ } | undefined;
35
+ setIdentity(value?: SessionIdentity): void;
36
+ clear: () => void;
37
+ get(): Promise<string>;
38
+ headers(method: string, path: string, body: string): Promise<Record<string, string>>;
39
+ };
40
+ requireVerified(): Promise<void>;
41
+ unlink(request?: UnlinkRequest, sign?: OwnerSign): Promise<{
42
+ unlinked: boolean;
43
+ summary: string;
44
+ }>;
45
+ accept(identity: SessionIdentity): Promise<SessionIdentity>;
46
+ link(identity: SessionIdentity, sign: OwnerSign): Promise<SessionIdentity>;
47
+ };
48
+ export type IdentityClient = ReturnType<typeof createIdentityClient>;
@@ -0,0 +1 @@
1
+ import{a,b,c,d,e,f,g,h,i}from"./chunks/5HTX664S.js";import"./chunks/4B2GMIK7.js";export{d as challengeExpired,i as createIdentityClient,h as identityError,a as identityPaused,b as identityUnknown,c as ownerMismatch,f as signingCancelled,g as signingUnavailable,e as wrongNetwork};
@@ -0,0 +1,53 @@
1
+ import { type Address, type Hex } from 'viem';
2
+ export interface JournalEntry {
3
+ nonce: number;
4
+ hash: Hex;
5
+ rawTx: Hex;
6
+ kind: 'approval' | 'main' | 'burn';
7
+ sentAt: number;
8
+ notAfter?: number;
9
+ chainId: number;
10
+ blockNumber: string;
11
+ previous?: Hex[];
12
+ }
13
+ export type ClearReason = 'nonce_consumed';
14
+ export interface ClearedEntry {
15
+ hash: Hex;
16
+ nonce: number;
17
+ chainId: number;
18
+ kind: 'approval' | 'main' | 'burn';
19
+ sentAt: number;
20
+ blockNumber: string;
21
+ reason: ClearReason;
22
+ clearedAt: number;
23
+ }
24
+ export declare const walletDirectory: () => string;
25
+ export declare const entryHashes: (entry: JournalEntry) => Hex[];
26
+ export declare function withWalletLock<T>(address: Address, action: () => Promise<T>, options?: {
27
+ directory?: string;
28
+ pollMs?: number;
29
+ timeoutMs?: number;
30
+ }): Promise<T>;
31
+ export declare class Journal {
32
+ readonly address: Address;
33
+ readonly directory: string;
34
+ readonly path: string;
35
+ readonly clearedPath: string;
36
+ readonly approvalsPath: string;
37
+ constructor(address: Address, directory?: string);
38
+ private signedCall;
39
+ private validate;
40
+ private validateCleared;
41
+ private load;
42
+ private store;
43
+ approvals(): Promise<JournalEntry[]>;
44
+ retainApproval(entry: JournalEntry): Promise<void>;
45
+ forgetApproval(hash: Hex): Promise<void>;
46
+ read(): Promise<JournalEntry[]>;
47
+ cleared(): Promise<ClearedEntry[]>;
48
+ private write;
49
+ append(entry: JournalEntry): Promise<void>;
50
+ replace(hash: Hex, rawTx: Hex, blockNumber: string, sentAt: number): Promise<JournalEntry>;
51
+ burn(hash: Hex, rawTx: Hex, blockNumber: string, sentAt: number, notAfter?: number): Promise<JournalEntry>;
52
+ clear(hash: Hex, reason?: ClearReason): Promise<void>;
53
+ }
@@ -0,0 +1 @@
1
+ import{a,b,c,d}from"./chunks/QIDB35RS.js";export{d as Journal,b as entryHashes,a as walletDirectory,c as withWalletLock};