@tokagent/tokagentos 2.0.14 → 2.0.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokagent/tokagentos",
3
- "version": "2.0.14",
3
+ "version": "2.0.15",
4
4
  "description": "tokagentOS CLI - Create and upgrade tokagentOS project templates",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokagent/plugin-tokagent-billing",
3
- "version": "2.0.7",
3
+ "version": "2.0.8",
4
4
  "description": "elizaOS plugin: Web3 credit-billing routes and middleware for the tokagentos LLM gateway.",
5
5
  "type": "module",
6
6
  "publishConfig": { "access": "public" },
@@ -19,7 +19,7 @@ import {
19
19
  } from "../state.js";
20
20
  import { resolveBillingIdentity } from "../middleware/api-key-resolve.js";
21
21
  import { pickForward, forward, ensureClientReady } from "../lib/forward.js";
22
- import { creditState } from "@tokagentos/billing";
22
+ import { creditState, hydrate as hydrateCredits, readCredits } from "@tokagentos/billing";
23
23
  import { eq } from "drizzle-orm";
24
24
 
25
25
  // ---------------------------------------------------------------------------
@@ -63,7 +63,7 @@ async function handleGetCreditsMe(
63
63
  _runtime: IAgentRuntime,
64
64
  ): Promise<void> {
65
65
  if (!isBillingStateInitialized()) return billingUnavailable(res);
66
- const { db, config } = getServerBillingState();
66
+ const { db, config, clients } = getServerBillingState();
67
67
  if (!config.enabled) return billingUnavailable(res);
68
68
 
69
69
  const identity = await resolveBillingIdentity(toIncomingMessage(req));
@@ -75,6 +75,35 @@ async function handleGetCreditsMe(
75
75
  const wallet: Address = identity.wallet;
76
76
  const walletKey = wallet.toLowerCase();
77
77
 
78
+ // Sync on-chain credits → DB ledger BEFORE returning the balance.
79
+ //
80
+ // Why hydrate-on-read instead of a separate deposit watcher service:
81
+ // - depositX402 is now PERMISSIONLESS (any wallet can submit a user's
82
+ // signed EIP-3009 auth) — handleTopupSettle is only ONE possible
83
+ // submitter, so we can't rely on the settle path to credit the DB.
84
+ // - A dedicated event listener could miss events during agent
85
+ // downtime or RPC outages; hydrate-on-read self-heals at request
86
+ // time.
87
+ // - The vault's `credits[user]` mapping is the source of truth.
88
+ // hydrate() reconciles: balance = onChain - (reserved + accrued).
89
+ //
90
+ // Costs: one eth_call per dashboard refresh. Acceptable — this route is
91
+ // not on the hot inference path.
92
+ //
93
+ // Failure handling: if the RPC call throws, fall back to the stale DB
94
+ // row rather than 500ing. The user sees a slightly old balance instead
95
+ // of a broken page.
96
+ try {
97
+ const onChainCredits = await readCredits(
98
+ clients,
99
+ config.vaultAddress,
100
+ wallet,
101
+ );
102
+ await hydrateCredits(db, wallet, onChainCredits);
103
+ } catch (_err) {
104
+ // Swallow — fall back to whatever the DB has. Logged at hydrate level.
105
+ }
106
+
78
107
  // Read the credit state row (may not exist for a new wallet).
79
108
  const rows = await db
80
109
  .select()
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "1.0.0",
3
- "generatedAt": "2026-05-19T14:54:21.961Z",
3
+ "generatedAt": "2026-05-19T17:46:05.725Z",
4
4
  "repoUrl": "https://github.com/elizaos/eliza",
5
5
  "templates": [
6
6
  {