@rubicon-caliga/agent-sdk 0.1.2 → 0.1.3

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.
@@ -6,10 +6,10 @@ import { ExactEvmScheme } from "@x402/evm/exact/client";
6
6
  import { serializeTypedData, toEip712Payload } from "./circle-agent-wallet.js";
7
7
  const execFileAsync = promisify(execFile);
8
8
  /**
9
- * Circle CLI / Agent Wallet payment engine. It creates the one-word x402
10
- * payment payload for Rubicon's session-first flow and delegates EIP-712
11
- * signing to `circle wallet sign typed-data`, so agents never need raw private
12
- * keys or hand-built x402 payloads.
9
+ * Circle CLI / Agent Wallet payment engine. It delegates EIP-712 signing to
10
+ * `circle wallet sign typed-data`, so agents never need raw private keys or
11
+ * hand-built Circle / Arc payloads. Current gateways may call the legacy
12
+ * one-word method as a chunk-compatibility path.
13
13
  */
14
14
  export class CircleCliGatewayPaymentEngine {
15
15
  x402 = new x402Client();
@@ -29,13 +29,29 @@ export class CircleCliGatewayPaymentEngine {
29
29
  }
30
30
  async createWordPayment(session) {
31
31
  if (!session.paymentRequired) {
32
- throw new Error("Session did not include an x402 one-word payment requirement");
32
+ throw new Error("Session did not include a legacy x402 payment requirement");
33
33
  }
34
34
  await this.signer.ensureAddress();
35
35
  return {
36
36
  paymentPayload: await this.x402.createPaymentPayload(session.paymentRequired),
37
37
  };
38
38
  }
39
+ async createChunkPayment(session, input) {
40
+ if (!session.paymentRequired) {
41
+ throw new Error("Session did not include an x402 payment requirement");
42
+ }
43
+ await this.signer.ensureAddress();
44
+ const amountAtomic = BigInt(session.wordPaymentAtomic) * BigInt(input.maxWords);
45
+ return {
46
+ paymentPayload: await this.x402.createPaymentPayload(withChunkRequirement(session.paymentRequired, {
47
+ amountAtomic: `${amountAtomic}`,
48
+ maxWords: input.maxWords,
49
+ nextSequence: input.nextSequence,
50
+ sessionId: session.sessionId,
51
+ })),
52
+ maxWords: input.maxWords,
53
+ };
54
+ }
39
55
  }
40
56
  export class CircleCliGatewaySigner {
41
57
  options;
@@ -198,6 +214,28 @@ function findString(value, keys) {
198
214
  }
199
215
  return undefined;
200
216
  }
