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.d.mts +156 -1
- package/dist/index.d.ts +156 -1
- package/dist/index.js +247 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +243 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -2
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
|
-
|
|
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
|