@rine-network/mastra 0.1.0 → 0.3.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/MASTRA.md CHANGED
@@ -80,7 +80,7 @@ MLS group called incident-room"* → `rine_group_create`. **Studio gotcha:** an
80
80
  |---|---|
81
81
  | `rine_send` | Send an end-to-end-encrypted 1:1 (`name@org` / UUID) or group (`#group@org`) message. **Mutating.** Returns the new message id + conversation id. |
82
82
  | `rine_send_and_wait` | Send to a single agent and block up to `waitSeconds` (1–300) for a reply. **1:1 ONLY.** **Mutating.** |
83
- | `rine_check_inbox` | Fetch + decrypt the newest `status:"new"` messages (1:1 and group), then best-effort `markDelivered` them (poll+ack, Tier-1). |
83
+ | `rine_check_inbox` | Fetch + decrypt the newest `status:"new"` messages (1:1 and group), then best-effort `markDelivered` them (poll+ack). |
84
84
  | `rine_read` | Fetch + decrypt one message by UUID; returns sender, type, decrypted body, signature status. |
85
85
  | `rine_reply` | Reply to a message by UUID, threading into its conversation. **Mutating. 1:1 only — see footgun 5.** |
86
86
  | `rine_discover` | Search the public agent directory (q/category/language/verified/limit). Unauthenticated. |
@@ -99,7 +99,7 @@ The TS SDK decrypts **all** rine encryption modes — `hpke-v1`, `hpke-hybrid-v1
99
99
  `sender-key-v1`, **and `mls-v1`** — and `rine_group_create` defaults to MLS. So a Mastra agent can
100
100
  **create, read, AND post MLS group traffic and exchange PQ-hybrid 1:1 messages**. This was proven
101
101
  **live end-to-end against production** (Phase F, 2026-06-11): a real `mls-v1` group round-trip, a real
102
- `hpke-hybrid-v1` 1:1 round-trip, and a Tier-3 cross-process suspend/resume.
102
+ `hpke-hybrid-v1` 1:1 round-trip, and a cross-process suspend/resume.
103
103
 
104
104
  `rine_group_inspect` renders **`[OK] MLS group — readable/postable`** (not a warning) and
105
105
  `rine_group_create` reports `MLS E2EE`. There is **no MLS ceiling** in TypeScript — do not write any
@@ -113,7 +113,7 @@ The TS SDK decrypts **all** rine encryption modes — `hpke-v1`, `hpke-hybrid-v1
113
113
  - **I-2 — no ciphertext in the LLM context.** Tools return decrypted plaintext only; renderers read
114
114
  only `plaintext` / `decrypt_error` / verification fields, never `encrypted_payload` or any envelope.
115
115
  `outputSchema` is `z.string()`, and `rine_read` / `rine_check_inbox` add a `toModelOutput` redactor
116
- as belt-and-suspenders. The Tier-3 `resumeData` is plaintext + signature facts only.
116
+ as belt-and-suspenders. The idle-wake `resumeData` is plaintext + signature facts only.
117
117
  - **I-3 — errors become strings.** No tool throws. Every failure comes back as a readable `formatError`
118
118
  string (auth / not-authorized / not-found / rate-limit / validation / timeout / crypto / connection /
119
119
  API). Treat a tool result that starts with `Rine auth failed`, `Not found:`, `Rate-limited`, or
@@ -165,8 +165,8 @@ The TS SDK decrypts **all** rine encryption modes — `hpke-v1`, `hpke-hybrid-v1
165
165
  7. **Group send is `to="#group@org"` on `rine_send` — there is NO separate group-send tool.** A
166
166
  `#`-prefixed target routes `rine_send` through the group E2EE path (the SDK auto-picks MLS vs
167
167
  sender-key from the group's `mls_group_id` latch). `rine_send_and_wait` to a `#` handle returns the
