@weave_protocol/domere 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 (104) hide show
  1. package/PLANNING.md +231 -0
  2. package/README.md +50 -0
  3. package/dist/anchoring/ethereum.d.ts +135 -0
  4. package/dist/anchoring/ethereum.d.ts.map +1 -0
  5. package/dist/anchoring/ethereum.js +474 -0
  6. package/dist/anchoring/ethereum.js.map +1 -0
  7. package/dist/anchoring/index.d.ts +93 -0
  8. package/dist/anchoring/index.d.ts.map +1 -0
  9. package/dist/anchoring/index.js +184 -0
  10. package/dist/anchoring/index.js.map +1 -0
  11. package/dist/anchoring/merkle.d.ts +91 -0
  12. package/dist/anchoring/merkle.d.ts.map +1 -0
  13. package/dist/anchoring/merkle.js +203 -0
  14. package/dist/anchoring/merkle.js.map +1 -0
  15. package/dist/anchoring/solana.d.ts +85 -0
  16. package/dist/anchoring/solana.d.ts.map +1 -0
  17. package/dist/anchoring/solana.js +301 -0
  18. package/dist/anchoring/solana.js.map +1 -0
  19. package/dist/constants.d.ts +130 -0
  20. package/dist/constants.d.ts.map +1 -0
  21. package/dist/constants.js +536 -0
  22. package/dist/constants.js.map +1 -0
  23. package/dist/index.d.ts +13 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +37 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/language/code-analyzer.d.ts +80 -0
  28. package/dist/language/code-analyzer.d.ts.map +1 -0
  29. package/dist/language/code-analyzer.js +489 -0
  30. package/dist/language/code-analyzer.js.map +1 -0
  31. package/dist/language/detector.d.ts +53 -0
  32. package/dist/language/detector.d.ts.map +1 -0
  33. package/dist/language/detector.js +248 -0
  34. package/dist/language/detector.js.map +1 -0
  35. package/dist/language/index.d.ts +61 -0
  36. package/dist/language/index.d.ts.map +1 -0
  37. package/dist/language/index.js +109 -0
  38. package/dist/language/index.js.map +1 -0
  39. package/dist/language/nl-analyzer.d.ts +59 -0
  40. package/dist/language/nl-analyzer.d.ts.map +1 -0
  41. package/dist/language/nl-analyzer.js +350 -0
  42. package/dist/language/nl-analyzer.js.map +1 -0
  43. package/dist/language/semantic.d.ts +48 -0
  44. package/dist/language/semantic.d.ts.map +1 -0
  45. package/dist/language/semantic.js +329 -0
  46. package/dist/language/semantic.js.map +1 -0
  47. package/dist/storage/index.d.ts +6 -0
  48. package/dist/storage/index.d.ts.map +1 -0
  49. package/dist/storage/index.js +6 -0
  50. package/dist/storage/index.js.map +1 -0
  51. package/dist/storage/memory.d.ts +48 -0
  52. package/dist/storage/memory.d.ts.map +1 -0
  53. package/dist/storage/memory.js +211 -0
  54. package/dist/storage/memory.js.map +1 -0
  55. package/dist/thread/drift.d.ts +43 -0
  56. package/dist/thread/drift.d.ts.map +1 -0
  57. package/dist/thread/drift.js +248 -0
  58. package/dist/thread/drift.js.map +1 -0
  59. package/dist/thread/index.d.ts +9 -0
  60. package/dist/thread/index.d.ts.map +1 -0
  61. package/dist/thread/index.js +9 -0
  62. package/dist/thread/index.js.map +1 -0
  63. package/dist/thread/intent.d.ts +68 -0
  64. package/dist/thread/intent.d.ts.map +1 -0
  65. package/dist/thread/intent.js +333 -0
  66. package/dist/thread/intent.js.map +1 -0
  67. package/dist/thread/manager.d.ts +85 -0
  68. package/dist/thread/manager.d.ts.map +1 -0
  69. package/dist/thread/manager.js +305 -0
  70. package/dist/thread/manager.js.map +1 -0
  71. package/dist/thread/weave.d.ts +61 -0
  72. package/dist/thread/weave.d.ts.map +1 -0
  73. package/dist/thread/weave.js +158 -0
  74. package/dist/thread/weave.js.map +1 -0
  75. package/dist/tools/index.d.ts +18 -0
  76. package/dist/tools/index.d.ts.map +1 -0
  77. package/dist/tools/index.js +102 -0
  78. package/dist/tools/index.js.map +1 -0
  79. package/dist/types.d.ts +466 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/types.js +48 -0
  82. package/dist/types.js.map +1 -0
  83. package/package.json +24 -0
  84. package/src/anchoring/ethereum.ts +568 -0
  85. package/src/anchoring/index.ts +236 -0
  86. package/src/anchoring/merkle.ts +256 -0
  87. package/src/anchoring/solana.ts +370 -0
  88. package/src/constants.ts +566 -0
  89. package/src/index.ts +43 -0
  90. package/src/language/code-analyzer.ts +564 -0
  91. package/src/language/detector.ts +297 -0
  92. package/src/language/index.ts +129 -0
  93. package/src/language/nl-analyzer.ts +411 -0
  94. package/src/language/semantic.ts +385 -0
  95. package/src/storage/index.ts +6 -0
  96. package/src/storage/memory.ts +271 -0
  97. package/src/thread/drift.ts +319 -0
  98. package/src/thread/index.ts +9 -0
  99. package/src/thread/intent.ts +409 -0
  100. package/src/thread/manager.ts +414 -0
  101. package/src/thread/weave.ts +205 -0
  102. package/src/tools/index.ts +107 -0
  103. package/src/types.ts +736 -0
  104. package/tsconfig.json +19 -0
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Dōmere - The Judge Protocol
3
+ * Anchoring Module
4
+ */
5
+
6
+ export { MerkleTree, BatchAnchor } from './merkle.js';
7
+ export { SolanaAnchorClient, SOLANA_PROGRAM_IDL } from './solana.js';
8
+ export { EthereumAnchorClient, ETHEREUM_CONTRACT_ABI, ETHEREUM_CONTRACT_SOURCE } from './ethereum.js';
9
+
10
+ import type {
11
+ AnchorRequest,
12
+ AnchorResult,
13
+ AnchorVerification,
14
+ BlockchainNetwork,
15
+ Thread,
16
+ } from '../types.js';
17
+ import { AnchoringError } from '../types.js';
18
+ import { SolanaAnchorClient } from './solana.js';
19
+ import { EthereumAnchorClient } from './ethereum.js';
20
+ import { MerkleTree, BatchAnchor } from './merkle.js';
21
+
22
+ // ============================================================================
23
+ // Unified Anchoring Service
24
+ // ============================================================================
25
+
26
+ export class AnchoringService {
27
+ private solana: SolanaAnchorClient;
28
+ private ethereum: EthereumAnchorClient;
29
+ private pendingBatch: BatchAnchor | null = null;
30
+
31
+ constructor(config?: {
32
+ solana?: { rpc_url?: string; program_id?: string };
33
+ ethereum?: { rpc_url?: string; contract_address?: string };
34
+ }) {
35
+ this.solana = new SolanaAnchorClient(config?.solana);
36
+ this.ethereum = new EthereumAnchorClient(config?.ethereum);
37
+ }
38
+
39
+ /**
40
+ * Prepare thread for anchoring
41
+ */
42
+ prepareThreadAnchor(thread: Thread): AnchorRequest {
43
+ // Build Merkle tree from hop signatures
44
+ const hopSignatures = thread.hops.map(hop => hop.hop_signature);
45
+ const tree = new MerkleTree(hopSignatures.length > 0 ? hopSignatures : ['empty']);
46
+
47
+ return {
48
+ thread_id: thread.id,
49
+ merkle_root: tree.getRootHex(),
50
+ hop_count: thread.hops.length,
51
+ intent_hash: thread.intent.hash,
52
+ compliant: thread.status !== 'violated',
53
+ network: 'solana', // Default to Solana
54
+ };
55
+ }
56
+
57
+ /**
58
+ * Estimate anchoring cost
59
+ */
60
+ async estimateCost(network: BlockchainNetwork): Promise<{
61
+ network: BlockchainNetwork;
62
+ network_fee: string;
63
+ protocol_fee: string;
64
+ total: string;
65
+ currency: string;
66
+ }> {
67
+ if (network === 'solana' || network === 'solana-devnet') {
68
+ const cost = await this.solana.estimateCost();
69
+ return {
70
+ network,
71
+ network_fee: cost.network_fee_sol,
72
+ protocol_fee: cost.protocol_fee_sol,
73
+ total: cost.total_sol,
74
+ currency: 'SOL',
75
+ };
76
+ } else {
77
+ const cost = await this.ethereum.estimateGas();
78
+ return {
79
+ network,
80
+ network_fee: cost.estimated_eth,
81
+ protocol_fee: cost.protocol_fee_eth,
82
+ total: cost.total_eth,
83
+ currency: 'ETH',
84
+ };
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Create anchor transaction (unsigned)
90
+ */
91
+ async createAnchorTransaction(request: AnchorRequest): Promise<{
92
+ network: BlockchainNetwork;
93
+ transaction_data: unknown;
94
+ estimated_cost: unknown;
95
+ instructions: string;
96
+ }> {
97
+ if (request.network === 'solana' || request.network === 'solana-devnet') {
98
+ const tx = await this.solana.createAnchorTransaction(request);
99
+ return {
100
+ network: request.network,
101
+ transaction_data: tx.unsigned_transaction,
102
+ estimated_cost: tx.estimated_cost,
103
+ instructions: `Sign this transaction with your Solana wallet to anchor thread ${request.thread_id}`,
104
+ };
105
+ } else {
106
+ const tx = await this.ethereum.createAnchorTransaction(request);
107
+ return {
108
+ network: request.network,
109
+ transaction_data: tx,
110
+ estimated_cost: tx.estimated_cost,
111
+ instructions: `Sign this transaction with your Ethereum wallet to anchor thread ${request.thread_id}`,
112
+ };
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Submit signed transaction
118
+ */
119
+ async submitSignedTransaction(
120
+ network: BlockchainNetwork,
121
+ signedTransaction: string
122
+ ): Promise<AnchorResult> {
123
+ if (network === 'solana' || network === 'solana-devnet') {
124
+ return this.solana.submitSignedTransaction(signedTransaction);
125
+ } else {
126
+ return this.ethereum.submitSignedTransaction(signedTransaction);
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Verify anchor on-chain
132
+ */
133
+ async verifyAnchor(
134
+ network: BlockchainNetwork,
135
+ threadId: string,
136
+ expectedMerkleRoot: string
137
+ ): Promise<AnchorVerification> {
138
+ if (network === 'solana' || network === 'solana-devnet') {
139
+ return this.solana.verifyAnchor(threadId, expectedMerkleRoot);
140
+ } else {
141
+ return this.ethereum.verifyAnchor(threadId, expectedMerkleRoot);
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Start a batch for efficient anchoring
147
+ */
148
+ startBatch(): void {
149
+ if (this.pendingBatch) {
150
+ throw new AnchoringError('Batch already in progress');
151
+ }
152
+ this.pendingBatch = new BatchAnchor();
153
+ }
154
+
155
+ /**
156
+ * Add thread to batch
157
+ */
158
+ addToBatch(thread: Thread): void {
159
+ if (!this.pendingBatch) {
160
+ throw new AnchoringError('No batch in progress');
161
+ }
162
+
163
+ const hopSignatures = thread.hops.map(hop => hop.hop_signature);
164
+ const tree = new MerkleTree(hopSignatures.length > 0 ? hopSignatures : ['empty']);
165
+
166
+ this.pendingBatch.add(thread.id, JSON.stringify({
167
+ thread_id: thread.id,
168
+ merkle_root: tree.getRootHex(),
169
+ intent_hash: thread.intent.hash,
170
+ compliant: thread.status !== 'violated',
171
+ }));
172
+ }
173
+
174
+ /**
175
+ * Finalize batch and get root
176
+ */
177
+ finalizeBatch(): {
178
+ root: string;
179
+ count: number;
180
+ thread_ids: string[];
181
+ } {
182
+ if (!this.pendingBatch) {
183
+ throw new AnchoringError('No batch in progress');
184
+ }
185
+
186
+ const root = this.pendingBatch.finalize();
187
+ const threadIds = this.pendingBatch.getItemIds();
188
+ const count = this.pendingBatch.getCount();
189
+
190
+ return { root, count, thread_ids: threadIds };
191
+ }
192
+
193
+ /**
194
+ * Get proof for specific thread in batch
195
+ */
196
+ getBatchProof(threadId: string): {
197
+ proof: string[];
198
+ positions: number[];
199
+ root: string;
200
+ } | null {
201
+ if (!this.pendingBatch) {
202
+ throw new AnchoringError('No batch in progress');
203
+ }
204
+
205
+ return this.pendingBatch.getProof(threadId);
206
+ }
207
+
208
+ /**
209
+ * Clear batch
210
+ */
211
+ clearBatch(): void {
212
+ this.pendingBatch = null;
213
+ }
214
+
215
+ /**
216
+ * Get explorer URL for transaction
217
+ */
218
+ getExplorerUrl(network: BlockchainNetwork, txHash: string): string {
219
+ if (network === 'solana' || network === 'solana-devnet') {
220
+ return this.solana.getExplorerUrl(txHash);
221
+ } else {
222
+ return this.ethereum.getExplorerUrl(txHash);
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Get client for direct access
228
+ */
229
+ getClient(network: BlockchainNetwork): SolanaAnchorClient | EthereumAnchorClient {
230
+ if (network === 'solana' || network === 'solana-devnet') {
231
+ return this.solana;
232
+ } else {
233
+ return this.ethereum;
234
+ }
235
+ }
236
+ }
@@ -0,0 +1,256 @@
1
+ /**
2
+ * Dōmere - The Judge Protocol
3
+ * Merkle Tree Utilities
4
+ */
5
+
6
+ import * as crypto from 'crypto';
7
+
8
+ // ============================================================================
9
+ // Merkle Tree
10
+ // ============================================================================
11
+
12
+ export class MerkleTree {
13
+ private leaves: Buffer[];
14
+ private layers: Buffer[][];
15
+ private root: Buffer | null = null;
16
+
17
+ constructor(leaves: (string | Buffer)[]) {
18
+ this.leaves = leaves.map(leaf =>
19
+ typeof leaf === 'string' ? this.hashLeaf(leaf) : leaf
20
+ );
21
+ this.layers = [this.leaves];
22
+ this.buildTree();
23
+ }
24
+
25
+ /**
26
+ * Build the Merkle tree
27
+ */
28
+ private buildTree(): void {
29
+ let currentLayer = this.leaves;
30
+
31
+ while (currentLayer.length > 1) {
32
+ const newLayer: Buffer[] = [];
33
+
34
+ for (let i = 0; i < currentLayer.length; i += 2) {
35
+ if (i + 1 < currentLayer.length) {
36
+ // Sort pair for consistent ordering
37
+ const [left, right] = this.sortPair(currentLayer[i], currentLayer[i + 1]);
38
+ newLayer.push(this.hashPair(left, right));
39
+ } else {
40
+ // Promote odd node
41
+ newLayer.push(currentLayer[i]);
42
+ }
43
+ }
44
+
45
+ this.layers.push(newLayer);
46
+ currentLayer = newLayer;
47
+ }
48
+
49
+ this.root = currentLayer.length > 0 ? currentLayer[0] : this.hashLeaf('empty');
50
+ }
51
+
52
+ /**
53
+ * Get the Merkle root
54
+ */
55
+ getRoot(): Buffer {
56
+ return this.root!;
57
+ }
58
+
59
+ /**
60
+ * Get root as hex string
61
+ */
62
+ getRootHex(): string {
63
+ return this.root!.toString('hex');
64
+ }
65
+
66
+ /**
67
+ * Get root as 32-byte array (for blockchain)
68
+ */
69
+ getRootBytes32(): number[] {
70
+ return Array.from(this.root!);
71
+ }
72
+
73
+ /**
74
+ * Get proof for a leaf at given index
75
+ */
76
+ getProof(index: number): {
77
+ proof: Buffer[];
78
+ proofHex: string[];
79
+ positions: number[]; // 0 = left, 1 = right
80
+ } {
81
+ if (index < 0 || index >= this.leaves.length) {
82
+ throw new Error('Index out of bounds');
83
+ }
84
+
85
+ const proof: Buffer[] = [];
86
+ const positions: number[] = [];
87
+ let currentIndex = index;
88
+
89
+ for (let i = 0; i < this.layers.length - 1; i++) {
90
+ const layer = this.layers[i];
91
+ const isRight = currentIndex % 2 === 1;
92
+ const siblingIndex = isRight ? currentIndex - 1 : currentIndex + 1;
93
+
94
+ if (siblingIndex < layer.length) {
95
+ proof.push(layer[siblingIndex]);
96
+ positions.push(isRight ? 0 : 1); // Sibling position
97
+ }
98
+
99
+ currentIndex = Math.floor(currentIndex / 2);
100
+ }
101
+
102
+ return {
103
+ proof,
104
+ proofHex: proof.map(p => p.toString('hex')),
105
+ positions,
106
+ };
107
+ }
108
+
109
+ /**
110
+ * Verify a proof
111
+ */
112
+ static verify(
113
+ leaf: string | Buffer,
114
+ proof: Buffer[],
115
+ positions: number[],
116
+ root: Buffer
117
+ ): boolean {
118
+ let current = typeof leaf === 'string'
119
+ ? crypto.createHash('sha256').update(leaf).digest()
120
+ : leaf;
121
+
122
+ for (let i = 0; i < proof.length; i++) {
123
+ const [left, right] = positions[i] === 0
124
+ ? [proof[i], current]
125
+ : [current, proof[i]];
126
+
127
+ current = crypto.createHash('sha256')
128
+ .update(Buffer.concat([left, right]))
129
+ .digest();
130
+ }
131
+
132
+ return current.equals(root);
133
+ }
134
+
135
+ /**
136
+ * Get all layers (for debugging)
137
+ */
138
+ getLayers(): Buffer[][] {
139
+ return this.layers;
140
+ }
141
+
142
+ /**
143
+ * Get leaf count
144
+ */
145
+ getLeafCount(): number {
146
+ return this.leaves.length;
147
+ }
148
+
149
+ /**
150
+ * Hash a leaf
151
+ */
152
+ private hashLeaf(data: string): Buffer {
153
+ return crypto.createHash('sha256').update(data).digest();
154
+ }
155
+
156
+ /**
157
+ * Hash a pair of nodes
158
+ */
159
+ private hashPair(left: Buffer, right: Buffer): Buffer {
160
+ return crypto.createHash('sha256')
161
+ .update(Buffer.concat([left, right]))
162
+ .digest();
163
+ }
164
+
165
+ /**
166
+ * Sort pair for consistent ordering
167
+ */
168
+ private sortPair(a: Buffer, b: Buffer): [Buffer, Buffer] {
169
+ return Buffer.compare(a, b) <= 0 ? [a, b] : [b, a];
170
+ }
171
+ }
172
+
173
+ // ============================================================================
174
+ // Batch Anchoring
175
+ // ============================================================================
176
+
177
+ export class BatchAnchor {
178
+ private items: Map<string, { data: string; index: number }> = new Map();
179
+ private tree: MerkleTree | null = null;
180
+
181
+ /**
182
+ * Add item to batch
183
+ */
184
+ add(id: string, data: string): void {
185
+ if (this.tree) {
186
+ throw new Error('Batch already finalized');
187
+ }
188
+ this.items.set(id, { data, index: this.items.size });
189
+ }
190
+
191
+ /**
192
+ * Finalize batch and build tree
193
+ */
194
+ finalize(): string {
195
+ if (this.items.size === 0) {
196
+ throw new Error('Cannot finalize empty batch');
197
+ }
198
+
199
+ const leaves = Array.from(this.items.values())
200
+ .sort((a, b) => a.index - b.index)
201
+ .map(item => item.data);
202
+
203
+ this.tree = new MerkleTree(leaves);
204
+ return this.tree.getRootHex();
205
+ }
206
+
207
+ /**
208
+ * Get proof for specific item
209
+ */
210
+ getProof(id: string): {
211
+ proof: string[];
212
+ positions: number[];
213
+ root: string;
214
+ } | null {
215
+ if (!this.tree) {
216
+ throw new Error('Batch not finalized');
217
+ }
218
+
219
+ const item = this.items.get(id);
220
+ if (!item) {
221
+ return null;
222
+ }
223
+
224
+ const { proofHex, positions } = this.tree.getProof(item.index);
225
+
226
+ return {
227
+ proof: proofHex,
228
+ positions,
229
+ root: this.tree.getRootHex(),
230
+ };
231
+ }
232
+
233
+ /**
234
+ * Get root
235
+ */
236
+ getRoot(): string {
237
+ if (!this.tree) {
238
+ throw new Error('Batch not finalized');
239
+ }
240
+ return this.tree.getRootHex();
241
+ }
242
+
243
+ /**
244
+ * Get item count
245
+ */
246
+ getCount(): number {
247
+ return this.items.size;
248
+ }
249
+
250
+ /**
251
+ * Get all item IDs
252
+ */
253
+ getItemIds(): string[] {
254
+ return Array.from(this.items.keys());
255
+ }
256
+ }