11import { AbstractProvider , AbstractSigner , Eip1193Provider } from 'ethers' ;
22import { IExec } from 'iexec' ;
3+ import { GraphQLClient } from 'graphql-request' ;
34import { fetchUserContacts } from './fetchUserContacts.js' ;
45import { fetchMyContacts } from './fetchMyContacts.js' ;
56import { sendEmail } from './sendEmail.js' ;
@@ -13,66 +14,75 @@ import {
1314 Web3SignerProvider ,
1415 FetchMyContactsParams ,
1516} from './types.js' ;
16- import { GraphQLClient } from 'graphql-request' ;
17- import {
18- WEB3_MAIL_DAPP_ADDRESS ,
19- IPFS_UPLOAD_URL ,
20- DEFAULT_IPFS_GATEWAY ,
21- DATAPROTECTOR_SUBGRAPH_ENDPOINT ,
22- WHITELIST_SMART_CONTRACT_ADDRESS ,
23- } from '../config/config.js' ;
17+ import { CHAIN_CONFIG } from '../config/config.js' ;
2418import { isValidProvider } from '../utils/validators.js' ;
19+ import { getChainIdFromProvider } from '../utils/getChainId.js' ;
20+
21+ type EthersCompatibleProvider =
22+ | AbstractProvider
23+ | AbstractSigner
24+ | Eip1193Provider
25+ | Web3SignerProvider
26+ | string ;
27+
28+ interface Web3mailResolvedConfig {
29+ dappAddressOrENS : AddressOrENS ;
30+ dappWhitelistAddress : AddressOrENS ;
31+ graphQLClient : GraphQLClient ;
32+ ipfsNode : string ;
33+ ipfsGateway : string ;
34+ defaultWorkerpool : string ;
35+ iexec : IExec ;
36+ }
2537
2638export class IExecWeb3mail {
27- private iexec : IExec ;
39+ private dappAddressOrENS ! : AddressOrENS ;
40+
41+ private dappWhitelistAddress ! : AddressOrENS ;
42+
43+ private graphQLClient ! : GraphQLClient ;
44+
45+ private ipfsNode ! : string ;
2846
29- private ipfsNode : string ;
47+ private ipfsGateway ! : string ;
3048
31- private ipfsGateway : string ;
49+ private defaultWorkerpool ! : string ;
3250
33- private dataProtectorSubgraph : string ;
51+ private iexec ! : IExec ;
3452
35- private dappAddressOrENS : AddressOrENS ;
53+ private initPromise : Promise < void > | null = null ;
3654
37- private dappWhitelistAddress : AddressOrENS ;
55+ private ethProvider : EthersCompatibleProvider ;
3856
39- private graphQLClient : GraphQLClient ;
57+ private options : Web3MailConfigOptions ;
4058
4159 constructor (
42- ethProvider ?:
43- | Eip1193Provider
44- | AbstractProvider
45- | AbstractSigner
46- | Web3SignerProvider
47- | string ,
60+ ethProvider ?: EthersCompatibleProvider ,
4861 options ?: Web3MailConfigOptions
4962 ) {
50- try {
51- this . iexec = new IExec (
52- { ethProvider : ethProvider || 'bellecour' } ,
53- options ?. iexecOptions
54- ) ;
55- } catch ( e ) {
56- throw Error ( 'Unsupported ethProvider' ) ;
57- }
63+ this . ethProvider = ethProvider || 'bellecour' ;
64+ this . options = options || { } ;
65+ }
5866
59- try {
60- this . dataProtectorSubgraph =
61- options ?. dataProtectorSubgraph || DATAPROTECTOR_SUBGRAPH_ENDPOINT ;
62- this . graphQLClient = new GraphQLClient ( this . dataProtectorSubgraph ) ;
63- } catch ( e ) {
64- throw Error ( 'Impossible to create GraphQLClient' ) ;
67+ async init ( ) : Promise < void > {
68+ if ( ! this . initPromise ) {
69+ this . initPromise = this . resolveConfig ( ) . then ( ( config ) => {
70+ this . dappAddressOrENS = config . dappAddressOrENS ;
71+ this . dappWhitelistAddress = config . dappWhitelistAddress ;
72+ this . graphQLClient = config . graphQLClient ;
73+ this . ipfsNode = config . ipfsNode ;
74+ this . ipfsGateway = config . ipfsGateway ;
75+ this . defaultWorkerpool = config . defaultWorkerpool ;
76+ this . iexec = config . iexec ;
77+ } ) ;
6578 }
66-
67- this . dappAddressOrENS = options ?. dappAddressOrENS || WEB3_MAIL_DAPP_ADDRESS ;
68- this . ipfsNode = options ?. ipfsNode || IPFS_UPLOAD_URL ;
69- this . ipfsGateway = options ?. ipfsGateway || DEFAULT_IPFS_GATEWAY ;
70- this . dappWhitelistAddress =
71- options ?. dappWhitelistAddress || WHITELIST_SMART_CONTRACT_ADDRESS ;
79+ return this . initPromise ;
7280 }
7381
7482 async fetchMyContacts ( args ?: FetchMyContactsParams ) : Promise < Contact [ ] > {
83+ await this . init ( ) ;
7584 await isValidProvider ( this . iexec ) ;
85+
7686 return fetchMyContacts ( {
7787 ...args ,
7888 iexec : this . iexec ,
@@ -82,7 +92,9 @@ export class IExecWeb3mail {
8292 } ) ;
8393 }
8494
85- fetchUserContacts ( args : FetchUserContactsParams ) : Promise < Contact [ ] > {
95+ async fetchUserContacts ( args : FetchUserContactsParams ) : Promise < Contact [ ] > {
96+ await this . init ( ) ;
97+
8698 return fetchUserContacts ( {
8799 ...args ,
88100 iexec : this . iexec ,
@@ -93,9 +105,12 @@ export class IExecWeb3mail {
93105 }
94106
95107 async sendEmail ( args : SendEmailParams ) : Promise < SendEmailResponse > {
108+ await this . init ( ) ;
96109 await isValidProvider ( this . iexec ) ;
97110 return sendEmail ( {
98111 ...args ,
112+ workerpoolAddressOrEns :
113+ args . workerpoolAddressOrEns || this . defaultWorkerpool ,
99114 iexec : this . iexec ,
100115 ipfsNode : this . ipfsNode ,
101116 ipfsGateway : this . ipfsGateway ,
@@ -105,4 +120,69 @@ export class IExecWeb3mail {
105120 useVoucher : args ?. useVoucher ,
106121 } ) ;
107122 }
123+
124+ private async resolveConfig ( ) : Promise < Web3mailResolvedConfig > {
125+ const chainId = await getChainIdFromProvider ( this . ethProvider ) ;
126+ const chainDefaultConfig = CHAIN_CONFIG [ chainId ] ;
127+
128+ const subgraphUrl =
129+ this . options ?. dataProtectorSubgraph ||
130+ chainDefaultConfig ?. dataProtectorSubgraph ;
131+ const dappAddressOrENS =
132+ this . options ?. dappAddressOrENS || chainDefaultConfig ?. dappAddress ;
133+ const dappWhitelistAddress =
134+ this . options ?. dappWhitelistAddress ||
135+ chainDefaultConfig ?. whitelistSmartContract ;
136+ const ipfsGateway =
137+ this . options ?. ipfsGateway || chainDefaultConfig ?. ipfsGateway ;
138+ const defaultWorkerpool = chainDefaultConfig ?. prodWorkerpoolAddress ;
139+ const ipfsNode =
140+ this . options ?. ipfsNode || chainDefaultConfig ?. ipfsUploadUrl ;
141+
142+ const missing = [ ] ;
143+ if ( ! subgraphUrl ) missing . push ( 'dataProtectorSubgraph' ) ;
144+ if ( ! dappAddressOrENS ) missing . push ( 'dappAddress' ) ;
145+ if ( ! dappWhitelistAddress ) missing . push ( 'whitelistSmartContract' ) ;
146+ if ( ! ipfsGateway ) missing . push ( 'ipfsGateway' ) ;
147+ if ( ! defaultWorkerpool ) missing . push ( 'prodWorkerpoolAddress' ) ;
148+ if ( ! ipfsNode ) missing . push ( 'ipfsUploadUrl' ) ;
149+
150+ if ( missing . length > 0 ) {
151+ throw new Error (
152+ `Missing required configuration for chainId ${ chainId } : ${ missing . join (
153+ ', '
154+ ) } `
155+ ) ;
156+ }
157+
158+ let iexec : IExec , graphQLClient : GraphQLClient ;
159+
160+ try {
161+ iexec = new IExec (
162+ { ethProvider : this . ethProvider } ,
163+ {
164+ ipfsGatewayURL : ipfsGateway ,
165+ ...this . options ?. iexecOptions ,
166+ }
167+ ) ;
168+ } catch ( e : any ) {
169+ throw new Error ( `Unsupported ethProvider: ${ e . message } ` ) ;
170+ }
171+
172+ try {
173+ graphQLClient = new GraphQLClient ( subgraphUrl ) ;
174+ } catch ( error : any ) {
175+ throw new Error ( `Failed to create GraphQLClient: ${ error . message } ` ) ;
176+ }
177+
178+ return {
179+ dappAddressOrENS,
180+ dappWhitelistAddress : dappWhitelistAddress . toLowerCase ( ) ,
181+ defaultWorkerpool,
182+ graphQLClient,
183+ ipfsNode,
184+ ipfsGateway,
185+ iexec,
186+ } ;
187+ }
108188}
0 commit comments