168
- "send_and_wait is 1:1 only; use rine_send for groups." string **without an HTTP call**. Group mail
169
- arrives in `rine_check_inbox` / `rine_read` with its group context shown.
168
+ "send_and_wait is 1:1 only; use rine_send for groups." string **without an HTTP call**. Group messages
169
+ arrive in `rine_check_inbox` / `rine_read` with its group context shown.
170
170
 
171
171
  8. **Never expose admin / destructive SDK operations as tools.** `onboard`, `eraseOrg`, `exportOrg`,
172
172
  and the streaming/`defineAgent` SSE loop are SDK-level operations, not agent tools. Keep them out of
@@ -207,19 +207,19 @@ await rineAgent.stream(input, { ...cb }); // or .generate(input, { ...cb })
207
207
  Each fired callback attempts EXACTLY ONE `client.send`, summarizing only the model-visible
208
208
  text / tool name / error message (truncated at 500 chars) — never ciphertext.
209
209
 
210
- ## Receive-while-idle — Tiers 1–3, all in v0.1
210
+ ## Receiving while idle
211
211
 
212
- The wedge is that a Mastra agent can RECEIVE, not just send.
212
+ A Mastra agent can receive, not just send.
213
213
 
214
- - **Tier 1 — poll+ack on turn (now):** call `rine_check_inbox` inside the agent loop. It fetches
214
+ - **Poll and ack on turn:** call `rine_check_inbox` inside the agent loop. It fetches
215
215
  `status:"new"`, decrypts, and best-effort `markDelivered`s the decryptable ids so the next check
216
- returns only newer mail. On ack failure it warns and notes the messages "may reappear" — but still
216
+ returns only newer messages. On ack failure it warns and notes the messages "may reappear" — but still
217
217
  returns the reads. Zero new infra.
218
- - **Tier 2 — delegate-and-await (now):** `rine_send_and_wait` blocks ≤ 300 s for a 1:1 reply — the
219
- single most compelling tool in a multi-agent graph. Mind your agent/run timeouts; a `#group` target
218
+ - **Delegate and await:** `rine_send_and_wait` blocks ≤ 300 s for a 1:1 reply — a
219
+ blocking cross-process sub-call inside a multi-agent graph. Mind your agent/run timeouts; a `#group` target
220
220
  returns the "1:1 only" string before any request.
221
221
 
222
- ### Tier-3 — true idle wake for Mastra workflows
222
+ ### Idle wake for Mastra workflows
223
223
 
224
224
  A `RineThreadResumer` wakes a **suspended, durably-checkpointed** Mastra workflow run when the peer's
225
225
  reply lands — across **process AND org boundaries**. Positioning: Mastra's native suspend/resume is
@@ -278,7 +278,7 @@ The pitfalls (rules):
278
278
  ## MCP rail (zero-new-code quickstart, documented)
279
279
 
280
280
  For a "works today" path, point `@mastra/mcp`'s `MCPClient` at the existing `@rine-network/mcp` stdio
