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,154 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"type": "constructor",
|
|
4
|
+
"inputs": [
|
|
5
|
+
{
|
|
6
|
+
"name": "_botAddress",
|
|
7
|
+
"type": "address",
|
|
8
|
+
"internalType": "address"
|
|
9
|
+
}
|
|
10
|
+
],
|
|
11
|
+
"stateMutability": "nonpayable"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"type": "function",
|
|
15
|
+
"name": "botAddress",
|
|
16
|
+
"inputs": [],
|
|
17
|
+
"outputs": [
|
|
18
|
+
{
|
|
19
|
+
"name": "",
|
|
20
|
+
"type": "address",
|
|
21
|
+
"internalType": "address"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"stateMutability": "view"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"type": "function",
|
|
28
|
+
"name": "createZoned",
|
|
29
|
+
"inputs": [
|
|
30
|
+
{
|
|
31
|
+
"name": "_creatorUserId",
|
|
32
|
+
"type": "string",
|
|
33
|
+
"internalType": "string"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "_name",
|
|
37
|
+
"type": "string",
|
|
38
|
+
"internalType": "string"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "_parameter",
|
|
42
|
+
"type": "uint256",
|
|
43
|
+
"internalType": "uint256"
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"outputs": [
|
|
47
|
+
{
|
|
48
|
+
"name": "",
|
|
49
|
+
"type": "address",
|
|
50
|
+
"internalType": "address"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"stateMutability": "nonpayable"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"type": "function",
|
|
57
|
+
"name": "listHolons",
|
|
58
|
+
"inputs": [],
|
|
59
|
+
"outputs": [
|
|
60
|
+
{
|
|
61
|
+
"name": "",
|
|
62
|
+
"type": "address[]",
|
|
63
|
+
"internalType": "address[]"
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"stateMutability": "view"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"type": "function",
|
|
70
|
+
"name": "listHolonsOf",
|
|
71
|
+
"inputs": [
|
|
72
|
+
{
|
|
73
|
+
"name": "_address",
|
|
74
|
+
"type": "address",
|
|
75
|
+
"internalType": "address"
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"outputs": [
|
|
79
|
+
{
|
|
80
|
+
"name": "",
|
|
81
|
+
"type": "address[]",
|
|
82
|
+
"internalType": "address[]"
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
"stateMutability": "view"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"type": "function",
|
|
89
|
+
"name": "newHolon",
|
|
90
|
+
"inputs": [
|
|
91
|
+
{
|
|
92
|
+
"name": "creatorUserId",
|
|
93
|
+
"type": "string",
|
|
94
|
+
"internalType": "string"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "_name",
|
|
98
|
+
"type": "string",
|
|
99
|
+
"internalType": "string"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "_parameter",
|
|
103
|
+
"type": "uint256",
|
|
104
|
+
"internalType": "uint256"
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"outputs": [
|
|
108
|
+
{
|
|
109
|
+
"name": "",
|
|
110
|
+
"type": "address",
|
|
111
|
+
"internalType": "address"
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
"stateMutability": "nonpayable"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "function",
|
|
118
|
+
"name": "toAddress",
|
|
119
|
+
"inputs": [
|
|
120
|
+
{
|
|
121
|
+
"name": "",
|
|
122
|
+
"type": "string",
|
|
123
|
+
"internalType": "string"
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"outputs": [
|
|
127
|
+
{
|
|
128
|
+
"name": "",
|
|
129
|
+
"type": "address",
|
|
130
|
+
"internalType": "address"
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
"stateMutability": "view"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"type": "event",
|
|
137
|
+
"name": "NewHolon",
|
|
138
|
+
"inputs": [
|
|
139
|
+
{
|
|
140
|
+
"name": "name",
|
|
141
|
+
"type": "string",
|
|
142
|
+
"indexed": false,
|
|
143
|
+
"internalType": "string"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"name": "addr",
|
|
147
|
+
"type": "address",
|
|
148
|
+
"indexed": false,
|
|
149
|
+
"internalType": "address"
|
|
150
|
+
}
|
|
151
|
+
],
|
|
152
|
+
"anonymous": false
|
|
153
|
+
}
|
|
154
|
+
]
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChainManager - Multi-chain connection management for Holosphere contracts
|
|
3
|
+
* Handles provider/signer setup, network switching, and wallet management
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { NETWORKS, getNetwork, isNetworkSupported } from './networks.js';
|
|
7
|
+
|
|
8
|
+
export class ChainManager {
|
|
9
|
+
constructor(config = {}) {
|
|
10
|
+
this.config = config;
|
|
11
|
+
this.provider = null;
|
|
12
|
+
this.signer = null;
|
|
13
|
+
this.network = null;
|
|
14
|
+
this.networkName = null;
|
|
15
|
+
this.ethers = null;
|
|
16
|
+
this._initialized = false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Initialize ethers.js (lazy load)
|
|
21
|
+
* @private
|
|
22
|
+
*/
|
|
23
|
+
async _loadEthers() {
|
|
24
|
+
if (!this.ethers) {
|
|
25
|
+
// Dynamic import for ethers
|
|
26
|
+
const ethersModule = await import('ethers');
|
|
27
|
+
this.ethers = ethersModule;
|
|
28
|
+
}
|
|
29
|
+
return this.ethers;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Connect to a network
|
|
34
|
+
* @param {string} networkName - Network name (e.g., 'sepolia', 'polygon')
|
|
35
|
+
* @param {string} [privateKey] - Private key for signing transactions
|
|
36
|
+
* @param {string} [rpcUrl] - Custom RPC URL (overrides default)
|
|
37
|
+
* @returns {Promise<{provider, signer, network}>}
|
|
38
|
+
*/
|
|
39
|
+
async connect(networkName, privateKey, rpcUrl) {
|
|
40
|
+
const ethers = await this._loadEthers();
|
|
41
|
+
|
|
42
|
+
if (!isNetworkSupported(networkName) && !rpcUrl) {
|
|
43
|
+
throw new Error(`Unsupported network: ${networkName}. Use a custom rpcUrl or choose from: ${Object.keys(NETWORKS).join(', ')}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const networkConfig = getNetwork(networkName) || { chainId: 0, name: networkName };
|
|
47
|
+
const url = rpcUrl || networkConfig.rpc;
|
|
48
|
+
|
|
49
|
+
// Create provider
|
|
50
|
+
this.provider = new ethers.JsonRpcProvider(url, {
|
|
51
|
+
chainId: networkConfig.chainId,
|
|
52
|
+
name: networkConfig.name
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Wait for provider to be ready
|
|
56
|
+
await this.provider.ready;
|
|
57
|
+
|
|
58
|
+
// Get actual network info
|
|
59
|
+
this.network = await this.provider.getNetwork();
|
|
60
|
+
this.networkName = networkName;
|
|
61
|
+
|
|
62
|
+
// Create signer if private key provided
|
|
63
|
+
if (privateKey) {
|
|
64
|
+
// Remove 0x prefix if present
|
|
65
|
+
const cleanKey = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`;
|
|
66
|
+
this.signer = new ethers.Wallet(cleanKey, this.provider);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
this._initialized = true;
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
provider: this.provider,
|
|
73
|
+
signer: this.signer,
|
|
74
|
+
network: this.network,
|
|
75
|
+
networkName: this.networkName,
|
|
76
|
+
config: networkConfig
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Connect using browser wallet (MetaMask, etc.)
|
|
82
|
+
* @param {string} [networkName] - Optionally switch to this network
|
|
83
|
+
* @returns {Promise<{provider, signer, network, address}>}
|
|
84
|
+
*/
|
|
85
|
+
async connectBrowser(networkName) {
|
|
86
|
+
const ethers = await this._loadEthers();
|
|
87
|
+
|
|
88
|
+
if (typeof window === 'undefined' || !window.ethereum) {
|
|
89
|
+
throw new Error('No browser wallet detected. Please install MetaMask or another Web3 wallet.');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Request account access
|
|
93
|
+
await window.ethereum.request({ method: 'eth_requestAccounts' });
|
|
94
|
+
|
|
95
|
+
// Create provider from browser
|
|
96
|
+
this.provider = new ethers.BrowserProvider(window.ethereum);
|
|
97
|
+
this.signer = await this.provider.getSigner();
|
|
98
|
+
this.network = await this.provider.getNetwork();
|
|
99
|
+
|
|
100
|
+
// Switch network if requested
|
|
101
|
+
if (networkName && isNetworkSupported(networkName)) {
|
|
102
|
+
const targetConfig = getNetwork(networkName);
|
|
103
|
+
if (this.network.chainId !== BigInt(targetConfig.chainId)) {
|
|
104
|
+
await this.switchNetwork(networkName);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const address = await this.signer.getAddress();
|
|
109
|
+
this._initialized = true;
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
provider: this.provider,
|
|
113
|
+
signer: this.signer,
|
|
114
|
+
network: this.network,
|
|
115
|
+
address
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Switch to a different network (browser wallet only)
|
|
121
|
+
* @param {string} networkName - Target network name
|
|
122
|
+
*/
|
|
123
|
+
async switchNetwork(networkName) {
|
|
124
|
+
if (typeof window === 'undefined' || !window.ethereum) {
|
|
125
|
+
throw new Error('Network switching requires a browser wallet');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const config = getNetwork(networkName);
|
|
129
|
+
if (!config) {
|
|
130
|
+
throw new Error(`Unknown network: ${networkName}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const chainIdHex = '0x' + config.chainId.toString(16);
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
// Try to switch to the network
|
|
137
|
+
await window.ethereum.request({
|
|
138
|
+
method: 'wallet_switchEthereumChain',
|
|
139
|
+
params: [{ chainId: chainIdHex }]
|
|
140
|
+
});
|
|
141
|
+
} catch (switchError) {
|
|
142
|
+
// If the network doesn't exist, add it
|
|
143
|
+
if (switchError.code === 4902) {
|
|
144
|
+
await window.ethereum.request({
|
|
145
|
+
method: 'wallet_addEthereumChain',
|
|
146
|
+
params: [{
|
|
147
|
+
chainId: chainIdHex,
|
|
148
|
+
chainName: config.name,
|
|
149
|
+
nativeCurrency: config.currency,
|
|
150
|
+
rpcUrls: [config.rpc],
|
|
151
|
+
blockExplorerUrls: config.explorer ? [config.explorer] : []
|
|
152
|
+
}]
|
|
153
|
+
});
|
|
154
|
+
} else {
|
|
155
|
+
throw switchError;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Refresh provider/signer after network switch
|
|
160
|
+
const ethers = await this._loadEthers();
|
|
161
|
+
this.provider = new ethers.BrowserProvider(window.ethereum);
|
|
162
|
+
this.signer = await this.provider.getSigner();
|
|
163
|
+
this.network = await this.provider.getNetwork();
|
|
164
|
+
this.networkName = networkName;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get the current provider
|
|
169
|
+
* @returns {Provider}
|
|
170
|
+
*/
|
|
171
|
+
getProvider() {
|
|
172
|
+
this._requireInitialized();
|
|
173
|
+
return this.provider;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Get the current signer
|
|
178
|
+
* @returns {Signer}
|
|
179
|
+
*/
|
|
180
|
+
getSigner() {
|
|
181
|
+
this._requireInitialized();
|
|
182
|
+
if (!this.signer) {
|
|
183
|
+
throw new Error('No signer available. Connect with a private key or use connectBrowser().');
|
|
184
|
+
}
|
|
185
|
+
return this.signer;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Get the connected address
|
|
190
|
+
* @returns {Promise<string>}
|
|
191
|
+
*/
|
|
192
|
+
async getAddress() {
|
|
193
|
+
const signer = this.getSigner();
|
|
194
|
+
return signer.getAddress();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Get ETH balance of an address
|
|
199
|
+
* @param {string} [address] - Address to check (defaults to signer)
|
|
200
|
+
* @returns {Promise<string>} Balance in ETH
|
|
201
|
+
*/
|
|
202
|
+
async getBalance(address) {
|
|
203
|
+
this._requireInitialized();
|
|
204
|
+
const ethers = await this._loadEthers();
|
|
205
|
+
const addr = address || (this.signer ? await this.signer.getAddress() : null);
|
|
206
|
+
if (!addr) {
|
|
207
|
+
throw new Error('No address provided and no signer available');
|
|
208
|
+
}
|
|
209
|
+
const balance = await this.provider.getBalance(addr);
|
|
210
|
+
return ethers.formatEther(balance);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Get current network configuration
|
|
215
|
+
* @returns {Object}
|
|
216
|
+
*/
|
|
217
|
+
getNetworkConfig() {
|
|
218
|
+
this._requireInitialized();
|
|
219
|
+
return getNetwork(this.networkName);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Get current chain ID
|
|
224
|
+
* @returns {number}
|
|
225
|
+
*/
|
|
226
|
+
getChainId() {
|
|
227
|
+
this._requireInitialized();
|
|
228
|
+
return Number(this.network.chainId);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Check if connected to the expected network
|
|
233
|
+
* @param {string} expectedNetwork - Expected network name
|
|
234
|
+
* @returns {boolean}
|
|
235
|
+
*/
|
|
236
|
+
isOnNetwork(expectedNetwork) {
|
|
237
|
+
if (!this._initialized) return false;
|
|
238
|
+
const expected = getNetwork(expectedNetwork);
|
|
239
|
+
if (!expected) return false;
|
|
240
|
+
return this.getChainId() === expected.chainId;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Create a contract instance
|
|
245
|
+
* @param {string} address - Contract address
|
|
246
|
+
* @param {Array} abi - Contract ABI
|
|
247
|
+
* @param {boolean} [useSigner=true] - Use signer for write operations
|
|
248
|
+
* @returns {Contract}
|
|
249
|
+
*/
|
|
250
|
+
async getContract(address, abi, useSigner = true) {
|
|
251
|
+
this._requireInitialized();
|
|
252
|
+
const ethers = await this._loadEthers();
|
|
253
|
+
const signerOrProvider = useSigner && this.signer ? this.signer : this.provider;
|
|
254
|
+
return new ethers.Contract(address, abi, signerOrProvider);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Deploy a contract
|
|
259
|
+
* @param {Array} abi - Contract ABI
|
|
260
|
+
* @param {string} bytecode - Contract bytecode
|
|
261
|
+
* @param {Array} [constructorArgs=[]] - Constructor arguments
|
|
262
|
+
* @returns {Promise<{contract, address, deployTx}>}
|
|
263
|
+
*/
|
|
264
|
+
async deployContract(abi, bytecode, constructorArgs = []) {
|
|
265
|
+
this._requireInitialized();
|
|
266
|
+
if (!this.signer) {
|
|
267
|
+
throw new Error('Signer required for contract deployment');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const ethers = await this._loadEthers();
|
|
271
|
+
const factory = new ethers.ContractFactory(abi, bytecode, this.signer);
|
|
272
|
+
const contract = await factory.deploy(...constructorArgs);
|
|
273
|
+
|
|
274
|
+
// Wait for deployment
|
|
275
|
+
await contract.waitForDeployment();
|
|
276
|
+
const address = await contract.getAddress();
|
|
277
|
+
const deployTx = contract.deploymentTransaction();
|
|
278
|
+
|
|
279
|
+
return {
|
|
280
|
+
contract,
|
|
281
|
+
address,
|
|
282
|
+
deployTx,
|
|
283
|
+
txHash: deployTx?.hash
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Wait for a transaction to be mined
|
|
289
|
+
* @param {string} txHash - Transaction hash
|
|
290
|
+
* @param {number} [confirmations=1] - Number of confirmations to wait for
|
|
291
|
+
* @returns {Promise<TransactionReceipt>}
|
|
292
|
+
*/
|
|
293
|
+
async waitForTransaction(txHash, confirmations = 1) {
|
|
294
|
+
this._requireInitialized();
|
|
295
|
+
return this.provider.waitForTransaction(txHash, confirmations);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Estimate gas for a transaction
|
|
300
|
+
* @param {Object} tx - Transaction object
|
|
301
|
+
* @returns {Promise<bigint>}
|
|
302
|
+
*/
|
|
303
|
+
async estimateGas(tx) {
|
|
304
|
+
this._requireInitialized();
|
|
305
|
+
return this.provider.estimateGas(tx);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Get current gas price
|
|
310
|
+
* @returns {Promise<{gasPrice: string, maxFeePerGas: string, maxPriorityFeePerGas: string}>}
|
|
311
|
+
*/
|
|
312
|
+
async getGasPrice() {
|
|
313
|
+
this._requireInitialized();
|
|
314
|
+
const ethers = await this._loadEthers();
|
|
315
|
+
const feeData = await this.provider.getFeeData();
|
|
316
|
+
return {
|
|
317
|
+
gasPrice: feeData.gasPrice ? ethers.formatUnits(feeData.gasPrice, 'gwei') : null,
|
|
318
|
+
maxFeePerGas: feeData.maxFeePerGas ? ethers.formatUnits(feeData.maxFeePerGas, 'gwei') : null,
|
|
319
|
+
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas ? ethers.formatUnits(feeData.maxPriorityFeePerGas, 'gwei') : null
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Parse units (e.g., ETH to wei)
|
|
325
|
+
* @param {string|number} value - Value to parse
|
|
326
|
+
* @param {string|number} [unit='ether'] - Unit name or decimals
|
|
327
|
+
* @returns {bigint}
|
|
328
|
+
*/
|
|
329
|
+
async parseUnits(value, unit = 'ether') {
|
|
330
|
+
const ethers = await this._loadEthers();
|
|
331
|
+
return ethers.parseUnits(value.toString(), unit);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Format units (e.g., wei to ETH)
|
|
336
|
+
* @param {bigint|string} value - Value to format
|
|
337
|
+
* @param {string|number} [unit='ether'] - Unit name or decimals
|
|
338
|
+
* @returns {string}
|
|
339
|
+
*/
|
|
340
|
+
async formatUnits(value, unit = 'ether') {
|
|
341
|
+
const ethers = await this._loadEthers();
|
|
342
|
+
return ethers.formatUnits(value, unit);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Check if manager is initialized
|
|
347
|
+
* @private
|
|
348
|
+
*/
|
|
349
|
+
_requireInitialized() {
|
|
350
|
+
if (!this._initialized) {
|
|
351
|
+
throw new Error('ChainManager not initialized. Call connect() or connectBrowser() first.');
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Check if connected
|
|
357
|
+
* @returns {boolean}
|
|
358
|
+
*/
|
|
359
|
+
isConnected() {
|
|
360
|
+
return this._initialized && this.provider !== null;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Disconnect and clean up
|
|
365
|
+
*/
|
|
366
|
+
disconnect() {
|
|
367
|
+
this.provider = null;
|
|
368
|
+
this.signer = null;
|
|
369
|
+
this.network = null;
|
|
370
|
+
this.networkName = null;
|
|
371
|
+
this._initialized = false;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export default ChainManager;
|