holosphere 2.0.0-alpha2 → 2.0.0-alpha4
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/2019-D2OG2idw.js +6680 -0
- package/dist/2019-D2OG2idw.js.map +1 -0
- package/dist/2019-EION3wKo.cjs +8 -0
- package/dist/2019-EION3wKo.cjs.map +1 -0
- package/dist/_commonjsHelpers-C37NGDzP.cjs +2 -0
- package/dist/_commonjsHelpers-C37NGDzP.cjs.map +1 -0
- package/dist/_commonjsHelpers-CUmg6egw.js +7 -0
- package/dist/_commonjsHelpers-CUmg6egw.js.map +1 -0
- package/dist/browser-BSniCNqO.js +3058 -0
- package/dist/browser-BSniCNqO.js.map +1 -0
- package/dist/browser-Cq59Ij19.cjs +2 -0
- package/dist/browser-Cq59Ij19.cjs.map +1 -0
- package/dist/cjs/holosphere.cjs +1 -1
- package/dist/esm/holosphere.js +50 -53
- package/dist/index-BB_vVJgv.cjs +5 -0
- package/dist/index-BB_vVJgv.cjs.map +1 -0
- package/dist/index-CBitK71M.cjs +12 -0
- package/dist/index-CBitK71M.cjs.map +1 -0
- package/dist/index-CV0eOogK.js +37423 -0
- package/dist/index-CV0eOogK.js.map +1 -0
- package/dist/index-Cz-PLCUR.js +15104 -0
- package/dist/index-Cz-PLCUR.js.map +1 -0
- package/dist/indexeddb-storage-CRsZyB2f.cjs +2 -0
- package/dist/indexeddb-storage-CRsZyB2f.cjs.map +1 -0
- package/dist/{indexeddb-storage-CMW4qRQS.js → indexeddb-storage-DZaGlY_a.js} +49 -13
- package/dist/indexeddb-storage-DZaGlY_a.js.map +1 -0
- package/dist/{memory-storage-DQzcAZlf.js → memory-storage-BkUi6sZG.js} +6 -2
- package/dist/memory-storage-BkUi6sZG.js.map +1 -0
- package/dist/{memory-storage-DmePEP2q.cjs → memory-storage-C0DuUsdY.cjs} +2 -2
- package/dist/memory-storage-C0DuUsdY.cjs.map +1 -0
- package/dist/secp256k1-0kPdAVkK.cjs +12 -0
- package/dist/secp256k1-0kPdAVkK.cjs.map +1 -0
- package/dist/{secp256k1-vOXp40Fx.js → secp256k1-DN4FVXcv.js} +2 -393
- package/dist/secp256k1-DN4FVXcv.js.map +1 -0
- package/docs/CONTRACTS.md +797 -0
- package/examples/demo.html +47 -0
- package/package.json +10 -5
- package/src/contracts/abis/Appreciative.json +1280 -0
- package/src/contracts/abis/AppreciativeFactory.json +101 -0
- package/src/contracts/abis/Bundle.json +1435 -0
- package/src/contracts/abis/BundleFactory.json +106 -0
- package/src/contracts/abis/Holon.json +881 -0
- package/src/contracts/abis/Holons.json +330 -0
- package/src/contracts/abis/Managed.json +1262 -0
- package/src/contracts/abis/ManagedFactory.json +149 -0
- package/src/contracts/abis/Membrane.json +261 -0
- package/src/contracts/abis/Splitter.json +1624 -0
- package/src/contracts/abis/SplitterFactory.json +220 -0
- package/src/contracts/abis/TestToken.json +321 -0
- package/src/contracts/abis/Zoned.json +1461 -0
- package/src/contracts/abis/ZonedFactory.json +154 -0
- package/src/contracts/chain-manager.js +375 -0
- package/src/contracts/deployer.js +443 -0
- package/src/contracts/event-listener.js +507 -0
- package/src/contracts/holon-contracts.js +344 -0
- package/src/contracts/index.js +83 -0
- package/src/contracts/networks.js +224 -0
- package/src/contracts/operations.js +670 -0
- package/src/contracts/queries.js +589 -0
- package/src/core/holosphere.js +453 -1
- package/src/crypto/nostr-utils.js +263 -0
- package/src/federation/handshake.js +455 -0
- package/src/federation/hologram.js +1 -1
- package/src/hierarchical/upcast.js +6 -5
- package/src/index.js +463 -1939
- package/src/lib/ai-methods.js +308 -0
- package/src/lib/contract-methods.js +293 -0
- package/src/lib/errors.js +23 -0
- package/src/lib/federation-methods.js +238 -0
- package/src/lib/index.js +26 -0
- package/src/spatial/h3-operations.js +2 -2
- package/src/storage/backends/gundb-backend.js +377 -46
- package/src/storage/global-tables.js +28 -1
- package/src/storage/gun-auth.js +303 -0
- package/src/storage/gun-federation.js +776 -0
- package/src/storage/gun-references.js +198 -0
- package/src/storage/gun-schema.js +291 -0
- package/src/storage/gun-wrapper.js +347 -31
- package/src/storage/indexeddb-storage.js +49 -11
- package/src/storage/memory-storage.js +5 -0
- package/src/storage/nostr-async.js +45 -23
- package/src/storage/nostr-client.js +11 -5
- package/src/storage/persistent-storage.js +6 -1
- package/src/storage/unified-storage.js +119 -0
- package/src/subscriptions/manager.js +1 -1
- package/types/index.d.ts +133 -0
- package/dist/index-CDfIuXew.js +0 -15974
- package/dist/index-CDfIuXew.js.map +0 -1
- package/dist/index-ifOgtDvd.cjs +0 -3
- package/dist/index-ifOgtDvd.cjs.map +0 -1
- package/dist/indexeddb-storage-CMW4qRQS.js.map +0 -1
- package/dist/indexeddb-storage-DLZOgetM.cjs +0 -2
- package/dist/indexeddb-storage-DLZOgetM.cjs.map +0 -1
- package/dist/memory-storage-DQzcAZlf.js.map +0 -1
- package/dist/memory-storage-DmePEP2q.cjs.map +0 -1
- package/dist/secp256k1-CP0ZkpAx.cjs +0 -13
- package/dist/secp256k1-CP0ZkpAx.cjs.map +0 -1
- package/dist/secp256k1-vOXp40Fx.js.map +0 -1
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HolonContracts - Per-holon contract management
|
|
3
|
+
* Links holons to their smart contracts for fractal fund distribution
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ContractDeployer, ABIs } from './deployer.js';
|
|
7
|
+
import { ContractOperations } from './operations.js';
|
|
8
|
+
|
|
9
|
+
export class HolonContracts {
|
|
10
|
+
constructor(chainManager, deployer) {
|
|
11
|
+
this.chainManager = chainManager;
|
|
12
|
+
this.deployer = deployer || new ContractDeployer(chainManager);
|
|
13
|
+
|
|
14
|
+
// Maps holonId -> { address, type, contract, operations }
|
|
15
|
+
this.holonContracts = new Map();
|
|
16
|
+
|
|
17
|
+
// Storage for persistence (can be overridden)
|
|
18
|
+
this.storage = null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Set storage adapter for persisting holon-contract mappings
|
|
23
|
+
* @param {Object} storage - Storage adapter with get/set methods
|
|
24
|
+
*/
|
|
25
|
+
setStorage(storage) {
|
|
26
|
+
this.storage = storage;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Deploy a new contract for a holon
|
|
31
|
+
* @param {string} holonId - Holon identifier
|
|
32
|
+
* @param {string} [type='Splitter'] - Contract type (Splitter, Managed, Zoned, Appreciative, Bundle)
|
|
33
|
+
* @param {Object} [options] - Deployment options
|
|
34
|
+
* @returns {Promise<{contract, address, operations}>}
|
|
35
|
+
*/
|
|
36
|
+
async deploy(holonId, type = 'Splitter', options = {}) {
|
|
37
|
+
if (this.holonContracts.has(holonId)) {
|
|
38
|
+
throw new Error(`Holon ${holonId} already has a contract. Use unlink() first to remove it.`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const name = options.name || holonId;
|
|
42
|
+
const creatorUserId = options.creatorUserId || holonId;
|
|
43
|
+
let result;
|
|
44
|
+
|
|
45
|
+
switch (type) {
|
|
46
|
+
case 'Splitter':
|
|
47
|
+
result = await this.deployer.deploySplitter(
|
|
48
|
+
holonId,
|
|
49
|
+
name,
|
|
50
|
+
options.splitPercentage || 70,
|
|
51
|
+
{ creatorUserId, ...options }
|
|
52
|
+
);
|
|
53
|
+
break;
|
|
54
|
+
|
|
55
|
+
case 'Managed':
|
|
56
|
+
result = await this.deployer.deployManaged(name, options);
|
|
57
|
+
break;
|
|
58
|
+
|
|
59
|
+
case 'Zoned':
|
|
60
|
+
result = await this.deployer.deployZoned(name, options.nZones || 6, options);
|
|
61
|
+
break;
|
|
62
|
+
|
|
63
|
+
case 'Appreciative':
|
|
64
|
+
result = await this.deployer.deployAppreciative(name, creatorUserId, options);
|
|
65
|
+
break;
|
|
66
|
+
|
|
67
|
+
case 'Bundle':
|
|
68
|
+
result = await this.deployer.deployBundle(
|
|
69
|
+
name,
|
|
70
|
+
options.steepness,
|
|
71
|
+
options.nZones || 6,
|
|
72
|
+
{ creatorUserId, ...options }
|
|
73
|
+
);
|
|
74
|
+
break;
|
|
75
|
+
|
|
76
|
+
default:
|
|
77
|
+
throw new Error(`Unknown contract type: ${type}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Create operations wrapper
|
|
81
|
+
const operations = new ContractOperations(result.contract, type, this.chainManager);
|
|
82
|
+
|
|
83
|
+
// Store mapping
|
|
84
|
+
const holonData = {
|
|
85
|
+
holonId,
|
|
86
|
+
address: result.address,
|
|
87
|
+
type,
|
|
88
|
+
contract: result.contract,
|
|
89
|
+
operations,
|
|
90
|
+
deployedAt: new Date().toISOString(),
|
|
91
|
+
txHash: result.txHash
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
this.holonContracts.set(holonId, holonData);
|
|
95
|
+
|
|
96
|
+
// Persist if storage available
|
|
97
|
+
await this._saveMapping(holonId, holonData);
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
contract: result.contract,
|
|
101
|
+
address: result.address,
|
|
102
|
+
operations,
|
|
103
|
+
txHash: result.txHash,
|
|
104
|
+
type
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Link a holon to an existing contract
|
|
110
|
+
* @param {string} holonId - Holon identifier
|
|
111
|
+
* @param {string} contractAddress - Existing contract address
|
|
112
|
+
* @param {string} [type='Splitter'] - Contract type
|
|
113
|
+
* @returns {Promise<{contract, address, operations}>}
|
|
114
|
+
*/
|
|
115
|
+
async link(holonId, contractAddress, type = 'Splitter') {
|
|
116
|
+
if (this.holonContracts.has(holonId)) {
|
|
117
|
+
throw new Error(`Holon ${holonId} already has a contract. Use unlink() first.`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const abi = ABIs[type];
|
|
121
|
+
if (!abi) {
|
|
122
|
+
throw new Error(`Unknown contract type: ${type}`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Create contract instance
|
|
126
|
+
const contract = await this.chainManager.getContract(contractAddress, abi.abi);
|
|
127
|
+
|
|
128
|
+
// Verify it's a valid contract by calling a read method
|
|
129
|
+
try {
|
|
130
|
+
await contract.name();
|
|
131
|
+
} catch (error) {
|
|
132
|
+
throw new Error(`Invalid contract at ${contractAddress}: ${error.message}`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Create operations wrapper
|
|
136
|
+
const operations = new ContractOperations(contract, type, this.chainManager);
|
|
137
|
+
|
|
138
|
+
// Store mapping
|
|
139
|
+
const holonData = {
|
|
140
|
+
holonId,
|
|
141
|
+
address: contractAddress,
|
|
142
|
+
type,
|
|
143
|
+
contract,
|
|
144
|
+
operations,
|
|
145
|
+
linkedAt: new Date().toISOString()
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
this.holonContracts.set(holonId, holonData);
|
|
149
|
+
|
|
150
|
+
// Persist if storage available
|
|
151
|
+
await this._saveMapping(holonId, holonData);
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
contract,
|
|
155
|
+
address: contractAddress,
|
|
156
|
+
operations,
|
|
157
|
+
type
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Unlink a holon from its contract
|
|
163
|
+
* @param {string} holonId - Holon identifier
|
|
164
|
+
* @returns {boolean} True if unlinked, false if no contract was linked
|
|
165
|
+
*/
|
|
166
|
+
async unlink(holonId) {
|
|
167
|
+
if (!this.holonContracts.has(holonId)) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
this.holonContracts.delete(holonId);
|
|
172
|
+
|
|
173
|
+
// Remove from storage if available
|
|
174
|
+
if (this.storage) {
|
|
175
|
+
await this.storage.delete?.(`holon_contract:${holonId}`);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Get contract for a holon
|
|
183
|
+
* @param {string} holonId - Holon identifier
|
|
184
|
+
* @returns {Contract|null}
|
|
185
|
+
*/
|
|
186
|
+
getContract(holonId) {
|
|
187
|
+
const data = this.holonContracts.get(holonId);
|
|
188
|
+
return data?.contract || null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Get contract address for a holon
|
|
193
|
+
* @param {string} holonId - Holon identifier
|
|
194
|
+
* @returns {string|null}
|
|
195
|
+
*/
|
|
196
|
+
getAddress(holonId) {
|
|
197
|
+
const data = this.holonContracts.get(holonId);
|
|
198
|
+
return data?.address || null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Get operations wrapper for a holon
|
|
203
|
+
* @param {string} holonId - Holon identifier
|
|
204
|
+
* @returns {ContractOperations|null}
|
|
205
|
+
*/
|
|
206
|
+
getOperations(holonId) {
|
|
207
|
+
const data = this.holonContracts.get(holonId);
|
|
208
|
+
return data?.operations || null;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Get contract type for a holon
|
|
213
|
+
* @param {string} holonId - Holon identifier
|
|
214
|
+
* @returns {string|null}
|
|
215
|
+
*/
|
|
216
|
+
getType(holonId) {
|
|
217
|
+
const data = this.holonContracts.get(holonId);
|
|
218
|
+
return data?.type || null;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Check if a holon has a contract
|
|
223
|
+
* @param {string} holonId - Holon identifier
|
|
224
|
+
* @returns {boolean}
|
|
225
|
+
*/
|
|
226
|
+
hasContract(holonId) {
|
|
227
|
+
return this.holonContracts.has(holonId);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Get all holon-contract mappings
|
|
232
|
+
* @returns {Array<{holonId, address, type}>}
|
|
233
|
+
*/
|
|
234
|
+
listAll() {
|
|
235
|
+
const result = [];
|
|
236
|
+
for (const [holonId, data] of this.holonContracts) {
|
|
237
|
+
result.push({
|
|
238
|
+
holonId,
|
|
239
|
+
address: data.address,
|
|
240
|
+
type: data.type,
|
|
241
|
+
deployedAt: data.deployedAt,
|
|
242
|
+
linkedAt: data.linkedAt
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Get holons by contract type
|
|
250
|
+
* @param {string} type - Contract type
|
|
251
|
+
* @returns {Array<{holonId, address}>}
|
|
252
|
+
*/
|
|
253
|
+
getByType(type) {
|
|
254
|
+
const result = [];
|
|
255
|
+
for (const [holonId, data] of this.holonContracts) {
|
|
256
|
+
if (data.type === type) {
|
|
257
|
+
result.push({
|
|
258
|
+
holonId,
|
|
259
|
+
address: data.address
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return result;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Load holon-contract mappings from storage
|
|
268
|
+
* @returns {Promise<number>} Number of mappings loaded
|
|
269
|
+
*/
|
|
270
|
+
async loadFromStorage() {
|
|
271
|
+
if (!this.storage) {
|
|
272
|
+
return 0;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const mappings = await this.storage.get?.('holon_contracts_index') || [];
|
|
276
|
+
let loaded = 0;
|
|
277
|
+
|
|
278
|
+
for (const holonId of mappings) {
|
|
279
|
+
try {
|
|
280
|
+
const data = await this.storage.get?.(`holon_contract:${holonId}`);
|
|
281
|
+
if (data && data.address && data.type) {
|
|
282
|
+
// Recreate contract instance
|
|
283
|
+
const abi = ABIs[data.type];
|
|
284
|
+
if (abi) {
|
|
285
|
+
const contract = await this.chainManager.getContract(data.address, abi.abi);
|
|
286
|
+
const operations = new ContractOperations(contract, data.type, this.chainManager);
|
|
287
|
+
|
|
288
|
+
this.holonContracts.set(holonId, {
|
|
289
|
+
...data,
|
|
290
|
+
contract,
|
|
291
|
+
operations
|
|
292
|
+
});
|
|
293
|
+
loaded++;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
} catch (error) {
|
|
297
|
+
console.warn(`Failed to load contract for holon ${holonId}: ${error.message}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return loaded;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Save a holon-contract mapping to storage
|
|
306
|
+
* @private
|
|
307
|
+
*/
|
|
308
|
+
async _saveMapping(holonId, data) {
|
|
309
|
+
if (!this.storage) return;
|
|
310
|
+
|
|
311
|
+
// Save the mapping (without contract/operations which can't be serialized)
|
|
312
|
+
await this.storage.set?.(`holon_contract:${holonId}`, {
|
|
313
|
+
holonId: data.holonId,
|
|
314
|
+
address: data.address,
|
|
315
|
+
type: data.type,
|
|
316
|
+
deployedAt: data.deployedAt,
|
|
317
|
+
linkedAt: data.linkedAt,
|
|
318
|
+
txHash: data.txHash
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
// Update index
|
|
322
|
+
const index = await this.storage.get?.('holon_contracts_index') || [];
|
|
323
|
+
if (!index.includes(holonId)) {
|
|
324
|
+
index.push(holonId);
|
|
325
|
+
await this.storage.set?.('holon_contracts_index', index);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Get required holon operations (throws if not linked)
|
|
331
|
+
* @param {string} holonId - Holon identifier
|
|
332
|
+
* @returns {ContractOperations}
|
|
333
|
+
* @throws {Error} If holon has no contract
|
|
334
|
+
*/
|
|
335
|
+
requireOperations(holonId) {
|
|
336
|
+
const ops = this.getOperations(holonId);
|
|
337
|
+
if (!ops) {
|
|
338
|
+
throw new Error(`Holon ${holonId} has no linked contract. Deploy or link one first.`);
|
|
339
|
+
}
|
|
340
|
+
return ops;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export default HolonContracts;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Holosphere Contracts Module
|
|
3
|
+
* Smart contract integration for fractal fund distribution
|
|
4
|
+
*
|
|
5
|
+
* @module contracts
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Core classes
|
|
9
|
+
export { ChainManager } from './chain-manager.js';
|
|
10
|
+
export { ContractDeployer, ABIs } from './deployer.js';
|
|
11
|
+
export { HolonContracts } from './holon-contracts.js';
|
|
12
|
+
export { ContractOperations } from './operations.js';
|
|
13
|
+
export { EventListener, SANKEY_EVENTS } from './event-listener.js';
|
|
14
|
+
export { ContractQueries } from './queries.js';
|
|
15
|
+
|
|
16
|
+
// Network utilities
|
|
17
|
+
export {
|
|
18
|
+
NETWORKS,
|
|
19
|
+
getNetwork,
|
|
20
|
+
getNetworksByType,
|
|
21
|
+
listNetworks,
|
|
22
|
+
isNetworkSupported,
|
|
23
|
+
getTxUrl,
|
|
24
|
+
getAddressUrl
|
|
25
|
+
} from './networks.js';
|
|
26
|
+
|
|
27
|
+
// Re-export ABIs for direct access
|
|
28
|
+
import SplitterABI from './abis/Splitter.json' with { type: 'json' };
|
|
29
|
+
import ManagedABI from './abis/Managed.json' with { type: 'json' };
|
|
30
|
+
import ZonedABI from './abis/Zoned.json' with { type: 'json' };
|
|
31
|
+
import AppreciativeABI from './abis/Appreciative.json' with { type: 'json' };
|
|
32
|
+
import BundleABI from './abis/Bundle.json' with { type: 'json' };
|
|
33
|
+
import HolonsABI from './abis/Holons.json' with { type: 'json' };
|
|
34
|
+
import TestTokenABI from './abis/TestToken.json' with { type: 'json' };
|
|
35
|
+
|
|
36
|
+
export const ContractABIs = {
|
|
37
|
+
Splitter: SplitterABI,
|
|
38
|
+
Managed: ManagedABI,
|
|
39
|
+
Zoned: ZonedABI,
|
|
40
|
+
Appreciative: AppreciativeABI,
|
|
41
|
+
Bundle: BundleABI,
|
|
42
|
+
Holons: HolonsABI,
|
|
43
|
+
TestToken: TestTokenABI
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Import for default export
|
|
47
|
+
import { ChainManager } from './chain-manager.js';
|
|
48
|
+
import { ContractDeployer } from './deployer.js';
|
|
49
|
+
import { HolonContracts } from './holon-contracts.js';
|
|
50
|
+
import { ContractOperations } from './operations.js';
|
|
51
|
+
import { EventListener, SANKEY_EVENTS } from './event-listener.js';
|
|
52
|
+
import { ContractQueries } from './queries.js';
|
|
53
|
+
import { NETWORKS } from './networks.js';
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Create a complete contracts module instance
|
|
57
|
+
* @param {Object} [config] - Configuration options
|
|
58
|
+
* @returns {Promise<Object>} Contracts module with all components
|
|
59
|
+
*/
|
|
60
|
+
export async function createContractsModule(config = {}) {
|
|
61
|
+
const chainManager = new ChainManager(config);
|
|
62
|
+
const deployer = new ContractDeployer(chainManager);
|
|
63
|
+
const holonContracts = new HolonContracts(chainManager, deployer);
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
chainManager,
|
|
67
|
+
deployer,
|
|
68
|
+
holonContracts
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default {
|
|
73
|
+
ChainManager,
|
|
74
|
+
ContractDeployer,
|
|
75
|
+
HolonContracts,
|
|
76
|
+
ContractOperations,
|
|
77
|
+
EventListener,
|
|
78
|
+
ContractQueries,
|
|
79
|
+
SANKEY_EVENTS,
|
|
80
|
+
NETWORKS,
|
|
81
|
+
ABIs: ContractABIs,
|
|
82
|
+
createContractsModule
|
|
83
|
+
};
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-chain network configurations for Holosphere contracts
|
|
3
|
+
* Supports Ethereum, Polygon, Arbitrum, Base, Optimism and testnets
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const NETWORKS = {
|
|
7
|
+
// ========== MAINNETS ==========
|
|
8
|
+
ethereum: {
|
|
9
|
+
name: 'Ethereum Mainnet',
|
|
10
|
+
chainId: 1,
|
|
11
|
+
rpc: 'https://eth.llamarpc.com',
|
|
12
|
+
explorer: 'https://etherscan.io',
|
|
13
|
+
currency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
|
14
|
+
type: 'mainnet'
|
|
15
|
+
},
|
|
16
|
+
polygon: {
|
|
17
|
+
name: 'Polygon Mainnet',
|
|
18
|
+
chainId: 137,
|
|
19
|
+
rpc: 'https://polygon-rpc.com',
|
|
20
|
+
explorer: 'https://polygonscan.com',
|
|
21
|
+
currency: { name: 'MATIC', symbol: 'MATIC', decimals: 18 },
|
|
22
|
+
type: 'mainnet'
|
|
23
|
+
},
|
|
24
|
+
arbitrum: {
|
|
25
|
+
name: 'Arbitrum One',
|
|
26
|
+
chainId: 42161,
|
|
27
|
+
rpc: 'https://arb1.arbitrum.io/rpc',
|
|
28
|
+
explorer: 'https://arbiscan.io',
|
|
29
|
+
currency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
|
30
|
+
type: 'mainnet'
|
|
31
|
+
},
|
|
32
|
+
base: {
|
|
33
|
+
name: 'Base',
|
|
34
|
+
chainId: 8453,
|
|
35
|
+
rpc: 'https://mainnet.base.org',
|
|
36
|
+
explorer: 'https://basescan.org',
|
|
37
|
+
currency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
|
38
|
+
type: 'mainnet'
|
|
39
|
+
},
|
|
40
|
+
optimism: {
|
|
41
|
+
name: 'Optimism',
|
|
42
|
+
chainId: 10,
|
|
43
|
+
rpc: 'https://mainnet.optimism.io',
|
|
44
|
+
explorer: 'https://optimistic.etherscan.io',
|
|
45
|
+
currency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
|
46
|
+
type: 'mainnet'
|
|
47
|
+
},
|
|
48
|
+
avalanche: {
|
|
49
|
+
name: 'Avalanche C-Chain',
|
|
50
|
+
chainId: 43114,
|
|
51
|
+
rpc: 'https://api.avax.network/ext/bc/C/rpc',
|
|
52
|
+
explorer: 'https://snowtrace.io',
|
|
53
|
+
currency: { name: 'AVAX', symbol: 'AVAX', decimals: 18 },
|
|
54
|
+
type: 'mainnet'
|
|
55
|
+
},
|
|
56
|
+
bsc: {
|
|
57
|
+
name: 'BNB Smart Chain',
|
|
58
|
+
chainId: 56,
|
|
59
|
+
rpc: 'https://bsc-dataseed.binance.org',
|
|
60
|
+
explorer: 'https://bscscan.com',
|
|
61
|
+
currency: { name: 'BNB', symbol: 'BNB', decimals: 18 },
|
|
62
|
+
type: 'mainnet'
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
// ========== TESTNETS ==========
|
|
66
|
+
sepolia: {
|
|
67
|
+
name: 'Sepolia',
|
|
68
|
+
chainId: 11155111,
|
|
69
|
+
rpc: 'https://rpc.sepolia.org',
|
|
70
|
+
explorer: 'https://sepolia.etherscan.io',
|
|
71
|
+
currency: { name: 'Sepolia ETH', symbol: 'ETH', decimals: 18 },
|
|
72
|
+
type: 'testnet',
|
|
73
|
+
faucet: 'https://sepoliafaucet.com'
|
|
74
|
+
},
|
|
75
|
+
goerli: {
|
|
76
|
+
name: 'Goerli',
|
|
77
|
+
chainId: 5,
|
|
78
|
+
rpc: 'https://rpc.goerli.eth.gateway.fm',
|
|
79
|
+
explorer: 'https://goerli.etherscan.io',
|
|
80
|
+
currency: { name: 'Goerli ETH', symbol: 'ETH', decimals: 18 },
|
|
81
|
+
type: 'testnet',
|
|
82
|
+
faucet: 'https://goerlifaucet.com'
|
|
83
|
+
},
|
|
84
|
+
mumbai: {
|
|
85
|
+
name: 'Polygon Mumbai',
|
|
86
|
+
chainId: 80001,
|
|
87
|
+
rpc: 'https://rpc-mumbai.maticvigil.com',
|
|
88
|
+
explorer: 'https://mumbai.polygonscan.com',
|
|
89
|
+
currency: { name: 'MATIC', symbol: 'MATIC', decimals: 18 },
|
|
90
|
+
type: 'testnet',
|
|
91
|
+
faucet: 'https://faucet.polygon.technology'
|
|
92
|
+
},
|
|
93
|
+
amoy: {
|
|
94
|
+
name: 'Polygon Amoy',
|
|
95
|
+
chainId: 80002,
|
|
96
|
+
rpc: 'https://rpc-amoy.polygon.technology',
|
|
97
|
+
explorer: 'https://amoy.polygonscan.com',
|
|
98
|
+
currency: { name: 'MATIC', symbol: 'MATIC', decimals: 18 },
|
|
99
|
+
type: 'testnet',
|
|
100
|
+
faucet: 'https://faucet.polygon.technology'
|
|
101
|
+
},
|
|
102
|
+
arbitrumSepolia: {
|
|
103
|
+
name: 'Arbitrum Sepolia',
|
|
104
|
+
chainId: 421614,
|
|
105
|
+
rpc: 'https://sepolia-rollup.arbitrum.io/rpc',
|
|
106
|
+
explorer: 'https://sepolia.arbiscan.io',
|
|
107
|
+
currency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
|
108
|
+
type: 'testnet'
|
|
109
|
+
},
|
|
110
|
+
baseSepolia: {
|
|
111
|
+
name: 'Base Sepolia',
|
|
112
|
+
chainId: 84532,
|
|
113
|
+
rpc: 'https://sepolia.base.org',
|
|
114
|
+
explorer: 'https://sepolia.basescan.org',
|
|
115
|
+
currency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
|
116
|
+
type: 'testnet'
|
|
117
|
+
},
|
|
118
|
+
optimismSepolia: {
|
|
119
|
+
name: 'Optimism Sepolia',
|
|
120
|
+
chainId: 11155420,
|
|
121
|
+
rpc: 'https://sepolia.optimism.io',
|
|
122
|
+
explorer: 'https://sepolia-optimism.etherscan.io',
|
|
123
|
+
currency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
|
124
|
+
type: 'testnet'
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
// ========== LOCAL ==========
|
|
128
|
+
hardhat: {
|
|
129
|
+
name: 'Hardhat Local',
|
|
130
|
+
chainId: 31337,
|
|
131
|
+
rpc: 'http://127.0.0.1:8545',
|
|
132
|
+
explorer: null,
|
|
133
|
+
currency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
|
134
|
+
type: 'local'
|
|
135
|
+
},
|
|
136
|
+
anvil: {
|
|
137
|
+
name: 'Anvil Local',
|
|
138
|
+
chainId: 31337,
|
|
139
|
+
rpc: 'http://127.0.0.1:8545',
|
|
140
|
+
explorer: null,
|
|
141
|
+
currency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
|
142
|
+
type: 'local'
|
|
143
|
+
},
|
|
144
|
+
ganache: {
|
|
145
|
+
name: 'Ganache Local',
|
|
146
|
+
chainId: 1337,
|
|
147
|
+
rpc: 'http://127.0.0.1:7545',
|
|
148
|
+
explorer: null,
|
|
149
|
+
currency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
|
150
|
+
type: 'local'
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Get network configuration by name or chain ID
|
|
156
|
+
* @param {string|number} networkOrChainId - Network name or chain ID
|
|
157
|
+
* @returns {Object|null} Network configuration or null if not found
|
|
158
|
+
*/
|
|
159
|
+
export function getNetwork(networkOrChainId) {
|
|
160
|
+
if (typeof networkOrChainId === 'string') {
|
|
161
|
+
return NETWORKS[networkOrChainId] || null;
|
|
162
|
+
}
|
|
163
|
+
// Search by chain ID
|
|
164
|
+
for (const [name, config] of Object.entries(NETWORKS)) {
|
|
165
|
+
if (config.chainId === networkOrChainId) {
|
|
166
|
+
return { ...config, key: name };
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get all networks of a specific type
|
|
174
|
+
* @param {'mainnet'|'testnet'|'local'} type - Network type
|
|
175
|
+
* @returns {Object} Networks of the specified type
|
|
176
|
+
*/
|
|
177
|
+
export function getNetworksByType(type) {
|
|
178
|
+
return Object.fromEntries(
|
|
179
|
+
Object.entries(NETWORKS).filter(([_, config]) => config.type === type)
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* List all available network names
|
|
185
|
+
* @returns {string[]} Array of network names
|
|
186
|
+
*/
|
|
187
|
+
export function listNetworks() {
|
|
188
|
+
return Object.keys(NETWORKS);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Check if a network is supported
|
|
193
|
+
* @param {string} network - Network name
|
|
194
|
+
* @returns {boolean}
|
|
195
|
+
*/
|
|
196
|
+
export function isNetworkSupported(network) {
|
|
197
|
+
return network in NETWORKS;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Get explorer URL for a transaction
|
|
202
|
+
* @param {string} network - Network name
|
|
203
|
+
* @param {string} txHash - Transaction hash
|
|
204
|
+
* @returns {string|null} Explorer URL or null
|
|
205
|
+
*/
|
|
206
|
+
export function getTxUrl(network, txHash) {
|
|
207
|
+
const config = NETWORKS[network];
|
|
208
|
+
if (!config?.explorer) return null;
|
|
209
|
+
return `${config.explorer}/tx/${txHash}`;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Get explorer URL for an address
|
|
214
|
+
* @param {string} network - Network name
|
|
215
|
+
* @param {string} address - Contract or wallet address
|
|
216
|
+
* @returns {string|null} Explorer URL or null
|
|
217
|
+
*/
|
|
218
|
+
export function getAddressUrl(network, address) {
|
|
219
|
+
const config = NETWORKS[network];
|
|
220
|
+
if (!config?.explorer) return null;
|
|
221
|
+
return `${config.explorer}/address/${address}`;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export default NETWORKS;
|