Skip to content

Commit 1de86f4

Browse files
fix: add web3mailAppAddress and explorerUrl to SUPPORTED_CHAINS configuration
1 parent 410b4bf commit 1de86f4

File tree

4 files changed

+117
-54
lines changed

4 files changed

+117
-54
lines changed

src/App.tsx

Lines changed: 73 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
1-
import { useState } from 'react';
21
import { Address } from '@iexec/dataprotector';
2+
import { useState } from 'react';
3+
import './App.css';
4+
import loader from './assets/loader.gif';
5+
import successIcon from './assets/success.png';
6+
import {
7+
getDataProtectorCoreClient,
8+
initDataProtectorClient,
9+
} from './externals/dataProtectorClient';
10+
import { useWalletConnection } from './hooks/useWalletConnection';
311
import {
412
AddressOrEnsName,
513
checkIsConnected,
6-
IEXEC_EXPLORER_URL,
7-
WEB3MAIL_APP_ENS,
814
SUPPORTED_CHAINS,
15+
WEB3MAIL_APP_ENS,
916
} from './utils/utils.ts';
10-
import { getDataProtectorCoreClient, initDataProtectorClient } from './externals/dataProtectorClient';
11-
import { useWalletConnection } from './hooks/useWalletConnection';
12-
import './App.css';
13-
import loader from './assets/loader.gif';
14-
import successIcon from './assets/success.png';
17+
import { NULL_ADDRESS } from 'iexec/utils';
1518

