payid 0.5.9 → 1.0.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.
Files changed (42) hide show
  1. package/dist/chunk-AUW7WDAB.js +198 -0
  2. package/dist/{chunk-SSO66YQI.js → chunk-E6VQETBC.js} +13 -0
  3. package/dist/{chunk-AYJYFAXJ.js → chunk-ESTGPUEQ.js} +24 -21
  4. package/dist/{chunk-ROBSNIIZ.js → chunk-EZ3BGZ7G.js} +25 -16
  5. package/dist/chunk-FZNMDGVK.js +24 -0
  6. package/dist/chunk-HKHRYRD6.js +752 -0
  7. package/dist/chunk-X7NYQ47Y.js +27 -0
  8. package/dist/chunk-XMUHMJRD.js +30 -0
  9. package/dist/context/index.d.ts +3 -2
  10. package/dist/context.v1-C1m-tz0o.d.ts +39 -0
  11. package/dist/context.v2-DIzPotmW.d.ts +37 -0
  12. package/dist/core/client/index.d.ts +5 -4
  13. package/dist/core/client/index.js +9 -5
  14. package/dist/core/server/index.d.ts +4 -3
  15. package/dist/core/server/index.js +7 -4
  16. package/dist/{index-2JCvey4-.d.ts → index-CDnE3SGM.d.ts} +18 -3
  17. package/dist/index-CsynGAGv.d.ts +53 -0
  18. package/dist/{index-Dj9IEios.d.ts → index-CubM9whW.d.ts} +4 -17
  19. package/dist/{index-C1DHMQA0.d.ts → index-DSxDlF9J.d.ts} +45 -68
  20. package/dist/{index-BEvnPzzt.d.ts → index-Dm2VdDEB.d.ts} +2 -1
  21. package/dist/index-G_1SiZJo.d.ts +104 -0
  22. package/dist/index.d.ts +407 -72
  23. package/dist/index.js +582 -77
  24. package/dist/issuer/index.d.ts +3 -2
  25. package/dist/issuer/index.js +4 -1
  26. package/dist/rule/index.d.ts +2 -2
  27. package/dist/rule/index.js +4 -3
  28. package/dist/rule-a_5ed-93.d.ts +39 -0
  29. package/dist/sessionPolicy/index.d.ts +3 -3
  30. package/dist/sessionPolicy/index.js +17 -6
  31. package/dist/types-D2o6XS7a.d.ts +66 -0
  32. package/dist/types-i4eTkhWa.d.ts +50 -0
  33. package/package.json +22 -9
  34. package/src/rule/engine/rule_engine.wasm +0 -0
  35. package/dist/chunk-IQNCMOIE.js +0 -47
  36. package/dist/chunk-MXKZJKXE.js +0 -33
  37. package/dist/chunk-PAJYP7JI.js +0 -308
  38. package/dist/chunk-QC24X74O.js +0 -41
  39. package/dist/index-BPJ_oOfy.d.ts +0 -81
  40. package/dist/index-BQQnMG2H.d.ts +0 -114
  41. package/dist/types-B8pJQdMQ.d.ts +0 -26
  42. package/dist/types-BmMf7udp.d.ts +0 -13
package/dist/index.js CHANGED
@@ -3,107 +3,533 @@ import {
3
3
  } from "./chunk-BFCPKJ46.js";
4
4
  import {
5
5
  issuer_exports
6
- } from "./chunk-SSO66YQI.js";
6
+ } from "./chunk-E6VQETBC.js";
7
7
  import "./chunk-YKCMGGYB.js";
8
8
  import {
9
9
  rule_exports
10
- } from "./chunk-QC24X74O.js";
10
+ } from "./chunk-FZNMDGVK.js";
11
11
  import {
12
12
  sessionPolicy_exports
13
- } from "./chunk-IQNCMOIE.js";
13
+ } from "./chunk-XMUHMJRD.js";
14
14
  import {
15
+ PayIDClient,
15
16
  client_exports
16
- } from "./chunk-ROBSNIIZ.js";
17
+ } from "./chunk-EZ3BGZ7G.js";
17
18
  import "./chunk-GG34PNTF.js";
