Skip to content

Commit d104c61

Browse files
feat(sdk): support dynamic config for multiple chains
Co-authored-by: pjt <[email protected]>
1 parent ceaddaa commit d104c61

File tree

21 files changed

+331
-140
lines changed

21 files changed

+331
-140
lines changed

packages/protected-data-delivery-dapp/deployment/abis/AddOnlyAppWhitelistRegistryABI.json

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@
44
"stateMutability": "nonpayable",
55
"type": "constructor"
66
},
7-
{
8-
"inputs": [],
9-
"name": "ERC1167FailedCreateClone",
10-
"type": "error"
11-
},
127
{
138
"inputs": [
149
{
@@ -112,6 +107,27 @@
112107
"name": "ERC721NonexistentToken",
113108
"type": "error"
114109
},
110+
{
111+
"inputs": [],
112+
"name": "FailedDeployment",
113+
"type": "error"
114+
},
115+
{
116+
"inputs": [
117+
{
118+
"internalType": "uint256",
119+
"name": "balance",
120+
"type": "uint256"
121+
},
122+
{
123+
"internalType": "uint256",
124+
"name": "needed",
125+
"type": "uint256"
126+
}
127+
],
128+
"name": "InsufficientBalance",
129+
"type": "error"
130+
},
115131
{
116132
"inputs": [],
117133
"name": "InvalidInitialization",

packages/protected-data-delivery-dapp/deployment/abis/DataProtectorSharingABI.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{
33
"inputs": [
44
{
5-
"internalType": "contract IExecPocoDelegate",
5+
"internalType": "address",
66
"name": "_proxy",
77
"type": "address"
88
},
@@ -195,7 +195,7 @@
195195
},
196196
{
197197
"inputs": [],
198-
"name": "FailedInnerCall",
198+
"name": "FailedCall",
199199
"type": "error"
200200
},
201201
{

packages/sdk/src/config/config.ts

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,37 @@
1-
export const DEFAULT_IPFS_GATEWAY = 'https://ipfs-gateway.v8-bellecour.iex.ec';
2-
3-
export const DEFAULT_IEXEC_IPFS_NODE =
4-
'https://ipfs-upload.v8-bellecour.iex.ec';
5-
1+
export type ChainId = number;
2+
3+
export interface ChainConfig {
4+
name: string;
5+
dataprotectorContractAddress: string;
6+
sharingContractAddress: string;
7+
subgraphUrl: string;
8+
ipfsGateway: string;
9+
ipfsNode: string;
10+
smsDebugURL: string;
11+
workerpoolAddress: string;
12+
}
13+
14+
export const CHAIN_CONFIG: Record<ChainId, ChainConfig> = {
15+
// Bellecour
16+
134: {
17+
name: 'bellecour',
18+
dataprotectorContractAddress: '0x3a4ab33f3d605e75b6d00a32a0fa55c3628f6a59',
19+
sharingContractAddress: '0x1390c3c6a545198809f1c7c5dd2600ef74d60925',
20+
subgraphUrl:
21+
'https://thegraph.iex.ec/subgraphs/name/bellecour/dataprotector-v2',
22+
ipfsGateway: 'https://ipfs-gateway.v8-bellecour.iex.ec',
23+
ipfsNode: 'https://ipfs-upload.v8-bellecour.iex.ec',
24+
smsDebugURL: 'https://sms-debug.iex.ec',
25+
workerpoolAddress: 'prod-v8-bellecour.main.pools.iexec.eth',
26+
},
27+
};
28+
29+
export const DEFAULT_CHAIN_ID = 134;
630
export const DEFAULT_DATA_NAME = '';
7-
8-
// Original DataProtector smart-contract
9-
export const DEFAULT_CONTRACT_ADDRESS =
10-
'0x3a4Ab33F3D605e75b6D00A32A0Fa55C3628F6A59'.toLowerCase();
11-
12-
export const DEFAULT_SHARING_CONTRACT_ADDRESS =
13-
'0x1390c3c6a545198809F1C7c5Dd2600ef74D60925'.toLowerCase();
14-
15-
export const DEFAULT_SUBGRAPH_URL =
16-
'https://thegraph.iex.ec/subgraphs/name/bellecour/dataprotector-v2';
17-
18-
export const DEFAULT_DEBUG_SMS_URL = 'https://sms-debug.iex.ec';
19-
20-
export const WORKERPOOL_ADDRESS = 'prod-v8-bellecour.main.pools.iexec.eth';
21-
2231
export const SCONE_TAG = ['tee', 'scone'];
23-
2432
export const DEFAULT_MAX_PRICE = 0;
25-
2633
export const MAX_DESIRED_DATA_ORDER_PRICE = 0;
27-
2834
export const MAX_DESIRED_APP_ORDER_PRICE = 0;
29-
3035
export const MAX_DESIRED_WORKERPOOL_ORDER_PRICE = 0;
31-
3236
export const KEY_PURPOSE_SELECTOR = 'keyHasPurpose(bytes32,uint256)';
33-
3437
export const GROUP_MEMBER_PURPOSE = 4;

packages/sdk/src/lib/IExecDataProtectorModule.ts

Lines changed: 119 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,156 @@
11
import { AbstractProvider, AbstractSigner, Eip1193Provider } from 'ethers';
22
import { GraphQLClient } from 'graphql-request';
33
import { IExec } from 'iexec';
4-
import {
5-
DEFAULT_CONTRACT_ADDRESS,
6-
DEFAULT_DEBUG_SMS_URL,
7-
DEFAULT_IEXEC_IPFS_NODE,
8-
DEFAULT_IPFS_GATEWAY,
9-
DEFAULT_SHARING_CONTRACT_ADDRESS,
10-
DEFAULT_SUBGRAPH_URL,
11-
} from '../config/config.js';
4+
import { CHAIN_CONFIG } from '../config/config.js';
5+
import { getChainIdFromProvider } from '../utils/getChainId.js';
126
import {
137
AddressOrENS,
148
DataProtectorConfigOptions,
159
Web3SignerProvider,
1610
} from './types/index.js';
1711

12+
type EthersCompatibleProvider =
13+
| AbstractProvider
14+
| AbstractSigner
15+
| Eip1193Provider
16+
| Web3SignerProvider
17+
| string;
18+
19+
interface IExecDataProtectorResolvedConfig {
20+
dataprotectorContractAddress: AddressOrENS;
21+
sharingContractAddress: AddressOrENS;
22+
graphQLClient: GraphQLClient;
23+
ipfsNode: string;
24+
ipfsGateway: string;
25+
defaultWorkerpool: string;
26+
iexec: IExec;
27+
iexecDebug: IExec;
28+
}
29+
1830
abstract class IExecDataProtectorModule {
19-
protected dataprotectorContractAddress: AddressOrENS;
31+
protected dataprotectorContractAddress!: AddressOrENS;
32+
33+
protected sharingContractAddress!: AddressOrENS;
34+
35+
protected graphQLClient!: GraphQLClient;
2036

21-
protected sharingContractAddress: AddressOrENS;
37+
protected ipfsNode!: string;
2238

23-
protected graphQLClient: GraphQLClient;
39+
protected ipfsGateway!: string;
2440

25-
protected ipfsNode: string;
41+
protected defaultWorkerpool!: string;
2642

27-
protected ipfsGateway: string;
43+
protected iexec!: IExec;
2844

29-
protected iexec: IExec;
45+
protected iexecDebug!: IExec;
3046

31-
protected iexecDebug: IExec;
47+
private initPromise: Promise<void> | null = null;
48+
49+
private ethProvider: EthersCompatibleProvider;
50+
51+
private options: DataProtectorConfigOptions;
3252

3353
constructor(
34-
ethProvider?:
35-
| AbstractProvider
36-
| AbstractSigner
37-
| Eip1193Provider
38-
| Web3SignerProvider
39-
| string,
54+
ethProvider?: EthersCompatibleProvider,
4055
options?: DataProtectorConfigOptions
4156
) {
42-
const ipfsGateway = options?.ipfsGateway || DEFAULT_IPFS_GATEWAY;
57+
this.ethProvider = ethProvider || 'bellecour';
58+
this.options = options || {};
59+
}
60+
61+
protected async init(): Promise<void> {
62+
if (!this.initPromise) {
63+
this.initPromise = this.resolveConfig().then((config) => {
64+
this.dataprotectorContractAddress = config.dataprotectorContractAddress;
65+
this.sharingContractAddress = config.sharingContractAddress;
66+
this.graphQLClient = config.graphQLClient;
67+
this.ipfsNode = config.ipfsNode;
68+
this.ipfsGateway = config.ipfsGateway;
69+
this.defaultWorkerpool = config.defaultWorkerpool;
70+
this.iexec = config.iexec;
71+
this.iexecDebug = config.iexecDebug;
72+
});
73+
}
74+
return this.initPromise;
75+
}
76+
77+
private async resolveConfig(): Promise<IExecDataProtectorResolvedConfig> {
78+
const chainId = await getChainIdFromProvider(this.ethProvider);
79+
const chainDefaultConfig = CHAIN_CONFIG[chainId];
80+
81+
const subgraphUrl =
82+
this.options?.subgraphUrl || chainDefaultConfig?.subgraphUrl;
83+
const dataprotectorContractAddress =
84+
this.options?.dataprotectorContractAddress ||
85+
chainDefaultConfig?.dataprotectorContractAddress;
86+
const sharingContractAddress =
87+
this.options?.sharingContractAddress ||
88+
chainDefaultConfig?.sharingContractAddress;
89+
const ipfsGateway =
90+
this.options?.ipfsGateway || chainDefaultConfig?.ipfsGateway;
91+
const defaultWorkerpool = chainDefaultConfig?.workerpoolAddress;
92+
const ipfsNode = this.options?.ipfsNode || chainDefaultConfig?.ipfsNode;
93+
const smsURL =
94+
this.options?.iexecOptions?.smsDebugURL ||
95+
chainDefaultConfig?.smsDebugURL;
96+
97+
const missing = [];
98+
if (!subgraphUrl) missing.push('subgraphUrl');
99+
if (!dataprotectorContractAddress)
100+
missing.push('dataprotectorContractAddress');
101+
if (!sharingContractAddress) missing.push('sharingContractAddress');
102+
if (!ipfsGateway) missing.push('ipfsGateway');
103+
if (!defaultWorkerpool) missing.push('defaultWorkerpool');
104+
if (!ipfsNode) missing.push('ipfsNode');
105+
if (!smsURL) missing.push('smsDebugURL');
106+
107+
if (missing.length > 0) {
108+
throw new Error(
109+
`Missing required configuration for chainId ${chainId}: ${missing.join(
110+
', '
111+
)}`
112+
);
113+
}
114+
115+
let iexec: IExec, iexecDebug: IExec, graphQLClient: GraphQLClient;
43116

44117
try {
45-
this.iexec = new IExec(
46-
{ ethProvider: ethProvider || 'bellecour' },
118+
iexec = new IExec(
119+
{ ethProvider: this.ethProvider },
47120
{
48121
ipfsGatewayURL: ipfsGateway,
49-
...options?.iexecOptions,
122+
...this.options?.iexecOptions,
50123
}
51124
);
52-
this.iexecDebug = new IExec(
53-
{ ethProvider: ethProvider || 'bellecour' },
125+
126+
iexecDebug = new IExec(
127+
{ ethProvider: this.ethProvider },
54128
{
55129
ipfsGatewayURL: ipfsGateway,
56-
...options?.iexecOptions,
57-
smsURL: options?.iexecOptions?.smsDebugURL || DEFAULT_DEBUG_SMS_URL,
130+
...this.options?.iexecOptions,
131+
smsURL,
58132
}
59133
);
60-
} catch (e) {
61-
throw new Error(`Unsupported ethProvider, ${e.message}`);
134+
} catch (e: any) {
135+
throw new Error(`Unsupported ethProvider: ${e.message}`);
62136
}
137+
63138
try {
64-
this.graphQLClient = new GraphQLClient(
65-
options?.subgraphUrl || DEFAULT_SUBGRAPH_URL
66-
);
67-
} catch (error) {
139+
graphQLClient = new GraphQLClient(subgraphUrl);
140+
} catch (error: any) {
68141
throw new Error(`Failed to create GraphQLClient: ${error.message}`);
69142
}
70-
this.dataprotectorContractAddress =
71-
options?.dataprotectorContractAddress?.toLowerCase() ||
72-
DEFAULT_CONTRACT_ADDRESS;
73-
this.sharingContractAddress =
74-
options?.sharingContractAddress?.toLowerCase() ||
75-
DEFAULT_SHARING_CONTRACT_ADDRESS;
76-
this.ipfsNode = options?.ipfsNode || DEFAULT_IEXEC_IPFS_NODE;
77-
this.ipfsGateway = ipfsGateway;
143+
144+
return {
145+
dataprotectorContractAddress: dataprotectorContractAddress.toLowerCase(),
146+
sharingContractAddress: sharingContractAddress.toLowerCase(),
147+
defaultWorkerpool,
148+
graphQLClient,
149+
ipfsNode,
150+
ipfsGateway,
151+
iexec,
152+
iexecDebug,
153+
};
78154
}
79155
}
80156

packages/sdk/src/lib/dataProtectorCore/IExecDataProtectorCore.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class IExecDataProtectorCore extends IExecDataProtectorModule {
3232
async protectData(
3333
args: ProtectDataParams
3434
): Promise<ProtectedDataWithSecretProps> {
35+
await this.init();
3536
await isValidProvider(this.iexec);
3637
return protectData({
3738
...args,
@@ -44,53 +45,64 @@ class IExecDataProtectorCore extends IExecDataProtectorModule {
4445
}
4546

4647
async grantAccess(args: GrantAccessParams): Promise<GrantedAccess> {
48+
await this.init();
4749
await isValidProvider(this.iexec);
4850
return grantAccess({ ...args, iexec: this.iexec });
4951
}
5052

5153
async revokeOneAccess(args: GrantedAccess): Promise<RevokedAccess> {
54+
await this.init();
5255
await isValidProvider(this.iexec);
5356
return revokeOneAccess({ ...args, iexec: this.iexec });
5457
}
5558

5659
async revokeAllAccess(args: RevokeAllAccessParams): Promise<RevokedAccess[]> {
60+
await this.init();
5761
await isValidProvider(this.iexec);
5862
return revokeAllAccess({ ...args, iexec: this.iexec });
5963
}
6064

6165
async transferOwnership(args: TransferParams): Promise<TransferResponse> {
66+
await this.init();
6267
await isValidProvider(this.iexec);
6368
return transferOwnership({ ...args, iexec: this.iexec });
6469
}
6570

6671
async processProtectedData(
6772
args: ProcessProtectedDataParams
6873
): Promise<ProcessProtectedDataResponse> {
74+
await this.init();
6975
await isValidProvider(this.iexec);
7076
return processProtectedData({
7177
...args,
7278
iexec: this.iexec,
79+
defaultWorkerpool: this.defaultWorkerpool,
7380
});
7481
}
7582

7683
// ----- READ METHODS -----
77-
getProtectedData(args?: GetProtectedDataParams): Promise<ProtectedData[]> {
84+
async getProtectedData(
85+
args?: GetProtectedDataParams
86+
): Promise<ProtectedData[]> {
87+
await this.init();
7888
return getProtectedData({
7989
...args,
8090
iexec: this.iexec,
8191
graphQLClient: this.graphQLClient,
8292
});
8393
}
8494

85-
getGrantedAccess(
95+
async getGrantedAccess(
8696
args: GetGrantedAccessParams
8797
): Promise<GrantedAccessResponse> {
98+
await this.init();
8899
return getGrantedAccess({ ...args, iexec: this.iexec });
89100
}
90101

91102
async getResultFromCompletedTask(
92103
args: GetResultFromCompletedTaskParams
93104
): Promise<GetResultFromCompletedTaskResponse> {
105+
await this.init();
94106
await isValidProvider(this.iexec);
95107
return getResultFromCompletedTask({
96108
...args,

0 commit comments

Comments
 (0)