web3ql-client 1.2.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 (86) hide show
  1. package/README.md +66 -0
  2. package/contracts/PublicKeyRegistry.sol +87 -0
  3. package/dist/src/access.d.ts +176 -0
  4. package/dist/src/access.d.ts.map +1 -0
  5. package/dist/src/access.js +283 -0
  6. package/dist/src/access.js.map +1 -0
  7. package/dist/src/batch.d.ts +107 -0
  8. package/dist/src/batch.d.ts.map +1 -0
  9. package/dist/src/batch.js +188 -0
  10. package/dist/src/batch.js.map +1 -0
  11. package/dist/src/cli.d.ts +40 -0
  12. package/dist/src/cli.d.ts.map +1 -0
  13. package/dist/src/cli.js +361 -0
  14. package/dist/src/cli.js.map +1 -0
  15. package/dist/src/constraints.d.ts +126 -0
  16. package/dist/src/constraints.d.ts.map +1 -0
  17. package/dist/src/constraints.js +192 -0
  18. package/dist/src/constraints.js.map +1 -0
  19. package/dist/src/crypto.d.ts +118 -0
  20. package/dist/src/crypto.d.ts.map +1 -0
  21. package/dist/src/crypto.js +192 -0
  22. package/dist/src/crypto.js.map +1 -0
  23. package/dist/src/factory-client.d.ts +106 -0
  24. package/dist/src/factory-client.d.ts.map +1 -0
  25. package/dist/src/factory-client.js +202 -0
  26. package/dist/src/factory-client.js.map +1 -0
  27. package/dist/src/index-cache.d.ts +156 -0
  28. package/dist/src/index-cache.d.ts.map +1 -0
  29. package/dist/src/index-cache.js +265 -0
  30. package/dist/src/index-cache.js.map +1 -0
  31. package/dist/src/index.d.ts +60 -0
  32. package/dist/src/index.d.ts.map +1 -0
  33. package/dist/src/index.js +60 -0
  34. package/dist/src/index.js.map +1 -0
  35. package/dist/src/migrations.d.ts +114 -0
  36. package/dist/src/migrations.d.ts.map +1 -0
  37. package/dist/src/migrations.js +173 -0
  38. package/dist/src/migrations.js.map +1 -0
  39. package/dist/src/model.d.ts +198 -0
  40. package/dist/src/model.d.ts.map +1 -0
  41. package/dist/src/model.js +379 -0
  42. package/dist/src/model.js.map +1 -0
  43. package/dist/src/query.d.ts +155 -0
  44. package/dist/src/query.d.ts.map +1 -0
  45. package/dist/src/query.js +386 -0
  46. package/dist/src/query.js.map +1 -0
  47. package/dist/src/registry.d.ts +45 -0
  48. package/dist/src/registry.d.ts.map +1 -0
  49. package/dist/src/registry.js +80 -0
  50. package/dist/src/registry.js.map +1 -0
  51. package/dist/src/schema-manager.d.ts +109 -0
  52. package/dist/src/schema-manager.d.ts.map +1 -0
  53. package/dist/src/schema-manager.js +259 -0
  54. package/dist/src/schema-manager.js.map +1 -0
  55. package/dist/src/table-client.d.ts +156 -0
  56. package/dist/src/table-client.d.ts.map +1 -0
  57. package/dist/src/table-client.js +292 -0
  58. package/dist/src/table-client.js.map +1 -0
  59. package/dist/src/typed-table.d.ts +159 -0
  60. package/dist/src/typed-table.d.ts.map +1 -0
  61. package/dist/src/typed-table.js +246 -0
  62. package/dist/src/typed-table.js.map +1 -0
  63. package/dist/src/types.d.ts +48 -0
  64. package/dist/src/types.d.ts.map +1 -0
  65. package/dist/src/types.js +222 -0
  66. package/dist/src/types.js.map +1 -0
  67. package/keyManager.js +337 -0
  68. package/package.json +38 -0
  69. package/src/access.ts +421 -0
  70. package/src/batch.ts +259 -0
  71. package/src/cli.ts +349 -0
  72. package/src/constraints.ts +283 -0
  73. package/src/crypto.ts +239 -0
  74. package/src/factory-client.ts +237 -0
  75. package/src/index-cache.ts +351 -0
  76. package/src/index.ts +171 -0
  77. package/src/migrations.ts +215 -0
  78. package/src/model.ts +538 -0
  79. package/src/query.ts +508 -0
  80. package/src/registry.ts +100 -0
  81. package/src/schema-manager.ts +301 -0
  82. package/src/table-client.ts +393 -0
  83. package/src/typed-table.ts +340 -0
  84. package/src/types.ts +284 -0
  85. package/tsconfig.json +22 -0
  86. package/walletUtils.js +204 -0