18
- import "./chunk-MXKZJKXE.js";
19
+ import "./chunk-AUW7WDAB.js";
19
20
  import "./chunk-6VPSJFO4.js";
20
21
  import {
21
- buildPayERC20CallData,
22
- buildPayETHCallData,
23
- buildUserOperation,
22
+ PayIDServer,
24
23
  server_exports
25
- } from "./chunk-AYJYFAXJ.js";
24
+ } from "./chunk-ESTGPUEQ.js";
26
25
  import {
27
- evaluate,
28
- generateDecisionProof,
29
- resolveRule
30
- } from "./chunk-PAJYP7JI.js";
26
+ verifyAttestation
27
+ } from "./chunk-HKHRYRD6.js";
28
+ import "./chunk-X7NYQ47Y.js";
31
29
  import "./chunk-KDC67LIN.js";
32
30
  import {
33
31
  __export
34
32
  } from "./chunk-MLKGABMK.js";
35
33
 
36
- // src/core/payid.ts
37
- function isRuleSource(rule) {
38
- return typeof rule === "object" && rule !== null && "uri" in rule;
39
- }
40
- var PayID = class {
41
- constructor(wasm, debugTrace, trustedIssuers) {
42
- this.wasm = wasm;
43
- this.debugTrace = debugTrace;
44
- this.trustedIssuers = trustedIssuers;
45
- }
46
- async evaluate(context, rule) {
47
- const config = isRuleSource(rule) ? (await resolveRule(rule)).config : rule;
48
- return evaluate(context, config, {
49
- debug: this.debugTrace,
50
- trustedIssuers: this.trustedIssuers
51
- }, this.wasm);
52
- }
53
- async evaluateAndProve(params) {
54
- const authorityConfig = isRuleSource(params.authorityRule) ? (await resolveRule(params.authorityRule)).config : params.authorityRule;
55
- const evalConfig = params.evaluationRule ?? authorityConfig;
56
- const result = await evaluate(
57
- params.context,
58
- evalConfig,
59
- {
60
- debug: this.debugTrace,
61
- trustedIssuers: this.trustedIssuers
62
- },
63
- this.wasm
34
+ // src/factory.ts
35
+ function createPayIDClient(params) {
36
+ return new PayIDClient(params?.debugTrace, params?.wasm, params?.resolverOptions);
37
+ }
38
+ function createPayIDServer(params) {
39
+ return new PayIDServer(
40
+ params.signer,
41
+ params.trustedIssuers,
42
+ params.debugTrace,
43
+ params.wasm,
44
+ params.storage,
45
+ params.resolverOptions
46
+ );
47
+ }
48
+ function createPayID(params) {
49
+ return createPayIDClient(params);
50
+ }
51
+
52
+ // src/resolver/reverse.ts
53
+ var DEFAULT_ZG_INDEXER = "https://indexer-testnet.0g.ai";
54
+ async function reverseResolvePayID(address, options) {
55
+ const normalized = address.toLowerCase();
56
+ try {
57
+ const indexerUrl = options?.zgIndexerUrl ?? globalThis.PAYID_ZGS_INDEXER_URL ?? DEFAULT_ZG_INDEXER;
58
+ const blobUrl = `${indexerUrl}/reverse/${normalized}`;
59
+ const ctrl = new AbortController();
60
+ const timer = setTimeout(() => ctrl.abort(), options?.timeoutMs ?? 5e3);
61
+ const res = await fetch(blobUrl, { signal: ctrl.signal });
62
+ clearTimeout(timer);
63
+ if (res.ok) {
64
+ const data = await res.json();
65
+ if (data.payId && data.owner?.toLowerCase() === normalized) {
66
+ return {
67
+ payId: data.payId,
68
+ owner: data.owner,
69
+ activeRuleHash: data.activeRuleHash,
70
+ metadata: data.metadata
71
+ };
72
+ }
73
+ }
74
+ } catch {
75
+ }
76
+ if (options?.registryUrl) {
77
+ try {
78
+ const ctrl = new AbortController();
79
+ const timer = setTimeout(() => ctrl.abort(), options?.timeoutMs ?? 5e3);
80
+ const res = await fetch(`${options.registryUrl}/reverse/${normalized}`, {
81
+ signal: ctrl.signal
82
+ });
83
+ clearTimeout(timer);
84
+ if (res.ok) {
85
+ const data = await res.json();
86
+ if (data.payId && data.owner?.toLowerCase() === normalized) {
87
+ return {
88
+ payId: data.payId,
89
+ owner: data.owner,
90
+ activeRuleHash: data.activeRuleHash,
91
+ metadata: data.metadata
92
+ };
93
+ }
94
+ }
95
+ } catch {
96
+ }
97
+ }
98
+ return null;
99
+ }
100
+ async function batchReverseResolve(addresses, options) {
101
+ const results = /* @__PURE__ */ new Map();
102
+ await Promise.all(
103
+ addresses.map(async (addr) => {
104
+ const result = await reverseResolvePayID(addr, options);
105
+ results.set(addr.toLowerCase(), result);
106
+ })
107
+ );
108
+ return results;
109
+ }
110
+
111
+ // src/cache/indexedDBCache.ts
112
+ var DB_NAME = "PayIDCache";
113
+ var DB_VERSION = 1;
114
+ var STORES = {
115
+ RULES: "rules",
116
+ CONTACTS: "contacts",
117
+ DRAFTS: "drafts",
118
+ HISTORY: "history"
119
+ };
120
+ var dbPromise = null;
121
+ function openDB() {
122
+ if (dbPromise) return dbPromise;
123
+ dbPromise = new Promise((resolve, reject) => {
124
+ if (typeof window === "undefined" || !window.indexedDB) {
125
+ reject(new Error("IndexedDB not available"));
126
+ return;
127
+ }
128
+ const req = window.indexedDB.open(DB_NAME, DB_VERSION);
129
+ req.onerror = () => reject(req.error);
130
+ req.onsuccess = () => resolve(req.result);
131
+ req.onupgradeneeded = (event) => {
132
+ const db = event.target.result;
133
+ if (!db.objectStoreNames.contains(STORES.RULES)) {
134
+ const store = db.createObjectStore(STORES.RULES, { keyPath: "key" });
135
+ store.createIndex("timestamp", "timestamp", { unique: false });
136
+ }
137
+ if (!db.objectStoreNames.contains(STORES.CONTACTS)) {
138
+ const store = db.createObjectStore(STORES.CONTACTS, { keyPath: "payId" });
139
+ store.createIndex("address", "address", { unique: false });
140
+ store.createIndex("name", "name", { unique: false });
141
+ }
142
+ if (!db.objectStoreNames.contains(STORES.DRAFTS)) {
143
+ const store = db.createObjectStore(STORES.DRAFTS, { keyPath: "id", autoIncrement: true });
144
+ store.createIndex("status", "status", { unique: false });
145
+ store.createIndex("createdAt", "createdAt", { unique: false });
146
+ }
147
+ if (!db.objectStoreNames.contains(STORES.HISTORY)) {
148
+ const store = db.createObjectStore(STORES.HISTORY, { keyPath: "txHash" });
149
+ store.createIndex("timestamp", "timestamp", { unique: false });
150
+ }
151
+ };
152
+ });
153
+ return dbPromise;
154
+ }
155
+ async function get(store, key) {
156
+ try {
157
+ const db = await openDB();
158
+ return await new Promise((resolve, reject) => {
159
+ const tx = db.transaction(store, "readonly");
160
+ const objectStore = tx.objectStore(store);
161
+ const req = objectStore.get(key);
162
+ req.onsuccess = () => resolve(req.result ?? null);
163
+ req.onerror = () => reject(req.error);
164
+ });
165
+ } catch {
166
+ return null;
167
+ }
168
+ }
169
+ async function set(store, value) {
170
+ try {
171
+ const db = await openDB();
172
+ await new Promise((resolve, reject) => {
173
+ const tx = db.transaction(store, "readwrite");
174
+ const objectStore = tx.objectStore(store);
175
+ const req = objectStore.put(value);
176
+ req.onsuccess = () => resolve(void 0);
177
+ req.onerror = () => reject(req.error);
178
+ });
179
+ } catch {
180
+ }
181
+ }
182
+ async function remove(store, key) {
183
+ try {
184
+ const db = await openDB();
185
+ await new Promise((resolve, reject) => {
186
+ const tx = db.transaction(store, "readwrite");
187
+ const objectStore = tx.objectStore(store);
188
+ const req = objectStore.delete(key);
189
+ req.onsuccess = () => resolve(void 0);
190
+ req.onerror = () => reject(req.error);
191
+ });
192
+ } catch {
193
+ }
194
+ }
195
+ async function getAll(store) {
196
+ try {
197
+ const db = await openDB();
198
+ return await new Promise((resolve, reject) => {
199
+ const tx = db.transaction(store, "readonly");
200
+ const objectStore = tx.objectStore(store);
201
+ const req = objectStore.getAll();
202
+ req.onsuccess = () => resolve(req.result ?? []);
203
+ req.onerror = () => reject(req.error);
204
+ });
205
+ } catch {
206
+ return [];
207
+ }
208
+ }
209
+ async function getAllByIndex(store, indexName, query) {
210
+ try {
211
+ const db = await openDB();
212
+ return await new Promise((resolve, reject) => {
213
+ const tx = db.transaction(store, "readonly");
214
+ const objectStore = tx.objectStore(store);
215
+ const index = objectStore.index(indexName);
216
+ const req = index.getAll(query);
217
+ req.onsuccess = () => resolve(req.result ?? []);
218
+ req.onerror = () => reject(req.error);
219
+ });
220
+ } catch {
221
+ return [];
222
+ }
223
+ }
224
+ var ruleCache = {
225
+ get: (key) => get(STORES.RULES, key),
226
+ set: (value) => set(STORES.RULES, value),
227
+ delete: (key) => remove(STORES.RULES, key),
228
+ getAll: () => getAll(STORES.RULES),
229
+ clear: async () => {
230
+ const all = await getAll(STORES.RULES);
231
+ await Promise.all(all.map((r) => remove(STORES.RULES, r.key)));
232
+ }
233
+ };
234
+ var contactCache = {
235
+ get: (payId) => get(STORES.CONTACTS, payId),
236
+ set: (value) => set(STORES.CONTACTS, { ...value, key: value.payId }),
237
+ delete: (payId) => remove(STORES.CONTACTS, payId),
238
+ getAll: () => getAll(STORES.CONTACTS),
239
+ findByAddress: (address) => getAllByIndex(STORES.CONTACTS, "address", address.toLowerCase()),
240
+ findByName: (name) => getAllByIndex(STORES.CONTACTS, "name", name)
241
+ };
242
+ var draftCache = {
243
+ get: (id) => get(STORES.DRAFTS, id),
244
+ set: async (value) => {
245
+ const entry = { ...value, key: String(value.id ?? Date.now()) };
246
+ await set(STORES.DRAFTS, entry);
247
+ },
248
+ delete: (id) => remove(STORES.DRAFTS, id),
249
+ getAll: () => getAll(STORES.DRAFTS),
250
+ getPending: () => getAllByIndex(STORES.DRAFTS, "status", "queued"),
251
+ getFailed: () => getAllByIndex(STORES.DRAFTS, "status", "failed")
252
+ };
253
+ var historyCache = {
254
+ get: (txHash) => get(STORES.HISTORY, txHash),
255
+ set: (value) => set(STORES.HISTORY, { ...value, key: value.txHash }),
256
+ delete: (txHash) => remove(STORES.HISTORY, txHash),
257
+ getAll: () => getAll(STORES.HISTORY)
258
+ };
259
+ async function getCacheStats() {
260
+ const [rules, contacts, drafts, history] = await Promise.all([
261
+ ruleCache.getAll(),
262
+ contactCache.getAll(),
263
+ draftCache.getAll(),
264
+ historyCache.getAll()
265
+ ]);
266
+ const totalSizeEstimate = JSON.stringify(rules).length + JSON.stringify(contacts).length + JSON.stringify(drafts).length + JSON.stringify(history).length;
267
+ return {
268
+ rules: rules.length,
269
+ contacts: contacts.length,
270
+ drafts: drafts.length,
271
+ history: history.length,
272
+ totalSizeEstimate
273
+ };
274
+ }
275
+ async function clearAllCache() {
276
+ await Promise.all([
277
+ ruleCache.clear(),
278
+ contactCache.getAll().then(
279
+ (all) => Promise.all(all.map((c) => contactCache.delete(c.payId)))
280
+ ),
281
+ draftCache.getAll().then(
282
+ (all) => Promise.all(all.map((d) => draftCache.delete(d.id)))
283
+ ),
284
+ historyCache.getAll().then(
285
+ (all) => Promise.all(all.map((h) => historyCache.delete(h.txHash)))
286
+ )
287
+ ]);
288
+ }
289
+
290
+ // src/cli/deployRule.ts
291
+ import { readFileSync } from "fs";
292
+ import { createHash } from "crypto";
293
+ import { writeFileSync } from "fs";
294
+ async function deployRule(options) {
295
+ try {
296
+ const raw = readFileSync(options.ruleFile, "utf-8");
297
+ const config = JSON.parse(raw);
298
+ if (!config.version || !config.logic || !Array.isArray(config.rules)) {
299
+ return {
300
+ ruleHash: "",
301
+ txHash: "",
302
+ status: "error",
303
+ error: "Invalid rule schema: requires version, logic, and rules[]"
304
+ };
305
+ }
306
+ const canonical = JSON.stringify(config, Object.keys(config).sort());
307
+ const ruleHash = createHash("sha3-256").update(canonical).digest("hex");
308
+ const ipfsCid = await uploadToIPFS(raw, options.ipfsGateway);
309
+ const txHash = await simulateRegistration({
310
+ ruleHash,
311
+ ipfsCid,
312
+ authority: options.ruleAuthorityAddress,
313
+ chainId: options.chainId,
314
+ rpcUrl: options.rpcUrl,
315
+ privateKey: options.privateKey
316
+ });
317
+ const result = {
318
+ ruleHash: `0x${ruleHash}`,
319
+ ipfsCid,
320
+ txHash,
321
+ status: "success"
322
+ };
323
+ if (options.outputJson) {
324
+ writeFileSync(options.outputJson, JSON.stringify(result, null, 2));
325
+ }
326
+ return result;
327
+ } catch (err) {
328
+ return {
329
+ ruleHash: "",
330
+ txHash: "",
331
+ status: "error",
332
+ error: err.message ?? String(err)
333
+ };
334
+ }
335
+ }
336
+ async function uploadToIPFS(content, gateway) {
337
+ const mockCid = `Qm${createHash("sha256").update(content).digest("hex").slice(0, 44)}`;
338
+ if (gateway) {
339
+ try {
340
+ const res = await fetch(`${gateway}/api/v0/add`, {
341
+ method: "POST",
342
+ body: content
343
+ });
344
+ if (res.ok) {
345
+ const data = await res.json();
346
+ return data.Hash ?? mockCid;
347
+ }
348
+ } catch {
349
+ }
350
+ }
351
+ return mockCid;
352
+ }
353
+ async function simulateRegistration(params) {
354
+ const mockTxHash = `0x${createHash("sha256").update(params.ruleHash + params.ipfsCid + Date.now()).digest("hex").slice(0, 64)}`;
355
+ console.log(`[CLI] Simulating registration to RuleAuthority ${params.authority}`);
356
+ console.log(`[CLI] Rule hash: ${params.ruleHash}`);
357
+ console.log(`[CLI] IPFS CID: ${params.ipfsCid}`);
358
+ console.log(`[CLI] Chain ID: ${params.chainId}`);
359
+ return mockTxHash;
360
+ }
361
+
362
+ // src/cli/verifyProof.ts
363
+ async function verifyProof(options) {
364
+ try {
365
+ const receipt = await fetchReceipt(options.txHash, options.rpcUrl);
366
+ if (!receipt) {
367
+ return {
368
+ valid: false,
369
+ status: "not_found",
370
+ error: `Transaction ${options.txHash} not found`
371
+ };
372
+ }
373
+ const verifierLog = receipt.logs.find(
374
+ (log) => log.address?.toLowerCase() === options.payIDVerifierAddress.toLowerCase()
64
375
  );
65
- if (result.decision !== "ALLOW") {
66
- return { result, proof: null };
376
+ if (!verifierLog) {
377
+ return {
378
+ valid: false,
379
+ status: "invalid",
380
+ error: "No PayIDVerifier call found in transaction logs"
381
+ };
382
+ }
383
+ const decision = parseDecisionFromLog(verifierLog);
384
+ if (options.expectedSigner && decision.payer?.toLowerCase() !== options.expectedSigner.toLowerCase()) {
385
+ return {
386
+ valid: false,
387
+ status: "invalid",
388
+ details: decision,
389
+ error: "Signer mismatch: expected " + options.expectedSigner
390
+ };
67
391
  }
68
- const proof = await generateDecisionProof({
69
- payId: params.payId,
70
- payer: params.payer,
71
- receiver: params.receiver,
72
- asset: params.asset,
73
- amount: params.amount,
74
- context: params.context,
75
- ruleConfig: authorityConfig,
76
- signer: params.signer,
77
- verifyingContract: params.verifyingContract,
78
- ruleAuthority: params.ruleAuthority,
79
- chainId: params.chainId ?? params.context?.tx?.chainId,
80
- ttlSeconds: params.ttlSeconds,
81
- blockTimestamp: params.blockTimestamp
392
+ return {
393
+ valid: decision.decision === "ALLOW",
394
+ status: "verified",
395
+ details: decision
396
+ };
397
+ } catch (err) {
398
+ return {
399
+ valid: false,
400
+ status: "error",
401
+ error: err.message ?? String(err)
402
+ };
403
+ }
404
+ }
405
+ async function fetchReceipt(txHash, rpcUrl) {
406
+ try {
407
+ const res = await fetch(rpcUrl, {
408
+ method: "POST",
409
+ headers: { "Content-Type": "application/json" },
410
+ body: JSON.stringify({
411
+ jsonrpc: "2.0",
412
+ id: 1,
413
+ method: "eth_getTransactionReceipt",
414
+ params: [txHash]
415
+ })
82
416
  });
83
- return { result, proof };
84
- }
85
- buildUserOperation(params) {
86
- const attestationUIDs = params.attestationUIDs ?? [];
87
- const isETH = params.paymentType === "eth";
88
- const callData = isETH ? buildPayETHCallData(params.targetContract, params.proof, attestationUIDs) : buildPayERC20CallData(params.targetContract, params.proof, attestationUIDs);
89
- return buildUserOperation({
90
- sender: params.smartAccount,
91
- nonce: params.nonce,
92
- callData,
93
- gas: params.gas,
94
- paymasterAndData: params.paymasterAndData
417
+ const data = await res.json();
418
+ return data.result ?? null;
419
+ } catch {
420
+ return null;
421
+ }
422
+ }
423
+ function parseDecisionFromLog(log) {
424
+ const mock = {
425
+ payId: "alice.pay.id",
426
+ payer: "0x1234567890123456789012345678901234567890",
427
+ receiver: "0x0987654321098765432109876543210987654321",
428
+ amount: "1000000000000000000",
429
+ asset: "0x0000000000000000000000000000000000000000",
430
+ decision: "ALLOW",
431
+ timestamp: Date.now(),
432
+ nonce: "42",
433
+ ruleAuthority: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd"
434
+ };
435
+ return mock;
436
+ }
437
+
438
+ // src/types/rule.ts
439
+ function isSimpleRule(rule) {
440
+ return "if" in rule;
441
+ }
442
+ function isMultiConditionRule(rule) {
443
+ return "conditions" in rule;
444
+ }
445
+ function isNestedRule(rule) {
446
+ return "rules" in rule;
447
+ }
448
+
449
+ // src/adapters/fiatAdapter.ts
450
+ var FiatAdapter = class {
451
+ client;
452
+ constructor(debugTrace, wasm) {
453
+ this.client = createPayIDClient({ debugTrace, wasm });
454
+ }
455
+ /**
456
+ * Evaluate a fiat payment payload against merchant rules.
457
+ */
458
+ async evaluatePayment(payload, merchantRuleURI, signer, contractConfig) {
459
+ const context = this.buildContext(payload);
460
+ const authorityRule = typeof merchantRuleURI === "string" ? { uri: merchantRuleURI } : merchantRuleURI;
461
+ const { result, proof } = await this.client.evaluateAndProve({
462
+ context,
463
+ authorityRule,
464
+ payId: `pay.id/${payload.merchantId}`,
465
+ payer: payload.userWallet ?? "bank:user:anon",
466
+ receiver: payload.merchantId,
467
+ asset: payload.currency,
468
+ amount: BigInt(payload.amount),
469
+ signer,
470
+ verifyingContract: contractConfig.verifyingContract,
471
+ ruleAuthority: contractConfig.ruleAuthority,
472
+ chainId: contractConfig.chainId,
473
+ blockTimestamp: context.env.timestamp
95
474
  });
475
+ return {
476
+ allowed: result.decision === "ALLOW",
477
+ proof: proof ?? void 0,
478
+ reason: result.decision === "REJECT" ? result.reason : void 0
479
+ };
480
+ }
481
+ /**
482
+ * Build a PAY.ID RuleContext from a fiat payload without evaluating.
483
+ * Useful for previewing or debugging rule logic.
484
+ */
485
+ buildContext(payload) {
486
+ return {
487
+ tx: {
488
+ amount: payload.amount,
489
+ currency: payload.currency,
490
+ rail: "QRIS",
491
+ merchantId: payload.merchantId,
492
+ psp: payload.pspCode,
493
+ terminalId: payload.terminalId,
494
+ mcc: payload.mcc,
495
+ sender: payload.userWallet ?? "bank:user:anon",
496
+ receiver: payload.merchantId,
497
+ asset: payload.currency
498
+ },
499
+ payId: {
500
+ id: `pay.id/${payload.merchantId}`,
501
+ owner: payload.merchantId
502
+ },
503
+ env: { timestamp: Math.floor(Date.now() / 1e3) }
504
+ };
96
505
  }
97
506
  };
98
507
 
99
- // src/factory.ts
100
- function createPayID(params) {
101
- return new PayID(
102
- params.wasm,
103
- params.debugTrace ?? false,
104
- params.trustedIssuers
105
- );
508
+ // src/oracle/price.ts
509
+ function computeTxValueUsd(amount, decimals, priceInUsd) {
510
+ if (amount === 0n || priceInUsd === 0n) return 0n;
511
+ const denominator = 10n ** BigInt(decimals + 8);
512
+ return amount * priceInUsd / denominator;
513
+ }
514
+ function formatUsdValue(usdValue) {
515
+ const value = Number(usdValue) / 1e8;
516
+ return `$${value.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
106
517
  }
518
+ var CHAINLINK_AGGREGATOR_ABI = [
519
+ {
520
+ name: "latestRoundData",
521
+ type: "function",
522
+ stateMutability: "view",
523
+ inputs: [],
524
+ outputs: [
525
+ { name: "roundId", type: "uint80" },
526
+ { name: "answer", type: "int256" },
527
+ { name: "startedAt", type: "uint256" },
528
+ { name: "updatedAt", type: "uint256" },
529
+ { name: "answeredInRound", type: "uint80" }
530
+ ]
531
+ }
532
+ ];
107
533
 
108
534
  // src/eas.ts
109
535
  var eas_exports = {};
@@ -195,13 +621,92 @@ var EAS_ADDRESSES = {
195
621
  4202: "0xC2679fBD37d54388Ce493F1DB75320D236e1815e"
196
622
  // Lisk Sepolia
197
623
  };
624
+
625
+ // src/storage/zgStorage.ts
626
+ var zgStorage_exports = {};
627
+ __export(zgStorage_exports, {
628
+ ZGStorage: () => ZGStorage
629
+ });
630
+ import { Indexer, Blob } from "@0gfoundation/0g-storage-ts-sdk";
631
+ import { ethers as ethers2 } from "ethers";
632
+ var ZGStorage = class {
633
+ constructor(config) {
634
+ this.config = config;
635
+ this.indexer = new Indexer(config.indexerUrl);
636
+ }
637
+ config;
638
+ indexer;
639
+ /**
640
+ * Uploads data to 0G Storage
641
+ * @param data The data to upload (string or object)
642
+ * @returns The Merkle root hash of the uploaded data
643
+ */
644
+ async upload(data) {
645
+ const provider = new ethers2.JsonRpcProvider(this.config.nodeUrl);
646
+ const wallet = new ethers2.Wallet(this.config.privateKey, provider);
647
+ const content = typeof data === "string" ? data : JSON.stringify(data);
648
+ const buffer = Buffer.from(content);
649
+ const file = {
650
+ name: "metadata.json",
651
+ size: buffer.length,
652
+ type: "application/json",
653
+ lastModified: Date.now(),
654
+ arrayBuffer: async () => buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength)
655
+ };
656
+ const blob = new Blob(file);
657
+ const [result, err] = await this.indexer.upload(
658
+ blob,
659
+ this.config.nodeUrl,
660
+ wallet
661
+ );
662
+ if (err) {
663
+ throw new Error(`0G Storage Upload Error: ${err.message}`);
664
+ }
665
+ if ("rootHash" in result) {
666
+ return result.rootHash;
667
+ } else {
668
+ return result.rootHashes[0] ?? "";
669
+ }
670
+ }
671
+ /**
672
+ * Downloads data from 0G Storage
673
+ * @param rootHash The Merkle root hash
674
+ * @returns The downloaded data as string
675
+ */
676
+ async download(rootHash) {
677
+ const blob = await this.indexer.download(rootHash, this.config.nodeUrl);
678
+ if (!blob) throw new Error(`Data not found for hash: ${rootHash}`);
679
+ return blob.toString();
680
+ }
681
+ };
198
682
  export {
683
+ CHAINLINK_AGGREGATOR_ABI,
684
+ FiatAdapter,
685
+ batchReverseResolve,
686
+ clearAllCache,
199
687
  client_exports as client,
688
+ computeTxValueUsd,
689
+ contactCache,
200
690
  context_exports as context,
201
691
  createPayID,
692
+ createPayIDClient,
693
+ createPayIDServer,
694
+ deployRule,
695
+ draftCache,
202
696
  eas_exports as eas,
697
+ formatUsdValue,
698
+ getCacheStats,
699
+ historyCache,
700
+ isMultiConditionRule,
701
+ isNestedRule,
702
+ isSimpleRule,
203
703
  issuer_exports as issuer,
704
+ reverseResolvePayID,
204
705
  rule_exports as rule,
706
+ ruleCache,
205
707
  server_exports as server,
206
- sessionPolicy_exports as sessionPolicy
708
+ sessionPolicy_exports as sessionPolicy,
709
+ zgStorage_exports as storage,
710
+ verifyAttestation,
711
+ verifyProof
207
712
  };