@iexec/web3mail 0.5.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/config/config.d.ts +3 -1
  2. package/dist/config/config.js +3 -1
  3. package/dist/config/config.js.map +1 -1
  4. package/dist/utils/errors.d.ts +1 -2
  5. package/dist/utils/errors.js +1 -2
  6. package/dist/utils/errors.js.map +1 -1
  7. package/dist/utils/ipfs-service.d.ts +7 -5
  8. package/dist/utils/ipfs-service.js +3 -3
  9. package/dist/utils/ipfs-service.js.map +1 -1
  10. package/dist/utils/subgraphQuery.js +2 -3
  11. package/dist/utils/subgraphQuery.js.map +1 -1
  12. package/dist/utils/validators.d.ts +4 -0
  13. package/dist/utils/validators.js +9 -4
  14. package/dist/utils/validators.js.map +1 -1
  15. package/dist/web3mail/IExecWeb3mail.d.ts +13 -8
  16. package/dist/web3mail/IExecWeb3mail.js +21 -8
  17. package/dist/web3mail/IExecWeb3mail.js.map +1 -1
  18. package/dist/web3mail/fetchMyContacts.d.ts +2 -2
  19. package/dist/web3mail/fetchMyContacts.js +8 -39
  20. package/dist/web3mail/fetchMyContacts.js.map +1 -1
  21. package/dist/web3mail/fetchUserContacts.d.ts +2 -0
  22. package/dist/web3mail/fetchUserContacts.js +82 -0
  23. package/dist/web3mail/fetchUserContacts.js.map +1 -0
  24. package/dist/web3mail/sendEmail.d.ts +2 -2
  25. package/dist/web3mail/sendEmail.js +103 -54
  26. package/dist/web3mail/sendEmail.js.map +1 -1
  27. package/dist/web3mail/types.d.ts +58 -7
  28. package/package.json +17 -16
  29. package/src/config/config.ts +3 -1
  30. package/src/utils/errors.ts +2 -3
  31. package/src/utils/ipfs-service.ts +20 -4
  32. package/src/utils/subgraphQuery.ts +2 -4
  33. package/src/utils/validators.ts +20 -6
  34. package/src/web3mail/IExecWeb3mail.ts +65 -23
  35. package/src/web3mail/fetchMyContacts.ts +15 -58
  36. package/src/web3mail/fetchUserContacts.ts +105 -0
  37. package/src/web3mail/sendEmail.ts +138 -73
  38. package/src/web3mail/types.ts +72 -7
@@ -1,14 +1,10 @@
1
- import {
2
- WEB3_MAIL_DAPP_ADDRESS,
3
- WHITELIST_SMART_CONTRACT_ADDRESS,
4
- } from '../config/config.js';
5
1
  import { WorkflowError } from '../utils/errors.js';
6
- import { autoPaginateRequest } from '../utils/paginate.js';
7
- import { getValidContact } from '../utils/subgraphQuery.js';
8
2
  import { throwIfMissing } from '../utils/validators.js';
3
+ import { fetchUserContacts } from './fetchUserContacts.js';
9
4
  import {
10
5
  Contact,
11
- FetchContactsParams,
6
+ DappAddressConsumer,
7
+ DappWhitelistAddressConsumer,
12
8
  IExecConsumer,
13
9
  SubgraphConsumer,
14
10
  } from './types.js';
