@invariance/sdk 0.0.1 → 0.1.1
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/{chunk-3ONNY6AX.js → chunk-2JGPNHE3.js} +1 -1
- package/dist/{chunk-3ONNY6AX.js.map → chunk-2JGPNHE3.js.map} +1 -1
- package/dist/{contract-helpers-XI4NOQLS.js → contract-helpers-2XZGNKCO.js} +2 -2
- package/dist/index.cjs +290 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +117 -4
- package/dist/index.d.ts +117 -4
- package/dist/index.js +282 -3
- package/dist/index.js.map +1 -1
- package/package.json +7 -3
- /package/dist/{contract-helpers-XI4NOQLS.js.map → contract-helpers-2XZGNKCO.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
pricingTypeToEnum,
|
|
37
37
|
toBytes32,
|
|
38
38
|
waitForReceipt
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-2JGPNHE3.js";
|
|
40
40
|
import {
|
|
41
41
|
InvarianceAtomicVerifierAbi,
|
|
42
42
|
InvarianceCompactLedgerAbi,
|
|
@@ -74,6 +74,7 @@ var ABI_MAP = {
|
|
|
74
74
|
atomicVerifier: InvarianceAtomicVerifierAbi,
|
|
75
75
|
voting: InvarianceVotingAbi
|
|
76
76
|
};
|
|
77
|
+
var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
77
78
|
var ADDRESS_KEY_MAP = {
|
|
78
79
|
identity: "identity",
|
|
79
80
|
policy: "policy",
|
|
@@ -167,6 +168,12 @@ var ContractFactory = class {
|
|
|
167
168
|
`Contract address not configured: ${name}`
|
|
168
169
|
);
|
|
169
170
|
}
|
|
171
|
+
if (addr === ZERO_ADDRESS) {
|
|
172
|
+
throw new InvarianceError(
|
|
173
|
+
ErrorCode.NETWORK_ERROR,
|
|
174
|
+
`Contract address for ${name} is the zero address. Contracts may not be deployed on this chain yet.`
|
|
175
|
+
);
|
|
176
|
+
}
|
|
170
177
|
return addr;
|
|
171
178
|
}
|
|
172
179
|
/**
|
|
@@ -5012,7 +5019,7 @@ var AutoBatchedEventLedgerCompact = class {
|
|
|
5012
5019
|
const optimistic = this.contracts.getConfirmation() === "optimistic";
|
|
5013
5020
|
const receiptClient = this.contracts.getReceiptClient();
|
|
5014
5021
|
const receipt = await waitForReceipt(receiptClient, txHash, { optimistic });
|
|
5015
|
-
const { parseCompactEntryIdFromLogs: parseCompactEntryIdFromLogs2 } = await import("./contract-helpers-
|
|
5022
|
+
const { parseCompactEntryIdFromLogs: parseCompactEntryIdFromLogs2 } = await import("./contract-helpers-2XZGNKCO.js");
|
|
5016
5023
|
const entryId = optimistic ? toBytes32(txHash) : parseCompactEntryIdFromLogs2(receipt.logs);
|
|
5017
5024
|
const explorerBase = this.contracts.getExplorerBaseUrl();
|
|
5018
5025
|
const result = {
|
|
@@ -8175,8 +8182,189 @@ var VotingManager = class {
|
|
|
8175
8182
|
}
|
|
8176
8183
|
};
|
|
8177
8184
|
|
|
8185
|
+
// src/modules/ledger/OffchainLedger.ts
|
|
8186
|
+
var OffchainLedger = class {
|
|
8187
|
+
events;
|
|
8188
|
+
telemetry;
|
|
8189
|
+
failOpen;
|
|
8190
|
+
adapter;
|
|
8191
|
+
constructor(events, telemetry, options) {
|
|
8192
|
+
this.events = events;
|
|
8193
|
+
this.telemetry = telemetry;
|
|
8194
|
+
this.adapter = options.adapter;
|
|
8195
|
+
this.failOpen = options.failOpen ?? true;
|
|
8196
|
+
}
|
|
8197
|
+
/**
|
|
8198
|
+
* Log a ledger event.
|
|
8199
|
+
*
|
|
8200
|
+
* @param event - Same `LedgerEventInput` used by on-chain ledger
|
|
8201
|
+
* @returns The created off-chain ledger entry
|
|
8202
|
+
*/
|
|
8203
|
+
async log(event) {
|
|
8204
|
+
this.telemetry.track("offchain_ledger.log", { action: event.action });
|
|
8205
|
+
const entryId = crypto.randomUUID();
|
|
8206
|
+
const timestamp = Date.now();
|
|
8207
|
+
const category = event.category ?? "custom";
|
|
8208
|
+
const severity = event.severity ?? "info";
|
|
8209
|
+
const entry = {
|
|
8210
|
+
entryId,
|
|
8211
|
+
action: event.action,
|
|
8212
|
+
actor: event.actor,
|
|
8213
|
+
category,
|
|
8214
|
+
severity,
|
|
8215
|
+
timestamp,
|
|
8216
|
+
createdAt: new Date(timestamp).toISOString()
|
|
8217
|
+
};
|
|
8218
|
+
if (event.metadata) {
|
|
8219
|
+
entry.metadata = event.metadata;
|
|
8220
|
+
}
|
|
8221
|
+
try {
|
|
8222
|
+
const persisted = await this.adapter.insert(entry);
|
|
8223
|
+
this.events.emit("ledger.logged", { entryId: persisted.entryId, action: persisted.action });
|
|
8224
|
+
return persisted;
|
|
8225
|
+
} catch (err) {
|
|
8226
|
+
if (this.failOpen) {
|
|
8227
|
+
this.events.emit("ledger.logged", { entryId: entry.entryId, action: entry.action });
|
|
8228
|
+
return entry;
|
|
8229
|
+
}
|
|
8230
|
+
throw err;
|
|
8231
|
+
}
|
|
8232
|
+
}
|
|
8233
|
+
/**
|
|
8234
|
+
* Query off-chain ledger entries.
|
|
8235
|
+
*
|
|
8236
|
+
* @param filters - Same `LedgerQueryFilters` used by on-chain ledger
|
|
8237
|
+
* @returns Matching off-chain ledger entries
|
|
8238
|
+
*/
|
|
8239
|
+
async query(filters) {
|
|
8240
|
+
this.telemetry.track("offchain_ledger.query", { action: filters.action });
|
|
8241
|
+
try {
|
|
8242
|
+
return await this.adapter.query(filters);
|
|
8243
|
+
} catch (err) {
|
|
8244
|
+
if (this.failOpen) {
|
|
8245
|
+
return [];
|
|
8246
|
+
}
|
|
8247
|
+
throw err;
|
|
8248
|
+
}
|
|
8249
|
+
}
|
|
8250
|
+
};
|
|
8251
|
+
|
|
8252
|
+
// src/modules/ledger/adapters/SupabaseLedgerAdapter.ts
|
|
8253
|
+
var TABLE_NAME = "offchain_ledger_entries";
|
|
8254
|
+
var SupabaseLedgerAdapter = class _SupabaseLedgerAdapter {
|
|
8255
|
+
url;
|
|
8256
|
+
key;
|
|
8257
|
+
client = null;
|
|
8258
|
+
clientPromise = null;
|
|
8259
|
+
constructor(options) {
|
|
8260
|
+
this.url = options.url;
|
|
8261
|
+
this.key = options.key;
|
|
8262
|
+
}
|
|
8263
|
+
/** @internal */
|
|
8264
|
+
async getClient() {
|
|
8265
|
+
if (this.client) return this.client;
|
|
8266
|
+
if (this.clientPromise) return this.clientPromise;
|
|
8267
|
+
this.clientPromise = (async () => {
|
|
8268
|
+
try {
|
|
8269
|
+
const { createClient } = await import("@supabase/supabase-js");
|
|
8270
|
+
this.client = createClient(this.url, this.key);
|
|
8271
|
+
return this.client;
|
|
8272
|
+
} catch {
|
|
8273
|
+
throw new InvarianceError(
|
|
8274
|
+
ErrorCode.NETWORK_ERROR,
|
|
8275
|
+
"Failed to import @supabase/supabase-js. Install it with: npm install @supabase/supabase-js"
|
|
8276
|
+
);
|
|
8277
|
+
}
|
|
8278
|
+
})();
|
|
8279
|
+
return this.clientPromise;
|
|
8280
|
+
}
|
|
8281
|
+
/** Persist a ledger entry to Supabase. */
|
|
8282
|
+
async insert(entry) {
|
|
8283
|
+
const row = {
|
|
8284
|
+
entry_id: entry.entryId,
|
|
8285
|
+
action: entry.action,
|
|
8286
|
+
actor_type: entry.actor.type,
|
|
8287
|
+
actor_address: entry.actor.address,
|
|
8288
|
+
category: entry.category,
|
|
8289
|
+
severity: entry.severity,
|
|
8290
|
+
metadata: entry.metadata ?? null,
|
|
8291
|
+
timestamp: entry.timestamp
|
|
8292
|
+
};
|
|
8293
|
+
const client = await this.getClient();
|
|
8294
|
+
const { data, error } = await client.from(TABLE_NAME).insert(row).select().single();
|
|
8295
|
+
if (error) {
|
|
8296
|
+
throw new InvarianceError(ErrorCode.NETWORK_ERROR, `Supabase insert failed: ${error.message}`);
|
|
8297
|
+
}
|
|
8298
|
+
return _SupabaseLedgerAdapter.toEntry(data);
|
|
8299
|
+
}
|
|
8300
|
+
/** Query ledger entries from Supabase. */
|
|
8301
|
+
async query(filters) {
|
|
8302
|
+
const client = await this.getClient();
|
|
8303
|
+
let q = client.from(TABLE_NAME).select("*");
|
|
8304
|
+
if (filters.actor) {
|
|
8305
|
+
q = q.eq("actor_address", filters.actor);
|
|
8306
|
+
}
|
|
8307
|
+
if (filters.actorType) {
|
|
8308
|
+
q = q.eq("actor_type", filters.actorType);
|
|
8309
|
+
}
|
|
8310
|
+
if (filters.action) {
|
|
8311
|
+
if (Array.isArray(filters.action)) {
|
|
8312
|
+
q = q.in("action", filters.action);
|
|
8313
|
+
} else {
|
|
8314
|
+
q = q.eq("action", filters.action);
|
|
8315
|
+
}
|
|
8316
|
+
}
|
|
8317
|
+
if (filters.category) {
|
|
8318
|
+
q = q.eq("category", filters.category);
|
|
8319
|
+
}
|
|
8320
|
+
if (filters.from !== void 0) {
|
|
8321
|
+
const fromTs = typeof filters.from === "string" ? new Date(filters.from).getTime() : filters.from;
|
|
8322
|
+
q = q.gte("timestamp", fromTs);
|
|
8323
|
+
}
|
|
8324
|
+
if (filters.to !== void 0) {
|
|
8325
|
+
const toTs = typeof filters.to === "string" ? new Date(filters.to).getTime() : filters.to;
|
|
8326
|
+
q = q.lte("timestamp", toTs);
|
|
8327
|
+
}
|
|
8328
|
+
const orderCol = filters.orderBy ?? "timestamp";
|
|
8329
|
+
const ascending = (filters.order ?? "desc") === "asc";
|
|
8330
|
+
q = q.order(orderCol, { ascending });
|
|
8331
|
+
if (filters.limit) {
|
|
8332
|
+
q = q.limit(filters.limit);
|
|
8333
|
+
}
|
|
8334
|
+
if (filters.offset) {
|
|
8335
|
+
q = q.range(filters.offset, filters.offset + (filters.limit ?? 100) - 1);
|
|
8336
|
+
}
|
|
8337
|
+
const { data, error } = await q;
|
|
8338
|
+
if (error) {
|
|
8339
|
+
throw new InvarianceError(ErrorCode.NETWORK_ERROR, `Supabase query failed: ${error.message}`);
|
|
8340
|
+
}
|
|
8341
|
+
return data.map(
|
|
8342
|
+
(row) => _SupabaseLedgerAdapter.toEntry(row)
|
|
8343
|
+
);
|
|
8344
|
+
}
|
|
8345
|
+
/** Map a Supabase row to an OffchainLedgerEntry. */
|
|
8346
|
+
static toEntry(row) {
|
|
8347
|
+
const entry = {
|
|
8348
|
+
entryId: row["entry_id"],
|
|
8349
|
+
action: row["action"],
|
|
8350
|
+
actor: {
|
|
8351
|
+
type: row["actor_type"],
|
|
8352
|
+
address: row["actor_address"]
|
|
8353
|
+
},
|
|
8354
|
+
category: row["category"],
|
|
8355
|
+
severity: row["severity"],
|
|
8356
|
+
timestamp: row["timestamp"],
|
|
8357
|
+
createdAt: row["created_at"]
|
|
8358
|
+
};
|
|
8359
|
+
if (row["metadata"] != null) {
|
|
8360
|
+
entry.metadata = row["metadata"];
|
|
8361
|
+
}
|
|
8362
|
+
return entry;
|
|
8363
|
+
}
|
|
8364
|
+
};
|
|
8365
|
+
|
|
8178
8366
|
// src/core/InvarianceClient.ts
|
|
8179
|
-
var SDK_VERSION = "0.
|
|
8367
|
+
var SDK_VERSION = "0.1.1";
|
|
8180
8368
|
var Invariance = class _Invariance {
|
|
8181
8369
|
config;
|
|
8182
8370
|
contracts;
|
|
@@ -8201,6 +8389,7 @@ var Invariance = class _Invariance {
|
|
|
8201
8389
|
_marketplace;
|
|
8202
8390
|
_auditTrail;
|
|
8203
8391
|
_voting;
|
|
8392
|
+
_ledgerOffchain;
|
|
8204
8393
|
// ===========================================================================
|
|
8205
8394
|
// Static Factory Methods
|
|
8206
8395
|
// ===========================================================================
|
|
@@ -8579,6 +8768,39 @@ var Invariance = class _Invariance {
|
|
|
8579
8768
|
}
|
|
8580
8769
|
return this._auditTrail;
|
|
8581
8770
|
}
|
|
8771
|
+
/**
|
|
8772
|
+
* Off-chain ledger module backed by a pluggable {@link LedgerAdapter}.
|
|
8773
|
+
*
|
|
8774
|
+
* Same `LedgerEventInput` interface as on-chain, zero gas.
|
|
8775
|
+
* Resolution order: `config.ledgerAdapter` > `config.supabase` > env vars.
|
|
8776
|
+
*
|
|
8777
|
+
* @example
|
|
8778
|
+
* ```typescript
|
|
8779
|
+
* const entry = await inv.ledgerOffchain.log({
|
|
8780
|
+
* action: 'model-inference',
|
|
8781
|
+
* actor: { type: 'agent', address: '0xBot' },
|
|
8782
|
+
* });
|
|
8783
|
+
* ```
|
|
8784
|
+
*/
|
|
8785
|
+
get ledgerOffchain() {
|
|
8786
|
+
if (!this._ledgerOffchain) {
|
|
8787
|
+
let adapter = this.config.ledgerAdapter;
|
|
8788
|
+
if (!adapter) {
|
|
8789
|
+
const url = this.config.supabase?.url ?? process.env["INVARIANCE_SUPABASE_URL"];
|
|
8790
|
+
const key = this.config.supabase?.key ?? process.env["INVARIANCE_SUPABASE_KEY"];
|
|
8791
|
+
if (!url || !key) {
|
|
8792
|
+
throw new InvarianceError(
|
|
8793
|
+
ErrorCode.INVALID_INPUT,
|
|
8794
|
+
"Off-chain ledger requires either config.ledgerAdapter, config.supabase (url + key), or INVARIANCE_SUPABASE_URL / INVARIANCE_SUPABASE_KEY env vars."
|
|
8795
|
+
);
|
|
8796
|
+
}
|
|
8797
|
+
adapter = new SupabaseLedgerAdapter({ url, key });
|
|
8798
|
+
}
|
|
8799
|
+
const failOpen = this.config.supabase?.failOpen ?? true;
|
|
8800
|
+
this._ledgerOffchain = new OffchainLedger(this.events, this.telemetry, { adapter, failOpen });
|
|
8801
|
+
}
|
|
8802
|
+
return this._ledgerOffchain;
|
|
8803
|
+
}
|
|
8582
8804
|
/**
|
|
8583
8805
|
* Off-chain batch voting with merkle root settlement.
|
|
8584
8806
|
*
|
|
@@ -9143,6 +9365,59 @@ var Invariance = class _Invariance {
|
|
|
9143
9365
|
}
|
|
9144
9366
|
};
|
|
9145
9367
|
|
|
9368
|
+
// src/modules/ledger/adapters/InMemoryLedgerAdapter.ts
|
|
9369
|
+
var InMemoryLedgerAdapter = class {
|
|
9370
|
+
/** @internal */
|
|
9371
|
+
entries = [];
|
|
9372
|
+
async insert(entry) {
|
|
9373
|
+
this.entries.push(entry);
|
|
9374
|
+
return entry;
|
|
9375
|
+
}
|
|
9376
|
+
async query(filters) {
|
|
9377
|
+
let results = [...this.entries];
|
|
9378
|
+
if (filters.actor) {
|
|
9379
|
+
results = results.filter((e) => e.actor.address === filters.actor);
|
|
9380
|
+
}
|
|
9381
|
+
if (filters.actorType) {
|
|
9382
|
+
results = results.filter((e) => e.actor.type === filters.actorType);
|
|
9383
|
+
}
|
|
9384
|
+
if (filters.action) {
|
|
9385
|
+
if (Array.isArray(filters.action)) {
|
|
9386
|
+
results = results.filter((e) => filters.action.includes(e.action));
|
|
9387
|
+
} else {
|
|
9388
|
+
results = results.filter((e) => e.action === filters.action);
|
|
9389
|
+
}
|
|
9390
|
+
}
|
|
9391
|
+
if (filters.category) {
|
|
9392
|
+
results = results.filter((e) => e.category === filters.category);
|
|
9393
|
+
}
|
|
9394
|
+
if (filters.from !== void 0) {
|
|
9395
|
+
const fromTs = typeof filters.from === "string" ? new Date(filters.from).getTime() : filters.from;
|
|
9396
|
+
results = results.filter((e) => e.timestamp >= fromTs);
|
|
9397
|
+
}
|
|
9398
|
+
if (filters.to !== void 0) {
|
|
9399
|
+
const toTs = typeof filters.to === "string" ? new Date(filters.to).getTime() : filters.to;
|
|
9400
|
+
results = results.filter((e) => e.timestamp <= toTs);
|
|
9401
|
+
}
|
|
9402
|
+
const ascending = (filters.order ?? "desc") === "asc";
|
|
9403
|
+
const orderBy = filters.orderBy ?? "timestamp";
|
|
9404
|
+
results.sort((a, b) => {
|
|
9405
|
+
const aVal = a[orderBy];
|
|
9406
|
+
const bVal = b[orderBy];
|
|
9407
|
+
if (aVal < bVal) return ascending ? -1 : 1;
|
|
9408
|
+
if (aVal > bVal) return ascending ? 1 : -1;
|
|
9409
|
+
return 0;
|
|
9410
|
+
});
|
|
9411
|
+
if (filters.offset) {
|
|
9412
|
+
results = results.slice(filters.offset);
|
|
9413
|
+
}
|
|
9414
|
+
if (filters.limit) {
|
|
9415
|
+
results = results.slice(0, filters.limit);
|
|
9416
|
+
}
|
|
9417
|
+
return results;
|
|
9418
|
+
}
|
|
9419
|
+
};
|
|
9420
|
+
|
|
9146
9421
|
// src/utils/webhook.ts
|
|
9147
9422
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
9148
9423
|
function verifyWebhookSignature(body, signature, secret) {
|
|
@@ -10104,6 +10379,7 @@ export {
|
|
|
10104
10379
|
GovernmentComplianceKit,
|
|
10105
10380
|
IdentityGatekeeper,
|
|
10106
10381
|
IdentityManager,
|
|
10382
|
+
InMemoryLedgerAdapter,
|
|
10107
10383
|
IntentProtocol,
|
|
10108
10384
|
Invariance,
|
|
10109
10385
|
InvarianceError,
|
|
@@ -10113,6 +10389,7 @@ export {
|
|
|
10113
10389
|
MarketplaceKit,
|
|
10114
10390
|
MarketplacePlugin,
|
|
10115
10391
|
MultiAgentComposer,
|
|
10392
|
+
OffchainLedger,
|
|
10116
10393
|
PipelineBuilder,
|
|
10117
10394
|
PolicyEngine,
|
|
10118
10395
|
ReputationBridge,
|
|
@@ -10121,8 +10398,10 @@ export {
|
|
|
10121
10398
|
SDK_VERSION,
|
|
10122
10399
|
SessionContext,
|
|
10123
10400
|
SocialGraphAdapter,
|
|
10401
|
+
SupabaseLedgerAdapter,
|
|
10124
10402
|
Telemetry,
|
|
10125
10403
|
Verifier,
|
|
10404
|
+
VotingManager,
|
|
10126
10405
|
WalletManager,
|
|
10127
10406
|
X402Manager,
|
|
10128
10407
|
generatePrivateKey2 as generatePrivateKey,
|