@hardkas/toolkit 0.11.2-alpha → 0.11.4-alpha

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 (56) hide show
  1. package/dist/fee-estimator.d.ts +9 -0
  2. package/dist/fee-estimator.d.ts.map +1 -0
  3. package/dist/fee-estimator.js +32 -0
  4. package/dist/fee-estimator.js.map +1 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +3 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/indexer.d.ts +1 -0
  10. package/dist/indexer.d.ts.map +1 -1
  11. package/dist/indexer.js +7 -0
  12. package/dist/indexer.js.map +1 -1
  13. package/dist/query-api.d.ts +22 -0
  14. package/dist/query-api.d.ts.map +1 -0
  15. package/dist/query-api.js +116 -0
  16. package/dist/query-api.js.map +1 -0
  17. package/dist/snapshot/serialization.d.ts +0 -9
  18. package/dist/snapshot/serialization.d.ts.map +1 -1
  19. package/dist/snapshot/serialization.js +0 -12
  20. package/dist/snapshot/serialization.js.map +1 -1
  21. package/dist/subscriptions.d.ts +22 -0
  22. package/dist/subscriptions.d.ts.map +1 -0
  23. package/dist/subscriptions.js +91 -0
  24. package/dist/subscriptions.js.map +1 -0
  25. package/dist/wallet.d.ts +71 -1
  26. package/dist/wallet.d.ts.map +1 -1
  27. package/dist/wallet.js +296 -44
  28. package/dist/wallet.js.map +1 -1
  29. package/package.json +24 -9
  30. package/.turbo/turbo-build.log +0 -4
  31. package/src/dag/consensus.ts +0 -150
  32. package/src/dag/index.ts +0 -73
  33. package/src/dag/store.ts +0 -40
  34. package/src/dag/topology.ts +0 -108
  35. package/src/dag/types.ts +0 -20
  36. package/src/index.ts +0 -10
  37. package/src/indexer.ts +0 -134
  38. package/src/jobs.ts +0 -63
  39. package/src/payment.ts +0 -100
  40. package/src/silver/index.ts +0 -102
  41. package/src/silver/templates.ts +0 -27
  42. package/src/silver/types.ts +0 -37
  43. package/src/snapshot/backends/FsSnapshotBackend.ts +0 -100
  44. package/src/snapshot/backends/MemorySnapshotBackend.ts +0 -65
  45. package/src/snapshot/index.ts +0 -102
  46. package/src/snapshot/serialization.ts +0 -35
  47. package/src/snapshot/types.ts +0 -45
  48. package/src/stores/invoice-store.ts +0 -62
  49. package/src/stores/utxo-control-store.ts +0 -78
  50. package/src/utxos.ts +0 -451
  51. package/src/wallet.ts +0 -158
  52. package/test/silver.test.ts +0 -59
  53. package/test/snapshot.test.ts +0 -99
  54. package/test/toolkit.test.ts +0 -140
  55. package/tsconfig.json +0 -9
  56. package/vitest.config.ts +0 -8