@@ -16,60 +12,21 @@ import {
16
12
  export const fetchMyContacts = async ({
17
13
  graphQLClient = throwIfMissing(),
18
14
  iexec = throwIfMissing(),
19
- page,
20
- pageSize,
21
- }: IExecConsumer & SubgraphConsumer & FetchContactsParams): Promise<
22
- Contact[]
23
- > => {
15
+ dappAddressOrENS = throwIfMissing(),
16
+ dappWhitelistAddress = throwIfMissing(),
17
+ }: IExecConsumer &
18
+ SubgraphConsumer &
19
+ DappAddressConsumer &
20
+ DappWhitelistAddressConsumer): Promise<Contact[]> => {
24
21
  try {
25
22
  const userAddress = await iexec.wallet.getAddress();
26
- const datasetOrderbookAuthorizedBySC =
27
- await iexec.orderbook.fetchDatasetOrderbook('any', {
28
- app: WHITELIST_SMART_CONTRACT_ADDRESS,
29
- requester: userAddress,
30
- page,
31
- pageSize,
32
- });
33
- const datasetOrderbookAuthorizedByENS =
34
- await iexec.orderbook.fetchDatasetOrderbook('any', {
35
- app: WEB3_MAIL_DAPP_ADDRESS,
36
- requester: userAddress,
37
- page,
38
- pageSize,
39
- });
40
-
41
- const { orders: ensOrders } = await autoPaginateRequest({
42
- request: datasetOrderbookAuthorizedByENS,
43
- });
44
- const { orders: scOrders } = await autoPaginateRequest({
45
- request: datasetOrderbookAuthorizedBySC,
23
+ return await fetchUserContacts({
24
+ iexec,
25
+ graphQLClient,
26
+ dappAddressOrENS,
27
+ dappWhitelistAddress,
28
+ userAddress,
46
29
  });
47
-
48
- const orders = ensOrders.concat(scOrders);
49
- const myContacts: Contact[] = [];
50
- const web3DappResolvedAddress = await iexec.ens.resolveName(
51
- WEB3_MAIL_DAPP_ADDRESS
52
- );
53
-
54
- orders.forEach((order) => {
55
- if (
56
- order.order.apprestrict.toLowerCase() ===
57
- web3DappResolvedAddress.toLowerCase() ||
58
- order.order.apprestrict.toLowerCase() ===
59
- WHITELIST_SMART_CONTRACT_ADDRESS.toLowerCase()
60
- ) {
61
- const contact = {
62
- address: order.order.dataset.toLowerCase(),
63
- owner: order.signer.toLowerCase(),
64
- accessGrantTimestamp: order.publicationTimestamp,
65
- };
66
- myContacts.push(contact);
67
- }
68
- });
69
-
70
- const validContacts = await getValidContact(graphQLClient, myContacts);
71
-
72
- return validContacts;
73
30
  } catch (error) {
74
31
  throw new WorkflowError(
75
32
  `Failed to fetch my contacts: ${error.message}`,
@@ -0,0 +1,105 @@
1
+ import { ANY_DATASET_ADDRESS } from '../config/config.js';
2
+ import { WorkflowError } from '../utils/errors.js';
3
+ import { autoPaginateRequest } from '../utils/paginate.js';
4
+ import { getValidContact } from '../utils/subgraphQuery.js';
5
+ import {
6
+ addressOrEnsSchema,
7
+ addressSchema,
8
+ isEnsTest,
9
+ throwIfMissing,
10
+ } from '../utils/validators.js';
11
+ import {
12
+ Contact,
13
+ DappAddressConsumer,
14
+ DappWhitelistAddressConsumer,
15
+ FetchUserContactsParams,
16
+ IExecConsumer,
17
+ SubgraphConsumer,
18
+ } from './types.js';
19
+
20
+ export const fetchUserContacts = async ({
21
+ graphQLClient = throwIfMissing(),
22
+ iexec = throwIfMissing(),
23
+ dappAddressOrENS = throwIfMissing(),
24
+ dappWhitelistAddress = throwIfMissing(),
25
+ userAddress,
26
+ }: IExecConsumer &
27
+ SubgraphConsumer &
28
+ DappAddressConsumer &
29
+ DappWhitelistAddressConsumer &
30
+ FetchUserContactsParams): Promise<Contact[]> => {
31
+ try {
32
+ const vDappAddressOrENS = addressOrEnsSchema()
33
+ .required()
34
+ .label('dappAddressOrENS')
35
+ .validateSync(dappAddressOrENS);
36
+ const vDappWhitelistAddress = addressSchema()
37
+ .required()
38
+ .label('dappWhitelistAddress')
39
+ .validateSync(dappWhitelistAddress);
40
+ const vUserAddress = addressOrEnsSchema()
41
+ .required()
42
+ .label('userAddress')
43
+ .validateSync(userAddress);
44
+
45
+ const [dappOrders, whitelistOrders] = await Promise.all([
46
+ fetchAllOrdersByApp({
47
+ iexec,
48
+ userAddress: vUserAddress,
49
+ appAddress: vDappAddressOrENS,
50
+ }),
51
+ fetchAllOrdersByApp({
52
+ iexec,
53
+ userAddress: vUserAddress,
54
+ appAddress: vDappWhitelistAddress,
55
+ }),
56
+ ]);
57
+
58
+ const orders = dappOrders.concat(whitelistOrders);
59
+ const myContacts: Contact[] = [];
60
+ let web3DappResolvedAddress = vDappAddressOrENS;
61
+ if (isEnsTest(vDappAddressOrENS)) {
62
+ web3DappResolvedAddress = await iexec.ens.resolveName(vDappAddressOrENS);
63
+ }
64
+ orders.forEach((order) => {
65
+ if (
66
+ order.order.apprestrict.toLowerCase() ===
67
+ web3DappResolvedAddress.toLowerCase() ||
68
+ order.order.apprestrict.toLowerCase() ===
69
+ vDappWhitelistAddress.toLowerCase()
70
+ ) {
71
+ const contact = {
72
+ address: order.order.dataset.toLowerCase(),
73
+ owner: order.signer.toLowerCase(),
74
+ accessGrantTimestamp: order.publicationTimestamp,
75
+ };
76
+ myContacts.push(contact);
77
+ }
78
+ });
79
+
80
+ //getValidContact function remove duplicated contacts for the same protectedData address,
81
+ //keeping the most recent one
82
+ return await getValidContact(graphQLClient, myContacts);
83
+ } catch (error) {
84
+ throw new WorkflowError(
85
+ `Failed to fetch my contacts: ${error.message}`,
86
+ error
87
+ );
88
+ }
89
+ };
90
+
91
+ async function fetchAllOrdersByApp({ iexec, userAddress, appAddress }) {
92
+ const ordersFirstPage = iexec.orderbook.fetchDatasetOrderbook(
93
+ ANY_DATASET_ADDRESS,
94
+ {
95
+ app: appAddress,
96
+ requester: userAddress,
97
+ // Use maxPageSize here to avoid too many round-trips (we want everything anyway)
98
+ pageSize: 1000,
99
+ }
100
+ );
101
+ const { orders: allOrders } = await autoPaginateRequest({
102
+ request: ordersFirstPage,
103
+ });
104
+ return allOrders;
105
+ }
@@ -1,39 +1,59 @@
1
1
  import {
2
2
  DEFAULT_CONTENT_TYPE,
3
3
  MAX_DESIRED_APP_ORDER_PRICE,
4
+ MAX_DESIRED_DATA_ORDER_PRICE,
4
5
  MAX_DESIRED_WORKERPOOL_ORDER_PRICE,
5
- WEB3_MAIL_DAPP_ADDRESS,
6
- WORKERPOOL_ADDRESS,
6
+ PROD_WORKERPOOL_ADDRESS,
7
7
  } from '../config/config.js';
8
8
  import { WorkflowError } from '../utils/errors.js';
9
9
  import { generateSecureUniqueId } from '../utils/generateUniqueId.js';
10
+ import * as ipfs from '../utils/ipfs-service.js';
10
11
  import { checkProtectedDataValidity } from '../utils/subgraphQuery.js';
11
12
  import {
12
13
  addressOrEnsSchema,
14
+ addressSchema,
13
15
  contentTypeSchema,
14
16
  emailContentSchema,
15
17
  emailSubjectSchema,
18
+ labelSchema,
19
+ positiveNumberSchema,
16
20
  senderNameSchema,
17
21
  throwIfMissing,
18
22
  } from '../utils/validators.js';
19
23
  import {
24
+ DappAddressConsumer,
25
+ DappWhitelistAddressConsumer,
20
26
  IExecConsumer,
27
+ IpfsGatewayConfigConsumer,
28
+ IpfsNodeConfigConsumer,
21
29
  SendEmailParams,
22
30
  SendEmailResponse,
23
31
  SubgraphConsumer,
24
32
  } from './types.js';
25
- import * as ipfs from './../utils/ipfs-service.js';
26
33
 
27
34
  export const sendEmail = async ({
28
35
  graphQLClient = throwIfMissing(),
29
36
  iexec = throwIfMissing(),
37
+ workerpoolAddressOrEns = PROD_WORKERPOOL_ADDRESS,
38
+ dappAddressOrENS,
39
+ dappWhitelistAddress,
40
+ ipfsNode,
41
+ ipfsGateway,
30
42
  emailSubject,
31
43
  emailContent,
32
44
  contentType = DEFAULT_CONTENT_TYPE,
45
+ label,
46
+ dataMaxPrice = MAX_DESIRED_DATA_ORDER_PRICE,
47
+ appMaxPrice = MAX_DESIRED_APP_ORDER_PRICE,
48
+ workerpoolMaxPrice = MAX_DESIRED_WORKERPOOL_ORDER_PRICE,
33
49
  senderName,
34
50
  protectedData,
35
51
  }: IExecConsumer &
36
52
  SubgraphConsumer &
53
+ DappAddressConsumer &
54
+ DappWhitelistAddressConsumer &
55
+ IpfsNodeConfigConsumer &
56
+ IpfsGatewayConfigConsumer &
37
57
  SendEmailParams): Promise<SendEmailResponse> => {
38
58
  try {
39
59
  const vDatasetAddress = addressOrEnsSchema()
@@ -55,6 +75,28 @@ export const sendEmail = async ({
55
75
  const vSenderName = senderNameSchema()
56
76
  .label('senderName')
57
77
  .validateSync(senderName);
78
+ const vLabel = labelSchema().label('label').validateSync(label);
79
+ const vWorkerpoolAddressOrEns = addressOrEnsSchema()
80
+ .required()
81
+ .label('WorkerpoolAddressOrEns')
82
+ .validateSync(workerpoolAddressOrEns);
83
+ const vDappAddressOrENS = addressOrEnsSchema()
84
+ .required()
85
+ .label('dappAddressOrENS')
86
+ .validateSync(dappAddressOrENS);
87
+ const vDappWhitelistAddress = addressSchema()
88
+ .required()
89
+ .label('dappWhitelistAddress')
90
+ .validateSync(dappWhitelistAddress);
91
+ const vDataMaxPrice = positiveNumberSchema()
92
+ .label('dataMaxPrice')
93
+ .validateSync(dataMaxPrice);
94
+ const vAppMaxPrice = positiveNumberSchema()
95
+ .label('appMaxPrice')
96
+ .validateSync(appMaxPrice);
97
+ const vWorkerpoolMaxPrice = positiveNumberSchema()
98
+ .label('workerpoolMaxPrice')
99
+ .validateSync(workerpoolMaxPrice);
58
100
 
59
101
  // Check protected data validity through subgraph
60
102
  const isValidProtectedData = await checkProtectedDataValidity(
@@ -75,67 +117,83 @@ export const sendEmail = async ({
75
117
  await iexec.storage.pushStorageToken(token);
76
118
  }
77
119
 
78
- // Fetch dataset order
79
- const datasetOrderbook = await iexec.orderbook.fetchDatasetOrderbook(
80
- vDatasetAddress,
81
- {
82
- app: WEB3_MAIL_DAPP_ADDRESS,
83
- requester: requesterAddress,
84
- }
85
- );
86
- const datasetorder = datasetOrderbook?.orders[0]?.order;
87
- if (!datasetorder) {
88
- throw new Error('Dataset order not found');
89
- }
90
-
91
- // Fetch app order
92
- const appOrderbook = await iexec.orderbook.fetchAppOrderbook(
93
- WEB3_MAIL_DAPP_ADDRESS,
94
- {
95
- minTag: ['tee', 'scone'],
96
- maxTag: ['tee', 'scone'],
97
- workerpool: WORKERPOOL_ADDRESS,
98
- }
99
- );
100
- const appOrder = appOrderbook?.orders[0]?.order;
101
- if (!appOrder) {
102
- throw new Error('App order not found');
103
- }
104
-
105
- const desiredPriceAppOrderbook = appOrderbook.orders.filter(
106
- (order) => order.order.appprice <= MAX_DESIRED_APP_ORDER_PRICE
107
- );
108
- const desiredPriceAppOrder = desiredPriceAppOrderbook[0]?.order;
109
- if (!desiredPriceAppOrder) {
110
- throw new Error('No App order found for the desired price');
111
- }
112
-
113
- // Fetch workerpool order
114
- const workerpoolOrderbook = await iexec.orderbook.fetchWorkerpoolOrderbook({
115
- workerpool: WORKERPOOL_ADDRESS,
116
- app: WEB3_MAIL_DAPP_ADDRESS,
117
- dataset: vDatasetAddress,
118
- minTag: ['tee', 'scone'],
119
- maxTag: ['tee', 'scone'],
120
- category: 0,
121
- });
122
-
123
- const workerpoolorder = workerpoolOrderbook?.orders[0]?.order;
124
- if (!workerpoolorder) {
125
- throw new Error('Workerpool order not found');
126
- }
120
+ const [
121
+ datasetorderForApp,
122
+ datasetorderForWhitelist,
123
+ apporder,
124
+ workerpoolorder,
125
+ ] = await Promise.all([
126
+ // Fetch dataset order for web3mail app
127
+ iexec.orderbook
128
+ .fetchDatasetOrderbook(vDatasetAddress, {
129
+ app: dappAddressOrENS,
130
+ requester: requesterAddress,
131
+ })
132
+ .then((datasetOrderbook) => {
133
+ const desiredPriceDataOrderbook = datasetOrderbook.orders.filter(
134
+ (order) => order.order.datasetprice <= vDataMaxPrice
135
+ );
136
+ return desiredPriceDataOrderbook[0]?.order; // may be undefined
137
+ }),
138
+ // Fetch dataset order for web3mail whitelist
139
+ iexec.orderbook
140
+ .fetchDatasetOrderbook(vDatasetAddress, {
141
+ app: vDappWhitelistAddress,
142
+ requester: requesterAddress,
143
+ })
144
+ .then((datasetOrderbook) => {
145
+ const desiredPriceDataOrderbook = datasetOrderbook.orders.filter(
146
+ (order) => order.order.datasetprice <= vDataMaxPrice
147
+ );
148
+ return desiredPriceDataOrderbook[0]?.order; // may be undefined
149
+ }),
150
+ // Fetch app order
151
+ iexec.orderbook
152
+ .fetchAppOrderbook(dappAddressOrENS, {
153
+ minTag: ['tee', 'scone'],
154
+ maxTag: ['tee', 'scone'],
155
+ workerpool: workerpoolAddressOrEns,
156
+ })
157
+ .then((appOrderbook) => {
158
+ const desiredPriceAppOrderbook = appOrderbook.orders.filter(
159
+ (order) => order.order.appprice <= vAppMaxPrice
160
+ );
161
+ const desiredPriceAppOrder = desiredPriceAppOrderbook[0]?.order;
162
+ if (!desiredPriceAppOrder) {
163
+ throw new Error('No App order found for the desired price');
164
+ }
165
+ return desiredPriceAppOrder;
166
+ }),
167
+ // Fetch workerpool order
168
+ iexec.orderbook
169
+ .fetchWorkerpoolOrderbook({
170
+ workerpool: workerpoolAddressOrEns,
171
+ app: dappAddressOrENS,
172
+ dataset: vDatasetAddress,
173
+ minTag: ['tee', 'scone'],
174
+ maxTag: ['tee', 'scone'],
175
+ category: 0,
176
+ })
177
+ .then((workerpoolOrderbook) => {
178
+ const desiredPriceWorkerpoolOrderbook =
179
+ workerpoolOrderbook.orders.filter(
180
+ (order) => order.order.workerpoolprice <= vWorkerpoolMaxPrice
181
+ );
182
+ const randomIndex = Math.floor(
183
+ Math.random() * desiredPriceWorkerpoolOrderbook.length
184
+ );
185
+ const desiredPriceWorkerpoolOrder =
186
+ desiredPriceWorkerpoolOrderbook[randomIndex]?.order;
187
+ if (!desiredPriceWorkerpoolOrder) {
188
+ throw new Error('No Workerpool order found for the desired price');
189
+ }
190
+ return desiredPriceWorkerpoolOrder;
191
+ }),
192
+ ]);
127
193
 
128
- const desiredPriceWorkerpoolOrderbook = workerpoolOrderbook.orders.filter(
129
- (order) =>
130
- order.order.workerpoolprice <= MAX_DESIRED_WORKERPOOL_ORDER_PRICE
131
- );
132
- const randomIndex = Math.floor(
133
- Math.random() * desiredPriceWorkerpoolOrderbook.length
134
- );
135
- const desiredPriceWorkerpoolOrder =
136
- desiredPriceWorkerpoolOrderbook[randomIndex]?.order;
137
- if (!desiredPriceWorkerpoolOrder) {
138
- throw new Error('No Workerpool order found for the desired price');
194
+ const datasetorder = datasetorderForApp || datasetorderForWhitelist;
195
+ if (!datasetorder) {
196
+ throw new Error('No Dataset order found for the desired price');
139
197
  }
140
198
 
141
199
  // Push requester secrets
@@ -146,9 +204,14 @@ export const sendEmail = async ({
146
204
  .catch((e) => {
147
205
  throw new WorkflowError('Failed to encrypt email content', e);
148
206
  });
149
- const cid = await ipfs.add(encryptedFile).catch((e) => {
150
- throw new WorkflowError('Failed to upload encrypted email content', e);
151
- });
207
+ const cid = await ipfs
208
+ .add(encryptedFile, {
209
+ ipfsNode: ipfsNode,
210
+ ipfsGateway: ipfsGateway,
211
+ })
212
+ .catch((e) => {
213
+ throw new WorkflowError('Failed to upload encrypted email content', e);
214
+ });
152
215
  const multiaddr = `/ipfs/${cid}`;
153
216
 
154
217
  await iexec.secrets.pushRequesterSecret(
@@ -163,27 +226,29 @@ export const sendEmail = async ({
163
226
  );
164
227
 
165
228
  const requestorderToSign = await iexec.order.createRequestorder({
166
- app: WEB3_MAIL_DAPP_ADDRESS,
167
- category: desiredPriceWorkerpoolOrder.category,
229
+ app: vDappAddressOrENS,
230
+ category: workerpoolorder.category,
168
231
  dataset: vDatasetAddress,
169
- appmaxprice: desiredPriceAppOrder.appprice,
170
- workerpoolmaxprice: desiredPriceWorkerpoolOrder.workerpoolprice,
232
+ datasetmaxprice: datasetorder.datasetprice,
233
+ appmaxprice: apporder.appprice,
234
+ workerpoolmaxprice: workerpoolorder.workerpoolprice,
171
235
  tag: ['tee', 'scone'],
172
- workerpool: WORKERPOOL_ADDRESS,
236
+ workerpool: vWorkerpoolAddressOrEns,
173
237
  params: {
174
238
  iexec_developer_logger: true,
175
239
  iexec_secrets: {
176
240
  1: requesterSecretId,
177
241
  },
242
+ iexec_args: vLabel,
178
243
  },
179
244
  });
180
245
  const requestorder = await iexec.order.signRequestorder(requestorderToSign);
181
246
 
182
247
  // Match orders and compute task ID
183
248
  const { dealid } = await iexec.order.matchOrders({
184
- apporder: desiredPriceAppOrder,
249
+ apporder: apporder,
185
250
  datasetorder: datasetorder,
186
- workerpoolorder: desiredPriceWorkerpoolOrder,
251
+ workerpoolorder: workerpoolorder,
187
252
  requestorder: requestorder,
188
253
  });
189
254
  const taskId = await iexec.deal.computeTaskId(dealid, 0);
@@ -1,5 +1,6 @@
1
1
  import { GraphQLClient } from 'graphql-request';
2
2
  import { EnhancedWallet, IExec } from 'iexec';
3
+ import { IExecConfigOptions } from 'iexec/IExecConfig';
3
4
 
4
5
  export type Web3SignerProvider = EnhancedWallet;
5
6
 
@@ -7,6 +8,10 @@ export type IExecConsumer = {
7
8
  iexec: IExec;
8
9
  };
9
10
 
11
+ export type ENS = string;
12
+
13
+ export type AddressOrENS = Address | ENS;
14
+
10
15
  export type Address = string;
11
16
 
12
17
  export type TimeStamp = string;
@@ -16,24 +21,27 @@ export type Contact = {
16
21
  owner: Address;
17
22
  accessGrantTimestamp: TimeStamp;
18
23
  };
24
+
19
25
  export type SendEmailParams = {
20
26
  emailSubject: string;
21
27
  emailContent: string;
22
28
  protectedData: Address;
23
29
  contentType?: string;
24
30
  senderName?: string;
31
+ label?: string;
32
+ workerpoolAddressOrEns?: AddressOrENS;
33
+ dataMaxPrice?: number;
34
+ appMaxPrice?: number;
35
+ workerpoolMaxPrice?: number;
25
36
  };
26
37
 
27
- export type FetchContactsParams = {
28
- /**
29
- * Index of the page to fetch
30
- */
31
- page?: number;
38
+ export type FetchUserContactsParams = {
32
39
  /**
33
- * Size of the page to fetch
40
+ * Address of the user
34
41
  */
35
- pageSize?: number;
42
+ userAddress: Address;
36
43
  };
44
+
37
45
  export type SendEmailResponse = {
38
46
  taskId: Address;
39
47
  };
@@ -52,3 +60,60 @@ export type GraphQLResponse = {
52
60
  export type SubgraphConsumer = {
53
61
  graphQLClient: GraphQLClient;
54
62
  };
63
+
64
+ /**
65
+ * Configuration options for Web3Mail.
66
+ */
67
+ export type Web3MailConfigOptions = {
68
+ /**
69
+ * The Ethereum contract address or ENS (Ethereum Name Service) for the email sender dapp.
70
+ * If not provided, the default web3mail address will be used.
71
+ */
72
+ dappAddressOrENS?: AddressOrENS;
73
+
74
+ /**
75
+ * The Ethereum contract address for the whitelist.
76
+ * If not provided, the default whitelist smart contract address will be used.
77
+ */
78
+ dappWhitelistAddress?: Address;
79
+
80
+ /**
81
+ * The subgraph URL for querying data.
82
+ * If not provided, the default data protector subgraph URL will be used.
83
+ */
84
+ dataProtectorSubgraph?: string;
85
+
86
+ /**
87
+ * Options specific to iExec integration.
88
+ * If not provided, default iexec options will be used.
89
+ */
90
+ iexecOptions?: IExecConfigOptions;
91
+
92
+ /**
93
+ * The IPFS node URL.
94
+ * If not provided, the default IPFS node URL will be used.
95
+ */
96
+ ipfsNode?: string;
97
+
98
+ /**
99
+ * The IPFS gateway URL.
100
+ * If not provided, the default IPFS gateway URL will be used.
101
+ */
102
+ ipfsGateway?: string;
103
+ };
104
+
105
+ export type DappAddressConsumer = {
106
+ dappAddressOrENS: AddressOrENS;
107
+ };
108
+
109
+ export type IpfsNodeConfigConsumer = {
110
+ ipfsNode: string;
111
+ };
112
+
113
+ export type IpfsGatewayConfigConsumer = {
114
+ ipfsGateway: string;
115
+ };
116
+
117
+ export type DappWhitelistAddressConsumer = {
118
+ dappWhitelistAddress: string;
119
+ };