1619
export default function App() {
1720
const { isConnected, address, chainId } = useWalletConnection();
18-
const [selectedChain, setSelectedChain] = useState(SUPPORTED_CHAINS[0].id);
21+
const [selectedChain, setSelectedChain] = useState(SUPPORTED_CHAINS[2].id);
1922
const [protectedData, setProtectedData] = useState<Address | ''>('');
2023
const [authorizedUser, setAuthorizedUser] = useState<AddressOrEnsName | ''>(
2124
''
@@ -43,7 +46,7 @@ export default function App() {
4346
}
4447

4548
// Find the chain configuration
46-
const chain = SUPPORTED_CHAINS.find(c => c.id === targetChainId);
49+
const chain = SUPPORTED_CHAINS.find((c) => c.id === targetChainId);
4750
if (!chain) {
4851
throw new Error(`Chain with ID ${targetChainId} not supported`);
4952
}
@@ -81,7 +84,9 @@ export default function App() {
8184
}
8285
};
8386

84-
const handleChainChange = async (event: React.ChangeEvent<HTMLSelectElement>) => {
87+
const handleChainChange = async (
88+
event: React.ChangeEvent<HTMLSelectElement>
89+
) => {
8590
const newChainId = Number(event.target.value);
8691
setSelectedChain(newChainId);
8792

@@ -112,7 +117,7 @@ export default function App() {
112117
// Reinitialize the DataProtector client with the correct chain
113118
await initDataProtectorClient({
114119
provider: window.ethereum,
115-
chainId: selectedChain
120+
chainId: selectedChain,
116121
});
117122
} catch (err) {
118123
setErrorProtect('Please install MetaMask or switch to the correct chain');
@@ -128,11 +133,10 @@ export default function App() {
128133
try {
129134
setLoadingProtect(true);
130135
const client = await getDataProtectorCoreClient();
131-
const protectedDataResponse =
132-
await client.protectData({
133-
data,
134-
name,
135-
});
136+
const protectedDataResponse = await client.protectData({
137+
data,
138+
name,
139+
});
136140
setProtectedData(protectedDataResponse.address as Address);
137141
setErrorProtect('');
138142
} catch (error) {
@@ -141,9 +145,13 @@ export default function App() {
141145

142146
// Provide more specific error messages
143147
if (String(error).includes('Internal JSON-RPC error')) {
144-
setErrorProtect('RPC Error: Please check your network connection and ensure you have sufficient xRLC for gas fees on Bellecour');
148+
setErrorProtect(
149+
'RPC Error: Please check your network connection and ensure you have sufficient xRLC for gas fees on Bellecour'
150+
);
145151
} else if (String(error).includes('insufficient funds')) {
146-
setErrorProtect('Insufficient funds: Please ensure you have enough xRLC tokens for gas fees');
152+
setErrorProtect(
153+
'Insufficient funds: Please ensure you have enough xRLC tokens for gas fees'
154+
);
147155
} else if (String(error).includes('user rejected')) {
148156
setErrorProtect('Transaction rejected by user');
149157
} else {
@@ -162,7 +170,7 @@ export default function App() {
162170
// Reinitialize the DataProtector client with the correct chain
163171
await initDataProtectorClient({
164172
provider: window.ethereum,
165-
chainId: selectedChain
173+
chainId: selectedChain,
166174
});
167175
} catch (err) {
168176
setErrorGrant('Please install MetaMask or switch to the correct chain');
@@ -179,7 +187,7 @@ export default function App() {
179187
await client.grantAccess({
180188
protectedData,
181189
authorizedUser: userAddress,
182-
authorizedApp: WEB3MAIL_APP_ENS,
190+
authorizedApp: SUPPORTED_CHAINS.find((c) => c.id === selectedChain)?.web3mailAppAddress as Address,
183191
numberOfAccess,
184192
});
185193
setAuthorizedUser(userAddress);
@@ -200,7 +208,7 @@ export default function App() {
200208
// Reinitialize the DataProtector client with the correct chain
201209
await initDataProtectorClient({
202210
provider: window.ethereum,
203-
chainId: selectedChain
211+
chainId: selectedChain,
204212
});
205213
} catch (err) {
206214
setErrorRevoke('Please install MetaMask or switch to the correct chain');
@@ -210,12 +218,11 @@ export default function App() {
210218
try {
211219
setLoadingRevoke(true);
212220
const client = await getDataProtectorCoreClient();
213-
const allGrantedAccess =
214-
await client.getGrantedAccess({
215-
protectedData,
216-
authorizedUser,
217-
authorizedApp: WEB3MAIL_APP_ENS,
218-
});
221+
const allGrantedAccess = await client.getGrantedAccess({
222+
protectedData,
223+
authorizedUser,
224+
authorizedApp: SUPPORTED_CHAINS.find((c) => c.id === selectedChain)?.web3mailAppAddress as Address,
225+
});
219226
if (allGrantedAccess.count === 0) {
220227
throw new Error('No access to revoke');
221228
}
@@ -242,7 +249,9 @@ export default function App() {
242249
setName(event.target.value);
243250
};
244251

245-
const handleNumberOfAccessChange = (event: React.ChangeEvent<HTMLInputElement>) => {
252+
const handleNumberOfAccessChange = (
253+
event: React.ChangeEvent<HTMLInputElement>
254+
) => {
246255
setNumberOfAccess(Number(event.target.value));
247256
};
248257

@@ -258,13 +267,31 @@ export default function App() {
258267
return (
259268
<>
260269
{/* Chain Selection */}
261-
<div style={{ marginBottom: '20px', padding: '20px', border: '1px solid #ddd', borderRadius: '8px' }}>
262-
<h2 style={{ margin: '0 0 10px 0', display: 'flex', alignItems: 'center', gap: '10px' }}>
270+
<div
271+
style={{
272+
marginBottom: '20px',
273+
padding: '20px',
274+
border: '1px solid #ddd',
275+
borderRadius: '8px',
276+
}}
277+
>
278+
<h2
279+
style={{
280+
margin: '0 0 10px 0',
281+
display: 'flex',
282+
alignItems: 'center',
283+
gap: '10px',
284+
}}
285+
>
263286
Chain Selection
264287
<select
265288
value={selectedChain}
266289
onChange={handleChainChange}
267-
style={{ padding: '5px', borderRadius: '4px', border: '1px solid #ccc' }}
290+
style={{
291+
padding: '5px',
292+
borderRadius: '4px',
293+
border: '1px solid #ccc',
294+
}}
268295
>
269296
{SUPPORTED_CHAINS.map((chain) => (
270297
<option key={chain.id} value={chain.id}>
@@ -274,22 +301,28 @@ export default function App() {
274301
</select>
275302
</h2>
276303
<p style={{ margin: '5px 0', color: '#666' }}>
277-
Selected chain: {SUPPORTED_CHAINS.find(c => c.id === selectedChain)?.name} (ID: {selectedChain})
304+
Selected chain:{' '}
305+
{SUPPORTED_CHAINS.find((c) => c.id === selectedChain)?.name} (ID:{' '}
306+
{selectedChain})
278307
</p>
279308

280309
{/* Wallet Status */}
281310
<div style={{ marginTop: '10px', fontSize: '14px' }}>
282311
<p style={{ margin: '2px 0' }}>
283-
<strong>Wallet Status:</strong> {isConnected ? 'Connected' : 'Disconnected'}
312+
<strong>Wallet Status:</strong>{' '}
313+
{isConnected ? 'Connected' : 'Disconnected'}
284314
</p>
285315
{address && (
286316
<p style={{ margin: '2px 0' }}>
287-
<strong>Address:</strong> {address.slice(0, 6)}...{address.slice(-4)}
317+
<strong>Address:</strong> {address.slice(0, 6)}...
318+
{address.slice(-4)}
288319
</p>
289320
)}
290321
{chainId && (
291322
<p style={{ margin: '2px 0' }}>
292-
<strong>Current MetaMask Chain:</strong> {SUPPORTED_CHAINS.find(c => c.id === chainId)?.name || `Chain ${chainId}`}
323+
<strong>Current MetaMask Chain:</strong>{' '}
324+
{SUPPORTED_CHAINS.find((c) => c.id === chainId)?.name ||
325+
`Chain ${chainId}`}
293326
</p>
294327
)}
295328
</div>
@@ -347,7 +380,10 @@ export default function App() {
347380
/>
348381
Your data has been protected!
349382
<a
350-
href={IEXEC_EXPLORER_URL + protectedData}
383+
href={
384+
SUPPORTED_CHAINS.find((c) => c.id === selectedChain)
385+
?.explorerUrl + protectedData
386+
}
351387
rel="noreferrer"
352388
target="_blank"
353389
>

src/externals/dataProtectorClient.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export function cleanDataProtectorClient() {
1414

1515
export async function initDataProtectorClient({
1616
provider,
17-
chainId
17+
chainId,
1818
}: {
1919
provider?: unknown;
2020
chainId?: number;
@@ -27,7 +27,9 @@ export async function initDataProtectorClient({
2727
// Only reinitialize if chain has changed
2828
if (currentChainId !== chainId) {
2929
try {
30-
const dataProtectorParent = new IExecDataProtector(provider as Eip1193Provider);
30+
const dataProtectorParent = new IExecDataProtector(
31+
provider as Eip1193Provider
32+
);
3133
iExecDataProtectorCore = dataProtectorParent.core;
3234
currentChainId = chainId || null;
3335
} catch (error) {
@@ -40,7 +42,9 @@ export async function initDataProtectorClient({
4042

4143
export async function getDataProtectorCoreClient(): Promise<IExecDataProtectorCore> {
4244
if (!iExecDataProtectorCore) {
43-
throw new Error('iExec SDK not initialized. Please connect your wallet first.');
45+
throw new Error(
46+
'iExec SDK not initialized. Please connect your wallet first.'
47+
);
4448
}
4549
return iExecDataProtectorCore;
4650
}

src/hooks/useWalletConnection.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { useEffect, useState } from 'react';
2-
import { cleanDataProtectorClient, initDataProtectorClient } from '../externals/dataProtectorClient';
2+
import {
3+
cleanDataProtectorClient,
4+
initDataProtectorClient,
5+
} from '../externals/dataProtectorClient';
36

47
export function useWalletConnection() {
58
const [isConnected, setIsConnected] = useState(false);
@@ -27,7 +30,10 @@ export function useWalletConnection() {
2730
const parsedChainId = parseInt(newChainId, 16);
2831
setChainId(parsedChainId);
2932

30-
initDataProtectorClient({ provider: window.ethereum, chainId: parsedChainId });
33+
initDataProtectorClient({
34+
provider: window.ethereum,
35+
chainId: parsedChainId,
36+
});
3137
}
3238
} catch (error) {
3339
console.error('Error checking connection:', error);
@@ -41,7 +47,10 @@ export function useWalletConnection() {
4147
setIsConnected(true);
4248
setAddress(accounts[0]);
4349
if (chainId) {
44-
initDataProtectorClient({ provider: window.ethereum, chainId: chainId });
50+
initDataProtectorClient({
51+
provider: window.ethereum,
52+
chainId: chainId,
53+
});
4554
}
4655
} else {
4756
setIsConnected(false);
@@ -53,15 +62,21 @@ export function useWalletConnection() {
5362
const handleChainChanged = (newChainHexId: string) => {
5463
const newChainId = parseInt(newChainHexId, 16);
5564
setChainId(newChainId);
56-
initDataProtectorClient({ provider: window.ethereum, chainId: newChainId });
65+
initDataProtectorClient({
66+
provider: window.ethereum,
67+
chainId: newChainId,
68+
});
5769
};
5870

5971
window.ethereum.on('accountsChanged', handleAccountsChanged);
6072
window.ethereum.on('chainChanged', handleChainChanged);
6173

6274
return () => {
6375
if (window.ethereum.removeListener) {
64-
window.ethereum.removeListener('accountsChanged', handleAccountsChanged);
76+
window.ethereum.removeListener(
77+
'accountsChanged',
78+
handleAccountsChanged
79+
);
6580
window.ethereum.removeListener('chainChanged', handleChainChanged);
6681
}
6782
};

src/utils/utils.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,26 @@ export const SUPPORTED_CHAINS = [
1515
blockExplorerUrl: 'https://blockscout-bellecour.iex.ec',
1616
tokenSymbol: 'xRLC',
1717
rpcUrls: ['https://bellecour.iex.ec'],
18-
},
19-
{
20-
id: 42161,
21-
name: 'Arbitrum',
22-
blockExplorerUrl: 'https://arbiscan.io/',
23-
tokenSymbol: 'RLC',
24-
rpcUrls: ['https://arb1.arbitrum.io/rpc'],
18+
explorerUrl: 'https://explorer.iex.ec/bellecour/dataset/',
19+
web3mailAppAddress: 'web3mail.apps.iexec.eth',
2520
},
2621
{
2722
id: 421614,
2823
name: 'Arbitrum Sepolia',
2924
blockExplorerUrl: 'https://sepolia.arbiscan.io/',
3025
tokenSymbol: 'RLC',
3126
rpcUrls: ['https://sepolia-rollup.arbitrum.io/rpc'],
27+
explorerUrl: 'https://explorer.iex.ec/arbitrum-sepolia-testnet/dataset/',
28+
web3mailAppAddress: '0x54f48937d1a26dd250dc8adbef07bc76f6e27df3',
29+
},
30+
{
31+
id: 42161,
32+
name: 'Arbitrum',
33+
blockExplorerUrl: 'https://arbiscan.io/',
34+
tokenSymbol: 'RLC',
35+
rpcUrls: ['https://arb1.arbitrum.io/rpc', 'https://1rpc.io/arb'],
36+
explorerUrl: 'https://explorer.iex.ec/abritrum-mainnet/dataset/',
37+
web3mailAppAddress: '0xcf0289a65a455a8d3c90153b796e8133e985b26c',
3238
},
3339
];
3440

@@ -46,10 +52,12 @@ export async function checkCurrentChain(selectedChainId?: number) {
4652
params: [],
4753
});
4854

49-
const targetChainId = selectedChainId ? `0x${selectedChainId.toString(16)}` : IEXEC_CHAIN_ID;
55+
const targetChainId = selectedChainId
56+
? `0x${selectedChainId.toString(16)}`
57+
: IEXEC_CHAIN_ID;
5058

5159
if (currentChainId !== targetChainId) {
52-
const chain = SUPPORTED_CHAINS.find(c => c.id === selectedChainId);
60+
const chain = SUPPORTED_CHAINS.find((c) => c.id === selectedChainId);
5361
if (!chain) {
5462
throw new Error(`Chain with ID ${selectedChainId} not supported`);
5563
}

0 commit comments

Comments
 (0)