Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
/.env
/*.log
/*.env
**/.env

# TypeScript specific
*.tsbuildinfo
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"buffer": "^6.0.3",
"ethers": "^6.8.1",
"graphql-request": "^6.1.0",
"iexec": "^8.13.1",
"iexec": "^8.16.1",
"kubo-rpc-client": "^4.1.3",
"yup": "^1.1.1"
},
Expand Down
34 changes: 23 additions & 11 deletions src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@ export const MAX_DESIRED_APP_ORDER_PRICE = 0;
export const MAX_DESIRED_WORKERPOOL_ORDER_PRICE = 0;
export const ANY_DATASET_ADDRESS = 'any';

export const CHAIN_IDS = {
BELLECOUR: 134,
AVALANCHE_FUJI: 43113,
ARBITRUM_SEPOLIA: 421614,
} as const;

export const DEFAULT_CHAIN_ID = CHAIN_IDS.BELLECOUR;
export const DEFAULT_CHAIN_ID = 134;

interface ChainConfig {
name: string;
Expand All @@ -19,10 +13,11 @@ interface ChainConfig {
ipfsUploadUrl: string;
ipfsGateway: string;
whitelistSmartContract: string;
isExperimental?: boolean;
}

export const CHAIN_CONFIG: Record<number, ChainConfig> = {
[CHAIN_IDS.BELLECOUR]: {
134: {
name: 'bellecour',
dappAddress: 'web3telegram.apps.iexec.eth',
prodWorkerpoolAddress: 'prod-v8-bellecour.main.pools.iexec.eth',
Expand All @@ -32,12 +27,29 @@ export const CHAIN_CONFIG: Record<number, ChainConfig> = {
ipfsGateway: 'https://ipfs-gateway.v8-bellecour.iex.ec',
whitelistSmartContract: '0x192C6f5AccE52c81Fcc2670f10611a3665AAA98F',
},
421614: {
name: 'arbitrum-sepolia-testnet',
dappAddress: 'web3telegram.apps.iexec.eth',
prodWorkerpoolAddress: '0x39c3cdd91a7f1c4ed59108a9da4e79de9a1c1b59',
dataProtectorSubgraph:
'https://thegraph.arbitrum-sepolia-testnet.iex.ec/api/subgraphs/id/5YjRPLtjS6GH6bB4yY55Qg4HzwtRGQ8TaHtGf9UBWWd',
ipfsGateway: 'https://ipfs-gateway.arbitrum-sepolia-testnet.iex.ec',
ipfsUploadUrl: 'https://ipfs-upload.arbitrum-sepolia-testnet.iex.ec',
whitelistSmartContract: '0x7291ff96100DA6CF97933C225B86124ef95aEc9b', // TODO: add the correct address
isExperimental: true,
},
};

export function getChainConfig(chainId: number): ChainConfig {
export const getChainDefaultConfig = (
chainId: number,
options?: { allowExperimentalNetworks?: boolean }
): ChainConfig | null => {
const config = CHAIN_CONFIG[chainId];
if (!config) {
throw new Error(`Unsupported chain ID: ${chainId}`);
return null;
}
if (config.isExperimental && !options?.allowExperimentalNetworks) {
return null;
}
return config;
}
};
12 changes: 10 additions & 2 deletions src/utils/getWeb3Provider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { getSignerFromPrivateKey } from 'iexec/utils';
import { Web3SignerProvider } from '../web3telegram/types.js';

export const getWeb3Provider = (privateKey: string): Web3SignerProvider =>
getSignerFromPrivateKey('bellecour', privateKey);
export const getWeb3Provider = (
privateKey: string,
options: { allowExperimentalNetworks?: boolean; host?: number | string } = {}
): Web3SignerProvider => {
const chainHost = options?.host ? `${options.host}` : 'bellecour';
return getSignerFromPrivateKey(chainHost, privateKey, {
allowExperimentalNetworks: options?.allowExperimentalNetworks,
providers: {},
});
};
7 changes: 5 additions & 2 deletions src/web3telegram/IExecWeb3telegram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
Web3SignerProvider,
FetchMyContactsParams,
} from './types.js';
import { CHAIN_CONFIG } from '../config/config.js';
import { getChainDefaultConfig } from '../config/config.js';
import { isValidProvider } from '../utils/validators.js';
import { getChainIdFromProvider } from '../utils/getChainId.js';

Expand Down Expand Up @@ -122,7 +122,9 @@

private async resolveConfig(): Promise<Web3telegramResolvedConfig> {
const chainId = await getChainIdFromProvider(this.ethProvider);
const chainDefaultConfig = CHAIN_CONFIG[chainId];
const chainDefaultConfig = getChainDefaultConfig(chainId, {
allowExperimentalNetworks: this.options.allowExperimentalNetworks,
});

const subgraphUrl =
this.options?.dataProtectorSubgraph ||
Expand Down Expand Up @@ -162,15 +164,16 @@
{
ipfsGatewayURL: ipfsGateway,
...this.options?.iexecOptions,
allowExperimentalNetworks: this.options.allowExperimentalNetworks,
}
);
} catch (e: any) {

Check warning on line 170 in src/web3telegram/IExecWeb3telegram.ts

View workflow job for this annotation

GitHub Actions / check-code

Unexpected any. Specify a different type
throw new Error(`Unsupported ethProvider: ${e.message}`);
}

try {
graphQLClient = new GraphQLClient(subgraphUrl);
} catch (error: any) {

Check warning on line 176 in src/web3telegram/IExecWeb3telegram.ts

View workflow job for this annotation

GitHub Actions / check-code

Unexpected any. Specify a different type
throw new Error(`Failed to create GraphQLClient: ${error.message}`);
}

Expand Down
7 changes: 7 additions & 0 deletions src/web3telegram/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ export type Web3TelegramConfigOptions = {
* If not provided, the default IPFS gateway URL for the detected chain will be used.
*/
ipfsGateway?: string;

/**
* if true allows using a provider connected to an experimental networks (default false)
*
* ⚠️ experimental networks are networks on which the iExec's stack is partially deployed, experimental networks can be subject to instabilities or discontinuity. Access is provided without warranties.
*/
allowExperimentalNetworks?: boolean;
};

export type DappAddressConsumer = {
Expand Down
8 changes: 0 additions & 8 deletions tests/.env

This file was deleted.

109 changes: 103 additions & 6 deletions tests/e2e/constructor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
// needed to access and assert IExecDataProtector's private properties
import { describe, expect, it } from '@jest/globals';
import { Wallet } from 'ethers';
import { IExecWeb3telegram } from '../../src/index.js';
import { getWeb3Provider, IExecWeb3telegram } from '../../src/index.js';
import {
getTestWeb3SignerProvider,
MAX_EXPECTED_WEB2_SERVICES_TIME,
} from '../test-utils.js';
import { CHAIN_CONFIG, CHAIN_IDS } from '../../src/config/config.js';
import {
DEFAULT_CHAIN_ID,
getChainDefaultConfig,
} from '../../src/config/config.js';

describe('IExecWeb3telegram()', () => {
it('instantiates with a valid ethProvider', async () => {
Expand All @@ -25,7 +28,9 @@ describe('IExecWeb3telegram()', () => {
);
await web3telegram.init();
const ipfsGateway = web3telegram['ipfsGateway'];
expect(ipfsGateway).toStrictEqual(CHAIN_CONFIG[CHAIN_IDS.BELLECOUR].ipfsGateway);
const defaultConfig = getChainDefaultConfig(DEFAULT_CHAIN_ID);
expect(defaultConfig).not.toBeNull();
expect(ipfsGateway).toStrictEqual(defaultConfig!.ipfsGateway);
});

it('should use provided ipfs gateway url when ipfsGateway is provided', async () => {
Expand All @@ -48,8 +53,10 @@ describe('IExecWeb3telegram()', () => {
getTestWeb3SignerProvider(wallet.privateKey)
);
await web3telegram.init();
const graphQLClientUrl = web3telegram['graphQLClient'];
expect(graphQLClientUrl['url']).toBe(CHAIN_CONFIG[CHAIN_IDS.BELLECOUR].dataProtectorSubgraph);
const graphQLClient = web3telegram['graphQLClient'];
const defaultConfig = getChainDefaultConfig(DEFAULT_CHAIN_ID);
expect(defaultConfig).not.toBeNull();
expect(graphQLClient['url']).toBe(defaultConfig!.dataProtectorSubgraph);
});

it('should use provided data Protector Subgraph URL when subgraphUrl is provided', async () => {
Expand Down Expand Up @@ -102,11 +109,101 @@ describe('IExecWeb3telegram()', () => {
expect(ipfsNode).toStrictEqual(customIpfsNode);
expect(ipfsGateway).toStrictEqual(customIpfsGateway);
expect(dappAddressOrENS).toStrictEqual(customDapp);
expect(whitelistAddress).toStrictEqual(customDappWhitelistAddress.toLowerCase());
expect(whitelistAddress).toStrictEqual(
customDappWhitelistAddress.toLowerCase()
);
expect(await iexec.config.resolveSmsURL()).toBe(smsURL);
expect(await iexec.config.resolveIexecGatewayURL()).toBe(iexecGatewayURL);
});

describe('When instantiating SDK with an experimental network', () => {
const experimentalNetworkSigner = getWeb3Provider(
Wallet.createRandom().privateKey,
{
host: 421614,
allowExperimentalNetworks: true,
}
);

describe('Without allowExperimentalNetworks', () => {
it('should throw a configuration error', async () => {
const web3telegram = new IExecWeb3telegram(experimentalNetworkSigner);
await expect(web3telegram.init()).rejects.toThrow(
'Missing required configuration for chainId 421614: dataProtectorSubgraph, dappAddress, whitelistSmartContract, ipfsGateway, prodWorkerpoolAddress, ipfsUploadUrl'
);
});
});

describe('With allowExperimentalNetworks: true', () => {
it('should resolve the configuration', async () => {
const web3telegram = new IExecWeb3telegram(experimentalNetworkSigner, {
allowExperimentalNetworks: true,
});
await expect(web3telegram.init()).resolves.toBeUndefined();
expect(web3telegram).toBeInstanceOf(IExecWeb3telegram);
});

it('should use Arbitrum Sepolia default configuration', async () => {
const web3telegram = new IExecWeb3telegram(experimentalNetworkSigner, {
allowExperimentalNetworks: true,
});
await web3telegram.init();

const arbitrumSepoliaConfig = getChainDefaultConfig(421614, {
allowExperimentalNetworks: true,
});
expect(arbitrumSepoliaConfig).not.toBeNull();

expect(web3telegram['ipfsGateway']).toBe(
arbitrumSepoliaConfig!.ipfsGateway
);
expect(web3telegram['ipfsNode']).toBe(arbitrumSepoliaConfig!.ipfsUploadUrl);
expect(web3telegram['dappAddressOrENS']).toBe(
arbitrumSepoliaConfig!.dappAddress
);
expect(web3telegram['dappWhitelistAddress']).toBe(
arbitrumSepoliaConfig!.whitelistSmartContract.toLowerCase()
);
expect(web3telegram['defaultWorkerpool']).toBe(
arbitrumSepoliaConfig!.prodWorkerpoolAddress
);
expect(web3telegram['graphQLClient']['url']).toBe(
arbitrumSepoliaConfig!.dataProtectorSubgraph
);
});

it('should allow custom configuration override for Arbitrum Sepolia', async () => {
const customIpfsGateway = 'https://custom-arbitrum-ipfs.com';
const customDappAddress = 'custom.arbitrum.app.eth';

const web3telegram = new IExecWeb3telegram(experimentalNetworkSigner, {
allowExperimentalNetworks: true,
ipfsGateway: customIpfsGateway,
dappAddressOrENS: customDappAddress,
});
await web3telegram.init();

expect(web3telegram['ipfsGateway']).toBe(customIpfsGateway);
expect(web3telegram['dappAddressOrENS']).toBe(customDappAddress);

const arbitrumSepoliaConfig = getChainDefaultConfig(421614, {
allowExperimentalNetworks: true,
});
expect(arbitrumSepoliaConfig).not.toBeNull();
expect(web3telegram['ipfsNode']).toBe(arbitrumSepoliaConfig!.ipfsUploadUrl);
expect(web3telegram['dappWhitelistAddress']).toBe(
arbitrumSepoliaConfig!.whitelistSmartContract.toLowerCase()
);
expect(web3telegram['defaultWorkerpool']).toBe(
arbitrumSepoliaConfig!.prodWorkerpoolAddress
);
expect(web3telegram['graphQLClient']['url']).toBe(
arbitrumSepoliaConfig!.dataProtectorSubgraph
);
});
});
});

it(
'When calling a read method should work as expected',
async () => {
Expand Down
21 changes: 11 additions & 10 deletions tests/e2e/fetchMyContacts.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { describe, expect, it } from '@jest/globals';
import { IExecDataProtector } from '@iexec/dataprotector';
import { IExecWeb3telegram } from '../../src/index.js';
import { CHAIN_CONFIG, CHAIN_IDS } from '../../src/config/config.js';
import {
getTestConfig,
waitSubgraphIndexing,
} from '../test-utils.js';
DEFAULT_CHAIN_ID,
getChainDefaultConfig,
} from '../../src/config/config.js';
import { getTestConfig, waitSubgraphIndexing } from '../test-utils.js';
import { HDNodeWallet, Wallet } from 'ethers';
import { NULL_ADDRESS } from 'iexec/utils';
import {
Expand All @@ -22,6 +22,7 @@ describe('web3telegram.fetchMyContacts()', () => {
let web3telegram: IExecWeb3telegram;
let dataProtector: IExecDataProtector;
let protectedData: any;
const defaultConfig = getChainDefaultConfig(DEFAULT_CHAIN_ID);

beforeAll(async () => {
wallet = Wallet.createRandom();
Expand All @@ -38,7 +39,7 @@ describe('web3telegram.fetchMyContacts()', () => {
'pass with a granted access for a specific requester',
async () => {
await dataProtector.core.grantAccess({
authorizedApp: CHAIN_CONFIG[CHAIN_IDS.BELLECOUR].dappAddress,
authorizedApp: defaultConfig.dappAddress,
protectedData: protectedData.address,
authorizedUser: wallet.address,
});
Expand All @@ -48,11 +49,11 @@ describe('web3telegram.fetchMyContacts()', () => {
});
expect(
foundContactForASpecificRequester &&
foundContactForASpecificRequester.address
foundContactForASpecificRequester.address
).toBeDefined();
expect(
foundContactForASpecificRequester &&
foundContactForASpecificRequester.address
foundContactForASpecificRequester.address
).toBe(protectedData.address.toLocaleLowerCase());
},
MAX_EXPECTED_WEB2_SERVICES_TIME
Expand All @@ -63,7 +64,7 @@ describe('web3telegram.fetchMyContacts()', () => {
async () => {
const grantedAccessForAnyRequester = await dataProtector.core.grantAccess(
{
authorizedApp: CHAIN_CONFIG[CHAIN_IDS.BELLECOUR].dappAddress,
authorizedApp: defaultConfig.dappAddress,
protectedData: protectedData.address,
authorizedUser: NULL_ADDRESS,
}
Expand Down Expand Up @@ -103,7 +104,7 @@ describe('web3telegram.fetchMyContacts()', () => {
const encryptionKey = await iexec.dataset.generateEncryptionKey();
await iexec.dataset.pushDatasetSecret(dataset.address, encryptionKey);
await dataProtector.core.grantAccess({
authorizedApp: CHAIN_CONFIG[CHAIN_IDS.BELLECOUR].dappAddress,
authorizedApp: defaultConfig.dappAddress,
protectedData: dataset.address,
authorizedUser: wallet.address,
});
Expand All @@ -125,7 +126,7 @@ describe('web3telegram.fetchMyContacts()', () => {
await waitSubgraphIndexing();

await dataProtector.core.grantAccess({
authorizedApp: CHAIN_CONFIG[CHAIN_IDS.BELLECOUR].dappAddress,
authorizedApp: defaultConfig.dappAddress,
protectedData: notValidProtectedData.address,
authorizedUser: wallet.address,
});
Expand Down
Loading
Loading