@iexec/web3mail 1.6.0 → 1.7.1
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.
- package/dist/utils/subgraphQuery.js +5 -2
- package/dist/utils/subgraphQuery.js.map +1 -1
- package/dist/utils/validators.d.ts +35 -0
- package/dist/utils/validators.js +45 -1
- package/dist/utils/validators.js.map +1 -1
- package/dist/web3mail/IExecWeb3mail.d.ts +4 -1
- package/dist/web3mail/IExecWeb3mail.js +38 -0
- package/dist/web3mail/IExecWeb3mail.js.map +1 -1
- package/dist/web3mail/fetchMyContacts.d.ts +1 -1
- package/dist/web3mail/fetchMyContacts.js +3 -1
- package/dist/web3mail/fetchMyContacts.js.map +1 -1
- package/dist/web3mail/fetchUserContacts.d.ts +1 -1
- package/dist/web3mail/fetchUserContacts.js +20 -3
- package/dist/web3mail/fetchUserContacts.js.map +1 -1
- package/dist/web3mail/internalTypes.d.ts +4 -0
- package/dist/web3mail/prepareEmailCampaign.d.ts +4 -0
- package/dist/web3mail/prepareEmailCampaign.js +106 -0
- package/dist/web3mail/prepareEmailCampaign.js.map +1 -0
- package/dist/web3mail/sendEmail.js +9 -5
- package/dist/web3mail/sendEmail.js.map +1 -1
- package/dist/web3mail/sendEmailCampaign.d.ts +4 -0
- package/dist/web3mail/sendEmailCampaign.js +43 -0
- package/dist/web3mail/sendEmailCampaign.js.map +1 -0
- package/dist/web3mail/types.d.ts +96 -1
- package/package.json +5 -6
- package/src/utils/subgraphQuery.ts +17 -14
- package/src/utils/validators.ts +68 -1
- package/src/web3mail/IExecWeb3mail.ts +53 -0
- package/src/web3mail/fetchMyContacts.ts +3 -0
- package/src/web3mail/fetchUserContacts.ts +28 -11
- package/src/web3mail/internalTypes.ts +5 -0
- package/src/web3mail/prepareEmailCampaign.ts +170 -0
- package/src/web3mail/sendEmail.ts +31 -5
- package/src/web3mail/sendEmailCampaign.ts +69 -0
- package/src/web3mail/types.ts +102 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_CONTENT_TYPE,
|
|
4
|
+
MAX_DESIRED_APP_ORDER_PRICE,
|
|
5
|
+
MAX_DESIRED_WORKERPOOL_ORDER_PRICE,
|
|
6
|
+
} from '../config/config.js';
|
|
7
|
+
import { handleIfProtocolError, WorkflowError } from '../utils/errors.js';
|
|
8
|
+
import * as ipfs from '../utils/ipfs-service.js';
|
|
9
|
+
import {
|
|
10
|
+
addressOrEnsSchema,
|
|
11
|
+
contentTypeSchema,
|
|
12
|
+
emailContentSchema,
|
|
13
|
+
emailSubjectSchema,
|
|
14
|
+
labelSchema,
|
|
15
|
+
positiveNumberSchema,
|
|
16
|
+
senderNameSchema,
|
|
17
|
+
throwIfMissing,
|
|
18
|
+
} from '../utils/validators.js';
|
|
19
|
+
import {
|
|
20
|
+
PrepareEmailCampaignParams,
|
|
21
|
+
PrepareEmailCampaignResponse,
|
|
22
|
+
} from './types.js';
|
|
23
|
+
import {
|
|
24
|
+
DappAddressConsumer,
|
|
25
|
+
DataProtectorConsumer,
|
|
26
|
+
IExecConsumer,
|
|
27
|
+
IpfsGatewayConfigConsumer,
|
|
28
|
+
IpfsNodeConfigConsumer,
|
|
29
|
+
} from './internalTypes.js';
|
|
30
|
+
|
|
31
|
+
export type PrepareEmailCampaign = typeof prepareEmailCampaign;
|
|
32
|
+
|
|
33
|
+
export const prepareEmailCampaign = async ({
|
|
34
|
+
iexec = throwIfMissing(),
|
|
35
|
+
dataProtector = throwIfMissing(),
|
|
36
|
+
workerpoolAddressOrEns,
|
|
37
|
+
dappAddressOrENS,
|
|
38
|
+
ipfsNode,
|
|
39
|
+
ipfsGateway,
|
|
40
|
+
senderName,
|
|
41
|
+
emailSubject,
|
|
42
|
+
emailContent,
|
|
43
|
+
contentType = DEFAULT_CONTENT_TYPE,
|
|
44
|
+
label,
|
|
45
|
+
appMaxPrice = MAX_DESIRED_APP_ORDER_PRICE,
|
|
46
|
+
workerpoolMaxPrice = MAX_DESIRED_WORKERPOOL_ORDER_PRICE,
|
|
47
|
+
grantedAccesses,
|
|
48
|
+
maxProtectedDataPerTask,
|
|
49
|
+
}: IExecConsumer &
|
|
50
|
+
DappAddressConsumer &
|
|
51
|
+
IpfsNodeConfigConsumer &
|
|
52
|
+
IpfsGatewayConfigConsumer &
|
|
53
|
+
DataProtectorConsumer &
|
|
54
|
+
PrepareEmailCampaignParams): Promise<PrepareEmailCampaignResponse> => {
|
|
55
|
+
try {
|
|
56
|
+
const vWorkerpoolAddressOrEns = addressOrEnsSchema()
|
|
57
|
+
.label('WorkerpoolAddressOrEns')
|
|
58
|
+
.validateSync(workerpoolAddressOrEns);
|
|
59
|
+
|
|
60
|
+
const vSenderName = senderNameSchema()
|
|
61
|
+
.label('senderName')
|
|
62
|
+
.validateSync(senderName);
|
|
63
|
+
|
|
64
|
+
const vEmailSubject = emailSubjectSchema()
|
|
65
|
+
.required()
|
|
66
|
+
.label('emailSubject')
|
|
67
|
+
.validateSync(emailSubject);
|
|
68
|
+
|
|
69
|
+
const vEmailContent = emailContentSchema()
|
|
70
|
+
.required()
|
|
71
|
+
.label('emailContent')
|
|
72
|
+
.validateSync(emailContent);
|
|
73
|
+
|
|
74
|
+
const vContentType = contentTypeSchema()
|
|
75
|
+
.label('contentType')
|
|
76
|
+
.validateSync(contentType);
|
|
77
|
+
|
|
78
|
+
const vLabel = labelSchema().label('label').validateSync(label);
|
|
79
|
+
|
|
80
|
+
const vDappAddressOrENS = addressOrEnsSchema()
|
|
81
|
+
.required()
|
|
82
|
+
.label('dappAddressOrENS')
|
|
83
|
+
.validateSync(dappAddressOrENS);
|
|
84
|
+
|
|
85
|
+
const vAppMaxPrice = positiveNumberSchema()
|
|
86
|
+
.label('appMaxPrice')
|
|
87
|
+
.validateSync(appMaxPrice);
|
|
88
|
+
|
|
89
|
+
const vWorkerpoolMaxPrice = positiveNumberSchema()
|
|
90
|
+
.label('workerpoolMaxPrice')
|
|
91
|
+
.validateSync(workerpoolMaxPrice);
|
|
92
|
+
|
|
93
|
+
const vMaxProtectedDataPerTask = positiveNumberSchema()
|
|
94
|
+
.label('maxProtectedDataPerTask')
|
|
95
|
+
.validateSync(maxProtectedDataPerTask);
|
|
96
|
+
|
|
97
|
+
// TODO: factor this
|
|
98
|
+
// Encrypt email content
|
|
99
|
+
const emailContentEncryptionKey = iexec.dataset.generateEncryptionKey();
|
|
100
|
+
const encryptedFile = await iexec.dataset
|
|
101
|
+
.encrypt(Buffer.from(vEmailContent, 'utf8'), emailContentEncryptionKey)
|
|
102
|
+
.catch((e) => {
|
|
103
|
+
throw new WorkflowError({
|
|
104
|
+
message: 'Failed to encrypt email content',
|
|
105
|
+
errorCause: e,
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Push email content to IPFS
|
|
110
|
+
const cid = await ipfs
|
|
111
|
+
.add(encryptedFile, {
|
|
112
|
+
ipfsNode,
|
|
113
|
+
ipfsGateway,
|
|
114
|
+
})
|
|
115
|
+
.catch((e) => {
|
|
116
|
+
throw new WorkflowError({
|
|
117
|
+
message: 'Failed to upload encrypted email content',
|
|
118
|
+
errorCause: e,
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const multiaddr = `/ipfs/${cid}`;
|
|
123
|
+
|
|
124
|
+
// Prepare secrets for the requester
|
|
125
|
+
// Use a positive integer as secret ID (required by iexec)
|
|
126
|
+
// Using "1" as a fixed ID for the requester secret
|
|
127
|
+
const requesterSecretId = 1;
|
|
128
|
+
const secrets = {
|
|
129
|
+
[requesterSecretId]: JSON.stringify({
|
|
130
|
+
emailSubject: vEmailSubject,
|
|
131
|
+
emailContentMultiAddr: multiaddr,
|
|
132
|
+
contentType: vContentType,
|
|
133
|
+
senderName: vSenderName,
|
|
134
|
+
emailContentEncryptionKey,
|
|
135
|
+
useCallback: true,
|
|
136
|
+
}),
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// TODO: end factor this
|
|
140
|
+
const { bulkRequest: campaignRequest } =
|
|
141
|
+
await dataProtector.prepareBulkRequest({
|
|
142
|
+
app: vDappAddressOrENS,
|
|
143
|
+
appMaxPrice: vAppMaxPrice,
|
|
144
|
+
workerpoolMaxPrice: vWorkerpoolMaxPrice,
|
|
145
|
+
workerpool: vWorkerpoolAddressOrEns,
|
|
146
|
+
args: vLabel,
|
|
147
|
+
inputFiles: [],
|
|
148
|
+
secrets,
|
|
149
|
+
bulkAccesses: grantedAccesses,
|
|
150
|
+
maxProtectedDataPerTask: vMaxProtectedDataPerTask,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
return { campaignRequest };
|
|
154
|
+
} catch (error) {
|
|
155
|
+
// Protocol error detected, re-throwing as-is
|
|
156
|
+
if ((error as any)?.isProtocolError === true) {
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Handle protocol errors - this will throw if it's an ApiCallError
|
|
161
|
+
// handleIfProtocolError transforms ApiCallError into a WorkflowError with isProtocolError=true
|
|
162
|
+
handleIfProtocolError(error);
|
|
163
|
+
|
|
164
|
+
// For all other errors
|
|
165
|
+
throw new WorkflowError({
|
|
166
|
+
message: 'Failed to prepareEmailCampaign',
|
|
167
|
+
errorCause: error,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
};
|
|
@@ -67,43 +67,55 @@ export const sendEmail = async ({
|
|
|
67
67
|
.required()
|
|
68
68
|
.label('protectedData')
|
|
69
69
|
.validateSync(protectedData);
|
|
70
|
+
|
|
70
71
|
const vEmailSubject = emailSubjectSchema()
|
|
71
72
|
.required()
|
|
72
73
|
.label('emailSubject')
|
|
73
74
|
.validateSync(emailSubject);
|
|
75
|
+
|
|
74
76
|
const vEmailContent = emailContentSchema()
|
|
75
77
|
.required()
|
|
76
78
|
.label('emailContent')
|
|
77
79
|
.validateSync(emailContent);
|
|
80
|
+
|
|
78
81
|
const vContentType = contentTypeSchema()
|
|
79
82
|
.required()
|
|
80
83
|
.label('contentType')
|
|
81
84
|
.validateSync(contentType);
|
|
85
|
+
|
|
82
86
|
const vSenderName = senderNameSchema()
|
|
83
87
|
.label('senderName')
|
|
84
88
|
.validateSync(senderName);
|
|
89
|
+
|
|
85
90
|
const vLabel = labelSchema().label('label').validateSync(label);
|
|
91
|
+
|
|
86
92
|
const vWorkerpoolAddressOrEns = addressOrEnsSchema()
|
|
87
93
|
.required()
|
|
88
94
|
.label('WorkerpoolAddressOrEns')
|
|
89
95
|
.validateSync(workerpoolAddressOrEns);
|
|
96
|
+
|
|
90
97
|
const vDappAddressOrENS = addressOrEnsSchema()
|
|
91
98
|
.required()
|
|
92
99
|
.label('dappAddressOrENS')
|
|
93
100
|
.validateSync(dappAddressOrENS);
|
|
101
|
+
|
|
94
102
|
const vDappWhitelistAddress = addressSchema()
|
|
95
103
|
.required()
|
|
96
104
|
.label('dappWhitelistAddress')
|
|
97
105
|
.validateSync(dappWhitelistAddress);
|
|
106
|
+
|
|
98
107
|
const vDataMaxPrice = positiveNumberSchema()
|
|
99
108
|
.label('dataMaxPrice')
|
|
100
109
|
.validateSync(dataMaxPrice);
|
|
110
|
+
|
|
101
111
|
const vAppMaxPrice = positiveNumberSchema()
|
|
102
112
|
.label('appMaxPrice')
|
|
103
113
|
.validateSync(appMaxPrice);
|
|
114
|
+
|
|
104
115
|
const vWorkerpoolMaxPrice = positiveNumberSchema()
|
|
105
116
|
.label('workerpoolMaxPrice')
|
|
106
117
|
.validateSync(workerpoolMaxPrice);
|
|
118
|
+
|
|
107
119
|
const vUseVoucher = booleanSchema()
|
|
108
120
|
.label('useVoucher')
|
|
109
121
|
.validateSync(useVoucher);
|
|
@@ -113,6 +125,7 @@ export const sendEmail = async ({
|
|
|
113
125
|
graphQLClient,
|
|
114
126
|
vDatasetAddress
|
|
115
127
|
);
|
|
128
|
+
|
|
116
129
|
if (!isValidProtectedData) {
|
|
117
130
|
throw new Error(
|
|
118
131
|
'This protected data does not contain "email:string" in its schema.'
|
|
@@ -145,7 +158,8 @@ export const sendEmail = async ({
|
|
|
145
158
|
] = await Promise.all([
|
|
146
159
|
// Fetch dataset order for web3mail app
|
|
147
160
|
iexec.orderbook
|
|
148
|
-
.fetchDatasetOrderbook(
|
|
161
|
+
.fetchDatasetOrderbook({
|
|
162
|
+
dataset: vDatasetAddress,
|
|
149
163
|
app: dappAddressOrENS,
|
|
150
164
|
requester: requesterAddress,
|
|
151
165
|
})
|
|
@@ -155,9 +169,11 @@ export const sendEmail = async ({
|
|
|
155
169
|
);
|
|
156
170
|
return desiredPriceDataOrderbook[0]?.order; // may be undefined
|
|
157
171
|
}),
|
|
172
|
+
|
|
158
173
|
// Fetch dataset order for web3mail whitelist
|
|
159
174
|
iexec.orderbook
|
|
160
|
-
.fetchDatasetOrderbook(
|
|
175
|
+
.fetchDatasetOrderbook({
|
|
176
|
+
dataset: vDatasetAddress,
|
|
161
177
|
app: vDappWhitelistAddress,
|
|
162
178
|
requester: requesterAddress,
|
|
163
179
|
})
|
|
@@ -167,9 +183,11 @@ export const sendEmail = async ({
|
|
|
167
183
|
);
|
|
168
184
|
return desiredPriceDataOrderbook[0]?.order; // may be undefined
|
|
169
185
|
}),
|
|
186
|
+
|
|
170
187
|
// Fetch app order
|
|
171
188
|
iexec.orderbook
|
|
172
|
-
.fetchAppOrderbook(
|
|
189
|
+
.fetchAppOrderbook({
|
|
190
|
+
app: dappAddressOrENS,
|
|
173
191
|
minTag: ['tee', 'scone'],
|
|
174
192
|
maxTag: ['tee', 'scone'],
|
|
175
193
|
workerpool: workerpoolAddressOrEns,
|
|
@@ -184,6 +202,7 @@ export const sendEmail = async ({
|
|
|
184
202
|
}
|
|
185
203
|
return desiredPriceAppOrder;
|
|
186
204
|
}),
|
|
205
|
+
|
|
187
206
|
// Fetch workerpool order for App or AppWhitelist
|
|
188
207
|
Promise.all([
|
|
189
208
|
// for app
|
|
@@ -219,9 +238,11 @@ export const sendEmail = async ({
|
|
|
219
238
|
useVoucher: vUseVoucher,
|
|
220
239
|
userVoucher,
|
|
221
240
|
});
|
|
241
|
+
|
|
222
242
|
if (!desiredPriceWorkerpoolOrder) {
|
|
223
243
|
throw new Error('No Workerpool order found for the desired price');
|
|
224
244
|
}
|
|
245
|
+
|
|
225
246
|
return desiredPriceWorkerpoolOrder;
|
|
226
247
|
}
|
|
227
248
|
),
|
|
@@ -247,6 +268,7 @@ export const sendEmail = async ({
|
|
|
247
268
|
errorCause: e,
|
|
248
269
|
});
|
|
249
270
|
});
|
|
271
|
+
|
|
250
272
|
const cid = await ipfs
|
|
251
273
|
.add(encryptedFile, {
|
|
252
274
|
ipfsNode: ipfsNode,
|
|
@@ -258,6 +280,7 @@ export const sendEmail = async ({
|
|
|
258
280
|
errorCause: e,
|
|
259
281
|
});
|
|
260
282
|
});
|
|
283
|
+
|
|
261
284
|
const multiaddr = `/ipfs/${cid}`;
|
|
262
285
|
|
|
263
286
|
await iexec.secrets.pushRequesterSecret(
|
|
@@ -289,10 +312,11 @@ export const sendEmail = async ({
|
|
|
289
312
|
iexec_args: vLabel,
|
|
290
313
|
},
|
|
291
314
|
});
|
|
315
|
+
|
|
292
316
|
const requestorder = await iexec.order.signRequestorder(requestorderToSign);
|
|
293
317
|
|
|
294
318
|
// Match orders and compute task ID
|
|
295
|
-
const { dealid } = await iexec.order.matchOrders(
|
|
319
|
+
const { dealid: dealId } = await iexec.order.matchOrders(
|
|
296
320
|
{
|
|
297
321
|
apporder: apporder,
|
|
298
322
|
datasetorder: datasetorder,
|
|
@@ -301,10 +325,12 @@ export const sendEmail = async ({
|
|
|
301
325
|
},
|
|
302
326
|
{ useVoucher: vUseVoucher }
|
|
303
327
|
);
|
|
304
|
-
|
|
328
|
+
|
|
329
|
+
const taskId = await iexec.deal.computeTaskId(dealId, 0);
|
|
305
330
|
|
|
306
331
|
return {
|
|
307
332
|
taskId,
|
|
333
|
+
dealId,
|
|
308
334
|
};
|
|
309
335
|
} catch (error) {
|
|
310
336
|
handleIfProtocolError(error);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { NULL_ADDRESS } from 'iexec/utils';
|
|
2
|
+
import { ValidationError } from 'yup';
|
|
3
|
+
import { handleIfProtocolError, WorkflowError } from '../utils/errors.js';
|
|
4
|
+
import {
|
|
5
|
+
addressOrEnsSchema,
|
|
6
|
+
campaignRequestSchema,
|
|
7
|
+
throwIfMissing,
|
|
8
|
+
} from '../utils/validators.js';
|
|
9
|
+
import {
|
|
10
|
+
CampaignRequest,
|
|
11
|
+
SendEmailCampaignParams,
|
|
12
|
+
SendEmailCampaignResponse,
|
|
13
|
+
} from './types.js';
|
|
14
|
+
import { DataProtectorConsumer } from './internalTypes.js';
|
|
15
|
+
|
|
16
|
+
export type SendEmailCampaign = typeof sendEmailCampaign;
|
|
17
|
+
|
|
18
|
+
export const sendEmailCampaign = async ({
|
|
19
|
+
dataProtector = throwIfMissing(),
|
|
20
|
+
workerpoolAddressOrEns = throwIfMissing(),
|
|
21
|
+
campaignRequest,
|
|
22
|
+
}: DataProtectorConsumer &
|
|
23
|
+
SendEmailCampaignParams): Promise<SendEmailCampaignResponse> => {
|
|
24
|
+
const vCampaignRequest = campaignRequestSchema()
|
|
25
|
+
.required()
|
|
26
|
+
.label('campaignRequest')
|
|
27
|
+
.validateSync(campaignRequest) as CampaignRequest;
|
|
28
|
+
|
|
29
|
+
const vWorkerpoolAddressOrEns = addressOrEnsSchema()
|
|
30
|
+
.required()
|
|
31
|
+
.label('workerpoolAddressOrEns')
|
|
32
|
+
.validateSync(workerpoolAddressOrEns);
|
|
33
|
+
|
|
34
|
+
if (
|
|
35
|
+
vCampaignRequest.workerpool !== NULL_ADDRESS &&
|
|
36
|
+
vCampaignRequest.workerpool.toLowerCase() !==
|
|
37
|
+
vWorkerpoolAddressOrEns.toLowerCase()
|
|
38
|
+
) {
|
|
39
|
+
throw new ValidationError(
|
|
40
|
+
"workerpoolAddressOrEns doesn't match campaignRequest workerpool"
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
// Process the prepared bulk request
|
|
46
|
+
const processBulkRequestResponse = await dataProtector.processBulkRequest({
|
|
47
|
+
bulkRequest: vCampaignRequest,
|
|
48
|
+
workerpool: vWorkerpoolAddressOrEns,
|
|
49
|
+
waitForResult: false,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
return processBulkRequestResponse;
|
|
53
|
+
} catch (error) {
|
|
54
|
+
// Protocol error detected, re-throwing as-is
|
|
55
|
+
if ((error as any)?.isProtocolError === true) {
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Handle protocol errors - this will throw if it's an ApiCallError
|
|
60
|
+
// handleIfProtocolError transforms ApiCallError into a WorkflowError with isProtocolError=true
|
|
61
|
+
handleIfProtocolError(error);
|
|
62
|
+
|
|
63
|
+
// For all other errors
|
|
64
|
+
throw new WorkflowError({
|
|
65
|
+
message: 'Failed to sendEmailCampaign',
|
|
66
|
+
errorCause: error,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
package/src/web3mail/types.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { EnhancedWallet } from 'iexec';
|
|
2
2
|
import { IExecConfigOptions } from 'iexec/IExecConfig';
|
|
3
|
+
import type { BulkRequest } from '@iexec/dataprotector';
|
|
3
4
|
|
|
4
5
|
export type Web3SignerProvider = EnhancedWallet;
|
|
5
6
|
|
|
@@ -11,14 +12,44 @@ export type Address = string;
|
|
|
11
12
|
|
|
12
13
|
export type TimeStamp = string;
|
|
13
14
|
|
|
15
|
+
/**
|
|
16
|
+
* request to send email in bulk
|
|
17
|
+
*
|
|
18
|
+
* use `prepareEmailCampaign()` to create a `CampaignRequest`
|
|
19
|
+
*
|
|
20
|
+
* then use `sendEmailCampaign()` to send the campaign
|
|
21
|
+
*/
|
|
22
|
+
export type CampaignRequest = BulkRequest;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* authorization signed by the data owner granting access to this contact
|
|
26
|
+
*
|
|
27
|
+
* `GrantedAccess` are obtained by fetching contacts (e.g. `fetchMyContacts()` or `fetchUserContacts()`)
|
|
28
|
+
*
|
|
29
|
+
* `GrantedAccess` can be consumed for email campaigns (e.g. `prepareEmailCampaign()` then `sendEmailCampaign()`)
|
|
30
|
+
*/
|
|
31
|
+
export type GrantedAccess = {
|
|
32
|
+
dataset: string;
|
|
33
|
+
datasetprice: string;
|
|
34
|
+
volume: string;
|
|
35
|
+
tag: string;
|
|
36
|
+
apprestrict: string;
|
|
37
|
+
workerpoolrestrict: string;
|
|
38
|
+
requesterrestrict: string;
|
|
39
|
+
salt: string;
|
|
40
|
+
sign: string;
|
|
41
|
+
remainingAccess: number;
|
|
42
|
+
};
|
|
43
|
+
|
|
14
44
|
export type Contact = {
|
|
15
45
|
address: Address;
|
|
16
46
|
owner: Address;
|
|
17
47
|
accessGrantTimestamp: TimeStamp;
|
|
18
48
|
isUserStrict: boolean;
|
|
19
|
-
name
|
|
49
|
+
name?: string;
|
|
20
50
|
remainingAccess: number;
|
|
21
51
|
accessPrice: number;
|
|
52
|
+
grantedAccess: GrantedAccess;
|
|
22
53
|
};
|
|
23
54
|
|
|
24
55
|
export type SendEmailParams = {
|
|
@@ -40,6 +71,10 @@ export type FetchMyContactsParams = {
|
|
|
40
71
|
* Get contacts for this specific user only
|
|
41
72
|
*/
|
|
42
73
|
isUserStrict?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* If true, returns only contacts with bulk processing access grants
|
|
76
|
+
*/
|
|
77
|
+
bulkOnly?: boolean;
|
|
43
78
|
};
|
|
44
79
|
|
|
45
80
|
export type FetchUserContactsParams = {
|
|
@@ -50,7 +85,14 @@ export type FetchUserContactsParams = {
|
|
|
50
85
|
} & FetchMyContactsParams;
|
|
51
86
|
|
|
52
87
|
export type SendEmailResponse = {
|
|
88
|
+
/**
|
|
89
|
+
* ID of the task
|
|
90
|
+
*/
|
|
53
91
|
taskId: string;
|
|
92
|
+
/**
|
|
93
|
+
* ID of the deal containing the task
|
|
94
|
+
*/
|
|
95
|
+
dealId: string;
|
|
54
96
|
};
|
|
55
97
|
|
|
56
98
|
/**
|
|
@@ -100,3 +142,62 @@ export type Web3MailConfigOptions = {
|
|
|
100
142
|
*/
|
|
101
143
|
allowExperimentalNetworks?: boolean;
|
|
102
144
|
};
|
|
145
|
+
|
|
146
|
+
export type PrepareEmailCampaignParams = {
|
|
147
|
+
/**
|
|
148
|
+
* List of `GrantedAccess` to contacts to send emails to in bulk.
|
|
149
|
+
*
|
|
150
|
+
* use `fetchMyContacts({ bulkOnly: true })` to get granted accesses.
|
|
151
|
+
*/
|
|
152
|
+
grantedAccesses: GrantedAccess[];
|
|
153
|
+
maxProtectedDataPerTask?: number;
|
|
154
|
+
senderName?: string;
|
|
155
|
+
emailSubject: string;
|
|
156
|
+
emailContent: string;
|
|
157
|
+
contentType?: string;
|
|
158
|
+
label?: string;
|
|
159
|
+
workerpoolAddressOrEns?: AddressOrENS;
|
|
160
|
+
dataMaxPrice?: number;
|
|
161
|
+
appMaxPrice?: number;
|
|
162
|
+
workerpoolMaxPrice?: number;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export type PrepareEmailCampaignResponse = {
|
|
166
|
+
/**
|
|
167
|
+
* The prepared campaign request
|
|
168
|
+
*
|
|
169
|
+
* Use this in `sendEmailCampaign()` to start or continue sending the campaign
|
|
170
|
+
*/
|
|
171
|
+
campaignRequest: CampaignRequest;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export type SendEmailCampaignParams = {
|
|
175
|
+
/**
|
|
176
|
+
* The prepared campaign request from `prepareEmailCampaign()`
|
|
177
|
+
*/
|
|
178
|
+
campaignRequest: CampaignRequest;
|
|
179
|
+
/**
|
|
180
|
+
* Workerpool address or ENS to use for processing
|
|
181
|
+
*/
|
|
182
|
+
workerpoolAddressOrEns?: AddressOrENS;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export type SendEmailCampaignResponse = {
|
|
186
|
+
/**
|
|
187
|
+
* List of tasks created for the campaign
|
|
188
|
+
*/
|
|
189
|
+
tasks: Array<{
|
|
190
|
+
/**
|
|
191
|
+
* ID of the task
|
|
192
|
+
*/
|
|
193
|
+
taskId: string;
|
|
194
|
+
/**
|
|
195
|
+
* ID of the deal containing the task
|
|
196
|
+
*/
|
|
197
|
+
dealId: string;
|
|
198
|
+
/**
|
|
199
|
+
* Index of the task in the bulk request
|
|
200
|
+
*/
|
|
201
|
+
bulkIndex: number;
|
|
202
|
+
}>;
|
|
203
|
+
};
|