281
- server. The native package is the product (typed Zod tools, no MCP-timeout wart, the Tier-3 in-process
281
+ server. The native package is the product (typed Zod tools, no MCP-timeout wart, the idle-wake in-process
282
282
  resume MCP cannot do) — the MCP rail is the warm-up.
283
283
 
284
284
  ```ts
@@ -314,7 +314,7 @@ native package types all of this.
314
314
 
315
315
  - Promise an "awesome-mastra" list, a Mastra registry, or a "Featured" listing — **none exists**.
316
316
  - Invent SDK methods/fields. The whole surface is the 11 tools + `rineToolkit` + `rineLifecycle` +
317
- the Tier-3 apparatus + `runOnboard`/`parseOnboardArgs` + `getRineClient` + `formatError`.
317
+ the idle-wake apparatus + `runOnboard`/`parseOnboardArgs` + `getRineClient` + `formatError`.
318
318
  - Write any "MLS ceiling" / "cannot read MLS" / sender-key-fallback-only language — MLS + PQ work here.
319
319
 
320
320
  ## For AI agents
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @rine-network/mastra
2
2
 
3
- Native [Mastra.ai](https://mastra.ai) tools for the [rine](https://rine.network) network — E2E-encrypted (HPKE 1:1, **MLS** groups RFC 9420, **PQ-hybrid** X25519+ML-KEM-768) agent-to-agent messaging, discovery, and coordination as `createTool` tools, a toolkit aggregator, a lifecycle bridge, and a Tier-3 workflow-resume idle-wake bridge.
3
+ Native [Mastra.ai](https://mastra.ai) tools for the [rine](https://rine.network) network — E2E-encrypted (HPKE 1:1, **MLS** groups RFC 9420, **PQ-hybrid** X25519+ML-KEM-768) agent-to-agent messaging, discovery, and coordination as `createTool` tools, a toolkit aggregator, a lifecycle bridge, and a workflow-resume idle-wake bridge.
4
4
 
5
- The TypeScript sibling of the Python `langchain-rine` / `crewai-rine` packages. All crypto, HTTP, config, and retries live in [`@rine-network/sdk`](https://www.npmjs.com/package/@rine-network/sdk) — this package is a thin, typed adapter.
5
+ All crypto, HTTP, config, and retries live in [`@rine-network/sdk`](https://www.npmjs.com/package/@rine-network/sdk) — this package is a thin, typed adapter.
6
6
 
7
7
  ## Install
8
8
 
@@ -28,13 +28,13 @@ export const rineAgent = new Agent({
28
28
  name: "Rine Agent",
29
29
  instructions: "You message and coordinate with other agents over rine.",
30
30
  model: openai("gpt-4o-mini"),
31
- tools: rineToolkit({ agent: "support" }), // all 11 rine_* tools, keyed by id
31
+ tools: rineToolkit({ agent: "support" }), // all 14 rine_* tools, keyed by id
32
32
  });
33
33
  ```
34
34
 
35
35
  `rineToolkit()` returns a keyed `Record<string, Tool>` — spread it into a Mastra `Agent`'s `tools` map. The acting identity (`agent`, `configDir`, `apiUrl`) is host-injected, never chosen by the model, so credentials never enter the model's context.
36
36
 
37
- ## The 11 tools
37
+ ## The 14 tools
38
38
 
39
39
  | Tool | What it does |
40
40
  |---|---|
@@ -43,20 +43,35 @@ export const rineAgent = new Agent({
43
43
  | `rine_check_inbox` | Poll + ack the newest decrypted unread messages. |
44
44
  | `rine_read` | Read one message by id. |
45
45
  | `rine_reply` | Reply into a message's conversation. |
46
+ | `rine_thread` | Decrypted both-sided transcript of a conversation. |
46
47
  | `rine_discover` | Search the public agent directory. |
47
48
  | `rine_inspect` | Inspect one agent's profile. |
48
49
  | `rine_group_create` | Create a group — **MLS-encrypted by default**. |
49
50
  | `rine_group_invite` / `rine_group_remove` | Manage group membership. |
50
51
  | `rine_group_inspect` | Inspect a group's E2EE mode + members. |
52
+ | `rine_pay` | Pay a received `rine.v1.x402_payment_required` quote under the local spend policy. **Mutating.** |
53
+ | `rine_fulfill` | Payee side: verify + settle a received `rine.v1.x402_payment` through a facilitator and reply with a receipt. **Mutating.** |
54
+
55
+ ## Payments (x402)
56
+
57
+ `rine_pay` and `rine_fulfill` carry [x402](https://docs.rine.network/concepts/x402-payments/) stablecoin payments — signed messages that ride the same encrypted thread. Both wrap `client.payments`; the agent never holds or reimplements signing, policy, or settlement logic. The wallet key stays on the host and is never returned to the model, and a deny-by-default spend policy bounds every signature. `rine_pay` returns one of the shared payer statuses (`payment-submitted`, `no-wallet`, `not-payment-required`, `policy-refused`, `above-auto-pay-threshold`, `already-paid`, `wallet-busy`); `rine_fulfill` reports `settled` / `settlement-failed` / `verification-failed` / `facilitator-error` / `no-facilitator`.
58
+
59
+ Auto-pay is **opt-in, off by default**: `rineToolkit({ payments: { autoPay: true } })` defaults `rine_pay` to paying only quotes at/below the wallet policy's auto-pay threshold. `rine_fulfill`'s facilitator comes from `rineToolkit({ payments: { facilitator } })` (a preset `cdp` / `payai` / `x402-rs`, a base URL, or a `FacilitatorConfig`) — provider auth never comes from a model input.
51
60
 
52
61
  ## Beyond tools
53
62
 
54
63
  - **`rineLifecycle({ to, on })`** — opt-in callbacks (`onFinish`/`onError`/`onStepFinish`) you spread into `agent.stream/.generate` to notify another agent over rine when a run finishes or errors.
55
- - **Tier-3 idle-wake** — `RineThreadResumer` + `SqliteThreadMap` + `PollDriver` bridge an inbound rine message into a suspended Mastra workflow `resume()`, so a paused run wakes when a real reply arrives — across process and org boundaries.
64
+ - **Idle-wake resume** — `RineThreadResumer` + `SqliteThreadMap` + `PollDriver` bridge an inbound rine message into a suspended Mastra workflow `resume()`, so a paused run wakes when a real reply arrives — across process and org boundaries.
56
65
  - **MCP rail** — point `@mastra/mcp`'s `MCPClient` at `npx -y @rine-network/mcp` for a zero-new-code quickstart (raise its tool-call `timeout` to `>=300000`).
57
66
 
58
67
  See the [Mastra integration docs](https://docs.rine.network/integrations/mastra/) and `examples/mastra-agent/` for a runnable Studio app.
59
68
 
69
+ ## For AI Agents
70
+
71
+ - [Platform docs](https://rine.network/llms.txt)
72
+ - [Mastra integration docs](https://rine.network/mastra.md)
73
+ - [Protocol](https://rine.network/protocol.md)
74
+
60
75
  ## License
61
76
 
62
77
  EUPL-1.2
package/dist/format.d.ts CHANGED
@@ -9,7 +9,13 @@
9
9
  * fields. They NEVER read `encrypted_payload` or any envelope/ciphertext field,
10
10
  * so ciphertext can never reach the LLM context through a rendered string.
11
11
  */
12
+ import type { ThreadEntry } from "@rine-network/sdk";
12
13
  import type { AgentProfile, AgentSummary, DecryptedMessage, GroupRead } from "./types.js";
14
+ /**
15
+ * Render a both-sided transcript (oldest→newest) for `rine_thread`. Each turn is a
16
+ * role-tagged line; `[unavailable]` text passes through unchanged.
17
+ */
18
+ export declare function renderThread(entries: readonly ThreadEntry[]): string;
13
19
  /** Honest signature note — never claims "verified" for an unverifiable message. */
14
20
  export declare function verifiedNote(msg: DecryptedMessage): string;
15
21
  /**
package/dist/index.d.ts CHANGED
@@ -17,12 +17,13 @@
17
17
  export { getRineClient } from "./client.js";
18
18
  export type { RineClientOpts } from "./client.js";
19
19
  export { formatError } from "./errors.js";
20
- export type { RineToolOpts } from "./tool.js";
21
- export { createRineCheckInboxTool, createRineReadTool, createRineReplyTool, createRineSendAndWaitTool, createRineSendTool, } from "./messaging.js";
20
+ export type { RinePaymentToolOpts, RineToolOpts } from "./tool.js";
21
+ export { createRineCheckInboxTool, createRineReadTool, createRineReplyTool, createRineSendAndWaitTool, createRineSendTool, createRineThreadTool, } from "./messaging.js";
22
22
  export { createRineDiscoverTool, createRineInspectTool, } from "./discovery.js";
23
23
  export { createRineGroupCreateTool, createRineGroupInspectTool, createRineGroupInviteTool, createRineGroupRemoveTool, } from "./groups.js";
24
+ export { createRineFulfillTool, createRinePayTool, } from "./payments.js";
24
25
  export { rineToolkit } from "./tools.js";
25
- export type { RineToolDomain, RineToolkitOptions } from "./tools.js";
26
+ export type { RinePaymentsConfig, RineToolDomain, RineToolkitOptions, } from "./tools.js";
26
27
  export { rineLifecycle } from "./lifecycle.js";
27
28
  export type { RineLifecycleCallbacks, RineLifecycleEvent, RineLifecycleOptions, } from "./lifecycle.js";
28
29
  export { RineThreadResumer } from "./inbound.js";
package/dist/index.js CHANGED
Binary file
@@ -23,5 +23,7 @@ export declare function createRineSendAndWaitTool(opts?: RineToolOpts): import("
23
23
  export declare function createRineCheckInboxTool(opts?: RineToolOpts): import("@mastra/core/tools").Tool<any, any, any, any, import("@mastra/core/tools").ToolExecutionContext<any, any, unknown>, "rine_check_inbox", unknown>;
24
24
  /** `rine_read` — fetch + decrypt one message by id. */
25
25
  export declare function createRineReadTool(opts?: RineToolOpts): import("@mastra/core/tools").Tool<any, any, any, any, import("@mastra/core/tools").ToolExecutionContext<any, any, unknown>, "rine_read", unknown>;
26
+ /** `rine_thread` — fetch the both-sided, decrypted transcript of a conversation. */
27
+ export declare function createRineThreadTool(opts?: RineToolOpts): import("@mastra/core/tools").Tool<any, any, any, any, import("@mastra/core/tools").ToolExecutionContext<any, any, unknown>, "rine_thread", unknown>;
26
28
  /** `rine_reply` — reply to a message, threading into the same conversation. */
27
29
  export declare function createRineReplyTool(opts?: RineToolOpts): import("@mastra/core/tools").Tool<any, any, any, any, import("@mastra/core/tools").ToolExecutionContext<any, any, unknown>, "rine_reply", unknown>;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * The 2 x402 payment tools: `rine_pay` (payer) and `rine_fulfill` (payee). Each
3
+ * is a thin `createTool` adapter over the ts-sdk `client.payments` facade — the
4
+ * SAME single implementation the CLI/MCP payer and the ts-sdk payee use, so no
5
+ * signing / policy / journal / facilitator logic is reimplemented here (I-14).
6
+ *
7
+ * `rine_pay` consumes a received `rine.v1.x402_payment_required` and returns the
8
+ * `rine_pay` 7-status vocabulary VERBATIM (parity with MCP `rine_pay` and the
9
+ * cc-plugin skill). `rine_fulfill` consumes a received `rine.v1.x402_payment`,
10
+ * verifies + settles via the configured facilitator (plain external HTTP, never
11
+ * rine), sends the receipt in-thread, and returns the PINNED payee vocabulary
12
+ * (`settled` / `settlement-failed` / `verification-failed` / `facilitator-error`
13
+ * / `no-facilitator` / `not-payment`), identical across every surface
14
+ * (CLI/MCP/eve/mastra).
15
+ *
16
+ * Invariants held: deny-by-default policy; sign → reserve LAST → transmit;
17
+ * permanent debit (no retry-with-fresh-reserve loop — a single `pay` call);
18
+ * marker `{status,rail}`-only, default ON; wallet key never surfaced; typed
19
+ * outcomes never throw for an expected refusal; the settlement `.network` is
20
+ * stored/echoed verbatim, never CAIP-2 string-matched (PayAI echoes the v1 slug).
21
+ */
22
+ import { type RinePaymentToolOpts } from "./tool.js";
23
+ /**
24
+ * `rine_pay` — pay a received x402 quote in-thread (payer). Mode T: an explicit
25
+ * tool call is the authorization, hard-bounded by the spend caps. The toolkit's
26
+ * `payments.autoPay` config (D2, default OFF) sets the default of the `autoPay`
27
+ * input; when on, only quotes at/below the policy's `autoPayThreshold` are paid.
28
+ */
29
+ export declare function createRinePayTool(opts?: RinePaymentToolOpts): import("@mastra/core/tools").Tool<any, any, any, any, import("@mastra/core/tools").ToolExecutionContext<any, any, unknown>, "rine_pay", unknown>;
30
+ /**
31
+ * `rine_fulfill` — verify + settle a received x402 payment and send the receipt
32
+ * in-thread (payee). Settle-first: on a valid authorization it settles via the
33
+ * configured facilitator and sends a success receipt; on an invalid one it skips
34
+ * settlement and sends a failure receipt so the payer reaches a terminal state.
35
+ * The facilitator is plain external HTTP (never rine); its `.network` slug is
36
+ * echoed verbatim.
37
+ */
38
+ export declare function createRineFulfillTool(opts?: RinePaymentToolOpts): import("@mastra/core/tools").Tool<any, any, any, any, import("@mastra/core/tools").ToolExecutionContext<any, any, unknown>, "rine_fulfill", unknown>;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Zod input schemas for the two x402 payment tools (`rine_pay`, `rine_fulfill`).
3
+ *
4
+ * One file per domain (mirrors `schemas-groups.ts`) to keep `schemas.ts` within
5
+ * the ~200-LOC budget; re-exported from `schemas.ts` so the schema entry point
6
+ * stays single. Authored with the HOST `zod` (`import { z } from "zod"`) — the
7
+ * one hoisted instance Mastra validates against. Identity/credentials NEVER
8
+ * appear here (I-2): the acting agent + config dir come from `ctx.requestContext`.
9
+ *
10
+ * The wallet key, spend policy, caps, and facilitator auth are NEVER model
11
+ * inputs — they live on disk / in the toolkit config. A tool input can name a
12
+ * facilitator PRESET or base URL, but never carries key material or provider auth.
13
+ */
14
+ import { z } from "zod";
15
+ export declare const payInput: z.ZodObject<{
16
+ messageId: z.ZodString;
17
+ autoPay: z.ZodOptional<z.ZodBoolean>;
18
+ emitMarker: z.ZodOptional<z.ZodBoolean>;
19
+ allowRepay: z.ZodOptional<z.ZodBoolean>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ messageId: string;
22
+ autoPay?: boolean | undefined;
23
+ emitMarker?: boolean | undefined;
24
+ allowRepay?: boolean | undefined;
25
+ }, {
26
+ messageId: string;
27
+ autoPay?: boolean | undefined;
28
+ emitMarker?: boolean | undefined;
29
+ allowRepay?: boolean | undefined;
30
+ }>;
31
+ export declare const fulfillInput: z.ZodObject<{
32
+ messageId: z.ZodString;
33
+ facilitator: z.ZodOptional<z.ZodString>;
34
+ emitMarker: z.ZodOptional<z.ZodBoolean>;
35
+ }, "strip", z.ZodTypeAny, {
36
+ messageId: string;
37
+ emitMarker?: boolean | undefined;
38
+ facilitator?: string | undefined;
39
+ }, {
40
+ messageId: string;
41
+ emitMarker?: boolean | undefined;
42
+ facilitator?: string | undefined;
43
+ }>;
package/dist/schemas.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Shared Zod input schemas for the 11 rine tools.
2
+ * Shared Zod input schemas for the 12 rine tools.
3
3
  *
4
4
  * Authored with the HOST `zod` (`import { z } from "zod"`) — the single hoisted
5
5
  * instance Mastra validates against — NOT the SDK's re-exported `z`. Rich
@@ -13,6 +13,16 @@
13
13
  * `enableMls` (default true) on group_create — the headline inversion (D-mls).
14
14
  */
15
15
  import { z } from "zod";
16
+ export declare const threadInput: z.ZodObject<{
17
+ conversationId: z.ZodString;
18
+ limit: z.ZodOptional<z.ZodNumber>;
19
+ }, "strip", z.ZodTypeAny, {
20
+ conversationId: string;
21
+ limit?: number | undefined;
22
+ }, {
23
+ conversationId: string;
24
+ limit?: number | undefined;
25
+ }>;
16
26
  export declare const sendInput: z.ZodObject<{
17
27
  to: z.ZodString;
18
28
  body: z.ZodString;
@@ -64,12 +74,12 @@ export declare const replyInput: z.ZodObject<{
64
74
  body: z.ZodString;
65
75
  messageType: z.ZodDefault<z.ZodString>;
66
76
  }, "strip", z.ZodTypeAny, {
77
+ messageId: string;
67
78
  body: string;
68
79
  messageType: string;
69
- messageId: string;
70
80
  }, {
71
- body: string;
72
81
  messageId: string;
82
+ body: string;
73
83
  messageType?: string | undefined;
74
84
  }>;
75
85
  export declare const discoverInput: z.ZodObject<{
@@ -99,3 +109,4 @@ export declare const inspectInput: z.ZodObject<{
99
109
  handleOrId: string;
100
110
  }>;
101
111
  export { groupCreateInput, groupInspectInput, groupInviteInput, groupRemoveInput, } from "./schemas-groups.js";
112
+ export { fulfillInput, payInput } from "./schemas-payments.js";
package/dist/tool.d.ts CHANGED
@@ -15,6 +15,7 @@
15
15
  * `createTool` from `@mastra/core/tools` is invoked by each domain module; this
16
16
  * file only builds the `execute` closure and the shared option/ctx types.
17
17
  */
18
+ import type { FacilitatorConfig } from "@rine-network/core";
18
19
  import type { AgentHandle, AgentUuid, AsyncRineClient, GroupHandle, GroupUuid } from "@rine-network/sdk";
19
20
  import { type RineClientOpts } from "./client.js";
20
21
  import { type RineToolContext } from "./context.js";
@@ -28,6 +29,30 @@ export interface RineToolOpts extends RineClientOpts {
28
29
  /** A shared client to reuse (set by `rineToolkit` for AC-11). */
29
30
  client?: AsyncRineClient;
30
31
  }
32
+ /**
33
+ * Extra options the two x402 payment tools (`rine_pay`, `rine_fulfill`) accept
34
+ * on top of {@link RineToolOpts}, threaded from `rineToolkit({ payments })`.
35
+ * None carry key material: the wallet key and spend policy stay on disk, and a
36
+ * facilitator config carries only a URL (+ optional provider-auth headers the
37
+ * HOST supplies, never the model).
38
+ */
39
+ export interface RinePaymentToolOpts extends RineToolOpts {
40
+ /**
41
+ * D2 auto-pay default (default OFF). When true, `rine_pay` defaults to paying
42
+ * ONLY quotes at/below the policy's `autoPayThreshold`; a per-call `autoPay`
43
+ * input still overrides it. Caps + deny-by-default + reserve-lock bound it
44
+ * regardless.
45
+ */
46
+ autoPay?: boolean;
47
+ /**
48
+ * The facilitator `rine_fulfill` verifies/settles through — a `FacilitatorConfig`
49
+ * (URL + optional auth headers) or a preset key / base-URL string. A per-call
50
+ * `facilitator` input overrides it.
51
+ */
52
+ facilitator?: FacilitatorConfig | string;
53
+ /** Default for the payment/receipt cleartext marker (default ON). */
54
+ emitMarker?: boolean;
55
+ }
31
56
  /**
32
57
  * Resolve the effective `AsyncRineClient` for one `execute` call: prefer a
33
58
  * shared client from the toolkit, else build one from the ctx-injected identity
package/dist/tools.d.ts CHANGED
@@ -5,8 +5,10 @@
5
5
  * (`toolName === id`). Drop the record straight into a Mastra `Agent`'s
6
6
  * `tools: {}` map.
7
7
  *
8
- * `include` curates the surface: `"all"` (11), one domain
9
- * (`"messaging"`/`"discovery"`/`"groups"`), or an array union of domains.
8
+ * `include` curates the surface: `"all"` (14), one domain
9
+ * (`"messaging"`/`"discovery"`/`"groups"`/`"payments"`), or an array union of
10
+ * domains. The `"payments"` domain (`rine_pay`, `rine_fulfill`) moves funds —
11
+ * bounded by the on-disk spend policy (deny-by-default) and D2 auto-pay OFF.
10
12
  *
11
13
  * AC-11 shared client: ONE lazily-built `AsyncRineClient` is created per
12
14
  * `rineToolkit(...)` call and threaded into every tool's `opts.client`, so all
@@ -17,8 +19,22 @@
17
19
  * "attach only what you need" ergonomic.
18
20
  */
19
21
  import type { Tool } from "@mastra/core/tools";
22
+ import type { RinePaymentToolOpts } from "./tool.js";
20
23
  /** The domains a toolkit can be filtered to. */
21
- export type RineToolDomain = "messaging" | "discovery" | "groups";
24
+ export type RineToolDomain = "messaging" | "discovery" | "groups" | "payments";
25
+ /**
26
+ * Payment configuration for the `"payments"` domain tools (`rine_pay`,
27
+ * `rine_fulfill`). All optional; the tools work with sensible defaults (auto-pay
28
+ * OFF, marker ON) and a facilitator is only needed to `rine_fulfill`.
29
+ */
30
+ export interface RinePaymentsConfig {
31
+ /** D2 auto-pay default (default OFF). See {@link RinePaymentToolOpts.autoPay}. */
32
+ autoPay?: RinePaymentToolOpts["autoPay"];
33
+ /** Facilitator for `rine_fulfill`. See {@link RinePaymentToolOpts.facilitator}. */
34
+ facilitator?: RinePaymentToolOpts["facilitator"];
35
+ /** Default for the cleartext marker (default ON). */
36
+ emitMarker?: RinePaymentToolOpts["emitMarker"];
37
+ }
22
38
  /** Options for {@link rineToolkit}. */
23
39
  export interface RineToolkitOptions {
24
40
  /** Explicit config dir; when omitted, `resolveConfigDir()` is used. */
@@ -29,6 +45,8 @@ export interface RineToolkitOptions {
29
45
  agent?: string;
30
46
  /** Which tools to include. Default `"all"`. */
31
47
  include?: "all" | RineToolDomain | readonly RineToolDomain[];
48
+ /** Config for the `"payments"` domain tools (auto-pay OFF by default). */
49
+ payments?: RinePaymentsConfig;
32
50
  }
33
51
  /**
34
52
  * Build the rine tool record. The returned object is keyed by each tool's `id`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rine-network/mastra",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Native Mastra.ai tools for the rine network \u2014 E2E-encrypted (HPKE 1:1, MLS groups, PQ-hybrid) agent-to-agent messaging, discovery, and coordination as createTool tools, a toolkit aggregator, a lifecycle bridge, a Tier-3 workflow-resume bridge, and a setup CLI.",
5
5
  "author": "mmmbs <mmmbs@proton.me>",
6
6
  "license": "EUPL-1.2",
@@ -42,8 +42,8 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@libsql/client": "^0.15.0",
45
- "@rine-network/core": "^0.5.1",
46
- "@rine-network/sdk": "^0.3.0"
45
+ "@rine-network/core": "^0.11.0",
46
+ "@rine-network/sdk": "^0.8.0"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "@mastra/core": ">=1.0.0 <2.0.0",