@belticlabs/agent-risk-sdk 0.3.0 → 0.5.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/dist/{adapter-BEpzr2R3.d.ts → adapter-DEdhsNt-.d.ts} +3 -10
- package/dist/ai/index.d.ts +2 -2
- package/dist/ai/index.js +6 -8
- package/dist/{chunk-46QN2KEZ.js → chunk-4BUUPU3O.js} +0 -9
- package/dist/chunk-GM4KEEZB.js +163 -0
- package/dist/chunk-JSE6JQJC.js +530 -0
- package/dist/index.d.ts +11 -33
- package/dist/index.js +40 -335
- package/dist/protocol/index.d.ts +2 -2
- package/dist/protocol/index.js +1 -5
- package/dist/{session-DsBWEP8d.d.ts → session-D9E-efc0.d.ts} +74 -97
- package/dist/{verdict-6vCyoAHE.d.ts → verdict-DMnbFuS5.d.ts} +1 -17
- package/dist/x402/hono.d.ts +16 -5
- package/dist/x402/hono.js +14 -8
- package/dist/x402/index.d.ts +15 -27
- package/dist/x402/index.js +15 -59
- package/package.json +2 -30
- package/dist/chunk-4MG6VNAU.js +0 -276
- package/dist/chunk-7G5EHNVW.js +0 -17
- package/dist/chunk-FAQ442YH.js +0 -24
- package/dist/chunk-LM4NIYE5.js +0 -92
- package/dist/chunk-NJVO2WIV.js +0 -17
- package/dist/chunk-OKC6VMFH.js +0 -84
- package/dist/mcp/index.d.ts +0 -58
- package/dist/mcp/index.js +0 -135
- package/dist/middleware-9gI0ou2i.d.ts +0 -15
- package/dist/seller/anti-fraud-gateway.d.ts +0 -40
- package/dist/seller/anti-fraud-gateway.js +0 -38
- package/dist/x402/express.d.ts +0 -13
- package/dist/x402/express.js +0 -27
package/dist/x402/index.js
CHANGED
|
@@ -1,71 +1,54 @@
|
|
|
1
|
-
import {
|
|
2
|
-
attachX402
|
|
3
|
-
} from "../chunk-OKC6VMFH.js";
|
|
4
1
|
import {
|
|
5
2
|
Session,
|
|
6
3
|
Sessions
|
|
7
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-JSE6JQJC.js";
|
|
8
5
|
import {
|
|
9
6
|
DECISION_EXTENSION,
|
|
10
|
-
DECISION_HEADER,
|
|
11
7
|
SESSION_EXTENSION,
|
|
12
8
|
SESSION_HEADER,
|
|
9
|
+
attachX402,
|
|
13
10
|
decisionIdOf,
|
|
14
|
-
sessionIdOf
|
|
15
|
-
} from "../chunk-FAQ442YH.js";
|
|
16
|
-
import "../chunk-X3W2Z5GC.js";
|
|
17
|
-
import "../chunk-46QN2KEZ.js";
|
|
18
|
-
import {
|
|
19
11
|
payerOf,
|
|
12
|
+
sessionIdOf,
|
|
20
13
|
x402Currency,
|
|
21
14
|
x402Moments,
|
|
22
15
|
x402Summary
|
|
23
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-GM4KEEZB.js";
|
|
24
17
|
import "../chunk-FQDHFTVR.js";
|
|
18
|
+
import "../chunk-X3W2Z5GC.js";
|
|
25
19
|
|
|
26
20
|
// src/x402/fetch.ts
|
|
27
21
|
var BASE64 = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
28
|
-
var CHALLENGE_MEMORY = 32;
|
|
29
22
|
function belticFetch(source, inner = globalThis.fetch) {
|
|
30
|
-
if (!source) return inner;
|
|
31
23
|
const run = source instanceof Session ? null : source;
|
|
32
|
-
const challenges = /* @__PURE__ */ new Map();
|
|
33
24
|
return async (input, init) => {
|
|
34
25
|
const session = await Sessions.resolve(source);
|
|
35
26
|
if (!session) return inner(input, init);
|
|
36
|
-
const url = urlOf(input);
|
|
37
27
|
const headers = new Headers(
|
|
38
28
|
init?.headers ?? (input instanceof Request ? input.headers : void 0)
|
|
39
29
|
);
|
|
40
30
|
headers.set(SESSION_HEADER, session.id);
|
|
41
31
|
const signature = headers.get("PAYMENT-SIGNATURE");
|
|
42
|
-
const
|
|
43
|
-
const payload = presented ? decodeHeader(presented) : null;
|
|
32
|
+
const payload = signature ? decodeHeader(signature) : null;
|
|
44
33
|
if (payload) {
|
|
45
|
-
const
|
|
46
|
-
const decision = run?.decisionFor(x402Moments.payload(payload, accepts));
|
|
34
|
+
const decision = run?.decisionFor(x402Moments.payload(payload));
|
|
47
35
|
const decisionId = decision && !decision.absent ? decision.decisionId : null;
|
|
48
|
-
const bound =
|
|
36
|
+
const bound = {
|
|
49
37
|
...payload,
|
|
50
38
|
extensions: {
|
|
51
39
|
...payload.extensions,
|
|
52
40
|
[SESSION_EXTENSION]: session.id,
|
|
53
41
|
...decisionId ? { [DECISION_EXTENSION]: decisionId } : {}
|
|
54
42
|
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
await session.emit("payment.presented", x402Moments.payload(bound, accepts));
|
|
43
|
+
};
|
|
44
|
+
headers.set("PAYMENT-SIGNATURE", encodeHeader(bound));
|
|
45
|
+
await session.emit("payment.presented", x402Moments.payload(bound));
|
|
59
46
|
await session.flush();
|
|
60
47
|
}
|
|
61
48
|
const res = await inner(input, { ...init, headers });
|
|
62
49
|
if (res.status !== 402) return res;
|
|
63
|
-
const required =
|
|
64
|
-
if (required)
|
|
65
|
-
challenges.set(url, required);
|
|
66
|
-
if (challenges.size > CHALLENGE_MEMORY) challenges.delete(challenges.keys().next().value);
|
|
67
|
-
await session.emit("payment.requested", x402Moments.required(required));
|
|
68
|
-
}
|
|
50
|
+
const required = challengeOf(res);
|
|
51
|
+
if (required) await session.emit("payment.requested", x402Moments.required(required));
|
|
69
52
|
return res;
|
|
70
53
|
};
|
|
71
54
|
}
|
|
@@ -81,35 +64,9 @@ function decodeHeader(value) {
|
|
|
81
64
|
function encodeHeader(value) {
|
|
82
65
|
return Buffer.from(JSON.stringify(value), "utf8").toString("base64");
|
|
83
66
|
}
|
|
84
|
-
function
|
|
85
|
-
return typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
86
|
-
}
|
|
87
|
-
async function challengeOf(res) {
|
|
67
|
+
function challengeOf(res) {
|
|
88
68
|
const header = res.headers.get("PAYMENT-REQUIRED");
|
|
89
|
-
|
|
90
|
-
if (!/json/i.test(res.headers.get("content-type") ?? "")) return null;
|
|
91
|
-
try {
|
|
92
|
-
const body = await res.clone().json();
|
|
93
|
-
return Array.isArray(body?.accepts) ? body : null;
|
|
94
|
-
} catch {
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
function answeredAccepts(required, payload) {
|
|
99
|
-
const auth = payload.payload?.authorization;
|
|
100
|
-
const payTo = typeof auth?.to === "string" ? auth.to : void 0;
|
|
101
|
-
const amount = typeof auth?.value === "string" ? auth.value : void 0;
|
|
102
|
-
const options = required?.accepts ?? [];
|
|
103
|
-
const answered = options.find(
|
|
104
|
-
(a) => a.payTo?.toLowerCase() === payTo?.toLowerCase() && (a.amount ?? a.maxAmountRequired) === amount
|
|
105
|
-
) ?? options[0];
|
|
106
|
-
if (answered) return answered;
|
|
107
|
-
if (!payTo && !amount) return void 0;
|
|
108
|
-
return {
|
|
109
|
-
...payTo ? { payTo } : {},
|
|
110
|
-
...amount ? { amount } : {},
|
|
111
|
-
...payload.network ? { network: payload.network } : {}
|
|
112
|
-
};
|
|
69
|
+
return header ? decodeHeader(header) : null;
|
|
113
70
|
}
|
|
114
71
|
|
|
115
72
|
// src/x402/intent.ts
|
|
@@ -126,7 +83,6 @@ function x402Intent(input) {
|
|
|
126
83
|
}
|
|
127
84
|
export {
|
|
128
85
|
DECISION_EXTENSION,
|
|
129
|
-
DECISION_HEADER,
|
|
130
86
|
SESSION_EXTENSION,
|
|
131
87
|
SESSION_HEADER,
|
|
132
88
|
attachX402,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@belticlabs/agent-risk-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "The Beltic Agent Risk SDK — one client, two halves: instrument the buyer agent (AI SDK, x402 fetch
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "The Beltic Agent Risk SDK — one client, two halves: instrument the buyer agent (AI SDK, x402 fetch) and guard the seller boundary (x402 over hono, evaluate).",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -32,18 +32,6 @@
|
|
|
32
32
|
"types": "./dist/x402/hono.d.ts",
|
|
33
33
|
"default": "./dist/x402/hono.js"
|
|
34
34
|
},
|
|
35
|
-
"./express": {
|
|
36
|
-
"types": "./dist/x402/express.d.ts",
|
|
37
|
-
"default": "./dist/x402/express.js"
|
|
38
|
-
},
|
|
39
|
-
"./mcp": {
|
|
40
|
-
"types": "./dist/mcp/index.d.ts",
|
|
41
|
-
"default": "./dist/mcp/index.js"
|
|
42
|
-
},
|
|
43
|
-
"./platform-adapter": {
|
|
44
|
-
"types": "./dist/seller/anti-fraud-gateway.d.ts",
|
|
45
|
-
"default": "./dist/seller/anti-fraud-gateway.js"
|
|
46
|
-
},
|
|
47
35
|
"./package.json": "./package.json"
|
|
48
36
|
},
|
|
49
37
|
"files": [
|
|
@@ -57,45 +45,29 @@
|
|
|
57
45
|
"zod": "^4.6.5"
|
|
58
46
|
},
|
|
59
47
|
"peerDependencies": {
|
|
60
|
-
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
61
48
|
"@x402/core": "^2.25.0",
|
|
62
|
-
"@x402/express": "^2.25.0",
|
|
63
49
|
"@x402/hono": "^2.25.0",
|
|
64
50
|
"ai": "^7.0.0",
|
|
65
|
-
"express": "^5.0.0",
|
|
66
51
|
"hono": "^4.0.0"
|
|
67
52
|
},
|
|
68
53
|
"peerDependenciesMeta": {
|
|
69
|
-
"@modelcontextprotocol/sdk": {
|
|
70
|
-
"optional": true
|
|
71
|
-
},
|
|
72
54
|
"@x402/core": {
|
|
73
55
|
"optional": true
|
|
74
56
|
},
|
|
75
|
-
"@x402/express": {
|
|
76
|
-
"optional": true
|
|
77
|
-
},
|
|
78
57
|
"@x402/hono": {
|
|
79
58
|
"optional": true
|
|
80
59
|
},
|
|
81
60
|
"ai": {
|
|
82
61
|
"optional": true
|
|
83
62
|
},
|
|
84
|
-
"express": {
|
|
85
|
-
"optional": true
|
|
86
|
-
},
|
|
87
63
|
"hono": {
|
|
88
64
|
"optional": true
|
|
89
65
|
}
|
|
90
66
|
},
|
|
91
67
|
"devDependencies": {
|
|
92
|
-
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
93
|
-
"@types/express": "^5.0.6",
|
|
94
68
|
"@x402/core": "^2.25.0",
|
|
95
|
-
"@x402/express": "^2.25.0",
|
|
96
69
|
"@x402/hono": "^2.25.0",
|
|
97
70
|
"ai": "^7.0.100",
|
|
98
|
-
"express": "^5.2.1",
|
|
99
71
|
"hono": "^4.13.7",
|
|
100
72
|
"tsup": "8.5.1",
|
|
101
73
|
"typescript": "5.9.3",
|
package/dist/chunk-4MG6VNAU.js
DELETED
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Chain
|
|
3
|
-
} from "./chunk-X3W2Z5GC.js";
|
|
4
|
-
|
|
5
|
-
// src/core/disabled-error.ts
|
|
6
|
-
var BelticDisabledError = class extends Error {
|
|
7
|
-
code = "SDK_DISABLED";
|
|
8
|
-
constructor(entry) {
|
|
9
|
-
super(`${entry} needs a configured client: this Beltic is disabled (no BELTIC_* configured)`);
|
|
10
|
-
this.name = "BelticDisabledError";
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
// src/core/record.ts
|
|
15
|
-
function errorOf(err) {
|
|
16
|
-
const e = err;
|
|
17
|
-
return { name: String(e?.name ?? "Error"), message: String(e?.message ?? err) };
|
|
18
|
-
}
|
|
19
|
-
function openCall(session, kind, callId, start) {
|
|
20
|
-
const started = Date.now();
|
|
21
|
-
const opened = session.emit(`${kind}.start`, { callId, ...start });
|
|
22
|
-
const close = async (outcome) => {
|
|
23
|
-
await opened;
|
|
24
|
-
return session.emit(
|
|
25
|
-
`${kind}.end`,
|
|
26
|
-
{ callId, ...outcome, durationMs: Date.now() - started }
|
|
27
|
-
);
|
|
28
|
-
};
|
|
29
|
-
return {
|
|
30
|
-
callId,
|
|
31
|
-
opened,
|
|
32
|
-
end: (outcome = {}) => close(outcome),
|
|
33
|
-
fail: (error, outcome = {}) => close({ error: errorOf(error), ...outcome })
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
async function recordCall(session, kind, callId, start, run, end = () => ({})) {
|
|
37
|
-
const span = openCall(session, kind, callId, start);
|
|
38
|
-
await span.opened;
|
|
39
|
-
try {
|
|
40
|
-
const result = await run();
|
|
41
|
-
await span.end(await end(result));
|
|
42
|
-
return result;
|
|
43
|
-
} catch (err) {
|
|
44
|
-
await span.fail(err);
|
|
45
|
-
throw err;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// src/core/session.ts
|
|
50
|
-
var Session = class {
|
|
51
|
-
constructor(deps, id, source, expiresAt, born) {
|
|
52
|
-
this.deps = deps;
|
|
53
|
-
this.id = id;
|
|
54
|
-
this.source = source;
|
|
55
|
-
this.expiresAt = expiresAt;
|
|
56
|
-
this.born = born;
|
|
57
|
-
this.chain = Chain.genesis(id, source);
|
|
58
|
-
this.now = deps.now ?? (() => /* @__PURE__ */ new Date());
|
|
59
|
-
}
|
|
60
|
-
chain;
|
|
61
|
-
building = Promise.resolve();
|
|
62
|
-
dropped = 0;
|
|
63
|
-
droppedFirstTs = null;
|
|
64
|
-
droppedLastTs = null;
|
|
65
|
-
closed = false;
|
|
66
|
-
now;
|
|
67
|
-
get head() {
|
|
68
|
-
return this.chain.head;
|
|
69
|
-
}
|
|
70
|
-
get droppedCount() {
|
|
71
|
-
return this.dropped;
|
|
72
|
-
}
|
|
73
|
-
get isClosed() {
|
|
74
|
-
return this.closed;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Resolves once the event is sequenced and buffered — not once it is
|
|
78
|
-
* acknowledged. `false` when the event was dropped, or (fail-open) when
|
|
79
|
-
* the chain can no longer take it.
|
|
80
|
-
*/
|
|
81
|
-
async emit(kind, payload) {
|
|
82
|
-
if (!this.deps.failOpen) return this.chainEvent(kind, payload);
|
|
83
|
-
try {
|
|
84
|
-
return await this.chainEvent(kind, payload);
|
|
85
|
-
} catch (err) {
|
|
86
|
-
this.deps.onError?.(err);
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/** The tool call whose `execute` the host runs itself; see `ToolCallSpan`. */
|
|
91
|
-
toolCall(call) {
|
|
92
|
-
const { callId, ...start } = call;
|
|
93
|
-
return openCall(this, "tool_call", callId, { transport: "local", ...start });
|
|
94
|
-
}
|
|
95
|
-
async chainEvent(kind, payload) {
|
|
96
|
-
const halted = this.deps.transport.haltedError(this.id, this.source);
|
|
97
|
-
if (halted) throw halted;
|
|
98
|
-
const ts = this.now().toISOString();
|
|
99
|
-
if (!this.deps.transport.hasRoom()) {
|
|
100
|
-
this.dropped++;
|
|
101
|
-
this.droppedFirstTs ??= ts;
|
|
102
|
-
this.droppedLastTs = ts;
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
if (this.dropped > 0) {
|
|
106
|
-
this.deps.transport.enqueue(
|
|
107
|
-
await this.next(
|
|
108
|
-
"transport.gap",
|
|
109
|
-
{ dropped: this.dropped, firstTs: this.droppedFirstTs, lastTs: this.droppedLastTs },
|
|
110
|
-
ts
|
|
111
|
-
)
|
|
112
|
-
);
|
|
113
|
-
this.dropped = 0;
|
|
114
|
-
this.droppedFirstTs = this.droppedLastTs = null;
|
|
115
|
-
}
|
|
116
|
-
const body = payload;
|
|
117
|
-
this.deps.transport.enqueue(
|
|
118
|
-
await this.next(kind, this.deps.redact ? this.deps.redact(kind, body) : body, ts)
|
|
119
|
-
);
|
|
120
|
-
return true;
|
|
121
|
-
}
|
|
122
|
-
async close(reason = "completed", extra = {}) {
|
|
123
|
-
if (this.closed) return;
|
|
124
|
-
this.closed = true;
|
|
125
|
-
await this.emit("session.close", { reason, ...extra });
|
|
126
|
-
await this.flush();
|
|
127
|
-
this.deps.onClosed?.(this);
|
|
128
|
-
}
|
|
129
|
-
/** Read-your-writes: the platform must hold the evidence before anyone judges it (GAP-16/66). */
|
|
130
|
-
flush() {
|
|
131
|
-
return this.deps.transport.flush();
|
|
132
|
-
}
|
|
133
|
-
/** Serialized: two concurrent emits get consecutive seqs, never the same one. */
|
|
134
|
-
next(kind, payload, ts) {
|
|
135
|
-
const run = this.building.then(async () => {
|
|
136
|
-
const built = await this.chain.append({ ts, kind, payload }, this.deps.signer);
|
|
137
|
-
this.chain = built.chain;
|
|
138
|
-
return built.event;
|
|
139
|
-
});
|
|
140
|
-
this.building = run.catch(() => void 0);
|
|
141
|
-
return run;
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
var DEFAULT_OPEN_RETRY_MS = 6e4;
|
|
145
|
-
var Sessions = class {
|
|
146
|
-
constructor(deps) {
|
|
147
|
-
this.deps = deps;
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* One session object per (session, source) per process: a chain's head
|
|
151
|
-
* lives in it, so two objects for the same chain would both start at
|
|
152
|
-
* seq 0 and fork it. Closed sessions are forgotten; a process restart
|
|
153
|
-
* mid-session still loses the head (GAP-67).
|
|
154
|
-
*/
|
|
155
|
-
attached = /* @__PURE__ */ new Map();
|
|
156
|
-
/** Buyer sessions by the host's own key (GAP-71). */
|
|
157
|
-
opened = /* @__PURE__ */ new Map();
|
|
158
|
-
retryAt = 0;
|
|
159
|
-
/** The session behind a source: itself, or the one the run opens (null when there is none). */
|
|
160
|
-
static resolve(source) {
|
|
161
|
-
if (!source) return Promise.resolve(null);
|
|
162
|
-
return source instanceof Session ? Promise.resolve(source) : source.session();
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Buyer half: the evidence session for a key of the host's own (its
|
|
166
|
-
* session, run or conversation id), opened on first use and reused
|
|
167
|
-
* after. A halted chain is reopened as a fresh session that continues
|
|
168
|
-
* the same key; a closed key is forgotten. When the platform refuses to
|
|
169
|
-
* open one, a fail-open client resolves null — the host runs without
|
|
170
|
-
* evidence — until `openRetryMs` has passed (GAP-71); otherwise the
|
|
171
|
-
* refusal is thrown and the next call tries again. The identity is
|
|
172
|
-
* required either way: that is configuration.
|
|
173
|
-
*/
|
|
174
|
-
open(key, input = {}) {
|
|
175
|
-
if (this.deps.enabled === false) return Promise.resolve(null);
|
|
176
|
-
const prior = this.opened.get(key) ?? Promise.resolve(null);
|
|
177
|
-
const next = prior.catch(() => null).then(
|
|
178
|
-
(session) => session && !session.isClosed && !this.deps.transport.haltedError(session.id, session.source) ? session : this.openFresh(input, () => this.forget(key, next))
|
|
179
|
-
);
|
|
180
|
-
this.opened.set(key, next);
|
|
181
|
-
next.catch(() => this.forget(key, next));
|
|
182
|
-
return next;
|
|
183
|
-
}
|
|
184
|
-
forget(key, entry) {
|
|
185
|
-
if (this.opened.get(key) === entry) this.opened.delete(key);
|
|
186
|
-
}
|
|
187
|
-
async openFresh(input, onClosed) {
|
|
188
|
-
this.identityFor("open");
|
|
189
|
-
const create = async () => this.create(typeof input === "function" ? await input() : input, onClosed);
|
|
190
|
-
if (!this.deps.failOpen) return create();
|
|
191
|
-
if (Date.now() < this.retryAt) return null;
|
|
192
|
-
try {
|
|
193
|
-
const session = await create();
|
|
194
|
-
this.retryAt = 0;
|
|
195
|
-
return session;
|
|
196
|
-
} catch (err) {
|
|
197
|
-
this.retryAt = Date.now() + (this.deps.openRetryMs ?? DEFAULT_OPEN_RETRY_MS);
|
|
198
|
-
this.deps.onError?.(err);
|
|
199
|
-
return null;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
/** Buyer half: create an AGENT_TRACE session bound to the agent identity, then announce it on the chain. */
|
|
203
|
-
start(input = {}) {
|
|
204
|
-
if (this.deps.enabled === false)
|
|
205
|
-
return Promise.reject(new BelticDisabledError("sessions.start"));
|
|
206
|
-
return this.create(input);
|
|
207
|
-
}
|
|
208
|
-
identityFor(entry) {
|
|
209
|
-
const identity = this.deps.identity;
|
|
210
|
-
if (!identity)
|
|
211
|
-
throw new Error(`sessions.${entry} needs an agent identity (createBeltic({ identity }))`);
|
|
212
|
-
return identity;
|
|
213
|
-
}
|
|
214
|
-
async create(input, onClosed) {
|
|
215
|
-
const identity = this.identityFor("start");
|
|
216
|
-
const body = {
|
|
217
|
-
source: "AGENT_TRACE",
|
|
218
|
-
agent: { did: identity.did, credential: identity.credential ?? identity.did },
|
|
219
|
-
...input.intent ? { intent: input.intent } : {}
|
|
220
|
-
};
|
|
221
|
-
const out = await this.deps.api.post("/v1/sessions", body);
|
|
222
|
-
const session = this.attach(out.sessionId, "AGENT_TRACE", out.expiresAt, "buyer", onClosed);
|
|
223
|
-
await session.emit("session.open", {
|
|
224
|
-
runtime: {
|
|
225
|
-
sdk: "@belticlabs/agent-risk-sdk",
|
|
226
|
-
version: this.deps.sdkVersion,
|
|
227
|
-
...input.runtime
|
|
228
|
-
},
|
|
229
|
-
...input.attestations ? { attestations: input.attestations } : {}
|
|
230
|
-
});
|
|
231
|
-
if (input.intent) await session.emit("intent.declared", input.intent);
|
|
232
|
-
return session;
|
|
233
|
-
}
|
|
234
|
-
/** Seller half: emit INTERNAL_NETWORK evidence into a session the buyer bound, or open a seller-born one. */
|
|
235
|
-
async ensure(sessionId) {
|
|
236
|
-
if (this.deps.enabled === false) throw new BelticDisabledError("sessions.ensure");
|
|
237
|
-
if (sessionId) return this.attach(sessionId, "INTERNAL_NETWORK", null, "buyer");
|
|
238
|
-
const out = await this.deps.api.post("/v1/sessions", {
|
|
239
|
-
source: "INTERNAL_NETWORK"
|
|
240
|
-
});
|
|
241
|
-
return this.attach(out.sessionId, "INTERNAL_NETWORK", out.expiresAt, "seller");
|
|
242
|
-
}
|
|
243
|
-
attach(id, source, expiresAt, born, onClosed) {
|
|
244
|
-
const key = `${id}:${source}`;
|
|
245
|
-
const existing = this.attached.get(key);
|
|
246
|
-
if (existing) return existing;
|
|
247
|
-
const session = new Session(
|
|
248
|
-
{
|
|
249
|
-
transport: this.deps.transport,
|
|
250
|
-
signer: source === "AGENT_TRACE" ? this.deps.identity?.signer : void 0,
|
|
251
|
-
redact: this.deps.redact,
|
|
252
|
-
now: this.deps.now,
|
|
253
|
-
failOpen: this.deps.failOpen,
|
|
254
|
-
onError: this.deps.onError,
|
|
255
|
-
onClosed: () => {
|
|
256
|
-
this.attached.delete(key);
|
|
257
|
-
onClosed?.();
|
|
258
|
-
}
|
|
259
|
-
},
|
|
260
|
-
id,
|
|
261
|
-
source,
|
|
262
|
-
expiresAt,
|
|
263
|
-
born
|
|
264
|
-
);
|
|
265
|
-
this.attached.set(key, session);
|
|
266
|
-
return session;
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
export {
|
|
271
|
-
BelticDisabledError,
|
|
272
|
-
recordCall,
|
|
273
|
-
Session,
|
|
274
|
-
DEFAULT_OPEN_RETRY_MS,
|
|
275
|
-
Sessions
|
|
276
|
-
};
|
package/dist/chunk-7G5EHNVW.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
// src/core/payment-moment.ts
|
|
2
|
-
function summaryOf(m) {
|
|
3
|
-
return {
|
|
4
|
-
protocol: m.protocol,
|
|
5
|
-
payee: m.payee,
|
|
6
|
-
amount: { value: m.amount.value, currency: m.amount.currency },
|
|
7
|
-
...m.payer ? { payer: m.payer } : {}
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
function presentedFrom(summary, raw) {
|
|
11
|
-
return { ...summary, artifact: "payment-signature", raw };
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export {
|
|
15
|
-
summaryOf,
|
|
16
|
-
presentedFrom
|
|
17
|
-
};
|
package/dist/chunk-FAQ442YH.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
// src/x402/binding.ts
|
|
2
|
-
var SESSION_EXTENSION = "beltic.sessionId";
|
|
3
|
-
var SESSION_HEADER = "Beltic-Session-Id";
|
|
4
|
-
var DECISION_EXTENSION = "beltic.decisionId";
|
|
5
|
-
var DECISION_HEADER = "Beltic-Decision-Id";
|
|
6
|
-
function sessionIdOf(extensions) {
|
|
7
|
-
return stringAt(extensions, SESSION_EXTENSION);
|
|
8
|
-
}
|
|
9
|
-
function decisionIdOf(extensions) {
|
|
10
|
-
return stringAt(extensions, DECISION_EXTENSION);
|
|
11
|
-
}
|
|
12
|
-
function stringAt(extensions, key) {
|
|
13
|
-
const v = extensions?.[key];
|
|
14
|
-
return typeof v === "string" && v.length > 0 ? v : null;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export {
|
|
18
|
-
SESSION_EXTENSION,
|
|
19
|
-
SESSION_HEADER,
|
|
20
|
-
DECISION_EXTENSION,
|
|
21
|
-
DECISION_HEADER,
|
|
22
|
-
sessionIdOf,
|
|
23
|
-
decisionIdOf
|
|
24
|
-
};
|
package/dist/chunk-LM4NIYE5.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
toJsonObject
|
|
3
|
-
} from "./chunk-FQDHFTVR.js";
|
|
4
|
-
|
|
5
|
-
// src/x402/moments.ts
|
|
6
|
-
function x402Currency(network, asset) {
|
|
7
|
-
return `${network}/${asset}`;
|
|
8
|
-
}
|
|
9
|
-
function x402Summary(accepts, opts = {}) {
|
|
10
|
-
const payer = opts.payer?.toLowerCase();
|
|
11
|
-
return {
|
|
12
|
-
protocol: "x402",
|
|
13
|
-
payee: accepts?.payTo ?? "unknown",
|
|
14
|
-
amount: {
|
|
15
|
-
value: accepts?.amount ?? accepts?.maxAmountRequired ?? "0",
|
|
16
|
-
currency: accepts ? x402Currency(accepts.network ?? "unknown", accepts.asset ?? "unknown") : "unknown"
|
|
17
|
-
},
|
|
18
|
-
...payer ? { payer } : {}
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
function fromAccepts(a, artifact, raw, payer) {
|
|
22
|
-
return { ...x402Summary(a, { payer }), artifact, raw };
|
|
23
|
-
}
|
|
24
|
-
function payerOf(payload) {
|
|
25
|
-
const p = payload.payload ?? {};
|
|
26
|
-
const auth = p.authorization;
|
|
27
|
-
const candidates = [
|
|
28
|
-
auth?.from,
|
|
29
|
-
p.from,
|
|
30
|
-
p.payer,
|
|
31
|
-
p.signer,
|
|
32
|
-
p.permit?.owner
|
|
33
|
-
];
|
|
34
|
-
const hit = candidates.find((c) => typeof c === "string" && c.length > 0);
|
|
35
|
-
return typeof hit === "string" ? hit.toLowerCase() : void 0;
|
|
36
|
-
}
|
|
37
|
-
var x402Moments = {
|
|
38
|
-
/** The 402 challenge as the buyer saw it, v2 header or v1 body. */
|
|
39
|
-
required(required) {
|
|
40
|
-
return fromAccepts(required.accepts?.[0], "http-402", toJsonObject(required));
|
|
41
|
-
},
|
|
42
|
-
/** The requirements the seller's resource server resolved for a request. */
|
|
43
|
-
requirements(req) {
|
|
44
|
-
return fromAccepts(req, "http-402", toJsonObject(req));
|
|
45
|
-
},
|
|
46
|
-
/** A route's static `accepts` config, before any payment header exists. */
|
|
47
|
-
route(route, raw) {
|
|
48
|
-
const accepts = route ?? {};
|
|
49
|
-
const extra = accepts.extra;
|
|
50
|
-
return fromAccepts(
|
|
51
|
-
{
|
|
52
|
-
payTo: typeof accepts.payTo === "string" ? accepts.payTo : "dynamic",
|
|
53
|
-
amount: priceValue(accepts.price),
|
|
54
|
-
network: accepts.network,
|
|
55
|
-
asset: extra?.asset ?? "route"
|
|
56
|
-
},
|
|
57
|
-
"http-402",
|
|
58
|
-
raw
|
|
59
|
-
);
|
|
60
|
-
},
|
|
61
|
-
/** An in-band ask (MRTR `input_required` or a `_meta` envelope) carrying an x402-style `accepts`. */
|
|
62
|
-
ask(first, raw) {
|
|
63
|
-
return fromAccepts(first, "mrtr-input-required", raw);
|
|
64
|
-
},
|
|
65
|
-
/**
|
|
66
|
-
* The signed payment the buyer presented. A v2 payload carries the
|
|
67
|
-
* requirement it accepted; a v1 payload does not, so the caller passes
|
|
68
|
-
* the `accepts` entry it answered.
|
|
69
|
-
*/
|
|
70
|
-
payload(payload, accepts) {
|
|
71
|
-
return fromAccepts(
|
|
72
|
-
accepts ?? payload.accepted,
|
|
73
|
-
"payment-signature",
|
|
74
|
-
toJsonObject(payload),
|
|
75
|
-
payerOf(payload)
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
function priceValue(price) {
|
|
80
|
-
if (typeof price === "string") return price.replace(/[^0-9.]/g, "") || "0";
|
|
81
|
-
if (typeof price === "number") return String(price);
|
|
82
|
-
if (price && typeof price === "object" && typeof price.amount === "string")
|
|
83
|
-
return price.amount;
|
|
84
|
-
return "0";
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export {
|
|
88
|
-
x402Currency,
|
|
89
|
-
x402Summary,
|
|
90
|
-
payerOf,
|
|
91
|
-
x402Moments
|
|
92
|
-
};
|
package/dist/chunk-NJVO2WIV.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
attachX402
|
|
3
|
-
} from "./chunk-OKC6VMFH.js";
|
|
4
|
-
|
|
5
|
-
// src/x402/middleware.ts
|
|
6
|
-
import {
|
|
7
|
-
x402HTTPResourceServer
|
|
8
|
-
} from "@x402/core/server";
|
|
9
|
-
function guardedPaymentMiddleware(fromHTTPServer, beltic, routes, server, opts = {}) {
|
|
10
|
-
const http = new x402HTTPResourceServer(server, routes);
|
|
11
|
-
attachX402(beltic, server, http, opts);
|
|
12
|
-
return fromHTTPServer(http, opts.paywall);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export {
|
|
16
|
-
guardedPaymentMiddleware
|
|
17
|
-
};
|