@telaro/evaluator-evm 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.
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # @telaro/evaluator-evm
2
+
3
+ EVM-side primitives for the Telaro Bonded Evaluator (Stage 3 W6).
4
+
5
+ Telaro acts as the `evaluator` slot on Virtuals' AgenticCommerceV3 contract
6
+ on Base mainnet. When a Solana-side bonded panel reaches a verdict, the
7
+ gateway needs to call `complete(jobId, ...)` or `reject(jobId, ...)` on Base,
8
+ signed by the Telaro evaluator EOA. This package owns that signing path
9
+ so anyone running a Telaro-compatible evaluator (Telaro itself, partner
10
+ juries, custom verdict pipelines) can ship the same EVM settlement.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ pnpm add @telaro/evaluator-evm viem
16
+ ```
17
+
18
+ `viem` is a peer dep. Lazy-loaded inside the package so importing the
19
+ helpers does not drag in the EVM bundle until you actually settle.
20
+
21
+ ## Usage
22
+
23
+ ```ts
24
+ import { signAndSendVerdict } from "@telaro/evaluator-evm";
25
+
26
+ const txHash = await signAndSendVerdict({
27
+ verdict: "complete",
28
+ evmJobId: 42n,
29
+ evmChainId: 8453,
30
+ baseRpcUrl: process.env.BASE_RPC_URL!,
31
+ virtualsContractAddress: "0x238E541BfefD82238730D00a2208E5497F1832E0",
32
+ evmPrivateKeyHex: process.env.TELARO_EVALUATOR_EVM_PRIVKEY!,
33
+ });
34
+ console.log("settled:", txHash);
35
+ ```
36
+
37
+ ## API
38
+
39
+ - `signAndSendVerdict(params)` — sign and submit a `complete` or `reject`
40
+ call. Returns the tx hash.
41
+ - `makeWalletClient(params)` — get a viem WalletClient bound to the
42
+ Telaro EOA. Use when you want to attach more calls in the same flow.
43
+ - `encodeVerdictCalldata(params)` — pure calldata builder. No tx submit.
44
+ Useful for Safe / Squads multisig flows or for dry-run logging.
45
+ - `validateConfig(params)` — pre-flight check on chain id, key shape,
46
+ and contract address. Returns `null` on success, a short error
47
+ string on failure.
48
+ - `VIRTUALS_BASE_MAINNET` — the canonical contract address constant.
49
+ - `EVALUATOR_ABI_FRAGMENTS` — the two ABI signatures we use.
50
+
51
+ ## Why a separate package
52
+
53
+ Before extracting this, the viem wiring lived inside
54
+ `@telaro/sacp-mcp-server/src/evaluator-middleware.ts`. That meant any
55
+ third party who wanted to run an evaluator had to fork the gateway or
56
+ re-derive the calldata by hand. The split lets the gateway depend on
57
+ this for the wire and gives external builders the same building block.
@@ -0,0 +1,87 @@
1
+ /**
2
+ * @telaro/evaluator-evm — Stage 3 W6 EVM side.
3
+ *
4
+ * Sign and submit Virtuals AgenticCommerceV3 complete / reject calls
5
+ * from the Telaro evaluator EOA. Extracted from the gateway so anyone
6
+ * building an evaluator (Telaro's bonded panel, an external partner,
7
+ * a custom verdict pipeline) can ship the same on-chain settlement
8
+ * path without reimplementing the viem plumbing.
9
+ *
10
+ * Usage:
11
+ *
12
+ * import { signAndSendVerdict } from "@telaro/evaluator-evm";
13
+ * const txHash = await signAndSendVerdict({
14
+ * verdict: "complete",
15
+ * evmJobId: 42n,
16
+ * baseRpcUrl: process.env.TELARO_BASE_RPC_URL!,
17
+ * evmChainId: 8453,
18
+ * virtualsContractAddress: "0x238E541BfefD82238730D00a2208E5497F1832E0",
19
+ * evmPrivateKeyHex: process.env.TELARO_EVALUATOR_EVM_PRIVKEY!,
20
+ * reasonHex: "0x" + "00".repeat(32),
21
+ * });
22
+ */
23
+ export type EvaluatorVerdict = "complete" | "reject";
24
+ /** Virtuals AgenticCommerceV3 proxy on Base mainnet. */
25
+ export declare const VIRTUALS_BASE_MAINNET = "0x238E541BfefD82238730D00a2208E5497F1832E0";
26
+ /** ERC-8183 + Virtuals lifecycle terminal call signatures used by an evaluator. */
27
+ export declare const EVALUATOR_ABI_FRAGMENTS: readonly ["function complete(uint256 jobId, bytes32 reason, bytes optParams)", "function reject(uint256 jobId, bytes32 reason, bytes optParams)"];
28
+ export interface SignAndSendVerdictParams {
29
+ verdict: EvaluatorVerdict;
30
+ /** u256 EVM jobId from the JobCreated event. */
31
+ evmJobId: bigint;
32
+ /** Base mainnet (8453) or Base Sepolia (84532). */
33
+ evmChainId: number;
34
+ /** EVM JSON-RPC URL. */
35
+ baseRpcUrl: string;
36
+ /** Virtuals AgenticCommerceV3 proxy on Base. */
37
+ virtualsContractAddress: string;
38
+ /** 32-byte hex EVM private key, with or without 0x prefix. */
39
+ evmPrivateKeyHex: string;
40
+ /** Optional 32-byte hex attestation pointer. Defaults to all zeros. */
41
+ reasonHex?: string;
42
+ /** Optional bytes-hex extra params. Defaults to 0x. */
43
+ optParamsHex?: string;
44
+ }
45
+ /**
46
+ * Sign and submit a complete/reject transaction on Base. viem is loaded
47
+ * lazily so importing this module doesn't drag in a 200KB ESM bundle on
48
+ * platforms that only need the planning helpers.
49
+ */
50
+ export declare function signAndSendVerdict(params: SignAndSendVerdictParams): Promise<`0x${string}`>;
51
+ export interface WalletClientParams {
52
+ baseRpcUrl: string;
53
+ evmChainId: number;
54
+ evmPrivateKeyHex: string;
55
+ }
56
+ /**
57
+ * Lazy-loaded viem wallet client tied to the Telaro EOA. The return
58
+ * type is intentionally erased to `unknown` shaped as a wallet client;
59
+ * downstream callers typically just need `.sendTransaction`. Cast to
60
+ * viem's `WalletClient` if you need the full typed surface.
61
+ */
62
+ export interface LooseWalletClient {
63
+ sendTransaction: (tx: {
64
+ to: `0x${string}`;
65
+ data: `0x${string}`;
66
+ value: bigint;
67
+ }) => Promise<`0x${string}`>;
68
+ }
69
+ export declare function makeWalletClient(params: WalletClientParams): Promise<LooseWalletClient>;
70
+ export interface EncodeVerdictParams {
71
+ verdict: EvaluatorVerdict;
72
+ evmJobId: bigint;
73
+ reasonHex?: string;
74
+ optParamsHex?: string;
75
+ }
76
+ /** Encode the complete/reject calldata. Pure function — no viem required for callers that just want bytes. */
77
+ export declare function encodeVerdictCalldata(params: EncodeVerdictParams): Promise<`0x${string}`>;
78
+ /**
79
+ * Sanity check on common config errors before paying the viem import.
80
+ * Returns null on success, a short error string on failure.
81
+ */
82
+ export declare function validateConfig(params: {
83
+ evmChainId: number;
84
+ evmPrivateKeyHex: string;
85
+ virtualsContractAddress: string;
86
+ }): string | null;
87
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAErD,wDAAwD;AACxD,eAAO,MAAM,qBAAqB,+CAA+C,CAAC;AAElF,mFAAmF;AACnF,eAAO,MAAM,uBAAuB,mJAG1B,CAAC;AAEX,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,uBAAuB,EAAE,MAAM,CAAC;IAChC,8DAA8D;IAC9D,gBAAgB,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAiBxB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,CAAC,EAAE,EAAE;QACpB,EAAE,EAAE,KAAK,MAAM,EAAE,CAAC;QAClB,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;KACf,KAAK,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;CAC9B;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,iBAAiB,CAAC,CAa5B;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,8GAA8G;AAC9G,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAYxB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,uBAAuB,EAAE,MAAM,CAAC;CACjC,GAAG,MAAM,GAAG,IAAI,CAYhB"}
package/dist/index.js ADDED
@@ -0,0 +1,98 @@
1
+ /**
2
+ * @telaro/evaluator-evm — Stage 3 W6 EVM side.
3
+ *
4
+ * Sign and submit Virtuals AgenticCommerceV3 complete / reject calls
5
+ * from the Telaro evaluator EOA. Extracted from the gateway so anyone
6
+ * building an evaluator (Telaro's bonded panel, an external partner,
7
+ * a custom verdict pipeline) can ship the same on-chain settlement
8
+ * path without reimplementing the viem plumbing.
9
+ *
10
+ * Usage:
11
+ *
12
+ * import { signAndSendVerdict } from "@telaro/evaluator-evm";
13
+ * const txHash = await signAndSendVerdict({
14
+ * verdict: "complete",
15
+ * evmJobId: 42n,
16
+ * baseRpcUrl: process.env.TELARO_BASE_RPC_URL!,
17
+ * evmChainId: 8453,
18
+ * virtualsContractAddress: "0x238E541BfefD82238730D00a2208E5497F1832E0",
19
+ * evmPrivateKeyHex: process.env.TELARO_EVALUATOR_EVM_PRIVKEY!,
20
+ * reasonHex: "0x" + "00".repeat(32),
21
+ * });
22
+ */
23
+ /** Virtuals AgenticCommerceV3 proxy on Base mainnet. */
24
+ export const VIRTUALS_BASE_MAINNET = "0x238E541BfefD82238730D00a2208E5497F1832E0";
25
+ /** ERC-8183 + Virtuals lifecycle terminal call signatures used by an evaluator. */
26
+ export const EVALUATOR_ABI_FRAGMENTS = [
27
+ "function complete(uint256 jobId, bytes32 reason, bytes optParams)",
28
+ "function reject(uint256 jobId, bytes32 reason, bytes optParams)",
29
+ ];
30
+ /**
31
+ * Sign and submit a complete/reject transaction on Base. viem is loaded
32
+ * lazily so importing this module doesn't drag in a 200KB ESM bundle on
33
+ * platforms that only need the planning helpers.
34
+ */
35
+ export async function signAndSendVerdict(params) {
36
+ const wallet = await makeWalletClient({
37
+ baseRpcUrl: params.baseRpcUrl,
38
+ evmChainId: params.evmChainId,
39
+ evmPrivateKeyHex: params.evmPrivateKeyHex,
40
+ });
41
+ const data = await encodeVerdictCalldata({
42
+ verdict: params.verdict,
43
+ evmJobId: params.evmJobId,
44
+ reasonHex: params.reasonHex,
45
+ optParamsHex: params.optParamsHex,
46
+ });
47
+ return wallet.sendTransaction({
48
+ to: params.virtualsContractAddress,
49
+ data,
50
+ value: 0n,
51
+ });
52
+ }
53
+ export async function makeWalletClient(params) {
54
+ const { createWalletClient, http } = await import("viem");
55
+ const { privateKeyToAccount } = await import("viem/accounts");
56
+ const { base, baseSepolia } = await import("viem/chains");
57
+ const chain = params.evmChainId === 8453 ? base : baseSepolia;
58
+ const pkHex = params.evmPrivateKeyHex.startsWith("0x")
59
+ ? params.evmPrivateKeyHex
60
+ : "0x" + params.evmPrivateKeyHex;
61
+ return createWalletClient({
62
+ account: privateKeyToAccount(pkHex),
63
+ chain,
64
+ transport: http(params.baseRpcUrl),
65
+ });
66
+ }
67
+ /** Encode the complete/reject calldata. Pure function — no viem required for callers that just want bytes. */
68
+ export async function encodeVerdictCalldata(params) {
69
+ const { encodeFunctionData, parseAbi } = await import("viem");
70
+ const abi = parseAbi(EVALUATOR_ABI_FRAGMENTS);
71
+ return encodeFunctionData({
72
+ abi,
73
+ functionName: params.verdict,
74
+ args: [
75
+ params.evmJobId,
76
+ (params.reasonHex ?? "0x" + "00".repeat(32)),
77
+ (params.optParamsHex ?? "0x"),
78
+ ],
79
+ });
80
+ }
81
+ /**
82
+ * Sanity check on common config errors before paying the viem import.
83
+ * Returns null on success, a short error string on failure.
84
+ */
85
+ export function validateConfig(params) {
86
+ if (params.evmChainId !== 8453 && params.evmChainId !== 84532) {
87
+ return `unsupported evmChainId ${params.evmChainId}; expected 8453 (Base mainnet) or 84532 (Base Sepolia)`;
88
+ }
89
+ const pk = params.evmPrivateKeyHex.replace(/^0x/, "");
90
+ if (!/^[0-9a-fA-F]{64}$/.test(pk)) {
91
+ return "evmPrivateKeyHex must be 32 bytes hex";
92
+ }
93
+ if (!/^0x[0-9a-fA-F]{40}$/.test(params.virtualsContractAddress)) {
94
+ return "virtualsContractAddress must be a 20-byte 0x-prefixed EVM address";
95
+ }
96
+ return null;
97
+ }
98
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@telaro/evaluator-evm",
3
+ "version": "0.1.0",
4
+ "description": "EVM-side primitives for the Telaro Bonded Evaluator. Sign and submit Virtuals AgenticCommerceV3 complete/reject transactions from any wallet that holds the Telaro evaluator EOA private key.",
5
+ "license": "MIT",
6
+ "homepage": "https://telaro.xyz",
7
+ "repository": "https://github.com/Telaro-Protocol/telaro-protocol",
8
+ "main": "dist/index.js",
9
+ "module": "dist/index.js",
10
+ "types": "dist/index.d.ts",
11
+ "type": "module",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsc -p tsconfig.json",
24
+ "test": "node --import tsx/esm --test tests/*.test.ts"
25
+ },
26
+ "peerDependencies": {
27
+ "viem": "^2.0.0"
28
+ },
29
+ "peerDependenciesMeta": {
30
+ "viem": {
31
+ "optional": false
32
+ }
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^22.0.0",
36
+ "tsx": "^4.16.0",
37
+ "typescript": "^5.5.0",
38
+ "viem": "^2.52.0"
39
+ },
40
+ "keywords": [
41
+ "erc-8183",
42
+ "evaluator",
43
+ "virtuals",
44
+ "base",
45
+ "viem",
46
+ "evm",
47
+ "telaro"
48
+ ]
49
+ }