@@ -0,0 +1,386 @@
1
+ /**
2
+ * @file query.ts
3
+ * @notice Web3QL v1.1 — client-side query engine.
4
+ *
5
+ * After decrypting records from the chain, this module provides:
6
+ * • WHERE filtering — eq, ne, gt, gte, lt, lte, in, notIn, like, between, isNull, isNotNull
7
+ * • ORDER BY — multi-column, ASC/DESC
8
+ * • LIMIT / OFFSET — pagination over decrypted records
9
+ * • SELECT projection — pick only specific fields
10
+ * • DISTINCT — deduplicate on a column value
11
+ * • COUNT / SUM / AVG / MIN / MAX / GROUP BY aggregations
12
+ *
13
+ * All operations run in-process on the decrypted plaintext — the chain
14
+ * sees only ciphertext. For large tables, use the relay-maintained index
15
+ * endpoint (v1.2) to avoid decrypting every record.
16
+ *
17
+ * Usage:
18
+ * ─────────────────────────────────────────────────────────────
19
+ * const results = query(records)
20
+ * .where('age', 'gt', 18n)
21
+ * .where('name', 'like', 'Ali%')
22
+ * .orderBy('age', 'asc')
23
+ * .limit(10)
24
+ * .select(['name', 'age'])
25
+ * .execute();
26
+ *
27
+ * const stats = query(records)
28
+ * .where('active', 'eq', true)
29
+ * .aggregate({ count: '*', avg: 'score', max: 'score' });
30
+ * ─────────────────────────────────────────────────────────────
31
+ */
32
+ // ─────────────────────────────────────────────────────────────
33
+ // Time-bucket helper
34
+ // ─────────────────────────────────────────────────────────────
35
+ function truncateTimestamp(ms, unit) {
36
+ const d = new Date(ms);
37
+ switch (unit) {
38
+ case 'minute':
39
+ d.setUTCSeconds(0, 0);
40
+ break;
41
+ case 'hour':
42
+ d.setUTCMinutes(0, 0, 0);
43
+ break;
44
+ case 'day':
45
+ d.setUTCHours(0, 0, 0, 0);
46
+ break;
47
+ case 'week': {
48
+ const dow = d.getUTCDay(); // 0=Sun
49
+ d.setUTCDate(d.getUTCDate() - dow);
50
+ d.setUTCHours(0, 0, 0, 0);
51
+ break;
52
+ }
53
+ case 'month':
54
+ d.setUTCDate(1);
55
+ d.setUTCHours(0, 0, 0, 0);
56
+ break;
57
+ case 'year':
58
+ d.setUTCMonth(0, 1);
59
+ d.setUTCHours(0, 0, 0, 0);
60
+ break;
61
+ }
62
+ return d.getTime();
63
+ }
64
+ // ─────────────────────────────────────────────────────────────
65
+ // HAVING filter
66
+ // ─────────────────────────────────────────────────────────────
67
+ function applyHaving(result, having) {
68
+ for (const h of having) {
69
+ const val = result[h.aggregate] ?? 0;
70
+ switch (h.op) {
71
+ case 'eq':
72
+ if (val !== h.value)
73
+ return false;
74
+ break;
75
+ case 'ne':
76
+ if (val === h.value)
77
+ return false;
78
+ break;
79
+ case 'gt':
80
+ if (val <= h.value)
81
+ return false;
82
+ break;
83
+ case 'gte':
84
+ if (val < h.value)
85
+ return false;
86
+ break;
87
+ case 'lt':
88
+ if (val >= h.value)
89
+ return false;
90
+ break;
91
+ case 'lte':
92
+ if (val > h.value)
93
+ return false;
94
+ break;
95
+ }
96
+ }
97
+ return true;
98
+ }
99
+ // ─────────────────────────────────────────────────────────────
100
+ // Predicate evaluator
101
+ // ─────────────────────────────────────────────────────────────
102
+ function likeToRegex(pattern, caseInsensitive) {
103
+ const escaped = pattern
104
+ .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
105
+ .replace(/%/g, '.*')
106
+ .replace(/_/g, '.');
107
+ return new RegExp(`^${escaped}$`, caseInsensitive ? 'i' : '');
108
+ }
109
+ function compare(a, b) {
110
+ if (a instanceof Date && b instanceof Date)
111
+ return a.getTime() - b.getTime();
112
+ if (typeof a === 'bigint' && typeof b === 'bigint')
113
+ return a < b ? -1 : a > b ? 1 : 0;
114
+ if (typeof a === 'number' && typeof b === 'number')
115
+ return a - b;
116
+ return String(a).localeCompare(String(b));
117
+ }
118
+ function applyWhere(row, clause) {
119
+ const rawVal = row[clause.field];
120
+ switch (clause.op) {
121
+ case 'eq': return rawVal === clause.value;
122
+ case 'ne': return rawVal !== clause.value;
123
+ case 'gt': return compare(rawVal, clause.value) > 0;
124
+ case 'gte': return compare(rawVal, clause.value) >= 0;
125
+ case 'lt': return compare(rawVal, clause.value) < 0;
126
+ case 'lte': return compare(rawVal, clause.value) <= 0;
127
+ case 'in': return (clause.values ?? []).includes(rawVal);
128
+ case 'notIn': return !(clause.values ?? []).includes(rawVal);
129
+ case 'like': return likeToRegex(String(clause.value), false).test(String(rawVal));
130
+ case 'ilike': return likeToRegex(String(clause.value), true).test(String(rawVal));
131
+ case 'between': {
132
+ const [lo, hi] = clause.range;
133
+ return compare(rawVal, lo) >= 0 && compare(rawVal, hi) <= 0;
134
+ }
135
+ case 'isNull': return rawVal === null || rawVal === undefined;
136
+ case 'isNotNull': return rawVal !== null && rawVal !== undefined;
137
+ default: return true;
138
+ }
139
+ }
140
+ // ─────────────────────────────────────────────────────────────
141
+ // QueryBuilder
142
+ // ─────────────────────────────────────────────────────────────
143
+ export class QueryBuilder {
144
+ _rows;
145
+ _wheres = [];
146
+ _orders = [];
147
+ _limitN;
148
+ _offsetN;
149
+ _fields;
150
+ _distinct;
151
+ _joins = [];
152
+ constructor(rows) {
153
+ this._rows = rows;
154
+ }
155
+ where(field, op, valueOrArr, _unused2) {
156
+ if (op === 'isNull' || op === 'isNotNull') {
157
+ this._wheres.push({ field, op });
158
+ }
159
+ else if (op === 'in' || op === 'notIn') {
160
+ this._wheres.push({ field, op, values: valueOrArr });
161
+ }
162
+ else if (op === 'between') {
163
+ this._wheres.push({ field, op, range: valueOrArr });
164
+ }
165
+ else {
166
+ this._wheres.push({ field, op, value: valueOrArr });
167
+ }
168
+ return this;
169
+ }
170
+ // ── Sorting ─────────────────────────────────────────────────
171
+ /** Add an ORDER BY clause. Multiple calls are applied in sequence. */
172
+ orderBy(field, direction = 'asc') {
173
+ this._orders.push({ field, direction });
174
+ return this;
175
+ }
176
+ // ── Pagination ──────────────────────────────────────────────
177
+ limit(n) { this._limitN = n; return this; }
178
+ offset(n) { this._offsetN = n; return this; }
179
+ // ── Projection ──────────────────────────────────────────────
180
+ /** Return only the specified fields from each row. */
181
+ select(fields) { this._fields = fields; return this; }
182
+ /** Deduplicate rows where `field` has the same value. */
183
+ distinct(field) { this._distinct = field; return this; }
184
+ // ── JOIN ────────────────────────────────────────────────────
185
+ /**
186
+ * Join this table with a `right` array on matching key columns.
187
+ *
188
+ * @example
189
+ * query(orders)
190
+ * .join('inner', users, { left: 'userId', right: 'id' })
191
+ * .execute()
192
+ * // Each matched row = order fields + user fields prefixed with 'j_'
193
+ *
194
+ * query(orders)
195
+ * .join('left', users, { left: 'userId', right: 'id' }, 'user_')
196
+ * .select(['id', 'user_name', 'amount'])
197
+ * .execute()
198
+ */
199
+ join(type, right, on, prefix = 'j_') {
200
+ this._joins.push({ type, right, on, prefix });
201
+ return this;
202
+ }
203
+ // ── Terminal: execute ───────────────────────────────────────
204
+ execute() {
205
+ // 0. Apply JOINs
206
+ let rows = [...this._rows];
207
+ for (const j of this._joins) {
208
+ rows = applyJoin(rows, j);
209
+ }
210
+ // 1. Filter
211
+ rows = this._wheres.length
212
+ ? rows.filter((r) => this._wheres.every((w) => applyWhere(r, w)))
213
+ : rows;
214
+ // 2. Distinct
215
+ if (this._distinct) {
216
+ const seen = new Set();
217
+ const field = this._distinct;
218
+ rows = rows.filter((r) => {
219
+ const v = r[field];
220
+ if (seen.has(v))
221
+ return false;
222
+ seen.add(v);
223
+ return true;
224
+ });
225
+ }
226
+ // 3. Sort
227
+ if (this._orders.length) {
228
+ rows.sort((a, b) => {
229
+ for (const ord of this._orders) {
230
+ const cmp = compare(a[ord.field], b[ord.field]);
231
+ if (cmp !== 0)
232
+ return ord.direction === 'asc' ? cmp : -cmp;
233
+ }
234
+ return 0;
235
+ });
236
+ }
237
+ // 4. Offset + Limit
238
+ const start = this._offsetN ?? 0;
239
+ const end = this._limitN != null ? start + this._limitN : undefined;
240
+ rows = rows.slice(start, end);
241
+ // 5. Projection
242
+ if (this._fields) {
243
+ const fields = this._fields;
244
+ return rows.map((r) => {
245
+ const out = {};
246
+ for (const f of fields)
247
+ out[f] = r[f];
248
+ return out;
249
+ });
250
+ }
251
+ return rows;
252
+ }
253
+ // ── Terminal: aggregate ─────────────────────────────────────
254
+ /**
255
+ * Run aggregation functions over filtered (but not sorted/limited) rows.
256
+ *
257
+ * @example
258
+ * query(rows).where('active', 'eq', true).aggregate({ count: '*', avg: 'score' })
259
+ * // => [{ count: 42, avg: 78.5 }]
260
+ *
261
+ * query(rows).aggregate({ count: '*', groupBy: 'status' })
262
+ * // => [{ group: 'active', count: 30 }, { group: 'inactive', count: 12 }]
263
+ */
264
+ aggregate(opts) {
265
+ // Apply JOINs first
266
+ let allRows = [...this._rows];
267
+ for (const j of this._joins)
268
+ allRows = applyJoin(allRows, j);
269
+ const filtered = this._wheres.length
270
+ ? allRows.filter((r) => this._wheres.every((w) => applyWhere(r, w)))
271
+ : allRows;
272
+ // Determine grouping key
273
+ const getGroupKey = (row) => {
274
+ if (opts.timeBucket) {
275
+ const rawMs = Number(row[opts.timeBucket.field]);
276
+ return truncateTimestamp(rawMs, opts.timeBucket.unit);
277
+ }
278
+ if (opts.groupBy)
279
+ return row[opts.groupBy];
280
+ return '__all__';
281
+ };
282
+ const groups = new Map();
283
+ for (const row of filtered) {
284
+ const gv = getGroupKey(row);
285
+ const bucket = groups.get(gv);
286
+ if (bucket)
287
+ bucket.push(row);
288
+ else
289
+ groups.set(gv, [row]);
290
+ }
291
+ const noGroupBy = !opts.groupBy && !opts.timeBucket;
292
+ if (noGroupBy) {
293
+ return [this._aggregateGroup('__all__', filtered, opts, noGroupBy)];
294
+ }
295
+ const results = Array.from(groups.entries()).map(([groupVal, rows]) => this._aggregateGroup(groupVal, rows, opts, false));
296
+ // Apply HAVING filter
297
+ if (opts.having?.length) {
298
+ return results.filter((r) => applyHaving(r, opts.having));
299
+ }
300
+ return results;
301
+ }
302
+ _aggregateGroup(groupVal, rows, opts, omitGroup) {
303
+ const result = {};
304
+ if (!omitGroup)
305
+ result.group = groupVal;
306
+ if (opts.count != null) {
307
+ result.count = rows.length;
308
+ }
309
+ if (opts.sum) {
310
+ result.sum = rows.reduce((acc, r) => acc + Number(r[opts.sum] ?? 0), 0);
311
+ }
312
+ if (opts.avg) {
313
+ result.avg = rows.length
314
+ ? rows.reduce((acc, r) => acc + Number(r[opts.avg] ?? 0), 0) / rows.length
315
+ : 0;
316
+ }
317
+ if (opts.min) {
318
+ const vals = rows.map((r) => r[opts.min]).filter((v) => v != null);
319
+ result.min = vals.reduce((a, b) => (compare(a, b) <= 0 ? a : b), vals[0]);
320
+ }
321
+ if (opts.max) {
322
+ const vals = rows.map((r) => r[opts.max]).filter((v) => v != null);
323
+ result.max = vals.reduce((a, b) => (compare(a, b) >= 0 ? a : b), vals[0]);
324
+ }
325
+ return result;
326
+ }
327
+ }
328
+ // ─────────────────────────────────────────────────────────────
329
+ // JOIN implementation
330
+ // ─────────────────────────────────────────────────────────────
331
+ function applyJoin(left, j) {
332
+ const prefix = j.prefix ?? 'j_';
333
+ const rightIndex = new Map();
334
+ for (const r of j.right) {
335
+ const k = r[j.on.right];
336
+ const bucket = rightIndex.get(k);
337
+ if (bucket)
338
+ bucket.push(r);
339
+ else
340
+ rightIndex.set(k, [r]);
341
+ }
342
+ const result = [];
343
+ for (const l of left) {
344
+ const k = l[j.on.left];
345
+ const matches = rightIndex.get(k);
346
+ if (matches && matches.length > 0) {
347
+ // INNER or LEFT: emit for each match
348
+ for (const r of matches) {
349
+ const merged = { ...l };
350
+ for (const [rk, rv] of Object.entries(r)) {
351
+ merged[`${prefix}${rk}`] = rv;
352
+ }
353
+ result.push(merged);
354
+ }
355
+ }
356
+ else {
357
+ // LEFT JOIN: emit left row with nulled right fields
358
+ if (j.type === 'left') {
359
+ result.push({ ...l });
360
+ }
361
+ // INNER JOIN: no match → skip
362
+ }
363
+ }
364
+ // RIGHT JOIN: also emit right rows with no match on left
365
+ if (j.type === 'right') {
366
+ const leftKeys = new Set(left.map((l) => l[j.on.left]));
367
+ for (const r of j.right) {
368
+ if (!leftKeys.has(r[j.on.right])) {
369
+ const merged = {};
370
+ for (const [rk, rv] of Object.entries(r)) {
371
+ merged[`${prefix}${rk}`] = rv;
372
+ }
373
+ result.push(merged);
374
+ }
375
+ }
376
+ }
377
+ return result;
378
+ }
379
+ // ─────────────────────────────────────────────────────────────
380
+ // Factory helper
381
+ // ─────────────────────────────────────────────────────────────
382
+ /** Fluent entry point: `query(records).where(...).orderBy(...).execute()` */
383
+ export function query(rows) {
384
+ return new QueryBuilder(rows);
385
+ }
386
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @file registry.ts
3
+ * @notice Client for the on-chain PublicKeyRegistry contract.
4
+ *
5
+ * Why is a registry needed?
6
+ * ─────────────────────────────────────────────────────────────
7
+ * When the owner wants to share a record with Alice, they need
8
+ * Alice's X25519 public key to encrypt the symmetric key for her.
9
+ * The registry is a simple on-chain mapping (address → bytes32)
10
+ * where each user registers their own encryption public key once,
11
+ * paying only ~40k gas. After that anyone can look it up.
12
+ *
13
+ * Security note:
14
+ * The public key stored here is the X25519 key DERIVED from the
15
+ * Ethereum private key (sha256(ethPrivKey) → nacl keypair).
16
+ * It does NOT expose the Ethereum private key in any way.
17
+ */
18
+ import { ethers } from 'ethers';
19
+ import type { EncryptionKeypair } from './crypto.js';
20
+ export declare class PublicKeyRegistryClient {
21
+ private contract;
22
+ constructor(registryAddress: string, signerOrProvider: ethers.Signer | ethers.Provider);
23
+ /**
24
+ * Register the caller's encryption public key on-chain.
25
+ * Call this once per wallet — ~40k gas on Celo (~$0.001).
26
+ *
27
+ * @param keypair Your EncryptionKeypair from deriveKeypairFromWallet(signer).
28
+ */
29
+ register(keypair: EncryptionKeypair): Promise<ethers.TransactionReceipt>;
30
+ /**
31
+ * Check whether an address has registered a public key.
32
+ */
33
+ hasKey(address: string): Promise<boolean>;
34
+ /**
35
+ * Get the X25519 public key for an address.
36
+ * Throws if the address has not registered.
37
+ */
38
+ getPublicKey(address: string): Promise<Uint8Array>;
39
+ /**
40
+ * Get public keys for multiple addresses in a single batch of calls.
41
+ * Returns `null` for any address that has not registered.
42
+ */
43
+ getPublicKeys(addresses: string[]): Promise<(Uint8Array | null)[]>;
44
+ }
45
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAoC,QAAQ,CAAC;AAE9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAoB,aAAa,CAAC;AAiBnE,qBAAa,uBAAuB;IAClC,OAAO,CAAC,QAAQ,CAAkB;gBAGhC,eAAe,EAAQ,MAAM,EAC7B,gBAAgB,EAAO,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ;IASxD;;;;;OAKG;IACG,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC;IAO9E;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK/C;;;OAGG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAMxD;;;OAGG;IACG,aAAa,CACjB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC;CAWlC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @file registry.ts
3
+ * @notice Client for the on-chain PublicKeyRegistry contract.
4
+ *
5
+ * Why is a registry needed?
6
+ * ─────────────────────────────────────────────────────────────
7
+ * When the owner wants to share a record with Alice, they need
8
+ * Alice's X25519 public key to encrypt the symmetric key for her.
9
+ * The registry is a simple on-chain mapping (address → bytes32)
10
+ * where each user registers their own encryption public key once,
11
+ * paying only ~40k gas. After that anyone can look it up.
12
+ *
13
+ * Security note:
14
+ * The public key stored here is the X25519 key DERIVED from the
15
+ * Ethereum private key (sha256(ethPrivKey) → nacl keypair).
16
+ * It does NOT expose the Ethereum private key in any way.
17
+ */
18
+ import { ethers } from 'ethers';
19
+ import { publicKeyToHex, hexToPublicKey } from './crypto.js';
20
+ // ─────────────────────────────────────────────────────────────
21
+ // ABI — only what we need
22
+ // ─────────────────────────────────────────────────────────────
23
+ const REGISTRY_ABI = [
24
+ 'function register(bytes32 pubKey) external',
25
+ 'function getKey(address user) external view returns (bytes32)',
26
+ 'function hasKey(address user) external view returns (bool)',
27
+ 'event KeyRegistered(address indexed user, bytes32 publicKey)',
28
+ ];
29
+ // ─────────────────────────────────────────────────────────────
30
+ // Client
31
+ // ─────────────────────────────────────────────────────────────
32
+ export class PublicKeyRegistryClient {
33
+ contract;
34
+ constructor(registryAddress, signerOrProvider) {
35
+ this.contract = new ethers.Contract(registryAddress, REGISTRY_ABI, signerOrProvider);
36
+ }
37
+ /**
38
+ * Register the caller's encryption public key on-chain.
39
+ * Call this once per wallet — ~40k gas on Celo (~$0.001).
40
+ *
41
+ * @param keypair Your EncryptionKeypair from deriveKeypairFromWallet(signer).
42
+ */
43
+ async register(keypair) {
44
+ const hex = publicKeyToHex(keypair.publicKey);
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ const tx = await this.contract.register(hex);
47
+ return tx.wait();
48
+ }
49
+ /**
50
+ * Check whether an address has registered a public key.
51
+ */
52
+ async hasKey(address) {
53
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
+ return this.contract.hasKey(address);
55
+ }
56
+ /**
57
+ * Get the X25519 public key for an address.
58
+ * Throws if the address has not registered.
59
+ */
60
+ async getPublicKey(address) {
61
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
+ const hex = await this.contract.getKey(address);
63
+ return hexToPublicKey(hex);
64
+ }
65
+ /**
66
+ * Get public keys for multiple addresses in a single batch of calls.
67
+ * Returns `null` for any address that has not registered.
68
+ */
69
+ async getPublicKeys(addresses) {
70
+ return Promise.all(addresses.map(async (addr) => {
71
+ try {
72
+ return await this.getPublicKey(addr);
73
+ }
74
+ catch {
75
+ return null;
76
+ }
77
+ }));
78
+ }
79
+ }
80
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAoC,QAAQ,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAY,aAAa,CAAC;AAGnE,gEAAgE;AAChE,2BAA2B;AAC3B,gEAAgE;AAEhE,MAAM,YAAY,GAAG;IACnB,4CAA4C;IAC5C,+DAA+D;IAC/D,4DAA4D;IAC5D,8DAA8D;CACtD,CAAC;AAEX,gEAAgE;AAChE,UAAU;AACV,gEAAgE;AAEhE,MAAM,OAAO,uBAAuB;IAC1B,QAAQ,CAAkB;IAElC,YACE,eAA6B,EAC7B,gBAAsD;QAEtD,IAAI,CAAC,QAAQ,GAAG,IAAI,MAAM,CAAC,QAAQ,CACjC,eAAe,EACf,YAAY,EACZ,gBAAgB,CACjB,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,CAAC,OAA0B;QACvC,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC9C,8DAA8D;QAC9D,MAAM,EAAE,GAAI,MAAO,IAAI,CAAC,QAAgB,CAAC,QAAQ,CAAC,GAAG,CAAmD,CAAC;QACzG,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,8DAA8D;QAC9D,OAAQ,IAAI,CAAC,QAAgB,CAAC,MAAM,CAAC,OAAO,CAAqB,CAAC;IACpE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY,CAAC,OAAe;QAChC,8DAA8D;QAC9D,MAAM,GAAG,GAAG,MAAO,IAAI,CAAC,QAAgB,CAAC,MAAM,CAAC,OAAO,CAAW,CAAC;QACnE,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,aAAa,CACjB,SAAmB;QAEnB,OAAO,OAAO,CAAC,GAAG,CAChB,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC3B,IAAI,CAAC;gBACH,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YACvC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * @file schema-manager.ts
3
+ * @notice Web3QL v1.2 — schema management: drop tables, rename, introspection.
4
+ *
5
+ * Schema is stored as ABI-encoded bytes in the database contract.
6
+ * This module provides:
7
+ *
8
+ * 1. SCHEMA INTROSPECTION — decode raw schema bytes → FieldDescriptor[]
9
+ * 2. DROP TABLE — bulk delete all owner records, then rename table to __dropped__
10
+ * 3. RENAME TABLE — soft-rename via a meta record (contract doesn't support rename natively)
11
+ * 4. SCHEMA DIFF — compare two schemas, produce a list of changes
12
+ * 5. SCHEMA VERSION — read + write the schema version stored in a meta record
13
+ *
14
+ * Usage:
15
+ * ─────────────────────────────────────────────────────────────
16
+ * const mgr = new SchemaManager(db, tableAddress, tableClient);
17
+ *
18
+ * // Inspect a deployed table's schema
19
+ * const fields = await mgr.introspect();
20
+ *
21
+ * // Diff two versions
22
+ * const changes = diffSchema(oldFields, newFields);
23
+ *
24
+ * // Soft-drop: mark table as dropped + purge all owner records
25
+ * await mgr.dropTable(ownerAddress);
26
+ *
27
+ * // Soft-rename: store alias mapping in meta record
28
+ * await mgr.renameTable('users', 'app_users');
29
+ * ─────────────────────────────────────────────────────────────
30
+ */
31
+ import { ethers } from 'ethers';
32
+ import type { DatabaseClient } from './factory-client.js';
33
+ import type { EncryptedTableClient } from './table-client.js';
34
+ import type { FieldDescriptor } from './types.js';
35
+ /**
36
+ * Decode raw schema bytes from the contract into an array of FieldDescriptors.
37
+ *
38
+ * Web3QL encodes schema as ABI-encoded:
39
+ * tuple(string name, string solidityType, bool primaryKey, bool notNull)[]
40
+ *
41
+ * This mirrors protocol/compiler/generator.ts compileSchema().
42
+ */
43
+ export declare function decodeSchemaBytes(schemaBytes: string | Uint8Array): FieldDescriptor[];
44
+ export type SchemaChangeType = 'added' | 'dropped' | 'typeChanged' | 'notNullChanged';
45
+ export interface SchemaChange {
46
+ type: SchemaChangeType;
47
+ column: string;
48
+ oldValue?: string;
49
+ newValue?: string;
50
+ }
51
+ /**
52
+ * Compute the diff between two schema versions.
53
+ * Returns an ordered list of changes from `from` → `to`.
54
+ */
55
+ export declare function diffSchema(from: FieldDescriptor[], to: FieldDescriptor[]): SchemaChange[];
56
+ export declare class SchemaManager {
57
+ private db;
58
+ private tableAddress;
59
+ private tableClient;
60
+ private dbContract;
61
+ constructor(db: DatabaseClient, tableAddress: string, tableClient: EncryptedTableClient, signer: ethers.Signer);
62
+ /**
63
+ * Read the schema bytes from the database contract and decode them
64
+ * into a usable FieldDescriptor array.
65
+ *
66
+ * @param tableName The name used when the table was created.
67
+ */
68
+ introspect(tableName: string): Promise<FieldDescriptor[]>;
69
+ /**
70
+ * List all table names in this database.
71
+ */
72
+ listTables(): Promise<string[]>;
73
+ /**
74
+ * Read the schema version stored in a meta record on-chain.
75
+ * Returns 0 if no version record has been written yet.
76
+ */
77
+ getSchemaVersion(tableName: string): Promise<number>;
78
+ /**
79
+ * Write (or update) the schema version meta record.
80
+ */
81
+ setSchemaVersion(tableName: string, version: number): Promise<void>;
82
+ /**
83
+ * Store a name alias mapping in a meta record.
84
+ * Future `introspect()` calls should use the new name.
85
+ *
86
+ * ⚠ The contract still uses the old name internally. This is a
87
+ * client-side alias only. To hard-rename, re-create the table.
88
+ */
89
+ renameTable(oldName: string, newName: string): Promise<void>;
90
+ /** Check if a table has been soft-renamed. Returns the new name or null. */
91
+ getRenamedTo(tableName: string): Promise<string | null>;
92
+ /**
93
+ * "Drop" a table by:
94
+ * 1. Deleting all owner records (batch, up to `maxRecords`).
95
+ * 2. Writing a __dropped__ meta record so the SDK knows to ignore it.
96
+ *
97
+ * ⚠ This is irreversible. The on-chain key->ciphertext mapping for
98
+ * deleted records is permanently unreadable (symmetric key scrubbed).
99
+ *
100
+ * @param ownerAddress Address whose records to delete.
101
+ * @param maxRecords Safety cap. Default: 500. Increase for large tables.
102
+ */
103
+ dropTable(ownerAddress: string, maxRecords?: number): Promise<{
104
+ deleted: number;
105
+ }>;
106
+ /** Check if a table has been soft-dropped. */
107
+ isDropped(): Promise<boolean>;
108
+ }
109
+ //# sourceMappingURL=schema-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-manager.d.ts","sourceRoot":"","sources":["../../src/schema-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAyB,QAAQ,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAY,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAW,YAAY,CAAC;AAyBvD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,GAAG,eAAe,EAAE,CAoBrF;AAMD,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,SAAS,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAEtF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAO,gBAAgB,CAAC;IAC5B,MAAM,EAAK,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,eAAe,EAAE,EACvB,EAAE,EAAI,eAAe,EAAE,GACtB,YAAY,EAAE,CAiChB;AAYD,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAA2B;IACrC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,UAAU,CAAoB;gBAGpC,EAAE,EAAY,cAAc,EAC5B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAG,oBAAoB,EAClC,MAAM,EAAQ,MAAM,CAAC,MAAM;IAU7B;;;;;OAKG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAU/D;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAMrC;;;OAGG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa1D;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAazE;;;;;;OAMG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWlE,4EAA4E;IACtE,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAe7D;;;;;;;;;;OAUG;IACG,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,SAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAkBrF,8CAA8C;IACxC,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAIpC"}