@taifoon/jev 0.2.9 → 0.2.11

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.
@@ -0,0 +1,62 @@
1
+ export declare const REGISTRY_ADDRESSES: {
2
+ /** jev · JevAnswerLog (devnet) (devnet-only) */
3
+ readonly devnetAnswerLog: {
4
+ readonly chainId: 36927;
5
+ readonly address: "0xD8c1d8188Fc8EE388792f6EB3B3dbd4f341Ba8e3";
6
+ readonly block: 1106754;
7
+ };
8
+ /** jev · JevDecisionLog (devnet) (devnet-only) */
9
+ readonly devnetDecisionLog: {
10
+ readonly chainId: 36927;
11
+ readonly address: "0x1D622511862DD7DEffB8fEeBc225E0FAdA1e9A05";
12
+ readonly block: 981099;
13
+ };
14
+ /** taifoon-assurance · JudgeAdapter (devnet) (devnet-only) */
15
+ readonly devnetJudgeAdapter: {
16
+ readonly chainId: 36927;
17
+ readonly address: "0xbd4c9e797a8DBbfdde9C77bc5A5b21ACf611Db8f";
18
+ readonly block: null;
19
+ };
20
+ /** taifoon-assurance · AssuranceHook (proxy, devnet) (devnet-only) */
21
+ readonly devnetAssuranceHook: {
22
+ readonly chainId: 36927;
23
+ readonly address: "0x7110C8951d17B69054395742e265bbd98259564A";
24
+ readonly block: 909786;
25
+ };
26
+ /** jev · JevAnswerLog (live) */
27
+ readonly baseAnswerLog: {
28
+ readonly chainId: 8453;
29
+ readonly address: "0x8e9B9cE86a2d55c10318607b0c815B7B8C66254d";
30
+ readonly block: 51863008;
31
+ };
32
+ /** jev · JevAnswerLog (first deploy) (superseded) */
33
+ readonly baseAnswerLogFirstDeploy: {
34
+ readonly chainId: 8453;
35
+ readonly address: "0x5bac70eb78224bbCBa83f5A36DF09D549d3f57fa";
36
+ readonly block: 51856203;
37
+ };
38
+ /** jev · JevDecisionLog (live) */
39
+ readonly baseDecisionLog: {
40
+ readonly chainId: 8453;
41
+ readonly address: "0x209490d6A0FFC5368A42b0c2208BDCda853f6a92";
42
+ readonly block: 51856200;
43
+ };
44
+ /** standards-erc8183 · Virtuals ACP v3 (ERC-8183) (live) */
45
+ readonly virtualsErc8183: {
46
+ readonly chainId: 8453;
47
+ readonly address: "0x238E541BfefD82238730D00a2208E5497F1832E0";
48
+ readonly block: 44427013;
49
+ };
50
+ /** standards-erc8183 · memo-ACP router (live) */
51
+ readonly virtualsMemoAcpRouter: {
52
+ readonly chainId: 8453;
53
+ readonly address: "0xa6C9BA866992cfD7fd6460ba912bfa405adA9df0";
54
+ readonly block: 36786061;
55
+ };
56
+ /** standards-erc8183 · BitAgent ERC-8183 escrow (live) */
57
+ readonly bitagentErc8183: {
58
+ readonly chainId: 8453;
59
+ readonly address: "0x5009ABB3A309115a4a682C66BAf3BC9E0329BaB7";
60
+ readonly block: 48395723;
61
+ };
62
+ };
@@ -0,0 +1,24 @@
1
+ // VENDORED from an address registry (addresses.json, public subset) by scripts/vendor-addresses.mjs - do not edit here.
2
+ // Only the contracts this SDK names; test/addresses-vendor.test.ts checks the copy against the registry.
3
+ export const REGISTRY_ADDRESSES = {
4
+ /** jev · JevAnswerLog (devnet) (devnet-only) */
5
+ devnetAnswerLog: { chainId: 36927, address: '0xD8c1d8188Fc8EE388792f6EB3B3dbd4f341Ba8e3', block: 1106754 },
6
+ /** jev · JevDecisionLog (devnet) (devnet-only) */
7
+ devnetDecisionLog: { chainId: 36927, address: '0x1D622511862DD7DEffB8fEeBc225E0FAdA1e9A05', block: 981099 },
8
+ /** taifoon-assurance · JudgeAdapter (devnet) (devnet-only) */
9
+ devnetJudgeAdapter: { chainId: 36927, address: '0xbd4c9e797a8DBbfdde9C77bc5A5b21ACf611Db8f', block: null },
10
+ /** taifoon-assurance · AssuranceHook (proxy, devnet) (devnet-only) */
11
+ devnetAssuranceHook: { chainId: 36927, address: '0x7110C8951d17B69054395742e265bbd98259564A', block: 909786 },
12
+ /** jev · JevAnswerLog (live) */
13
+ baseAnswerLog: { chainId: 8453, address: '0x8e9B9cE86a2d55c10318607b0c815B7B8C66254d', block: 51863008 },
14
+ /** jev · JevAnswerLog (first deploy) (superseded) */
15
+ baseAnswerLogFirstDeploy: { chainId: 8453, address: '0x5bac70eb78224bbCBa83f5A36DF09D549d3f57fa', block: 51856203 },
16
+ /** jev · JevDecisionLog (live) */
17
+ baseDecisionLog: { chainId: 8453, address: '0x209490d6A0FFC5368A42b0c2208BDCda853f6a92', block: 51856200 },
18
+ /** standards-erc8183 · Virtuals ACP v3 (ERC-8183) (live) */
19
+ virtualsErc8183: { chainId: 8453, address: '0x238E541BfefD82238730D00a2208E5497F1832E0', block: 44427013 },
20
+ /** standards-erc8183 · memo-ACP router (live) */
21
+ virtualsMemoAcpRouter: { chainId: 8453, address: '0xa6C9BA866992cfD7fd6460ba912bfa405adA9df0', block: 36786061 },
22
+ /** standards-erc8183 · BitAgent ERC-8183 escrow (live) */
23
+ bitagentErc8183: { chainId: 8453, address: '0x5009ABB3A309115a4a682C66BAf3BC9E0329BaB7', block: 48395723 },
24
+ };
@@ -15,7 +15,7 @@ export declare const CONTRACTS: Readonly<{
15
15
  };