217
+ function withChunkRequirement(paymentRequired, chunk) {
218
+ const source = paymentRequired;
219
+ if (!Array.isArray(source.accepts)) {
220
+ return paymentRequired;
221
+ }
222
+ return {
223
+ ...paymentRequired,
224
+ accepts: source.accepts.map((accept) => ({
225
+ ...accept,
226
+ amount: chunk.amountAtomic,
227
+ extra: {
228
+ ...(accept.extra ?? {}),
229
+ amountAtomic: chunk.amountAtomic,
230
+ maxWords: chunk.maxWords,
231
+ sequence: chunk.nextSequence,
232
+ authorizationMode: "chunk",
233
+ nonce: `${chunk.sessionId}:${chunk.nextSequence}:${chunk.maxWords}`,
234
+ idempotencyKey: `${chunk.sessionId}:${chunk.nextSequence}:${chunk.maxWords}`,
235
+ },
236
+ })),
237
+ };
238
+ }
201
239
  function parseJson(value) {
202
240
  try {
203
241
  return JSON.parse(value);
@@ -1 +1 @@
1
- {"version":3,"file":"circle-cli-gateway-payment.js","sourceRoot":"","sources":["../src/circle-cli-gateway-payment.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"circle-cli-gateway-payment.js","sourceRoot":"","sources":["../src/circle-cli-gateway-payment.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,30 @@
1
- import type { StartSessionResponse, StreamPaymentRequest } from "@rubicon-caliga/core";
1
+ import type { StartSessionResponse, StreamAuthorizationRequest, StreamPaymentRequest } from "@rubicon-caliga/core";
2
2
  /**
3
- * Produces the payment payload for exactly one word. Called once per word by the
4
- * SDK's read loop application developers never assemble payments themselves.
3
+ * Produces Circle / Arc authorization payloads for Rubicon reads. Preferred
4
+ * engines authorize a whole session once; fallback engines authorize chunks.
5
+ * Legacy one-word payloads remain supported for older gateways and tests.
5
6
  */
6
7
  export interface AgentPaymentEngine {
8
+ createSessionAuthorization?(session: StartSessionResponse): Promise<StreamAuthorizationRequest>;
9
+ createChunkPayment?(session: StartSessionResponse, input: {
10
+ nextSequence: number;
11
+ maxWords: number;
12
+ }): Promise<StreamPaymentRequest>;
13
+ /** @deprecated Compatibility path for one-word x402 gateways. */
7
14
  createWordPayment(session: StartSessionResponse): Promise<StreamPaymentRequest>;
8
15
  }
9
16
  /**
10
- * Development engine. Declares the one-word amount without settling real funds,
11
- * for use against a dev-mode gateway. NOT for production.
17
+ * Development engine. Declares the authorized amount without settling real
18
+ * funds, for use against a dev-mode gateway. NOT for production.
12
19
  */
13
20
  export declare class StaticPaymentEngine implements AgentPaymentEngine {
14
21
  private readonly network;
15
22
  constructor(network?: string);
23
+ createSessionAuthorization(session: StartSessionResponse): Promise<StreamAuthorizationRequest>;
24
+ createChunkPayment(session: StartSessionResponse, input: {
25
+ nextSequence: number;
26
+ maxWords: number;
27
+ }): Promise<StreamPaymentRequest>;
16
28
  createWordPayment(session: StartSessionResponse): Promise<StreamPaymentRequest>;
17
29
  }
18
30
  //# sourceMappingURL=payment-engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"payment-engine.d.ts","sourceRoot":"","sources":["../src/payment-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEvF;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACjF;AAED;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,kBAAkB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,SAAmB;IAEjD,iBAAiB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAWtF"}
1
+ {"version":3,"file":"payment-engine.d.ts","sourceRoot":"","sources":["../src/payment-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEnH;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,0BAA0B,CAAC,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAChG,kBAAkB,CAAC,CAAC,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACrI,iEAAiE;IACjE,iBAAiB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACjF;AAED;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,kBAAkB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,SAAmB;IAEjD,0BAA0B,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,0BAA0B,CAAC;IAa9F,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAiBnI,iBAAiB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAWtF"}
@@ -1,12 +1,40 @@
1
1
  /**
2
- * Development engine. Declares the one-word amount without settling real funds,
3
- * for use against a dev-mode gateway. NOT for production.
2
+ * Development engine. Declares the authorized amount without settling real
3
+ * funds, for use against a dev-mode gateway. NOT for production.
4
4
  */
5
5
  export class StaticPaymentEngine {
6
6
  network;
7
7
  constructor(network = "eip155:5042002") {
8
8
  this.network = network;
9
9
  }
10
+ async createSessionAuthorization(session) {
11
+ return {
12
+ authorizationPayload: {
13
+ scheme: "development-static",
14
+ network: this.network,
15
+ sessionId: session.sessionId,
16
+ amountAtomic: session.authorizationRequired?.maxAuthorizedAtomic ?? session.maxArticlePriceAtomic,
17
+ meteringUnit: "word",
18
+ authorizationMode: "session",
19
+ },
20
+ };
21
+ }
22
+ async createChunkPayment(session, input) {
23
+ const amountAtomic = BigInt(session.wordPaymentAtomic) * BigInt(input.maxWords);
24
+ return {
25
+ paymentPayload: {
26
+ scheme: "development-static",
27
+ network: this.network,
28
+ sessionId: session.sessionId,
29
+ amountAtomic: `${amountAtomic}`,
30
+ meteringUnit: "word",
31
+ authorizationMode: "chunk",
32
+ maxWords: input.maxWords,
33
+ nextSequence: input.nextSequence,
34
+ },
35
+ maxWords: input.maxWords,
36
+ };
37
+ }
10
38
  async createWordPayment(session) {
11
39
  return {
12
40
  paymentPayload: {
@@ -1 +1 @@
1
- {"version":3,"file":"payment-engine.js","sourceRoot":"","sources":["../src/payment-engine.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,MAAM,OAAO,mBAAmB;IACD;IAA7B,YAA6B,UAAU,gBAAgB;QAA1B,YAAO,GAAP,OAAO,CAAmB;IAAG,CAAC;IAE3D,KAAK,CAAC,iBAAiB,CAAC,OAA6B;QACnD,OAAO;YACL,cAAc,EAAE;gBACd,MAAM,EAAE,oBAAoB;gBAC5B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,YAAY,EAAE,OAAO,CAAC,iBAAiB;gBACvC,YAAY,EAAE,MAAM;aACrB;SACF,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"payment-engine.js","sourceRoot":"","sources":["../src/payment-engine.ts"],"names":[],"mappings":"AAcA;;;GAGG;AACH,MAAM,OAAO,mBAAmB;IACD;IAA7B,YAA6B,UAAU,gBAAgB;QAA1B,YAAO,GAAP,OAAO,CAAmB;IAAG,CAAC;IAE3D,KAAK,CAAC,0BAA0B,CAAC,OAA6B;QAC5D,OAAO;YACL,oBAAoB,EAAE;gBACpB,MAAM,EAAE,oBAAoB;gBAC5B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,YAAY,EAAE,OAAO,CAAC,qBAAqB,EAAE,mBAAmB,IAAI,OAAO,CAAC,qBAAqB;gBACjG,YAAY,EAAE,MAAM;gBACpB,iBAAiB,EAAE,SAAS;aAC7B;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,OAA6B,EAAE,KAAiD;QACvG,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChF,OAAO;YACL,cAAc,EAAE;gBACd,MAAM,EAAE,oBAAoB;gBAC5B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,YAAY,EAAE,GAAG,YAAY,EAAE;gBAC/B,YAAY,EAAE,MAAM;gBACpB,iBAAiB,EAAE,OAAO;gBAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,YAAY,EAAE,KAAK,CAAC,YAAY;aACjC;YACD,QAAQ,EAAE,KAAK,CAAC,QAAQ;SACzB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,OAA6B;QACnD,OAAO;YACL,cAAc,EAAE;gBACd,MAAM,EAAE,oBAAoB;gBAC5B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,YAAY,EAAE,OAAO,CAAC,iBAAiB;gBACvC,YAAY,EAAE,MAAM;aACrB;SACF,CAAC;IACJ,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubicon-caliga/agent-sdk",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Client SDK for autonomous agents consuming per-word article streams via Rubicon x402.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -31,7 +31,7 @@
31
31
  "@x402/evm": "^2.15.0",
32
32
  "eventsource": "^4.0.0",
33
33
  "viem": "^2.52.2",
34
- "@rubicon-caliga/core": "0.1.0"
34
+ "@rubicon-caliga/core": "0.1.1"
35
35
  },
36
36
  "scripts": {
37
37
  "build": "tsc -p tsconfig.json",
@@ -9,6 +9,18 @@ const paymentEngine: AgentPaymentEngine = {
9
9
  },
10
10
  };
11
11
 
12
+ const chunkPaymentEngine: AgentPaymentEngine = {
13
+ async createWordPayment() {
14
+ throw new Error("word fallback should not be used");
15
+ },
16
+ async createChunkPayment(_session, input) {
17
+ return {
18
+ paymentPayload: { amountAtomic: `${input.maxWords}` },
19
+ maxWords: input.maxWords,
20
+ };
21
+ },
22
+ };
23
+
12
24
  test("run receipt preserves Gateway settlement receipt fields", async () => {
13
25
  const fetcher = (async (input: Parameters<typeof fetch>[0]) => {
14
26
  const url = String(input);
@@ -80,6 +92,67 @@ test("run receipt preserves Gateway settlement receipt fields", async () => {
80
92
  assert.equal(receipt.network, "eip155:5042002");
81
93
  });
82
94
 
95
+ test("run can consume chunk stream while preserving per-word receipt fields", async () => {
96
+ const fetcher = (async (input: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]) => {
97
+ const url = String(input);
98
+ if (url.endsWith("/v1/sessions")) {
99
+ return jsonResponse({
100
+ sessionId: "session_1",
101
+ state: "active",
102
+ article: article(),
103
+ navigation: navigation(),
104
+ pricePerWordAtomic: "1",
105
+ maxArticlePriceAtomic: "10",
106
+ conversationId: "conversation_1",
107
+ wordPaymentAtomic: "1",
108
+ gatewayFeeBps: 0,
109
+ paymentRequired: { accepts: [{ amount: "1" }] },
110
+ expiresAt: "2026-06-18T12:00:00.000Z",
111
+ wordsPaid: 0,
112
+ wordsDelivered: 0,
113
+ paidAtomic: "0",
114
+ });
115
+ }
116
+ if (url.endsWith("/v1/sessions/session_1/stream")) {
117
+ const body = JSON.parse(String(init?.body)) as { maxWords: number };
118
+ assert.equal(body.maxWords, 3);
119
+ return jsonResponse({
120
+ accepted: true,
121
+ words: [
122
+ { sequence: 0, word: "Rubicon", priceAtomic: "1", payment: payment(0, "Rubicon") },
123
+ { sequence: 1, word: "streams", priceAtomic: "1", payment: payment(1, "streams") },
124
+ { sequence: 2, word: "chunks", priceAtomic: "1", payment: payment(2, "chunks") },
125
+ ],
126
+ text: "Rubicon streams chunks",
127
+ wordsPaid: 3,
128
+ wordsDelivered: 3,
129
+ paidAtomic: "3",
130
+ completed: true,
131
+ settlementIds: ["settlement_chunk"],
132
+ });
133
+ }
134
+ throw new Error(`Unexpected fetch: ${url}`);
135
+ }) as typeof fetch;
136
+
137
+ const client = new RubiconClient({
138
+ baseUrl: "http://rubicon.test",
139
+ paymentEngine: chunkPaymentEngine,
140
+ fetch: fetcher,
141
+ });
142
+
143
+ const receipt = await client.run({
144
+ articleId: "article_1",
145
+ maxSpendAtomic: "10",
146
+ chunkWords: 3,
147
+ });
148
+
149
+ assert.equal(receipt.text, "Rubicon streams chunks");
150
+ assert.equal(receipt.wordsRead, 3);
151
+ assert.equal(receipt.amountPaidAtomic, "3");
152
+ assert.equal(receipt.payments.length, 3);
153
+ assert.deepEqual(receipt.settlementIds, ["settlement_chunk"]);
154
+ });
155
+
83
156
  function jsonResponse(body: unknown): Response {
84
157
  return new Response(JSON.stringify(body), {
85
158
  status: 200,
@@ -116,3 +189,17 @@ function navigation() {
116
189
  stopConditions: [],
117
190
  };
118
191
  }
192
+
193
+ function payment(sequence: number, word: string) {
194
+ return {
195
+ paymentId: `payment_${sequence}`,
196
+ sessionId: "session_1",
197
+ articleId: "article_1",
198
+ sequence,
199
+ meteringUnit: "word",
200
+ amountAtomic: "1",
201
+ currency: "USDC",
202
+ settledAt: "2026-06-18T12:00:00.000Z",
203
+ word,
204
+ };
205
+ }
@@ -7,6 +7,7 @@ import type {
7
7
  StartConversationResponse,
8
8
  StartSessionRequest,
9
9
  StartSessionResponse,
10
+ StreamChunkResponse,
10
11
  StreamPaymentRequest,
11
12
  StreamPaymentResponse,
12
13
  WordPaymentReceipt,
@@ -63,6 +64,14 @@ export type RubiconReadEvent =
63
64
  payment?: WordPaymentReceipt;
64
65
  text: string;
65
66
  }
67
+ | {
68
+ type: "article.chunk";
69
+ words: Array<{ sequence: number; word: string; priceAtomic: `${bigint}`; payment?: WordPaymentReceipt }>;
70
+ text: string;
71
+ wordsRead: number;
72
+ amountPaidAtomic: `${bigint}`;
73
+ completed: boolean;
74
+ }
66
75
  | { type: "article.usage"; wordsPaid: number; wordsDelivered: number; paidAtomic: `${bigint}` }
67
76
  | { type: "article.completed"; receipt: ReadReceipt }
68
77
  | { type: "article.error"; message: string };
@@ -76,6 +85,8 @@ export interface ReadOptions {
76
85
  maxSpendAtomic?: `${bigint}`;
77
86
  budget?: Budget;
78
87
  maxWords?: number;
88
+ /** Number of words to authorize and deliver per gateway round trip when supported. */
89
+ chunkWords?: number;
79
90
  /** Return true to stop reading once enough information has been collected. */
80
91
  stopWhen?: (state: {
81
92
  text: string;
@@ -92,8 +103,8 @@ export interface RunOptions extends ReadOptions {
92
103
 
93
104
  /**
94
105
  * High-level buyer-agent client for Rubicon. `read()` runs the entire
95
- * pay -> word -> usage loop one word at a time until a stop condition is met,
96
- * so application developers never send a payment for every word themselves.
106
+ * authorize -> word -> usage loop until a stop condition is met, so application
107
+ * developers never drive a payment flow for every word themselves.
97
108
  */
98
109
  export class RubiconClient {
99
110
  private readonly fetcher: typeof fetch;
@@ -170,6 +181,18 @@ export class RubiconClient {
170
181
  return response.json() as Promise<StreamPaymentResponse>;
171
182
  }
172
183
 
184
+ async streamChunk(sessionId: string, payment: StreamPaymentRequest): Promise<StreamChunkResponse> {
185
+ const response = await this.fetcher(`${this.baseUrl}/v1/sessions/${sessionId}/stream`, {
186
+ method: "POST",
187
+ headers: this.headers({ "content-type": "application/json" }),
188
+ body: JSON.stringify(payment),
189
+ });
190
+ if (!response.ok) {
191
+ throw new Error(`Chunk stream rejected: ${response.status} ${await response.text()}`);
192
+ }
193
+ return response.json() as Promise<StreamChunkResponse>;
194
+ }
195
+
173
196
  async abort(sessionId: string, reason = "agent_cancelled"): Promise<void> {
174
197
  await this.fetcher(`${this.baseUrl}/v1/sessions/${sessionId}/abort`, {
175
198
  method: "POST",
@@ -222,8 +245,8 @@ export class RubiconClient {
222
245
  }
223
246
 
224
247
  /**
225
- * Read an article one paid word at a time. Yields seller messages, paid words,
226
- * running usage, and a final completion event carrying the receipt.
248
+ * Read an article with word-level metering. Yields seller messages, paid
249
+ * words, running usage, and a final completion event carrying the receipt.
227
250
  */
228
251
  async *read(options: ReadOptions): AsyncGenerator<RubiconReadEvent, ReadReceipt> {
229
252
  const budget: Budget =
@@ -274,6 +297,8 @@ export class RubiconClient {
274
297
  const transactionHashes: string[] = [];
275
298
  const settlementIds: string[] = [];
276
299
  const payments: WordPaymentReceipt[] = [];
300
+ const chunkWords = normalizeChunkWords(options.chunkWords);
301
+ const useChunks = chunkWords > 1 && typeof this.paymentEngine.createChunkPayment === "function";
277
302
  let stopReason: ReadReceipt["stopReason"] = "article_completed";
278
303
  let completed = false;
279
304
 
@@ -308,6 +333,64 @@ export class RubiconClient {
308
333
  break;
309
334
  }
310
335
 
336
+ if (useChunks) {
337
+ const remainingWords = options.maxWords === undefined ? chunkWords : Math.max(0, options.maxWords - wordsRead);
338
+ const affordableWords = Number((budgetAtomic - amountPaid) / wordPaymentAtomic);
339
+ const maxWords = Math.max(1, Math.min(chunkWords, remainingWords || chunkWords, affordableWords));
340
+ const payment = await this.paymentEngine.createChunkPayment!(session, {
341
+ nextSequence: wordsRead,
342
+ maxWords,
343
+ });
344
+ const idempotencyKey = `${session.sessionId}:${wordsRead}:${maxWords}`;
345
+ let result: StreamChunkResponse;
346
+ try {
347
+ result = await this.streamChunk(session.sessionId, { ...payment, idempotencyKey, maxWords });
348
+ } catch (error) {
349
+ yield { type: "article.error", message: error instanceof Error ? error.message : String(error) };
350
+ stopReason = "aborted";
351
+ break;
352
+ }
353
+ if (result.words.length === 0 && result.completed) {
354
+ completed = true;
355
+ stopReason = "article_completed";
356
+ const receipt = makeReceipt();
357
+ yield { type: "article.completed", receipt };
358
+ return receipt;
359
+ }
360
+ for (const entry of result.words) {
361
+ if (entry.payment) {
362
+ payments.push(entry.payment);
363
+ }
364
+ text = text ? `${text} ${entry.word}` : entry.word;
365
+ }
366
+ wordsRead = result.wordsDelivered;
367
+ amountPaid = BigInt(result.paidAtomic);
368
+ transactionHashes.push(...(result.transactionHashes ?? (result.transactionHash ? [result.transactionHash] : [])));
369
+ settlementIds.push(...(result.settlementIds ?? (result.settlementId ? [result.settlementId] : [])));
370
+ yield {
371
+ type: "article.chunk",
372
+ words: result.words,
373
+ text,
374
+ wordsRead,
375
+ amountPaidAtomic: `${amountPaid}`,
376
+ completed: result.completed,
377
+ };
378
+ yield {
379
+ type: "article.usage",
380
+ wordsPaid: result.wordsPaid,
381
+ wordsDelivered: result.wordsDelivered,
382
+ paidAtomic: result.paidAtomic,
383
+ };
384
+ if (result.completed) {
385
+ completed = true;
386
+ stopReason = "article_completed";
387
+ const receipt = makeReceipt();
388
+ yield { type: "article.completed", receipt };
389
+ return receipt;
390
+ }
391
+ continue;
392
+ }
393
+
311
394
  const payment = await this.paymentEngine.createWordPayment(session);
312
395
  // Idempotency key ties this payment to the specific next word; safe retries.
313
396
  const idempotencyKey = `${session.sessionId}:${wordsRead}`;
@@ -391,3 +474,9 @@ export class RubiconClient {
391
474
 
392
475
  /** Backwards-compatible alias. */
393
476
  export const AgentClient = RubiconClient;
477
+
478
+ function normalizeChunkWords(chunkWords: number | undefined): number {
479
+ if (chunkWords === undefined) return 1;
480
+ if (!Number.isInteger(chunkWords) || chunkWords < 1) return 1;
481
+ return Math.min(chunkWords, 256);
482
+ }
@@ -2,10 +2,8 @@ import type { StartSessionResponse, StreamPaymentRequest } from "@rubicon-caliga
2
2
  import { x402Client } from "@x402/core/client";
3
3
  import { registerBatchScheme } from "@circle-fin/x402-batching/client";
4
4
  import { ExactEvmScheme } from "@x402/evm/exact/client";
5
- import {
6
- initiateDeveloperControlledWalletsClient,
7
- type CircleDeveloperControlledWalletsClient,
8
- } from "@circle-fin/developer-controlled-wallets";
5
+ import * as CircleWallets from "@circle-fin/developer-controlled-wallets";
6
+ import type { CircleDeveloperControlledWalletsClient } from "@circle-fin/developer-controlled-wallets";
9
7
  import type { AgentPaymentEngine } from "./payment-engine.js";
10
8
 
11
9
  export interface CircleAgentWalletEngineOptions {
@@ -13,7 +11,7 @@ export interface CircleAgentWalletEngineOptions {
13
11
  apiKey: string;
14
12
  /** Entity secret registered for the Circle developer account. */
15
13
  entitySecret: string;
16
- /** The Agent Wallet that holds USDC and signs each one-word payment. */
14
+ /** The Agent Wallet that holds USDC and signs Circle / Arc authorizations. */
17
15
  walletId: string;
18
16
  /**
19
17
  * The wallet's on-chain address. Optional — when omitted it is resolved once
@@ -80,7 +78,7 @@ class CircleAgentWalletSigner {
80
78
  const res = await this.client.signTypedData({
81
79
  walletId: this.walletId,
82
80
  data: serializeTypedData(toEip712Payload(typed)),
83
- memo: "Rubicon one-word payment",
81
+ memo: "Rubicon reading authorization",
84
82
  });
85
83
  const signature = res.data?.signature;
86
84
  if (!signature) {
@@ -91,10 +89,10 @@ class CircleAgentWalletSigner {
91
89
  }
92
90
 
93
91
  /**
94
- * Circle Agent Wallet engine. Signs the gateway's one-word x402 terms with a
95
- * custodial Circle Agent Wallet the recommended buyer setup so the agent
96
- * never handles a local signing key. Settlement may be batched by Circle, but
97
- * each signed payload still corresponds to exactly one word.
92
+ * Circle Agent Wallet engine. Signs gateway authorization terms with a
93
+ * custodial Circle Agent Wallet so the buyer agent never handles a local
94
+ * signing key. Current gateways may still call the legacy one-word method as a
95
+ * chunk-compatibility path.
98
96
  */
99
97
  export class CircleAgentWalletEngine implements AgentPaymentEngine {
100
98
  private readonly x402 = new x402Client();
@@ -103,7 +101,7 @@ export class CircleAgentWalletEngine implements AgentPaymentEngine {
103
101
  constructor(options: CircleAgentWalletEngineOptions) {
104
102
  const client =
105
103
  options.client ??
106
- initiateDeveloperControlledWalletsClient({
104
+ CircleWallets.initiateDeveloperControlledWalletsClient({
107
105
  apiKey: options.apiKey,
108
106
  entitySecret: options.entitySecret,
109
107
  ...(options.baseUrl ? { baseUrl: options.baseUrl } : {}),
@@ -119,7 +117,7 @@ export class CircleAgentWalletEngine implements AgentPaymentEngine {
119
117
 
120
118
  async createWordPayment(session: StartSessionResponse): Promise<StreamPaymentRequest> {
121
119
  if (!session.paymentRequired) {
122
- throw new Error("Session did not include an x402 one-word payment requirement");
120
+ throw new Error("Session did not include a legacy x402 payment requirement");
123
121
  }
124
122
  // Resolve the wallet address up front so the synchronous `address` read
125
123
  // inside createPaymentPayload sees a real value.
@@ -49,10 +49,10 @@ interface TypedDataRequest {
49
49
  }
50
50
 
51
51
  /**
52
- * Circle CLI / Agent Wallet payment engine. It creates the one-word x402
53
- * payment payload for Rubicon's session-first flow and delegates EIP-712
54
- * signing to `circle wallet sign typed-data`, so agents never need raw private
55
- * keys or hand-built x402 payloads.
52
+ * Circle CLI / Agent Wallet payment engine. It delegates EIP-712 signing to
53
+ * `circle wallet sign typed-data`, so agents never need raw private keys or
54
+ * hand-built Circle / Arc payloads. Current gateways may call the legacy
55
+ * one-word method as a chunk-compatibility path.
56
56
  */
57
57
  export class CircleCliGatewayPaymentEngine implements AgentPaymentEngine {
58
58
  private readonly x402 = new x402Client();
@@ -74,13 +74,32 @@ export class CircleCliGatewayPaymentEngine implements AgentPaymentEngine {
74
74
 
75
75
  async createWordPayment(session: StartSessionResponse): Promise<StreamPaymentRequest> {
76
76
  if (!session.paymentRequired) {
77
- throw new Error("Session did not include an x402 one-word payment requirement");
77
+ throw new Error("Session did not include a legacy x402 payment requirement");
78
78
  }
79
79
  await this.signer.ensureAddress();
80
80
  return {
81
81
  paymentPayload: await this.x402.createPaymentPayload(session.paymentRequired as never),
82
82
  };
83
83
  }
84
+
85
+ async createChunkPayment(session: StartSessionResponse, input: { nextSequence: number; maxWords: number }): Promise<StreamPaymentRequest> {
86
+ if (!session.paymentRequired) {
87
+ throw new Error("Session did not include an x402 payment requirement");
88
+ }
89
+ await this.signer.ensureAddress();
90
+ const amountAtomic = BigInt(session.wordPaymentAtomic) * BigInt(input.maxWords);
91
+ return {
92
+ paymentPayload: await this.x402.createPaymentPayload(
93
+ withChunkRequirement(session.paymentRequired, {
94
+ amountAtomic: `${amountAtomic}`,
95
+ maxWords: input.maxWords,
96
+ nextSequence: input.nextSequence,
97
+ sessionId: session.sessionId,
98
+ }) as never,
99
+ ),
100
+ maxWords: input.maxWords,
101
+ };
102
+ }
84
103
  }
85
104
 
86
105
  export class CircleCliGatewaySigner {
@@ -263,6 +282,32 @@ function findString(value: unknown, keys: string[]): string | undefined {
263
282
  return undefined;
264
283
  }
265
284
 
285
+ function withChunkRequirement(
286
+ paymentRequired: unknown,
287
+ chunk: { amountAtomic: `${bigint}`; maxWords: number; nextSequence: number; sessionId: string },
288
+ ): unknown {
289
+ const source = paymentRequired as { accepts?: Array<Record<string, unknown>> };
290
+ if (!Array.isArray(source.accepts)) {
291
+ return paymentRequired;
292
+ }
293
+ return {
294
+ ...(paymentRequired as Record<string, unknown>),
295
+ accepts: source.accepts.map((accept) => ({
296
+ ...accept,
297
+ amount: chunk.amountAtomic,
298
+ extra: {
299
+ ...((accept.extra as Record<string, unknown> | undefined) ?? {}),
300
+ amountAtomic: chunk.amountAtomic,
301
+ maxWords: chunk.maxWords,
302
+ sequence: chunk.nextSequence,
303
+ authorizationMode: "chunk",
304
+ nonce: `${chunk.sessionId}:${chunk.nextSequence}:${chunk.maxWords}`,
305
+ idempotencyKey: `${chunk.sessionId}:${chunk.nextSequence}:${chunk.maxWords}`,
306
+ },
307
+ })),
308
+ };
309
+ }
310
+
266
311
  function parseJson(value: string): unknown {
267
312
  try {
268
313
  return JSON.parse(value);