@@ -1,99 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { SnapshotToolkit } from '../src/snapshot/index.js';
3
- import { JobsToolkit } from '../src/jobs.js';
4
- import fs from 'fs-extra';
5
- import path from 'path';
6
-
7
- describe('SnapshotToolkit (Time Travel)', () => {
8
- let snapshots: SnapshotToolkit;
9
- let jobs: JobsToolkit;
10
-
11
- const testDir = path.join(process.cwd(), '.test-snapshots');
12
-
13
- beforeEach(async () => {
14
- await fs.ensureDir(testDir);
15
- snapshots = SnapshotToolkit.open({ backend: 'filesystem', dir: testDir });
16
- jobs = JobsToolkit.open({ storePath: path.join(testDir, 'jobs.json') });
17
- snapshots.register('jobs', jobs);
18
- });
19
-
20
- afterEach(async () => {
21
- await fs.remove(testDir);
22
- });
23
-
24
- it('should save, mutate, and restore state', async () => {
25
- // State 1
26
- await jobs.enqueue('payment', { to: 'alice' });
27
- const s1 = await snapshots.create('state1');
28
-
29
- let job1 = await jobs.getJob((await jobs.snapshot() as any)[Object.keys(await jobs.snapshot())[0]].id);
30
- expect(job1).toBeDefined();
31
-
32
- // Mutate State 2
33
- await jobs.enqueue('payment', { to: 'bob' });
34
-
35
- let stateKeys = Object.keys(await jobs.snapshot());
36
- expect(stateKeys.length).toBe(2);
37
-
38
- // Restore State 1
39
- await snapshots.restore(s1.snapshotId);
40
-
41
- // Verify restored
42
- stateKeys = Object.keys(await jobs.snapshot());
43
- expect(stateKeys.length).toBe(1); // bob's job is gone
44
-
45
- // Branch from State 1
46
- const b1 = await snapshots.branch(s1.snapshotId, 'experiment-a');
47
- expect(b1.name).toBe('experiment-a');
48
- });
49
-
50
- it('should handle partial restore failures gracefully', async () => {
51
- // Enqueue some initial jobs
52
- await jobs.enqueue('payment', { to: 'alice' });
53
- const base = await snapshots.create('base');
54
-
55
- // Register a malicious participant that fails on restore
56
- const failingParticipant = {
57
- snapshot: async () => ({ bad: 'state' }),
58
- restore: async () => { throw new Error('Simulated restore failure'); },
59
- reload: async () => {}
60
- };
61
- snapshots.register('failing', failingParticipant);
62
- const badSnapshot = await snapshots.create('bad');
63
-
64
- // Restore should throw and mention the participant
65
- await expect(snapshots.restore(badSnapshot.snapshotId)).rejects.toThrow(/Failed to restore participant 'failing'/);
66
- });
67
-
68
- it('should fail if participant is missing on restore', async () => {
69
- await jobs.enqueue('payment', { to: 'alice' });
70
- const base = await snapshots.create('base');
71
-
72
- // Unregister a participant by creating a new snapshots instance
73
- const newSnapshots = SnapshotToolkit.open({ backend: 'filesystem', dir: testDir });
74
- // Didn't register 'jobs' this time
75
-
76
- await expect(newSnapshots.restore(base.snapshotId)).rejects.toThrow(/not registered/);
77
- });
78
-
79
- it('should generate deterministic diffs and valid filesystem manifests', async () => {
80
- await jobs.enqueue('payment', { to: 'alice' });
81
- const s1 = await snapshots.create('s1');
82
-
83
- await jobs.enqueue('payment', { to: 'bob' });
84
- const s2 = await snapshots.create('s2');
85
-
86
- const diff = await snapshots.diff(s1.snapshotId, s2.snapshotId);
87
- expect(diff).toHaveProperty('jobs');
88
-
89
- // Assert filesystem manifest created properly
90
- const manifestPath = path.join(testDir, s1.snapshotId, 'manifest.json');
91
- expect(await fs.pathExists(manifestPath)).toBe(true);
92
-
93
- const manifest = await fs.readJson(manifestPath);
94
- expect(manifest.schema).toBe('hardkas.snapshot.v1');
95
- expect(manifest.backend).toBe('filesystem');
96
- expect(manifest.participants).toContain('jobs');
97
- expect(manifest.stateHashes).toHaveProperty('jobs');
98
- });
99
- });
@@ -1,140 +0,0 @@
1
- import { describe, it, expect, beforeAll, afterAll } from 'vitest';
2
- import { WalletToolkit, PaymentToolkit, IndexerToolkit } from '../src/index.js';
3
- import * as fs from 'node:fs/promises';
4
- import * as path from 'node:path';
5
-
6
- describe('@hardkas/toolkit V1', () => {
7
- const tmpDir = path.join(process.cwd(), '.test-toolkit');
8
-
9
- beforeAll(async () => {
10
- try { await fs.mkdir(tmpDir, { recursive: true }); } catch (e) {}
11
- });
12
-
13
- afterAll(async () => {
14
- try { await fs.rm(tmpDir, { recursive: true, force: true }); } catch (e) {}
15
- });
16
-
17
- describe('WalletToolkit', () => {
18
- it('should instantiate and return address', async () => {
19
- const wallet = WalletToolkit.open('alice', { storePath: path.join(tmpDir, 'wallets.json') });
20
- await wallet.create();
21
- const addr = await wallet.address();
22
- expect(addr).toBeDefined();
23
- expect(typeof addr).toBe('string');
24
- expect(addr.startsWith('kaspasim:') || addr.startsWith('kaspa:')).toBe(true);
25
- });
26
-
27
- it('should estimate fee and plan send', async () => {
28
- const wallet = WalletToolkit.open('alice', { storePath: path.join(tmpDir, 'wallets.json') });
29
- // Mock the internal walletQuery for the test
30
- (wallet as any).walletQuery.getUtxos = async () => ({ ok: true, utxos: {} });
31
-
32
- await wallet.create(); // Create it so we can fetch it
33
-
34
- // This is a facade test, we just want to ensure it doesn't crash on wiring
35
- const utxos = await wallet.utxos.list();
36
- expect(Array.isArray(utxos)).toBe(true);
37
-
38
- // To test estimateFee, CoinSelector might throw if not enough funds,
39
- // but we at least know it wired up the query correctly.
40
- });
41
- });
42
-
43
- describe('PaymentToolkit', () => {
44
- it('should create invoice and receipt with persistence', async () => {
45
- const pt = PaymentToolkit.openMerchant('store-1', { storePath: path.join(tmpDir, 'invoices.json') });
46
- const inv = await pt.createInvoice({ amount: 150n, currency: 'KAS' });
47
- expect(inv.id).toBeDefined();
48
- expect(inv.uri).toContain('kaspa:store-1');
49
- expect(inv.uri).toContain('amount=150');
50
- expect(inv.status).toBe('pending');
51
-
52
- const status = await pt.check(inv.id);
53
- expect(status).toBe('pending');
54
-
55
- // Simulate payment
56
- await pt.simulatePay(inv.id);
57
- const paidStatus = await pt.check(inv.id);
58
- expect(paidStatus).toBe('paid');
59
-
60
- const receipt = await pt.receipt(inv.id);
61
- expect(receipt.schema).toBe('paymentReceipt.v1');
62
- expect(receipt.merchantId).toBe('store-1');
63
-
64
- const list = await pt.listInvoices();
65
- expect(list.length).toBe(1);
66
-
67
- const stats = await pt.stats();
68
- expect(stats.totalInvoices).toBe(1);
69
- expect(stats.paidInvoices).toBe(1);
70
- });
71
-
72
- it('should throw when requesting receipt for pending or non-existent invoice', async () => {
73
- const pt = PaymentToolkit.openMerchant('store-err', { storePath: path.join(tmpDir, 'invoices-err.json') });
74
- const inv = await pt.createInvoice({ amount: 150n, currency: 'KAS' });
75
-
76
- await expect(pt.receipt(inv.id)).rejects.toThrow('Invoice is not paid');
77
- await expect(pt.receipt('non-existent')).rejects.toThrow('Invoice not found');
78
- });
79
-
80
- it('should allow creating invoice with amountSompi', async () => {
81
- const pt = PaymentToolkit.openMerchant('store-sompi', { storePath: path.join(tmpDir, 'invoices-sompi.json') });
82
- const inv = await pt.createInvoice({ amountSompi: 150000000n }); // 1.5 KAS
83
-
84
- expect(inv.amount).toBe(1n); // 150000000 / 100000000 = 1 (truncates)
85
- expect(inv.uri).toContain('amount=1.5');
86
- });
87
- });
88
-
89
- describe('JobsToolkit', () => {
90
- it('should initialize and enqueue jobs', async () => {
91
- const { JobsToolkit } = await import('../src/index.js');
92
- const jobs = JobsToolkit.open({ storePath: path.join(tmpDir, 'jobs.json') });
93
- jobs.registerHandler('test-job', async (ctx) => {
94
- ctx.progress.update({ total: 10, processed: 10 });
95
- });
96
- const id = await jobs.enqueue('test-job', {});
97
- expect(id).toBeDefined();
98
-
99
- // Allow a tick for async job to execute
100
- await new Promise(r => setTimeout(r, 50));
101
-
102
- const job = await jobs.getJob(id);
103
- expect(job).toBeDefined();
104
- expect(job?.type).toBe('test-job');
105
- });
106
- });
107
-
108
- describe('IndexerToolkit', () => {
109
- it('should bind mock data to address watch and trigger handler', async () => {
110
- const idx = await IndexerToolkit.open({ dataDir: tmpDir });
111
-
112
- let called = false;
113
- await idx.watch('kaspa:store-1', async (evt) => {
114
- called = true;
115
- });
116
-
117
- // Trigger the internal subscriber handler manually since we don't have the timer easily accessible
118
- const sub = (idx as any).subscriber;
119
- const handler = Array.from(sub.activeIntervals.entries())[0];
120
- // Actually the interval doesn't trigger unless we mock options.source.getUtxos, which is empty here.
121
- // But we can verify it registers correctly.
122
- await idx.watch(['kaspa:store-1', 'kaspa:store-2']); // should also work
123
- });
124
- it('should ingest and find artifacts', async () => {
125
- const idx = IndexerToolkit.open({ dataDir: tmpDir });
126
-
127
- await idx.watch('kaspa:store-1'); // should just bind
128
-
129
- await idx.ingestArtifact({
130
- id: '123',
131
- schema: 'test.v1',
132
- tags: ['test:abc']
133
- });
134
-
135
- const found = await idx.findReceipts({ tags: ['test:abc'] });
136
- expect(found.length).toBe(1);
137
- expect(found[0].hash).toBe('123');
138
- });
139
- });
140
- });
package/tsconfig.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "./dist",
5
- "rootDir": "./src",
6
- "declaration": true
7
- },
8
- "include": ["src/**/*"]
9
- }
package/vitest.config.ts DELETED
@@ -1,8 +0,0 @@
1
- import { defineConfig } from 'vitest/config';
2
-
3
- export default defineConfig({
4
- test: {
5
- environment: 'node',
6
- include: ['test/**/*.test.ts'],
7
- }
8
- });