16
16
  /** JudgeAdapter: posts a verdict (with the decision digest) to the devnet assurance hook */
17
17
  readonly judgeAdapter: "0xbd4c9e797a8DBbfdde9C77bc5A5b21ACf611Db8f";
18
- readonly assuranceHook: "0x7110c8951d17b69054395742e265bbd98259564a";
18
+ readonly assuranceHook: string;
19
19
  };
20
20
  /** Base (8453): both logs are live. Only the KMS recorder 0xe9F0E71e7Fc66864126C0aE5588a7858b25dE51D is `trusted` on the answer log. */
21
21
  readonly base: {
package/dist/contracts.js CHANGED
@@ -1,31 +1,33 @@
1
1
  // Where the records and the evaluator seats live. Every address here was read from the chain or from its deploy
2
- // broadcast; nothing is deployed by this package.
2
+ // broadcast; nothing is deployed by this package. The contract addresses come from the address registry (src/addresses.ts,
3
+ // vendored by scripts/vendor-addresses.mjs); the recorder and the BitAgent evaluator are accounts, not registry contracts.
4
+ import { REGISTRY_ADDRESSES as R } from './addresses.js';
3
5
  export const CONTRACTS = Object.freeze({
4
6
  /** the public devnet the logs live on: chain 36927, free gas; anyone may send */
5
7
  devnet: {
6
8
  chainId: 36927,
7
9
  rpc: 'https://rpc.taifoon.dev',
8
10
  /** JevAnswerLog: append-only, no owner. Recorders fixed at deploy are `trusted`; any other sender is logged with trusted = false */
9
- answerLog: { address: '0xD8c1d8188Fc8EE388792f6EB3B3dbd4f341Ba8e3', fromBlock: 1_106_754 },
11
+ answerLog: { address: R.devnetAnswerLog.address, fromBlock: R.devnetAnswerLog.block },
10
12
  /** JevDecisionLog: append-only, no owner, no upgrade; the recorder is msg.sender */
11
- decisionLog: { address: '0x1D622511862DD7DEffB8fEeBc225E0FAdA1e9A05', fromBlock: 981_099 },
13
+ decisionLog: { address: R.devnetDecisionLog.address, fromBlock: R.devnetDecisionLog.block },
12
14
  /** JudgeAdapter: posts a verdict (with the decision digest) to the devnet assurance hook */
13
- judgeAdapter: '0xbd4c9e797a8DBbfdde9C77bc5A5b21ACf611Db8f',
14
- assuranceHook: '0x7110c8951d17b69054395742e265bbd98259564a',
15
+ judgeAdapter: R.devnetJudgeAdapter.address,
16
+ assuranceHook: R.devnetAssuranceHook.address.toLowerCase(),
15
17
  },
16
18
  /** Base (8453): both logs are live. Only the KMS recorder 0xe9F0E71e7Fc66864126C0aE5588a7858b25dE51D is `trusted` on the answer log. */
17
19
  base: {
18
20
  chainId: 8453,
19
21
  rpc: 'https://mainnet.base.org',
20
22
  /** JevAnswerLog, redeployed 2026-09-27 (tx 0xeb7d2dac…ae87); supersedes 0x5bac70eb78224bbCBa83f5A36DF09D549d3f57fa */
21
- answerLog: { address: '0x8e9B9cE86a2d55c10318607b0c815B7B8C66254d', fromBlock: 51_863_008 },
23
+ answerLog: { address: R.baseAnswerLog.address, fromBlock: R.baseAnswerLog.block },
22
24
  /** JevDecisionLog, deployed 2026-09-27 (tx 0x0e6300c0…4fc7); the recorder is msg.sender */
23
- decisionLog: { address: '0x209490d6A0FFC5368A42b0c2208BDCda853f6a92', fromBlock: 51_856_200 },
25
+ decisionLog: { address: R.baseDecisionLog.address, fromBlock: R.baseDecisionLog.block },
24
26
  /** the one trusted recorder of the Base answer log */
25
27
  answerRecorder: '0xe9F0E71e7Fc66864126C0aE5588a7858b25dE51D',
26
- virtualsErc8183: '0x238E541BfefD82238730D00a2208E5497F1832E0',
27
- virtualsMemoAcpRouter: '0xa6C9BA866992cfD7fd6460ba912bfa405adA9df0',
28
- bitagentErc8183: '0x5009ABB3A309115a4a682C66BAf3BC9E0329BaB7',
28
+ virtualsErc8183: R.virtualsErc8183.address,
29
+ virtualsMemoAcpRouter: R.virtualsMemoAcpRouter.address,
30
+ bitagentErc8183: R.bitagentErc8183.address,
29
31
  bitagentEvaluator: '0x4302e523D982f3b89Cfc43cE4530C012b495Ec11',
30
32
  },
31
33
  });
package/dist/pipeline.js CHANGED
@@ -5,7 +5,7 @@
5
5
  // (https://coord.taifoon.dev by default) the job comes from /v1/judge/queue, the pack from /v1/judge/evidence, the
6
6
  // seller's terms from /v1/pools/quote, and — only with a relayer key — the answers are recorded on the layer through
7
7
  // /v1/judge/answers/record. Nothing here signs a transaction.
8
- import { premium as wilsonPremium, wilson } from '@taifoon/jev-wilson';
8
+ import { premium as wilsonPremium, wilson } from './wilson.js';
9
9
  import { facts as runFacts } from './facts.js';
10
10
  import { grade } from './grade.js';
11
11
  import { record } from './record.js';
@@ -0,0 +1,49 @@
1
+ /** z for a two-sided 95% interval, as the layer pins it. */
2
+ export declare const Z = 1.959963984540054;
3
+ /** The layer's pool rule: no pool covers above this premium ratio. */
4
+ export declare const MAX_PREMIUM_RATIO = 0.3;
5
+ /** The premium ratio is rounded to millionths before it multiplies the price. */
6
+ export declare const RATIO_SCALE = 1000000;
7
+ /** The Wilson score interval for `successes` of `n`. [0, 1] when n = 0. Same operations, same order as the layer. */
8
+ export declare function wilson(successes: number, n: number, z?: number): [number, number];
9
+ /** u_F: the upper Wilson bound on the failure rate, n - k failed of n. This is the layer's π ratio. */
10
+ export declare function wilsonUpperFailure(k: number, n: number, z?: number): number;
11
+ /** floor(price × round(ratio × 1e6) / 1e6), exactly as the layer's pool-quote computes it. */
12
+ export declare function premiumAmount(price: bigint, ratio: number): bigint;
13
+ export type SellerRecord = {
14
+ k: number;
15
+ n: number;
16
+ };
17
+ export type PremiumOpts = {
18
+ /** floor on the ratio; default 0 (the layer has none) */
19
+ min?: number;
20
+ /** cover only when ratio <= max; default 0.30 (the layer's pool rule) */
21
+ max?: number;
22
+ /** price in the token's smallest unit; when given, `amount` is computed */
23
+ price?: bigint | number | string;
24
+ /** z for the record form; default Z */
25
+ z?: number;
26
+ };
27
+ export type Premium = {
28
+ insurable: false;
29
+ reason: 'UNKNOWN';
30
+ ratio: null;
31
+ amount: null;
32
+ covered: false;
33
+ basis: 'record';
34
+ } | {
35
+ insurable: true;
36
+ ratio: number;
37
+ amount: bigint | null;
38
+ covered: boolean;
39
+ basis: 'record' | 'p_L';
40
+ };
41
+ /**
42
+ * The premium for the next job.
43
+ *
44
+ * premium({ k, n }, opts) prices from the record: ratio = u_F, bit-for-bit with the layer.
45
+ * premium(pL, opts) prices from a lower bound you already hold: ratio = 1 - p_L. Equal in real
46
+ * arithmetic, but 1 - p_L can differ from u_F in the last bits of a double.
47
+ * Use the record form when you need the layer's number to the last digit.
48
+ */
49
+ export declare function premium(input: number | SellerRecord, opts?: PremiumOpts): Premium;
package/dist/wilson.js ADDED
@@ -0,0 +1,66 @@
1
+ // GENERATED from @taifoon/jev-wilson 0.1.0 (src/wilson.ts) by scripts/vendor-wilson.mjs. Do not edit here.
2
+ // The pricing half only: z, the Wilson interval, the premium. Same numbers as the layer's /v1/pools/quote.
3
+ /** z for a two-sided 95% interval, as the layer pins it. */
4
+ export const Z = 1.959963984540054;
5
+ /** The layer's pool rule: no pool covers above this premium ratio. */
6
+ export const MAX_PREMIUM_RATIO = 0.3;
7
+ /** The premium ratio is rounded to millionths before it multiplies the price. */
8
+ export const RATIO_SCALE = 1_000_000;
9
+ function checkRecord(k, n) {
10
+ if (!Number.isInteger(k) || !Number.isInteger(n) || k < 0 || n < 0 || k > n) {
11
+ throw new RangeError(`need integers 0 <= k <= n, got k=${k}, n=${n}`);
12
+ }
13
+ }
14
+ /** The Wilson score interval for `successes` of `n`. [0, 1] when n = 0. Same operations, same order as the layer. */
15
+ export function wilson(successes, n, z = Z) {
16
+ if (n <= 0)
17
+ return [0, 1];
18
+ const p = successes / n, z2 = z * z;
19
+ const d = 1 + z2 / n;
20
+ const c = p + z2 / (2 * n);
21
+ const s = z * Math.sqrt((p * (1 - p) + z2 / (4 * n)) / n);
22
+ return [Math.max(0, (c - s) / d), Math.min(1, (c + s) / d)];
23
+ }
24
+ /** u_F: the upper Wilson bound on the failure rate, n - k failed of n. This is the layer's π ratio. */
25
+ export function wilsonUpperFailure(k, n, z = Z) {
26
+ checkRecord(k, n);
27
+ return wilson(n - k, n, z)[1];
28
+ }
29
+ /** JavaScript Math.round, kept explicit so the Python twin can match it. */
30
+ const roundHalfUp = (x) => Math.round(x);
31
+ /** floor(price × round(ratio × 1e6) / 1e6), exactly as the layer's pool-quote computes it. */
32
+ export function premiumAmount(price, ratio) {
33
+ if (price <= 0n)
34
+ throw new RangeError('price must be a positive integer in the token’s smallest unit');
35
+ return (price * BigInt(roundHalfUp(ratio * RATIO_SCALE))) / BigInt(RATIO_SCALE);
36
+ }
37
+ /**
38
+ * The premium for the next job.
39
+ *
40
+ * premium({ k, n }, opts) prices from the record: ratio = u_F, bit-for-bit with the layer.
41
+ * premium(pL, opts) prices from a lower bound you already hold: ratio = 1 - p_L. Equal in real
42
+ * arithmetic, but 1 - p_L can differ from u_F in the last bits of a double.
43
+ * Use the record form when you need the layer's number to the last digit.
44
+ */
45
+ export function premium(input, opts = {}) {
46
+ const min = opts.min ?? 0;
47
+ const max = opts.max ?? MAX_PREMIUM_RATIO;
48
+ let raw;
49
+ let basis;
50
+ if (typeof input === 'number') {
51
+ if (!(input >= 0 && input <= 1))
52
+ throw new RangeError(`p_L must be in [0, 1], got ${input}`);
53
+ raw = 1 - input;
54
+ basis = 'p_L';
55
+ }
56
+ else {
57
+ checkRecord(input.k, input.n);
58
+ if (input.k <= 0)
59
+ return { insurable: false, reason: 'UNKNOWN', ratio: null, amount: null, covered: false, basis: 'record' };
60
+ raw = wilsonUpperFailure(input.k, input.n, opts.z ?? Z);
61
+ basis = 'record';
62
+ }
63
+ const ratio = raw < min ? min : raw;
64
+ const amount = opts.price === undefined ? null : premiumAmount(BigInt(opts.price), ratio);
65
+ return { insurable: true, ratio, amount, covered: ratio <= max, basis };
66
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taifoon/jev",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "description": "Grade AI agent jobs with TypeSafe's Jev and record the verdict on chain: code checks the facts, Jev answers a published rubric, and you get a receipt, the on-chain record and the evaluator call for ERC-8183 and Virtuals ACP. No runtime dependencies, no key inside.",
5
5
  "keywords": [
6
6
  "jev",
@@ -70,6 +70,7 @@
70
70
  "access": "public"
71
71
  },
72
72
  "devDependencies": {
73
+ "@taifoon/jev-wilson": "^0.1.0",
73
74
  "@types/node": "^25.9.2",
74
75
  "typescript": "5.9.2",
75
76
  "viem": "2.52.2",
@@ -78,8 +79,5 @@
78
79
  "bin": {
79
80
  "jev": "bin/jev.mjs",
80
81
  "taifoon-jev": "bin/jev.mjs"
81
- },
82
- "dependencies": {
83
- "@taifoon/jev-wilson": "^0.1.0"
84
82
  }
85
83
  }