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
9 changes: 5 additions & 4 deletions packages/sdk/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 packages/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"debug": "^4.3.4",
"ethers": "^6.13.2",
"graphql-request": "^6.0.0",
"iexec": "^8.14.0",
"iexec": "^8.16.0",
"jszip": "^3.7.1",
"kubo-rpc-client": "^4.1.1",
"magic-bytes.js": "^1.0.15",
Expand Down
43 changes: 34 additions & 9 deletions packages/sdk/src/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
export type ChainId = number;

export interface ChainConfig {
name: string;
dataprotectorContractAddress: string;
sharingContractAddress: string;
subgraphUrl: string;
ipfsGateway: string;
ipfsNode: string;
smsDebugURL: string;
workerpoolAddress: string;
name?: string;
dataprotectorContractAddress?: string;
sharingContractAddress?: string;
subgraphUrl?: string;
ipfsGateway?: string;
ipfsNode?: string;
smsDebugURL?: string;
workerpoolAddress?: string;
isExperimental?: boolean;
}

export const CHAIN_CONFIG: Record<ChainId, ChainConfig> = {
const CHAIN_CONFIG: Record<ChainId, ChainConfig> = {
// Bellecour
134: {
name: 'bellecour',
Expand All @@ -24,6 +25,30 @@ export const CHAIN_CONFIG: Record<ChainId, ChainConfig> = {
smsDebugURL: 'https://sms-debug.iex.ec',
workerpoolAddress: 'prod-v8-bellecour.main.pools.iexec.eth',
},
// Arbitrum Sepolia
421614: {
name: 'arbitrum-sepolia-testnet',
dataprotectorContractAddress: '0x2296daeDD3090750a80fFB2D0147669984909ED2',
sharingContractAddress: '0x2485Ed90d4566516298B7D01462df8d1A41E13AE',
subgraphUrl:
'https://thegraph.arbitrum-sepolia-testnet.iex.ec/api/subgraphs/id/5YjRPLtjS6GH6bB4yY55Qg4HzwtRGQ8TaHtGf9UBWWd',
ipfsGateway: 'https://ipfs-gateway.arbitrum-sepolia-testnet.iex.ec',
ipfsNode: 'https://ipfs-upload.arbitrum-sepolia-testnet.iex.ec',
smsDebugURL: 'https://sms.arbitrum-sepolia-testnet.iex.ec', // ⚠️ default SMS is a debug SMS
workerpoolAddress: '0x39c3cdd91a7f1c4ed59108a9da4e79de9a1c1b59',
isExperimental: true,
},
};

export const getChainConfig = (
chainId: ChainId,
options?: { allowExperimentalNetworks?: boolean }
): ChainConfig => {
const config = CHAIN_CONFIG[chainId] || {};
if (config?.isExperimental && !options?.allowExperimentalNetworks) {
return {};
}
return config;
};

export const DEFAULT_CHAIN_ID = 134;
Expand Down
11 changes: 9 additions & 2 deletions packages/sdk/src/lib/IExecDataProtectorModule.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { AbstractProvider, AbstractSigner, Eip1193Provider } from 'ethers';
import { GraphQLClient } from 'graphql-request';
import { IExec } from 'iexec';
import { CHAIN_CONFIG, DEFAULT_ARWEAVE_UPLOAD_API } from '../config/config.js';
import {
getChainConfig,
DEFAULT_ARWEAVE_UPLOAD_API,
} from '../config/config.js';
import { getChainIdFromProvider } from '../utils/getChainId.js';
import {
AddressOrENS,
Expand Down Expand Up @@ -78,7 +81,9 @@ abstract class IExecDataProtectorModule {

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

const subgraphUrl =
this.options?.subgraphUrl || chainDefaultConfig?.subgraphUrl;
Expand Down Expand Up @@ -122,6 +127,7 @@ abstract class IExecDataProtectorModule {
{
ipfsGatewayURL: ipfsGateway,
...this.options?.iexecOptions,
allowExperimentalNetworks: this.options.allowExperimentalNetworks,
}
);

Expand All @@ -131,6 +137,7 @@ abstract class IExecDataProtectorModule {
ipfsGatewayURL: ipfsGateway,
...this.options?.iexecOptions,
smsURL,
allowExperimentalNetworks: this.options.allowExperimentalNetworks,
}
);
} catch (e: any) {
Expand Down
7 changes: 7 additions & 0 deletions packages/sdk/src/lib/types/commonTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ export type DataProtectorConfigOptions = {
* If not provided, default iexec options will be used.
*/
iexecOptions?: IExecConfigOptionsExtended;

/**
* 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;
};

interface IExecConfigOptionsExtended extends IExecConfigOptions {
Expand Down
13 changes: 11 additions & 2 deletions packages/sdk/src/utils/getWeb3Provider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { getSignerFromPrivateKey } from 'iexec/utils';
import { ChainId } from '../config/config.js';
import { Web3SignerProvider } from '../lib/types/index.js';

export const getWeb3Provider = (privateKey: string): Web3SignerProvider =>
getSignerFromPrivateKey('bellecour', privateKey);
export const getWeb3Provider = (
privateKey: string,
options: { allowExperimentalNetworks?: boolean; host?: ChainId | string } = {}
): Web3SignerProvider => {
const chainHost = options?.host ? `${options.host}` : 'bellecour';
return getSignerFromPrivateKey(chainHost, privateKey, {
allowExperimentalNetworks: options?.allowExperimentalNetworks,
providers: {},
});
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { HDNodeWallet, Wallet } from 'ethers';
import { Address, IExec } from 'iexec';
import { ValidationError } from 'yup';
import { CHAIN_CONFIG } from '../../../src/config/config.js';
import { getChainConfig } from '../../../src/config/config.js';
import { IExecDataProtector } from '../../../src/index.js';
import {
getTestConfig,
Expand Down Expand Up @@ -38,7 +38,7 @@ describe('dataProtector.addAppToAddOnlyAppWhitelist()', () => {
appWhitelistAddress = createAppWhitelistResponse.addOnlyAppWhitelist;
appAddress = await createAppFor(
wallet,
CHAIN_CONFIG['134'].sharingContractAddress
getChainConfig(134).sharingContractAddress
);
}, timeouts.createAddOnlyAppWhitelist + timeouts.createAppInPocoRegistry);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { beforeAll, describe, expect, it, jest } from '@jest/globals';
import { type HDNodeWallet, Wallet } from 'ethers';
import { IExec } from 'iexec';
import { CHAIN_CONFIG } from '../../../src/config/config.js';
import { getChainConfig } from '../../../src/config/config.js';
import { IExecDataProtector } from '../../../src/index.js';
import { approveProtectedDataForCollectionContract } from '../../../src/lib/dataProtectorSharing/smartContract/approveProtectedDataForCollectionContract.js';
import { getTestConfig, timeouts } from '../../test-utils.js';
Expand Down Expand Up @@ -76,7 +76,7 @@ describe('dataProtector.addToCollection()', () => {
await approveProtectedDataForCollectionContract({
iexec,
protectedData,
sharingContractAddress: CHAIN_CONFIG['134'].sharingContractAddress,
sharingContractAddress: getChainConfig(134).sharingContractAddress,
});

// --- WHEN
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { beforeAll, describe, expect, it } from '@jest/globals';
import { Wallet, type HDNodeWallet } from 'ethers';
import { ValidationError } from 'yup';
import { CHAIN_CONFIG } from '../../../src/config/config.js';
import { getChainConfig } from '../../../src/config/config.js';
import { IExecDataProtector } from '../../../src/index.js';
import {
approveAccount,
Expand Down Expand Up @@ -104,7 +104,7 @@ describe('dataProtector.buyProtectedData()', () => {
await depositNRlcForAccount(buyer.address, price);
await approveAccount(
buyer.privateKey,
CHAIN_CONFIG['134'].sharingContractAddress,
getChainConfig(134).sharingContractAddress,
price
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { beforeAll, describe, expect, it } from '@jest/globals';
import { HDNodeWallet, Wallet } from 'ethers';
import { CHAIN_CONFIG } from '../../../src/config/config.js';
import { getChainConfig } from '../../../src/config/config.js';
import { IExecDataProtector } from '../../../src/index.js';
import {
approveAccount,
Expand Down Expand Up @@ -154,7 +154,7 @@ describe('dataProtector.rentProtectedData()', () => {
);
await approveAccount(
walletEndUser.privateKey,
CHAIN_CONFIG['134'].sharingContractAddress,
getChainConfig(134).sharingContractAddress,
rentingParams.price
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { beforeAll, describe, expect, it } from '@jest/globals';
import { HDNodeWallet, Wallet } from 'ethers';
import { CHAIN_CONFIG } from '../../../src/config/config.js';
import { getChainConfig } from '../../../src/config/config.js';
import { IExecDataProtector } from '../../../src/index.js';
import {
approveAccount,
Expand Down Expand Up @@ -107,7 +107,7 @@ describe('dataProtector.subscribeToCollection()', () => {
);
await approveAccount(
walletEndUser.privateKey,
CHAIN_CONFIG['134'].sharingContractAddress,
getChainConfig(134).sharingContractAddress,
subscriptionParams.price
);

Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/tests/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export const MAX_EXPECTED_MARKET_API_PURGE_TIME = 5_000;

export const MAX_EXPECTED_WEB2_SERVICES_TIME = 80_000;

const SUBGRAPH_CALL_TIMEOUT = 2_000;
const SUBGRAPH_CALL_TIMEOUT = 5_000;
const SMART_CONTRACT_CALL_TIMEOUT = 10_000;

const ONE_SMART_CONTRACT_WRITE_CALL =
Expand Down
49 changes: 44 additions & 5 deletions packages/sdk/tests/unit/constructor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// needed to access and assert IExecDataProtector's private properties
import { describe, it, expect } from '@jest/globals';
import { Wallet } from 'ethers';
import { CHAIN_CONFIG } from '../../src/config/config.js';
import { getChainConfig } from '../../src/config/config.js';
import { IExecDataProtector, getWeb3Provider } from '../../src/index.js';

describe('IExecDataProtector()', () => {
Expand All @@ -12,7 +12,7 @@ describe('IExecDataProtector()', () => {
);
await dataProtector['init']();
const ipfsNode = dataProtector['ipfsNode'];
expect(ipfsNode).toStrictEqual(CHAIN_CONFIG['134'].ipfsNode);
expect(ipfsNode).toStrictEqual(getChainConfig(134).ipfsNode);
});

it('should use provided ipfs node url when ipfsNode is provided', async () => {
Expand All @@ -34,7 +34,7 @@ describe('IExecDataProtector()', () => {
);
await dataProtector['init']();
const ipfsGateway = dataProtector['ipfsGateway'];
expect(ipfsGateway).toStrictEqual(CHAIN_CONFIG['134'].ipfsGateway);
expect(ipfsGateway).toStrictEqual(getChainConfig(134).ipfsGateway);
});

it('should use default ipfs gateway url when ipfsGateway is provided', async () => {
Expand All @@ -58,7 +58,7 @@ describe('IExecDataProtector()', () => {
const dataprotectorContractAddress =
dataProtector['dataprotectorContractAddress'];
expect(dataprotectorContractAddress).toStrictEqual(
CHAIN_CONFIG['134'].dataprotectorContractAddress
getChainConfig(134).dataprotectorContractAddress
);
});

Expand All @@ -84,7 +84,7 @@ describe('IExecDataProtector()', () => {
);
await dataProtector['init']();
const graphQLClientUrl = dataProtector['graphQLClient'];
expect(graphQLClientUrl['url']).toBe(CHAIN_CONFIG['134'].subgraphUrl);
expect(graphQLClientUrl['url']).toBe(getChainConfig(134).subgraphUrl);
});

it('should use provided subgraph URL when subgraphUrl is provided', async () => {
Expand Down Expand Up @@ -188,4 +188,43 @@ describe('IExecDataProtector()', () => {
});
});
});

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 dataProtector = new IExecDataProtector(experimentalNetworkSigner);
await expect(dataProtector['init']()).rejects.toThrow(
'Missing required configuration for chainId 421614: subgraphUrl, dataprotectorContractAddress, sharingContractAddress, ipfsGateway, defaultWorkerpool, ipfsNode, smsDebugURL'
);
});
});

describe('With allowExperimentalNetworks: true', () => {
it('should resolve the configuration', async () => {
const dataProtector = new IExecDataProtector(
experimentalNetworkSigner,
{ allowExperimentalNetworks: true }
);
await expect(dataProtector['init']()).resolves.toBeUndefined();
expect(dataProtector['arweaveUploadApi']).toBeDefined();
expect(dataProtector['dataprotectorContractAddress']).toBeDefined();
expect(dataProtector['defaultWorkerpool']).toBeDefined();
expect(dataProtector['ethProvider']).toBeDefined();
expect(dataProtector['graphQLClient']).toBeDefined();
expect(dataProtector['iexec']).toBeDefined();
expect(dataProtector['iexecDebug']).toBeDefined();
expect(dataProtector['ipfsGateway']).toBeDefined();
expect(dataProtector['ipfsNode']).toBeDefined();
expect(dataProtector['sharingContractAddress']).toBeDefined();
});
});
});
});
8 changes: 4 additions & 4 deletions packages/sdk/tests/unit/dataProtectorCore/protectData.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import path from 'path';
import { beforeEach, describe, expect, it, jest } from '@jest/globals';
import { Wallet, HDNodeWallet, Contract } from 'ethers';
import { IExec, utils } from 'iexec';
import { CHAIN_CONFIG } from '../../../src/config/config.js';
import { getChainConfig } from '../../../src/config/config.js';
import { type ProtectData } from '../../../src/lib/dataProtectorCore/protectData.js';
import { ValidationError, WorkflowError } from '../../../src/utils/errors.js';
import { getRandomAddress } from '../../test-utils.js';
Expand Down Expand Up @@ -36,9 +36,9 @@ jest.unstable_mockModule('../../../src/utils/getEventFromLogs.js', () => ({
}));

const protectDataDefaultArgs = {
contractAddress: CHAIN_CONFIG['134'].dataprotectorContractAddress,
ipfsNode: CHAIN_CONFIG['134'].ipfsNode,
ipfsGateway: CHAIN_CONFIG['134'].ipfsGateway,
contractAddress: getChainConfig(134).dataprotectorContractAddress,
ipfsNode: getChainConfig(134).ipfsNode,
ipfsGateway: getChainConfig(134).ipfsGateway,
};

describe('protectData()', () => {
Expand Down
Loading