@cofhe/sdk 0.0.0-alpha-20260409113701
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/CHANGELOG.md +146 -0
- package/adapters/ethers5.test.ts +174 -0
- package/adapters/ethers5.ts +36 -0
- package/adapters/ethers6.test.ts +169 -0
- package/adapters/ethers6.ts +36 -0
- package/adapters/hardhat-node.ts +167 -0
- package/adapters/hardhat.hh2.test.ts +159 -0
- package/adapters/hardhat.ts +36 -0
- package/adapters/index.test.ts +20 -0
- package/adapters/index.ts +5 -0
- package/adapters/smartWallet.ts +99 -0
- package/adapters/test-utils.ts +53 -0
- package/adapters/types.ts +6 -0
- package/adapters/wagmi.test.ts +156 -0
- package/adapters/wagmi.ts +17 -0
- package/chains/chains/arbSepolia.ts +14 -0
- package/chains/chains/baseSepolia.ts +14 -0
- package/chains/chains/hardhat.ts +15 -0
- package/chains/chains/localcofhe.ts +14 -0
- package/chains/chains/sepolia.ts +14 -0
- package/chains/chains.test.ts +50 -0
- package/chains/defineChain.ts +18 -0
- package/chains/index.ts +35 -0
- package/chains/types.ts +32 -0
- package/core/baseBuilder.ts +119 -0
- package/core/client.test.ts +429 -0
- package/core/client.ts +341 -0
- package/core/clientTypes.ts +119 -0
- package/core/config.test.ts +242 -0
- package/core/config.ts +225 -0
- package/core/consts.ts +22 -0
- package/core/decrypt/MockThresholdNetworkAbi.ts +179 -0
- package/core/decrypt/cofheMocksDecryptForTx.ts +84 -0
- package/core/decrypt/cofheMocksDecryptForView.ts +48 -0
- package/core/decrypt/decryptForTxBuilder.ts +359 -0
- package/core/decrypt/decryptForViewBuilder.ts +332 -0
- package/core/decrypt/decryptUtils.ts +28 -0
- package/core/decrypt/pollCallbacks.test.ts +194 -0
- package/core/decrypt/polling.ts +14 -0
- package/core/decrypt/tnDecryptUtils.ts +65 -0
- package/core/decrypt/tnDecryptV1.ts +171 -0
- package/core/decrypt/tnDecryptV2.ts +365 -0
- package/core/decrypt/tnSealOutputV1.ts +59 -0
- package/core/decrypt/tnSealOutputV2.ts +324 -0
- package/core/decrypt/verifyDecryptResult.ts +52 -0
- package/core/encrypt/MockZkVerifierAbi.ts +106 -0
- package/core/encrypt/cofheMocksZkVerifySign.ts +281 -0
- package/core/encrypt/encryptInputsBuilder.test.ts +747 -0
- package/core/encrypt/encryptInputsBuilder.ts +583 -0
- package/core/encrypt/encryptUtils.ts +67 -0
- package/core/encrypt/zkPackProveVerify.ts +335 -0
- package/core/error.ts +168 -0
- package/core/fetchKeys.test.ts +195 -0
- package/core/fetchKeys.ts +144 -0
- package/core/index.ts +106 -0
- package/core/keyStore.test.ts +226 -0
- package/core/keyStore.ts +154 -0
- package/core/permits.test.ts +493 -0
- package/core/permits.ts +201 -0
- package/core/types.ts +419 -0
- package/core/utils.ts +130 -0
- package/dist/adapters.cjs +88 -0
- package/dist/adapters.d.cts +14576 -0
- package/dist/adapters.d.ts +14576 -0
- package/dist/adapters.js +83 -0
- package/dist/chains.cjs +111 -0
- package/dist/chains.d.cts +121 -0
- package/dist/chains.d.ts +121 -0
- package/dist/chains.js +1 -0
- package/dist/chunk-36FBWLUS.js +3310 -0
- package/dist/chunk-7HLGHV67.js +990 -0
- package/dist/chunk-TBLR7NNE.js +102 -0
- package/dist/clientTypes-AVSCBet7.d.cts +998 -0
- package/dist/clientTypes-flH1ju82.d.ts +998 -0
- package/dist/core.cjs +4362 -0
- package/dist/core.d.cts +138 -0
- package/dist/core.d.ts +138 -0
- package/dist/core.js +3 -0
- package/dist/node.cjs +4225 -0
- package/dist/node.d.cts +22 -0
- package/dist/node.d.ts +22 -0
- package/dist/node.js +91 -0
- package/dist/permit-jRirYqFt.d.cts +376 -0
- package/dist/permit-jRirYqFt.d.ts +376 -0
- package/dist/permits.cjs +1025 -0
- package/dist/permits.d.cts +353 -0
- package/dist/permits.d.ts +353 -0
- package/dist/permits.js +1 -0
- package/dist/types-YiAC4gig.d.cts +33 -0
- package/dist/types-YiAC4gig.d.ts +33 -0
- package/dist/web.cjs +4434 -0
- package/dist/web.d.cts +42 -0
- package/dist/web.d.ts +42 -0
- package/dist/web.js +256 -0
- package/dist/zkProve.worker.cjs +93 -0
- package/dist/zkProve.worker.d.cts +2 -0
- package/dist/zkProve.worker.d.ts +2 -0
- package/dist/zkProve.worker.js +91 -0
- package/node/client.test.ts +159 -0
- package/node/config.test.ts +68 -0
- package/node/encryptInputs.test.ts +155 -0
- package/node/index.ts +97 -0
- package/node/storage.ts +51 -0
- package/package.json +121 -0
- package/permits/index.ts +68 -0
- package/permits/localstorage.test.ts +113 -0
- package/permits/onchain-utils.ts +221 -0
- package/permits/permit.test.ts +534 -0
- package/permits/permit.ts +386 -0
- package/permits/sealing.test.ts +84 -0
- package/permits/sealing.ts +131 -0
- package/permits/signature.ts +79 -0
- package/permits/store.test.ts +88 -0
- package/permits/store.ts +156 -0
- package/permits/test-utils.ts +28 -0
- package/permits/types.ts +204 -0
- package/permits/utils.ts +58 -0
- package/permits/validation.test.ts +361 -0
- package/permits/validation.ts +327 -0
- package/web/client.web.test.ts +159 -0
- package/web/config.web.test.ts +69 -0
- package/web/const.ts +2 -0
- package/web/encryptInputs.web.test.ts +172 -0
- package/web/index.ts +166 -0
- package/web/storage.ts +49 -0
- package/web/worker.builder.web.test.ts +148 -0
- package/web/worker.config.web.test.ts +329 -0
- package/web/worker.output.web.test.ts +84 -0
- package/web/workerManager.test.ts +80 -0
- package/web/workerManager.ts +214 -0
- package/web/workerManager.web.test.ts +114 -0
- package/web/zkProve.worker.ts +133 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { parseEther, createPublicClient, createWalletClient, http, type PublicClient, type WalletClient } from 'viem';
|
|
3
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
4
|
+
import { WagmiAdapter } from './wagmi.js';
|
|
5
|
+
|
|
6
|
+
describe('WagmiAdapter', () => {
|
|
7
|
+
const testRpcUrl = 'https://ethereum-sepolia.rpc.subquery.network/public';
|
|
8
|
+
const SEPOLIA_CHAIN_ID = 11155111;
|
|
9
|
+
let account: ReturnType<typeof privateKeyToAccount>;
|
|
10
|
+
let publicClient: PublicClient;
|
|
11
|
+
let walletClient: WalletClient;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
// Create common setup for all tests - no chain needed
|
|
15
|
+
account = privateKeyToAccount(('0x' + '1'.repeat(64)) as `0x${string}`);
|
|
16
|
+
|
|
17
|
+
publicClient = createPublicClient({
|
|
18
|
+
transport: http(testRpcUrl),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
walletClient = createWalletClient({
|
|
22
|
+
transport: http(testRpcUrl),
|
|
23
|
+
account,
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should work with real Wagmi clients', async () => {
|
|
28
|
+
const result = await WagmiAdapter(walletClient, publicClient);
|
|
29
|
+
|
|
30
|
+
expect(result).toHaveProperty('publicClient');
|
|
31
|
+
expect(result).toHaveProperty('walletClient');
|
|
32
|
+
expect(result.publicClient).toBe(publicClient);
|
|
33
|
+
expect(result.walletClient).toBe(walletClient);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should throw error when wallet client is missing', async () => {
|
|
37
|
+
const mockPublicClient = {} as any;
|
|
38
|
+
|
|
39
|
+
await expect(async () => {
|
|
40
|
+
await WagmiAdapter(null as any, mockPublicClient);
|
|
41
|
+
}).rejects.toThrow('WalletClient is required');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should throw error when public client is missing', async () => {
|
|
45
|
+
const mockWalletClient = {} as any;
|
|
46
|
+
|
|
47
|
+
await expect(async () => {
|
|
48
|
+
await WagmiAdapter(mockWalletClient, null as any);
|
|
49
|
+
}).rejects.toThrow('PublicClient is required');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('Provider Functions', () => {
|
|
53
|
+
it('should support getChainId', async () => {
|
|
54
|
+
const { publicClient: resultPublic } = await WagmiAdapter(walletClient, publicClient);
|
|
55
|
+
|
|
56
|
+
const chainId = await resultPublic.getChainId();
|
|
57
|
+
expect(typeof chainId).toBe('number');
|
|
58
|
+
expect(chainId).toBe(SEPOLIA_CHAIN_ID);
|
|
59
|
+
}, 10000);
|
|
60
|
+
|
|
61
|
+
it('should support call (contract read)', async () => {
|
|
62
|
+
const { publicClient: resultPublic } = await WagmiAdapter(walletClient, publicClient);
|
|
63
|
+
|
|
64
|
+
// Test eth_call - get ETH balance of zero address
|
|
65
|
+
const balance = await resultPublic.getBalance({
|
|
66
|
+
address: '0x0000000000000000000000000000000000000000',
|
|
67
|
+
});
|
|
68
|
+
expect(typeof balance).toBe('bigint');
|
|
69
|
+
}, 10000);
|
|
70
|
+
|
|
71
|
+
it('should support request (raw RPC)', async () => {
|
|
72
|
+
const { publicClient: resultPublic } = await WagmiAdapter(walletClient, publicClient);
|
|
73
|
+
|
|
74
|
+
// Test raw RPC request
|
|
75
|
+
const blockNumber = (await resultPublic.request({
|
|
76
|
+
method: 'eth_blockNumber',
|
|
77
|
+
})) as string;
|
|
78
|
+
expect(typeof blockNumber).toBe('string');
|
|
79
|
+
expect(blockNumber.startsWith('0x')).toBe(true);
|
|
80
|
+
}, 10000);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('Signer Functions', () => {
|
|
84
|
+
it('should support getAddress', async () => {
|
|
85
|
+
const { walletClient: resultWallet } = await WagmiAdapter(walletClient, publicClient);
|
|
86
|
+
|
|
87
|
+
const addresses = await resultWallet.getAddresses();
|
|
88
|
+
expect(Array.isArray(addresses)).toBe(true);
|
|
89
|
+
// Should contain the account address
|
|
90
|
+
expect(addresses).toContain(account.address);
|
|
91
|
+
}, 10000);
|
|
92
|
+
|
|
93
|
+
it('should support signTypedData', async () => {
|
|
94
|
+
const { walletClient: resultWallet } = await WagmiAdapter(walletClient, publicClient);
|
|
95
|
+
|
|
96
|
+
const domain = {
|
|
97
|
+
name: 'Test',
|
|
98
|
+
version: '1',
|
|
99
|
+
chainId: SEPOLIA_CHAIN_ID, // Sepolia
|
|
100
|
+
verifyingContract: '0x0000000000000000000000000000000000000000' as const,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const types = {
|
|
104
|
+
Message: [{ name: 'content', type: 'string' }],
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const message = { content: 'Hello World' };
|
|
108
|
+
|
|
109
|
+
const signature = await resultWallet.signTypedData({
|
|
110
|
+
domain,
|
|
111
|
+
types,
|
|
112
|
+
primaryType: 'Message',
|
|
113
|
+
message,
|
|
114
|
+
account: resultWallet.account!,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
expect(typeof signature).toBe('string');
|
|
118
|
+
expect(signature.startsWith('0x')).toBe(true);
|
|
119
|
+
}, 10000);
|
|
120
|
+
|
|
121
|
+
it('should support sendTransaction', async () => {
|
|
122
|
+
const { publicClient: resultPublic, walletClient: resultWallet } = await WagmiAdapter(walletClient, publicClient);
|
|
123
|
+
|
|
124
|
+
// Try to send a transaction - this will fail due to insufficient funds
|
|
125
|
+
try {
|
|
126
|
+
console.log('estimating gas');
|
|
127
|
+
const gas = await resultPublic.estimateGas({
|
|
128
|
+
account: account.address,
|
|
129
|
+
to: '0x0000000000000000000000000000000000000000',
|
|
130
|
+
value: parseEther('0'),
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
console.log('sending transaction', account.address);
|
|
134
|
+
const hash = await resultWallet.sendTransaction({
|
|
135
|
+
to: '0x0000000000000000000000000000000000000000' as `0x${string}`,
|
|
136
|
+
value: parseEther('0'),
|
|
137
|
+
gas,
|
|
138
|
+
account: resultWallet.account!,
|
|
139
|
+
chain: resultWallet.chain,
|
|
140
|
+
});
|
|
141
|
+
console.log('transaction sent', hash);
|
|
142
|
+
|
|
143
|
+
// If it succeeds (shouldn't due to no funds), verify the format
|
|
144
|
+
expect(typeof hash).toBe('string');
|
|
145
|
+
expect(hash.startsWith('0x')).toBe(true);
|
|
146
|
+
expect(hash.length).toBe(66);
|
|
147
|
+
} catch (error: any) {
|
|
148
|
+
// Expected error: insufficient funds (good!)
|
|
149
|
+
const isInsufficientFunds = error.message.includes('insufficient funds') || error.message.includes('balance');
|
|
150
|
+
|
|
151
|
+
expect(isInsufficientFunds).toBe(true);
|
|
152
|
+
console.log('Expected error (insufficient funds):', error.message);
|
|
153
|
+
}
|
|
154
|
+
}, 10000);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type PublicClient, type WalletClient } from 'viem';
|
|
2
|
+
|
|
3
|
+
export async function WagmiAdapter(walletClient: WalletClient, publicClient: PublicClient) {
|
|
4
|
+
if (!walletClient) {
|
|
5
|
+
throw new Error('WalletClient is required');
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (!publicClient) {
|
|
9
|
+
throw new Error('PublicClient is required');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Wagmi provides real viem clients, so we just pass them through
|
|
13
|
+
return {
|
|
14
|
+
publicClient,
|
|
15
|
+
walletClient,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineChain } from '../defineChain.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Arbitrum Sepolia testnet chain configuration
|
|
5
|
+
*/
|
|
6
|
+
export const arbSepolia = defineChain({
|
|
7
|
+
id: 421614,
|
|
8
|
+
name: 'Arbitrum Sepolia',
|
|
9
|
+
network: 'arb-sepolia',
|
|
10
|
+
coFheUrl: 'https://testnet-cofhe.fhenix.zone',
|
|
11
|
+
verifierUrl: 'https://testnet-cofhe-vrf.fhenix.zone',
|
|
12
|
+
thresholdNetworkUrl: 'https://testnet-cofhe-tn.fhenix.zone',
|
|
13
|
+
environment: 'TESTNET',
|
|
14
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineChain } from '../defineChain.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base Sepolia testnet chain configuration
|
|
5
|
+
*/
|
|
6
|
+
export const baseSepolia = defineChain({
|
|
7
|
+
id: 84532,
|
|
8
|
+
name: 'Base Sepolia',
|
|
9
|
+
network: 'base-sepolia',
|
|
10
|
+
coFheUrl: 'https://testnet-cofhe.fhenix.zone',
|
|
11
|
+
verifierUrl: 'https://testnet-cofhe-vrf.fhenix.zone',
|
|
12
|
+
thresholdNetworkUrl: 'https://testnet-cofhe-tn.fhenix.zone',
|
|
13
|
+
environment: 'TESTNET',
|
|
14
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineChain } from '../defineChain.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hardhat local development chain configuration
|
|
5
|
+
*/
|
|
6
|
+
export const hardhat = defineChain({
|
|
7
|
+
id: 31337,
|
|
8
|
+
name: 'Hardhat',
|
|
9
|
+
network: 'localhost',
|
|
10
|
+
// These are unused in the mock environment
|
|
11
|
+
coFheUrl: 'http://127.0.0.1:8448',
|
|
12
|
+
verifierUrl: 'http://127.0.0.1:3001',
|
|
13
|
+
thresholdNetworkUrl: 'http://127.0.0.1:3000',
|
|
14
|
+
environment: 'MOCK',
|
|
15
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineChain } from '../defineChain.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Localcofhe chain configuration
|
|
5
|
+
*/
|
|
6
|
+
export const localcofhe = defineChain({
|
|
7
|
+
id: 420105,
|
|
8
|
+
name: 'Local Cofhe',
|
|
9
|
+
network: 'localhost',
|
|
10
|
+
coFheUrl: 'http://127.0.0.1:9448',
|
|
11
|
+
verifierUrl: 'http://127.0.0.1:3001',
|
|
12
|
+
thresholdNetworkUrl: 'http://127.0.0.1:3000',
|
|
13
|
+
environment: 'TESTNET',
|
|
14
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineChain } from '../defineChain.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sepolia testnet chain configuration
|
|
5
|
+
*/
|
|
6
|
+
export const sepolia = defineChain({
|
|
7
|
+
id: 11155111,
|
|
8
|
+
name: 'Sepolia',
|
|
9
|
+
network: 'sepolia',
|
|
10
|
+
coFheUrl: 'https://testnet-cofhe.fhenix.zone',
|
|
11
|
+
verifierUrl: 'https://testnet-cofhe-vrf.fhenix.zone',
|
|
12
|
+
thresholdNetworkUrl: 'https://testnet-cofhe-tn.fhenix.zone',
|
|
13
|
+
environment: 'TESTNET',
|
|
14
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { sepolia, arbSepolia, baseSepolia, hardhat, chains, getChainById, getChainByName } from './index.js';
|
|
3
|
+
|
|
4
|
+
describe('Chains', () => {
|
|
5
|
+
it('should export all chains', () => {
|
|
6
|
+
expect(Object.keys(chains)).toHaveLength(5);
|
|
7
|
+
expect(chains).toHaveProperty('sepolia');
|
|
8
|
+
expect(chains).toHaveProperty('arbSepolia');
|
|
9
|
+
expect(chains).toHaveProperty('baseSepolia');
|
|
10
|
+
expect(chains).toHaveProperty('hardhat');
|
|
11
|
+
expect(chains).toHaveProperty('localcofhe');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should have correct chain configurations', () => {
|
|
15
|
+
expect(sepolia.id).toBe(11155111);
|
|
16
|
+
expect(sepolia.name).toBe('Sepolia');
|
|
17
|
+
expect(sepolia.environment).toBe('TESTNET');
|
|
18
|
+
|
|
19
|
+
expect(hardhat.id).toBe(31337);
|
|
20
|
+
expect(hardhat.name).toBe('Hardhat');
|
|
21
|
+
expect(hardhat.environment).toBe('MOCK');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should find chains by ID', () => {
|
|
25
|
+
expect(getChainById(11155111)).toBe(sepolia);
|
|
26
|
+
expect(getChainById(31337)).toBe(hardhat);
|
|
27
|
+
expect(getChainById(999999)).toBeUndefined();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should find chains by name', () => {
|
|
31
|
+
expect(getChainByName('sepolia')).toBe(sepolia);
|
|
32
|
+
expect(getChainByName('Sepolia')).toBe(sepolia);
|
|
33
|
+
expect(getChainByName('hardhat')).toBe(hardhat);
|
|
34
|
+
expect(getChainByName('nonexistent')).toBeUndefined();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should validate chain properties', () => {
|
|
38
|
+
const allChains = [sepolia, arbSepolia, baseSepolia, hardhat];
|
|
39
|
+
|
|
40
|
+
allChains.forEach((chain) => {
|
|
41
|
+
expect(typeof chain.id).toBe('number');
|
|
42
|
+
expect(typeof chain.name).toBe('string');
|
|
43
|
+
expect(typeof chain.network).toBe('string');
|
|
44
|
+
expect(typeof chain.coFheUrl).toBe('string');
|
|
45
|
+
expect(typeof chain.verifierUrl).toBe('string');
|
|
46
|
+
expect(typeof chain.thresholdNetworkUrl).toBe('string');
|
|
47
|
+
expect(['MOCK', 'TESTNET', 'MAINNET']).toContain(chain.environment);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CofheChainSchema, type CofheChain } from './types.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Defines and validates a CofheChain configuration
|
|
6
|
+
* @param chainConfig - The chain configuration object to validate
|
|
7
|
+
* @returns The validated chain configuration unchanged
|
|
8
|
+
* @throws {Error} If the chain configuration is invalid
|
|
9
|
+
*/
|
|
10
|
+
export function defineChain(chainConfig: CofheChain): CofheChain {
|
|
11
|
+
const result = CofheChainSchema.safeParse(chainConfig);
|
|
12
|
+
|
|
13
|
+
if (!result.success) {
|
|
14
|
+
throw new Error(`Invalid chain configuration: ${z.prettifyError(result.error)}`, { cause: result.error });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return result.data;
|
|
18
|
+
}
|
package/chains/index.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Export types
|
|
2
|
+
export type { CofheChain, Environment } from './types.js';
|
|
3
|
+
|
|
4
|
+
// Import and export individual chains
|
|
5
|
+
import { sepolia } from './chains/sepolia.js';
|
|
6
|
+
import { arbSepolia } from './chains/arbSepolia.js';
|
|
7
|
+
import { baseSepolia } from './chains/baseSepolia.js';
|
|
8
|
+
import { hardhat } from './chains/hardhat.js';
|
|
9
|
+
import { localcofhe } from './chains/localcofhe.js';
|
|
10
|
+
|
|
11
|
+
export { sepolia, arbSepolia, baseSepolia, hardhat, localcofhe };
|
|
12
|
+
|
|
13
|
+
// Export all chains as a collection
|
|
14
|
+
export const chains = {
|
|
15
|
+
sepolia,
|
|
16
|
+
arbSepolia,
|
|
17
|
+
baseSepolia,
|
|
18
|
+
hardhat,
|
|
19
|
+
localcofhe,
|
|
20
|
+
} as const;
|
|
21
|
+
|
|
22
|
+
// Import CofheChain type for helper functions
|
|
23
|
+
import type { CofheChain } from './types.js';
|
|
24
|
+
|
|
25
|
+
// Export chain by ID helper
|
|
26
|
+
export const getChainById = (chainId: number): CofheChain | undefined => {
|
|
27
|
+
return Object.values(chains).find((chain) => chain.id === chainId);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// Export chain by name helper
|
|
31
|
+
export const getChainByName = (name: string): CofheChain | undefined => {
|
|
32
|
+
return Object.values(chains).find(
|
|
33
|
+
(chain) => chain.name.toLowerCase() === name.toLowerCase() || chain.network.toLowerCase() === name.toLowerCase()
|
|
34
|
+
);
|
|
35
|
+
};
|
package/chains/types.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Environment schema for @cofhe/sdk chains
|
|
5
|
+
*/
|
|
6
|
+
export const EnvironmentSchema = z.enum(['MOCK', 'TESTNET', 'MAINNET']);
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Zod schema for CofheChain validation
|
|
10
|
+
*/
|
|
11
|
+
export const CofheChainSchema = z.object({
|
|
12
|
+
/** Chain ID */
|
|
13
|
+
id: z.number().int().positive(),
|
|
14
|
+
/** Human-readable chain name */
|
|
15
|
+
name: z.string().min(1),
|
|
16
|
+
/** Network identifier */
|
|
17
|
+
network: z.string().min(1),
|
|
18
|
+
/** coFhe service URL */
|
|
19
|
+
coFheUrl: z.url(),
|
|
20
|
+
/** Verifier service URL */
|
|
21
|
+
verifierUrl: z.url(),
|
|
22
|
+
/** Threshold network service URL */
|
|
23
|
+
thresholdNetworkUrl: z.url(),
|
|
24
|
+
/** Environment type */
|
|
25
|
+
environment: EnvironmentSchema,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Type inference from the schema
|
|
30
|
+
*/
|
|
31
|
+
export type CofheChain = z.infer<typeof CofheChainSchema>;
|
|
32
|
+
export type Environment = z.infer<typeof EnvironmentSchema>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { type PublicClient, type WalletClient } from 'viem';
|
|
2
|
+
import { type CofheConfig } from './config.js';
|
|
3
|
+
import { CofheError, CofheErrorCode } from './error.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Base parameters that all builders need
|
|
7
|
+
*/
|
|
8
|
+
export type BaseBuilderParams = {
|
|
9
|
+
config: CofheConfig | undefined;
|
|
10
|
+
publicClient: PublicClient | undefined;
|
|
11
|
+
walletClient: WalletClient | undefined;
|
|
12
|
+
|
|
13
|
+
chainId: number | undefined;
|
|
14
|
+
account: string | undefined;
|
|
15
|
+
|
|
16
|
+
requireConnected: (() => void) | undefined;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Abstract base class for builders that provides common functionality
|
|
21
|
+
* for working with clients, config, and chain IDs
|
|
22
|
+
*/
|
|
23
|
+
export abstract class BaseBuilder {
|
|
24
|
+
protected config: CofheConfig;
|
|
25
|
+
|
|
26
|
+
protected publicClient: PublicClient | undefined;
|
|
27
|
+
protected walletClient: WalletClient | undefined;
|
|
28
|
+
|
|
29
|
+
protected chainId: number | undefined;
|
|
30
|
+
protected account: string | undefined;
|
|
31
|
+
|
|
32
|
+
constructor(params: BaseBuilderParams) {
|
|
33
|
+
// Check that config is provided
|
|
34
|
+
if (!params.config) {
|
|
35
|
+
throw new CofheError({
|
|
36
|
+
code: CofheErrorCode.MissingConfig,
|
|
37
|
+
message: 'Builder config is undefined',
|
|
38
|
+
hint: 'Ensure client has been created with a config.',
|
|
39
|
+
context: {
|
|
40
|
+
config: params.config,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
this.config = params.config;
|
|
45
|
+
|
|
46
|
+
this.publicClient = params.publicClient;
|
|
47
|
+
this.walletClient = params.walletClient;
|
|
48
|
+
|
|
49
|
+
this.chainId = params.chainId;
|
|
50
|
+
this.account = params.account;
|
|
51
|
+
|
|
52
|
+
// Require the client to be connected if passed as param
|
|
53
|
+
params.requireConnected?.();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Asserts that this.chainId is populated
|
|
58
|
+
* @throws {CofheError} If chainId is not set
|
|
59
|
+
*/
|
|
60
|
+
protected assertChainId(): asserts this is this & { chainId: number } {
|
|
61
|
+
if (this.chainId) return;
|
|
62
|
+
throw new CofheError({
|
|
63
|
+
code: CofheErrorCode.ChainIdUninitialized,
|
|
64
|
+
message: 'Chain ID is not set',
|
|
65
|
+
hint: 'Ensure client.connect() has been called and awaited, or use setChainId(...) to set the chainId explicitly.',
|
|
66
|
+
context: {
|
|
67
|
+
chainId: this.chainId,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Asserts that this.account is populated
|
|
74
|
+
* @throws {CofheError} If account is not set
|
|
75
|
+
*/
|
|
76
|
+
protected assertAccount(): asserts this is this & { account: string } {
|
|
77
|
+
if (this.account) return;
|
|
78
|
+
throw new CofheError({
|
|
79
|
+
code: CofheErrorCode.AccountUninitialized,
|
|
80
|
+
message: 'Account is not set',
|
|
81
|
+
hint: 'Ensure client.connect() has been called and awaited, or use setAccount(...) to set the account explicitly.',
|
|
82
|
+
context: {
|
|
83
|
+
account: this.account,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Asserts that this.publicClient is populated
|
|
90
|
+
* @throws {CofheError} If publicClient is not set
|
|
91
|
+
*/
|
|
92
|
+
protected assertPublicClient(): asserts this is this & { publicClient: PublicClient } {
|
|
93
|
+
if (this.publicClient) return;
|
|
94
|
+
throw new CofheError({
|
|
95
|
+
code: CofheErrorCode.MissingPublicClient,
|
|
96
|
+
message: 'Public client not found',
|
|
97
|
+
hint: 'Ensure client.connect() has been called with a publicClient.',
|
|
98
|
+
context: {
|
|
99
|
+
publicClient: this.publicClient,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Asserts that this.walletClient is populated
|
|
106
|
+
* @throws {CofheError} If walletClient is not set
|
|
107
|
+
*/
|
|
108
|
+
protected assertWalletClient(): asserts this is this & { walletClient: WalletClient } {
|
|
109
|
+
if (this.walletClient) return;
|
|
110
|
+
throw new CofheError({
|
|
111
|
+
code: CofheErrorCode.MissingWalletClient,
|
|
112
|
+
message: 'Wallet client not found',
|
|
113
|
+
hint: 'Ensure client.connect() has been called with a walletClient.',
|
|
114
|
+
context: {
|
|
115
|
+
walletClient: this.walletClient,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|