kontext-sdk 0.6.0 → 0.7.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/index.mjs CHANGED
@@ -2,12 +2,229 @@ import { createHash } from 'crypto';
2
2
  import * as fs4 from 'fs';
3
3
  import * as path4 from 'path';
4
4
 
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
7
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
6
8
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
7
9
  }) : x)(function(x) {
8
10
  if (typeof require !== "undefined") return require.apply(this, arguments);
9
11
  throw Error('Dynamic require of "' + x + '" is not supported');
10
12
  });
13
+ var __esm = (fn, res) => function __init() {
14
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
15
+ };
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+
21
+ // src/onchain.ts
22
+ var onchain_exports = {};
23
+ __export(onchain_exports, {
24
+ OnChainExporter: () => OnChainExporter,
25
+ anchorDigest: () => anchorDigest,
26
+ getAnchor: () => getAnchor,
27
+ verifyAnchor: () => verifyAnchor
28
+ });
29
+ async function rpcCall(rpcUrl, method, params) {
30
+ const res = await fetch(rpcUrl, {
31
+ method: "POST",
32
+ headers: { "Content-Type": "application/json" },
33
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params })
34
+ });
35
+ const json = await res.json();
36
+ if (json.error) throw new Error(`RPC error: ${json.error.message}`);
37
+ return json.result;
38
+ }
39
+ function encodeBytes32(hex) {
40
+ const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
41
+ return clean.padStart(64, "0");
42
+ }
43
+ function decodeUint256(hex) {
44
+ const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
45
+ return parseInt(clean, 16);
46
+ }
47
+ function decodeAddress(hex) {
48
+ const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
49
+ return "0x" + clean.slice(24);
50
+ }
51
+ async function verifyAnchor(rpcUrl, contractAddress, digest) {
52
+ const calldata = SEL_VERIFY + encodeBytes32(digest);
53
+ const result = await rpcCall(rpcUrl, "eth_call", [
54
+ { to: contractAddress, data: calldata },
55
+ "latest"
56
+ ]);
57
+ const anchored = decodeUint256(result) !== 0;
58
+ return { anchored, digest };
59
+ }
60
+ async function getAnchor(rpcUrl, contractAddress, digest) {
61
+ const calldata = SEL_GET_ANCHOR + encodeBytes32(digest);
62
+ try {
63
+ const result = await rpcCall(rpcUrl, "eth_call", [
64
+ { to: contractAddress, data: calldata },
65
+ "latest"
66
+ ]);
67
+ const clean = result.startsWith("0x") ? result.slice(2) : result;
68
+ if (clean.length < 192) return null;
69
+ const anchorer = decodeAddress(clean.slice(0, 64));
70
+ const projectHash = "0x" + clean.slice(64, 128);
71
+ const timestamp = decodeUint256("0x" + clean.slice(128, 192));
72
+ return { anchorer, projectHash, timestamp };
73
+ } catch {
74
+ return null;
75
+ }
76
+ }
77
+ async function anchorDigest(config, digest, projectId) {
78
+ let viem;
79
+ let viemChains;
80
+ let viemAccounts;
81
+ try {
82
+ viem = await import('viem');
83
+ viemChains = await import('viem/chains');
84
+ viemAccounts = await import('viem/accounts');
85
+ } catch {
86
+ throw new Error(
87
+ "On-chain anchoring requires viem. Install it: npm install viem"
88
+ );
89
+ }
90
+ if (!config.privateKey) {
91
+ throw new Error("privateKey is required for on-chain anchoring");
92
+ }
93
+ const account = viemAccounts.privateKeyToAccount(config.privateKey);
94
+ const chain = config.rpcUrl.includes("sepolia") ? viemChains.baseSepolia : viemChains.base;
95
+ const client = viem.createWalletClient({
96
+ account,
97
+ chain,
98
+ transport: viem.http(config.rpcUrl)
99
+ });
100
+ const publicClient = viem.createPublicClient({
101
+ chain,
102
+ transport: viem.http(config.rpcUrl)
103
+ });
104
+ const projectHash = viem.keccak256(viem.toBytes(projectId));
105
+ const digestBytes32 = digest.startsWith("0x") ? digest : `0x${digest}`;
106
+ const abi = [
107
+ {
108
+ name: "anchor",
109
+ type: "function",
110
+ stateMutability: "nonpayable",
111
+ inputs: [
112
+ { name: "digest", type: "bytes32" },
113
+ { name: "projectHash", type: "bytes32" }
114
+ ],
115
+ outputs: []
116
+ }
117
+ ];
118
+ const txHash = await client.writeContract({
119
+ address: config.contractAddress,
120
+ abi,
121
+ functionName: "anchor",
122
+ args: [digestBytes32, projectHash]
123
+ });
124
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
125
+ return {
126
+ digest,
127
+ txHash,
128
+ blockNumber: Number(receipt.blockNumber),
129
+ timestamp: Math.floor(Date.now() / 1e3),
130
+ contractAddress: config.contractAddress,
131
+ chain: chain.name.toLowerCase()
132
+ };
133
+ }
134
+ var SEL_VERIFY, SEL_GET_ANCHOR, OnChainExporter;
135
+ var init_onchain = __esm({
136
+ "src/onchain.ts"() {
137
+ SEL_VERIFY = "0x75e36616";
138
+ SEL_GET_ANCHOR = "0x7feb51d9";
139
+ OnChainExporter = class {
140
+ config;
141
+ projectId;
142
+ batchSize;
143
+ getTerminalDigest;
144
+ eventCount = 0;
145
+ constructor(config, projectId, getTerminalDigest) {
146
+ this.config = config;
147
+ this.projectId = projectId;
148
+ this.batchSize = 10;
149
+ this.getTerminalDigest = getTerminalDigest;
150
+ }
151
+ async export(events) {
152
+ this.eventCount += events.length;
153
+ if (this.eventCount >= this.batchSize) {
154
+ const digest = this.getTerminalDigest();
155
+ await anchorDigest(this.config, digest, this.projectId);
156
+ this.eventCount = 0;
157
+ }
158
+ return { success: true, exportedCount: events.length };
159
+ }
160
+ async flush() {
161
+ if (this.eventCount > 0) {
162
+ const digest = this.getTerminalDigest();
163
+ await anchorDigest(this.config, digest, this.projectId);
164
+ this.eventCount = 0;
165
+ }
166
+ }
167
+ async shutdown() {
168
+ await this.flush();
169
+ }
170
+ };
171
+ }
172
+ });
173
+
174
+ // src/attestation.ts
175
+ var attestation_exports = {};
176
+ __export(attestation_exports, {
177
+ exchangeAttestation: () => exchangeAttestation,
178
+ fetchAgentCard: () => fetchAgentCard
179
+ });
180
+ async function fetchAgentCard(endpoint, timeoutMs = DEFAULT_TIMEOUT_MS) {
181
+ const url = `${endpoint.replace(/\/$/, "")}/.well-known/kontext.json`;
182
+ const response = await fetch(url, {
183
+ signal: AbortSignal.timeout(timeoutMs),
184
+ headers: { Accept: "application/json" }
185
+ });
186
+ if (!response.ok) {
187
+ throw new Error(`Failed to fetch agent card from ${url}: ${response.status}`);
188
+ }
189
+ return response.json();
190
+ }
191
+ async function exchangeAttestation(config, request) {
192
+ const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
193
+ const card = await fetchAgentCard(config.endpoint, timeoutMs);
194
+ if (config.agentId && card.agentId !== config.agentId) {
195
+ throw new Error(
196
+ `Agent ID mismatch: expected ${config.agentId}, got ${card.agentId}`
197
+ );
198
+ }
199
+ if (!card.capabilities.includes("attest")) {
200
+ throw new Error(
201
+ `Counterparty ${card.agentId} does not support attestation`
202
+ );
203
+ }
204
+ const attestUrl = `${config.endpoint.replace(/\/$/, "")}${card.attestEndpoint}`;
205
+ const response = await fetch(attestUrl, {
206
+ method: "POST",
207
+ headers: { "Content-Type": "application/json" },
208
+ body: JSON.stringify(request),
209
+ signal: AbortSignal.timeout(timeoutMs)
210
+ });
211
+ if (!response.ok) {
212
+ throw new Error(`Attestation request failed: ${response.status}`);
213
+ }
214
+ const result = await response.json();
215
+ return {
216
+ attested: result.attested,
217
+ digest: result.receiverDigest,
218
+ agentId: result.receiverAgentId,
219
+ timestamp: result.timestamp
220
+ };
221
+ }
222
+ var DEFAULT_TIMEOUT_MS;
223
+ var init_attestation = __esm({
224
+ "src/attestation.ts"() {
225
+ DEFAULT_TIMEOUT_MS = 1e4;
226
+ }
227
+ });
11
228
 
12
229
  // src/utils.ts
13
230
  function generateId() {
@@ -3755,6 +3972,24 @@ var Kontext = class _Kontext {
3755
3972
  const verification = this.verifyDigestChain();
3756
3973
  const chainLength = this.logger.getDigestChain().getChainLength();
3757
3974
  const terminalDigest = this.getTerminalDigest();
3975
+ let anchorProof;
3976
+ if (input.anchor) {
3977
+ const { anchorDigest: anchorDigest2 } = await Promise.resolve().then(() => (init_onchain(), onchain_exports));
3978
+ anchorProof = await anchorDigest2(input.anchor, terminalDigest, this.config.projectId);
3979
+ }
3980
+ let counterpartyResult;
3981
+ if (input.counterparty) {
3982
+ const { exchangeAttestation: exchangeAttestation2 } = await Promise.resolve().then(() => (init_attestation(), attestation_exports));
3983
+ counterpartyResult = await exchangeAttestation2(input.counterparty, {
3984
+ senderDigest: terminalDigest,
3985
+ senderAgentId: input.agentId,
3986
+ txHash: input.txHash,
3987
+ chain: input.chain,
3988
+ amount: input.amount,
3989
+ token: input.token,
3990
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
3991
+ });
3992
+ }
3758
3993
  let requiresApproval;
3759
3994
  let task;
3760
3995
  if (this.config.approvalThreshold) {
@@ -3796,7 +4031,9 @@ var Kontext = class _Kontext {
3796
4031
  valid: verification.valid
3797
4032
  },
3798
4033
  ...reasoningId ? { reasoningId } : {},
3799
- ...requiresApproval ? { requiresApproval, task } : {}
4034
+ ...requiresApproval ? { requiresApproval, task } : {},
4035
+ ...anchorProof ? { anchorProof } : {},
4036
+ ...counterpartyResult ? { counterparty: counterpartyResult } : {}
3800
4037
  };
3801
4038
  }
3802
4039
  // --------------------------------------------------------------------------
@@ -4177,6 +4414,10 @@ var FileStorage = class {
4177
4414
  }
4178
4415
  };
4179
4416
 
4180
- export { AnomalyDetector, ConsoleExporter, DigestChain, FeatureFlagManager, FileStorage, JsonFileExporter, Kontext, KontextError, KontextErrorCode, MemoryStorage, NoopExporter, PLAN_LIMITS, PaymentCompliance, PlanManager, TrustScorer, UsdcCompliance, isCryptoTransaction, isFeatureAvailable, requirePlan, verifyExportedChain };
4417
+ // src/index.ts
4418
+ init_onchain();
4419
+ init_attestation();
4420
+
4421
+ export { AnomalyDetector, ConsoleExporter, DigestChain, FeatureFlagManager, FileStorage, JsonFileExporter, Kontext, KontextError, KontextErrorCode, MemoryStorage, NoopExporter, OnChainExporter, PLAN_LIMITS, PaymentCompliance, PlanManager, TrustScorer, UsdcCompliance, anchorDigest, exchangeAttestation, fetchAgentCard, getAnchor, isCryptoTransaction, isFeatureAvailable, requirePlan, verifyAnchor, verifyExportedChain };
4181
4422
  //# sourceMappingURL=index.mjs.map
4182
4423
  //# sourceMappingURL=index.mjs.map