@iexec/web3mail 1.0.0 → 1.0.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/config/config.d.ts +11 -0
- package/dist/config/config.js +12 -0
- package/dist/config/config.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/errors.d.ts +9 -0
- package/dist/utils/errors.js +19 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/generateUniqueId.d.ts +1 -0
- package/dist/utils/generateUniqueId.js +6 -0
- package/dist/utils/generateUniqueId.js.map +1 -0
- package/dist/utils/getWeb3Provider.d.ts +2 -0
- package/dist/utils/getWeb3Provider.js +3 -0
- package/dist/utils/getWeb3Provider.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/ipfs-service.d.ts +9 -0
- package/dist/utils/ipfs-service.js +20 -0
- package/dist/utils/ipfs-service.js.map +1 -0
- package/dist/utils/paginate.d.ts +5 -0
- package/dist/utils/paginate.js +14 -0
- package/dist/utils/paginate.js.map +1 -0
- package/dist/utils/subgraphQuery.d.ts +4 -0
- package/dist/utils/subgraphQuery.js +87 -0
- package/dist/utils/subgraphQuery.js.map +1 -0
- package/dist/utils/validators.d.ts +13 -0
- package/dist/utils/validators.js +34 -0
- package/dist/utils/validators.js.map +1 -0
- package/dist/web3mail/IExecWeb3mail.d.ts +15 -0
- package/dist/web3mail/IExecWeb3mail.js +68 -0
- package/dist/web3mail/IExecWeb3mail.js.map +1 -0
- package/dist/web3mail/fetchMyContacts.d.ts +2 -0
- package/dist/web3mail/fetchMyContacts.js +17 -0
- package/dist/web3mail/fetchMyContacts.js.map +1 -0
- package/dist/web3mail/fetchUserContacts.d.ts +2 -0
- package/dist/web3mail/fetchUserContacts.js +82 -0
- package/dist/web3mail/fetchUserContacts.js.map +1 -0
- package/dist/web3mail/sendEmail.d.ts +2 -0
- package/dist/web3mail/sendEmail.js +191 -0
- package/dist/web3mail/sendEmail.js.map +1 -0
- package/dist/web3mail/types.d.ts +102 -0
- package/dist/web3mail/types.js +2 -0
- package/dist/web3mail/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const WEB3_MAIL_DAPP_ADDRESS = "web3mail.apps.iexec.eth";
|
|
2
|
+
export declare const PROD_WORKERPOOL_ADDRESS = "prod-v8-bellecour.main.pools.iexec.eth";
|
|
3
|
+
export declare const DATAPROTECTOR_SUBGRAPH_ENDPOINT = "https://thegraph-product.iex.ec/subgraphs/name/bellecour/dataprotector";
|
|
4
|
+
export declare const MAX_DESIRED_DATA_ORDER_PRICE = 0;
|
|
5
|
+
export declare const MAX_DESIRED_APP_ORDER_PRICE = 0;
|
|
6
|
+
export declare const MAX_DESIRED_WORKERPOOL_ORDER_PRICE = 0;
|
|
7
|
+
export declare const DEFAULT_CONTENT_TYPE = "text/plain";
|
|
8
|
+
export declare const IPFS_UPLOAD_URL = "/dns4/ipfs-upload.v8-bellecour.iex.ec/https";
|
|
9
|
+
export declare const DEFAULT_IPFS_GATEWAY = "https://ipfs-gateway.v8-bellecour.iex.ec";
|
|
10
|
+
export declare const WHITELIST_SMART_CONTRACT_ADDRESS = "0x781482C39CcE25546583EaC4957Fb7Bf04C277D2";
|
|
11
|
+
export declare const ANY_DATASET_ADDRESS = "any";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const WEB3_MAIL_DAPP_ADDRESS = 'web3mail.apps.iexec.eth';
|
|
2
|
+
export const PROD_WORKERPOOL_ADDRESS = 'prod-v8-bellecour.main.pools.iexec.eth';
|
|
3
|
+
export const DATAPROTECTOR_SUBGRAPH_ENDPOINT = 'https://thegraph-product.iex.ec/subgraphs/name/bellecour/dataprotector';
|
|
4
|
+
export const MAX_DESIRED_DATA_ORDER_PRICE = 0;
|
|
5
|
+
export const MAX_DESIRED_APP_ORDER_PRICE = 0;
|
|
6
|
+
export const MAX_DESIRED_WORKERPOOL_ORDER_PRICE = 0;
|
|
7
|
+
export const DEFAULT_CONTENT_TYPE = 'text/plain';
|
|
8
|
+
export const IPFS_UPLOAD_URL = '/dns4/ipfs-upload.v8-bellecour.iex.ec/https';
|
|
9
|
+
export const DEFAULT_IPFS_GATEWAY = 'https://ipfs-gateway.v8-bellecour.iex.ec';
|
|
10
|
+
export const WHITELIST_SMART_CONTRACT_ADDRESS = '0x781482C39CcE25546583EaC4957Fb7Bf04C277D2';
|
|
11
|
+
export const ANY_DATASET_ADDRESS = 'any';
|
|
12
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG,yBAAyB,CAAC;AAChE,MAAM,CAAC,MAAM,uBAAuB,GAAG,wCAAwC,CAAC;AAChF,MAAM,CAAC,MAAM,+BAA+B,GAC1C,wEAAwE,CAAC;AAC3E,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC;AAC9C,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAC7C,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,CAAC;AACpD,MAAM,CAAC,MAAM,oBAAoB,GAAG,YAAY,CAAC;AACjD,MAAM,CAAC,MAAM,eAAe,GAAG,6CAA6C,CAAC;AAC7E,MAAM,CAAC,MAAM,oBAAoB,GAAG,0CAA0C,CAAC;AAC/E,MAAM,CAAC,MAAM,gCAAgC,GAC3C,4CAA4C,CAAC;AAC/C,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class WorkflowError extends Error {
|
|
2
|
+
isProtocolError: boolean;
|
|
3
|
+
constructor({ message, errorCause, isProtocolError, }: {
|
|
4
|
+
message: string;
|
|
5
|
+
errorCause: Error;
|
|
6
|
+
isProtocolError?: boolean;
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
export declare function handleIfProtocolError(error: Error): void;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ApiCallError } from 'iexec/errors';
|
|
2
|
+
export class WorkflowError extends Error {
|
|
3
|
+
isProtocolError;
|
|
4
|
+
constructor({ message, errorCause, isProtocolError = false, }) {
|
|
5
|
+
super(message, { cause: errorCause });
|
|
6
|
+
this.name = this.constructor.name;
|
|
7
|
+
this.isProtocolError = isProtocolError;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export function handleIfProtocolError(error) {
|
|
11
|
+
if (error instanceof ApiCallError) {
|
|
12
|
+
throw new WorkflowError({
|
|
13
|
+
message: "A service in the iExec protocol appears to be unavailable. You can retry later or contact iExec's technical support for help.",
|
|
14
|
+
errorCause: error,
|
|
15
|
+
isProtocolError: true,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,eAAe,CAAU;IAEzB,YAAY,EACV,OAAO,EACP,UAAU,EACV,eAAe,GAAG,KAAK,GAKxB;QACC,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAClC,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;IACzC,CAAC;CACF;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAY;IAChD,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;QAClC,MAAM,IAAI,aAAa,CAAC;YACtB,OAAO,EACL,+HAA+H;YACjI,UAAU,EAAE,KAAK;YACjB,eAAe,EAAE,IAAI;SACtB,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateSecureUniqueId(length: any): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateUniqueId.js","sourceRoot":"","sources":["../../src/utils/generateUniqueId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,MAAM,UAAU,sBAAsB,CAAC,MAAM;IAC3C,OAAO,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getWeb3Provider.js","sourceRoot":"","sources":["../../src/utils/getWeb3Provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAGtD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,UAAkB,EAAsB,EAAE,CACxE,uBAAuB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { WorkflowError } from './errors.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface GetOptions {
|
|
2
|
+
ipfsGateway?: string;
|
|
3
|
+
}
|
|
4
|
+
interface AddOptions extends GetOptions {
|
|
5
|
+
ipfsNode?: string;
|
|
6
|
+
}
|
|
7
|
+
declare const get: (cid: any, { ipfsGateway }?: GetOptions) => Promise<Uint8Array>;
|
|
8
|
+
declare const add: (content: any, { ipfsNode, ipfsGateway, }?: AddOptions) => Promise<any>;
|
|
9
|
+
export { add, get };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { create } from 'kubo-rpc-client';
|
|
2
|
+
import { IPFS_UPLOAD_URL, DEFAULT_IPFS_GATEWAY } from '../config/config.js';
|
|
3
|
+
const get = async (cid, { ipfsGateway = DEFAULT_IPFS_GATEWAY } = {}) => {
|
|
4
|
+
const multiaddr = `/ipfs/${cid.toString()}`;
|
|
5
|
+
const publicUrl = `${ipfsGateway}${multiaddr}`;
|
|
6
|
+
const res = await fetch(publicUrl);
|
|
7
|
+
if (!res.ok) {
|
|
8
|
+
throw Error(`Failed to load content from ${publicUrl}`);
|
|
9
|
+
}
|
|
10
|
+
const arrayBuffer = await res.arrayBuffer();
|
|
11
|
+
return new Uint8Array(arrayBuffer);
|
|
12
|
+
};
|
|
13
|
+
const add = async (content, { ipfsNode = IPFS_UPLOAD_URL, ipfsGateway = DEFAULT_IPFS_GATEWAY, } = {}) => {
|
|
14
|
+
const ipfsClient = create(ipfsNode);
|
|
15
|
+
const { cid } = await ipfsClient.add(content);
|
|
16
|
+
await get(cid.toString(), { ipfsGateway });
|
|
17
|
+
return cid.toString();
|
|
18
|
+
};
|
|
19
|
+
export { add, get };
|
|
20
|
+
//# sourceMappingURL=ipfs-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipfs-service.js","sourceRoot":"","sources":["../../src/utils/ipfs-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAS5E,MAAM,GAAG,GAAG,KAAK,EACf,GAAG,EACH,EAAE,WAAW,GAAG,oBAAoB,KAAiB,EAAE,EACvD,EAAE;IACF,MAAM,SAAS,GAAG,SAAS,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,GAAG,WAAW,GAAG,SAAS,EAAE,CAAC;IAC/C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;IACnC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,KAAK,CAAC,+BAA+B,SAAS,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;IAC5C,OAAO,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,GAAG,GAAG,KAAK,EACf,OAAO,EACP,EACE,QAAQ,GAAG,eAAe,EAC1B,WAAW,GAAG,oBAAoB,MACpB,EAAE,EAClB,EAAE;IACF,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IAC3C,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC,CAAC;AAEF,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const autoPaginateRequest = async ({ request }, { orders = [] } = {}) => {
|
|
2
|
+
const res = await request;
|
|
3
|
+
const totalCount = res.count;
|
|
4
|
+
if (res.orders.length > 0) {
|
|
5
|
+
orders.push(...res.orders);
|
|
6
|
+
if (res.more && typeof res.more === 'function') {
|
|
7
|
+
return autoPaginateRequest({
|
|
8
|
+
request: res.more(),
|
|
9
|
+
}, { orders });
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return { orders, count: totalCount };
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=paginate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginate.js","sourceRoot":"","sources":["../../src/utils/paginate.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EACtC,EAAE,OAAO,EAAE,EACX,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,EAAE,EACpB,EAAE;IACF,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC;IAC1B,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC;IAC7B,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,GAAG,CAAC,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/C,OAAO,mBAAmB,CACxB;gBACE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE;aACpB,EACD,EAAE,MAAM,EAAE,CACX,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AACvC,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { GraphQLClient } from 'graphql-request';
|
|
2
|
+
import { Contact } from '../index.js';
|
|
3
|
+
export declare const getValidContact: (graphQLClient: GraphQLClient, contacts: Contact[]) => Promise<Contact[]>;
|
|
4
|
+
export declare const checkProtectedDataValidity: (graphQLClient: GraphQLClient, protectedData: string) => Promise<boolean>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { gql } from 'graphql-request';
|
|
2
|
+
import { WorkflowError } from './errors.js';
|
|
3
|
+
const checkProtectedDataQuery = gql `
|
|
4
|
+
query GetValidContacts(
|
|
5
|
+
$requiredSchema: [String!]!
|
|
6
|
+
$id: [String!]!
|
|
7
|
+
$start: Int!
|
|
8
|
+
$range: Int!
|
|
9
|
+
) {
|
|
10
|
+
protectedDatas(
|
|
11
|
+
where: {
|
|
12
|
+
transactionHash_not: "0x"
|
|
13
|
+
schema_contains: $requiredSchema
|
|
14
|
+
id_in: $id
|
|
15
|
+
}
|
|
16
|
+
skip: $start
|
|
17
|
+
first: $range
|
|
18
|
+
orderBy: creationTimestamp
|
|
19
|
+
orderDirection: desc
|
|
20
|
+
) {
|
|
21
|
+
id
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
`;
|
|
25
|
+
export const getValidContact = async (graphQLClient, contacts) => {
|
|
26
|
+
try {
|
|
27
|
+
// Contacts addresses
|
|
28
|
+
const contactsAddresses = contacts.map((contact) => contact.address);
|
|
29
|
+
// Pagination
|
|
30
|
+
const protectedDataList = [];
|
|
31
|
+
let start = 0;
|
|
32
|
+
const range = 1000;
|
|
33
|
+
let continuePagination = true;
|
|
34
|
+
do {
|
|
35
|
+
const variables = {
|
|
36
|
+
requiredSchema: ['email:string'],
|
|
37
|
+
id: contactsAddresses,
|
|
38
|
+
start,
|
|
39
|
+
range,
|
|
40
|
+
};
|
|
41
|
+
const protectedDataResultQuery = await graphQLClient.request(checkProtectedDataQuery, variables);
|
|
42
|
+
const { protectedDatas } = protectedDataResultQuery;
|
|
43
|
+
protectedDataList.push(...protectedDatas);
|
|
44
|
+
continuePagination = protectedDatas.length === range;
|
|
45
|
+
start += range;
|
|
46
|
+
} while (continuePagination);
|
|
47
|
+
// Convert contacts array into a map where the key is the contact's address
|
|
48
|
+
const contactsMap = new Map(contacts.map((contact) => [contact.address, contact]));
|
|
49
|
+
// Convert protectedData[] into Contact[] using the map for constant time lookups
|
|
50
|
+
return protectedDataList.map(({ id }) => {
|
|
51
|
+
const contact = contactsMap.get(id);
|
|
52
|
+
if (contact) {
|
|
53
|
+
return {
|
|
54
|
+
address: id,
|
|
55
|
+
owner: contact.owner,
|
|
56
|
+
accessGrantTimestamp: contact.accessGrantTimestamp,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
throw new WorkflowError({
|
|
63
|
+
message: 'Failed to fetch subgraph',
|
|
64
|
+
errorCause: error,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
export const checkProtectedDataValidity = async (graphQLClient, protectedData) => {
|
|
69
|
+
try {
|
|
70
|
+
const variables = {
|
|
71
|
+
requiredSchema: ['email:string'],
|
|
72
|
+
id: [protectedData],
|
|
73
|
+
start: 0,
|
|
74
|
+
range: 1,
|
|
75
|
+
};
|
|
76
|
+
const protectedDataResultQuery = await graphQLClient.request(checkProtectedDataQuery, variables);
|
|
77
|
+
const { protectedDatas } = protectedDataResultQuery;
|
|
78
|
+
return protectedDatas.length === 1;
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
throw new WorkflowError({
|
|
82
|
+
message: 'Failed to fetch subgraph',
|
|
83
|
+
errorCause: error,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=subgraphQuery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subgraphQuery.js","sourceRoot":"","sources":["../../src/utils/subgraphQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,uBAAuB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;CAqBlC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,aAA4B,EAC5B,QAAmB,EACC,EAAE;IACtB,IAAI,CAAC;QACH,qBAAqB;QACrB,MAAM,iBAAiB,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAErE,aAAa;QACb,MAAM,iBAAiB,GAAyB,EAAE,CAAC;QACnD,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,MAAM,KAAK,GAAG,IAAI,CAAC;QACnB,IAAI,kBAAkB,GAAG,IAAI,CAAC;QAE9B,GAAG,CAAC;YACF,MAAM,SAAS,GAAG;gBAChB,cAAc,EAAE,CAAC,cAAc,CAAC;gBAChC,EAAE,EAAE,iBAAiB;gBACrB,KAAK;gBACL,KAAK;aACN,CAAC;YAEF,MAAM,wBAAwB,GAC5B,MAAM,aAAa,CAAC,OAAO,CAAC,uBAAuB,EAAE,SAAS,CAAC,CAAC;YAElE,MAAM,EAAE,cAAc,EAAE,GAAG,wBAAwB,CAAC;YACpD,iBAAiB,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;YAE1C,kBAAkB,GAAG,cAAc,CAAC,MAAM,KAAK,KAAK,CAAC;YACrD,KAAK,IAAI,KAAK,CAAC;QACjB,CAAC,QAAQ,kBAAkB,EAAE;QAE7B,2EAA2E;QAC3E,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CACtD,CAAC;QAEF,iFAAiF;QACjF,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;YACtC,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpC,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO;oBACL,OAAO,EAAE,EAAE;oBACX,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;iBACnD,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,aAAa,CAAC;YACtB,OAAO,EAAE,0BAA0B;YACnC,UAAU,EAAE,KAAK;SAClB,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG,KAAK,EAC7C,aAA4B,EAC5B,aAAqB,EACH,EAAE;IACpB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG;YAChB,cAAc,EAAE,CAAC,cAAc,CAAC;YAChC,EAAE,EAAE,CAAC,aAAa,CAAC;YACnB,KAAK,EAAE,CAAC;YACR,KAAK,EAAE,CAAC;SACT,CAAC;QAEF,MAAM,wBAAwB,GAC5B,MAAM,aAAa,CAAC,OAAO,CAAC,uBAAuB,EAAE,SAAS,CAAC,CAAC;QAElE,MAAM,EAAE,cAAc,EAAE,GAAG,wBAAwB,CAAC;QAEpD,OAAO,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,aAAa,CAAC;YACtB,OAAO,EAAE,0BAA0B;YACnC,UAAU,EAAE,KAAK;SAClB,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IExec } from 'iexec';
|
|
2
|
+
export declare const isValidProvider: (iexec: IExec) => Promise<void>;
|
|
3
|
+
export declare const throwIfMissing: () => never;
|
|
4
|
+
export declare const isEnsTest: (value: string) => boolean;
|
|
5
|
+
export declare const addressOrEnsSchema: () => import("yup").StringSchema<string, import("yup").AnyObject, undefined, "">;
|
|
6
|
+
export declare const addressSchema: () => import("yup").StringSchema<string, import("yup").AnyObject, undefined, "">;
|
|
7
|
+
export declare const emailSubjectSchema: () => import("yup").StringSchema<string, import("yup").AnyObject, undefined, "">;
|
|
8
|
+
export declare const emailContentSchema: () => import("yup").StringSchema<string, import("yup").AnyObject, undefined, "">;
|
|
9
|
+
export declare const contentTypeSchema: () => import("yup").StringSchema<string, import("yup").AnyObject, undefined, "">;
|
|
10
|
+
export declare const senderNameSchema: () => import("yup").StringSchema<string, import("yup").AnyObject, undefined, "">;
|
|
11
|
+
export declare const labelSchema: () => import("yup").StringSchema<string, import("yup").AnyObject, undefined, "">;
|
|
12
|
+
export declare const positiveNumberSchema: () => import("yup").NumberSchema<number, import("yup").AnyObject, undefined, "">;
|
|
13
|
+
export declare const booleanSchema: () => import("yup").BooleanSchema<boolean, import("yup").AnyObject, undefined, "">;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { isAddress } from 'ethers';
|
|
2
|
+
import { ValidationError, boolean, number, string } from 'yup';
|
|
3
|
+
export const isValidProvider = async (iexec) => {
|
|
4
|
+
const client = await iexec.config.resolveContractsClient();
|
|
5
|
+
if (!client.signer) {
|
|
6
|
+
throw new Error('Unauthorized method. Please log in with your wallet, you must set a valid provider with a signer.');
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
export const throwIfMissing = () => {
|
|
10
|
+
throw new ValidationError('Missing parameter');
|
|
11
|
+
};
|
|
12
|
+
const isUndefined = (value) => value === undefined;
|
|
13
|
+
const isAddressTest = (value) => isAddress(value);
|
|
14
|
+
export const isEnsTest = (value) => value.endsWith('.eth') && value.length > 6;
|
|
15
|
+
export const addressOrEnsSchema = () => string()
|
|
16
|
+
.transform((value) => value?.toLowerCase() || value)
|
|
17
|
+
.test('is-address-or-ens', '${path} should be an ethereum address or a ENS name', (value) => isUndefined(value) || isAddressTest(value) || isEnsTest(value));
|
|
18
|
+
export const addressSchema = () => string()
|
|
19
|
+
.transform((value) => value?.toLowerCase() || value)
|
|
20
|
+
.test('is-address', '${path} should be an ethereum address', (value) => isUndefined(value) || isAddressTest(value));
|
|
21
|
+
// 78 char length for email subject (rfc2822)
|
|
22
|
+
export const emailSubjectSchema = () => string().max(78).strict();
|
|
23
|
+
// Limit of 512,000 bytes (512 kilo-bytes)
|
|
24
|
+
export const emailContentSchema = () => string().max(512000);
|
|
25
|
+
// Valid content types for the variable 'contentType'
|
|
26
|
+
const validContentTypes = ['text/plain', 'text/html'];
|
|
27
|
+
export const contentTypeSchema = () => string().oneOf(validContentTypes, 'Invalid contentType').optional();
|
|
28
|
+
// Minimum of 3 characters and max of 20 to avoid sender being flagged as spam
|
|
29
|
+
export const senderNameSchema = () => string().trim().min(3).max(20).optional();
|
|
30
|
+
// Used to identify the email campaign, minimum of 3 characters and max of 10
|
|
31
|
+
export const labelSchema = () => string().trim().min(3).max(10).optional();
|
|
32
|
+
export const positiveNumberSchema = () => number().integer().min(0).typeError('${path} must be a non-negative number');
|
|
33
|
+
export const booleanSchema = () => boolean();
|
|
34
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Eip1193Provider } from 'ethers';
|
|
2
|
+
import { Contact, FetchUserContactsParams, SendEmailParams, Web3MailConfigOptions, SendEmailResponse, Web3SignerProvider } from './types.js';
|
|
3
|
+
export declare class IExecWeb3mail {
|
|
4
|
+
private iexec;
|
|
5
|
+
private ipfsNode;
|
|
6
|
+
private ipfsGateway;
|
|
7
|
+
private dataProtectorSubgraph;
|
|
8
|
+
private dappAddressOrENS;
|
|
9
|
+
private dappWhitelistAddress;
|
|
10
|
+
private graphQLClient;
|
|
11
|
+
constructor(ethProvider?: Eip1193Provider | Web3SignerProvider | string, options?: Web3MailConfigOptions);
|
|
12
|
+
fetchMyContacts(): Promise<Contact[]>;
|
|
13
|
+
fetchUserContacts(args?: FetchUserContactsParams): Promise<Contact[]>;
|
|
14
|
+
sendEmail(args: SendEmailParams): Promise<SendEmailResponse>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { IExec } from 'iexec';
|
|
2
|
+
import { fetchUserContacts } from './fetchUserContacts.js';
|
|
3
|
+
import { fetchMyContacts } from './fetchMyContacts.js';
|
|
4
|
+
import { sendEmail } from './sendEmail.js';
|
|
5
|
+
import { GraphQLClient } from 'graphql-request';
|
|
6
|
+
import { WEB3_MAIL_DAPP_ADDRESS, IPFS_UPLOAD_URL, DEFAULT_IPFS_GATEWAY, DATAPROTECTOR_SUBGRAPH_ENDPOINT, WHITELIST_SMART_CONTRACT_ADDRESS, } from '../config/config.js';
|
|
7
|
+
import { isValidProvider } from '../utils/validators.js';
|
|
8
|
+
export class IExecWeb3mail {
|
|
9
|
+
iexec;
|
|
10
|
+
ipfsNode;
|
|
11
|
+
ipfsGateway;
|
|
12
|
+
dataProtectorSubgraph;
|
|
13
|
+
dappAddressOrENS;
|
|
14
|
+
dappWhitelistAddress;
|
|
15
|
+
graphQLClient;
|
|
16
|
+
constructor(ethProvider, options) {
|
|
17
|
+
try {
|
|
18
|
+
this.iexec = new IExec({ ethProvider: ethProvider || 'bellecour' }, options?.iexecOptions);
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
throw Error('Unsupported ethProvider');
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
this.dataProtectorSubgraph =
|
|
25
|
+
options?.dataProtectorSubgraph || DATAPROTECTOR_SUBGRAPH_ENDPOINT;
|
|
26
|
+
this.graphQLClient = new GraphQLClient(this.dataProtectorSubgraph);
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
throw Error('Impossible to create GraphQLClient');
|
|
30
|
+
}
|
|
31
|
+
this.dappAddressOrENS = options?.dappAddressOrENS || WEB3_MAIL_DAPP_ADDRESS;
|
|
32
|
+
this.ipfsNode = options?.ipfsNode || IPFS_UPLOAD_URL;
|
|
33
|
+
this.ipfsGateway = options?.ipfsGateway || DEFAULT_IPFS_GATEWAY;
|
|
34
|
+
this.dappWhitelistAddress =
|
|
35
|
+
options?.dappWhitelistAddress || WHITELIST_SMART_CONTRACT_ADDRESS;
|
|
36
|
+
}
|
|
37
|
+
async fetchMyContacts() {
|
|
38
|
+
await isValidProvider(this.iexec);
|
|
39
|
+
return fetchMyContacts({
|
|
40
|
+
iexec: this.iexec,
|
|
41
|
+
graphQLClient: this.graphQLClient,
|
|
42
|
+
dappAddressOrENS: this.dappAddressOrENS,
|
|
43
|
+
dappWhitelistAddress: this.dappWhitelistAddress,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
fetchUserContacts(args) {
|
|
47
|
+
return fetchUserContacts({
|
|
48
|
+
...args,
|
|
49
|
+
iexec: this.iexec,
|
|
50
|
+
graphQLClient: this.graphQLClient,
|
|
51
|
+
dappAddressOrENS: this.dappAddressOrENS,
|
|
52
|
+
dappWhitelistAddress: this.dappWhitelistAddress,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async sendEmail(args) {
|
|
56
|
+
await isValidProvider(this.iexec);
|
|
57
|
+
return sendEmail({
|
|
58
|
+
...args,
|
|
59
|
+
iexec: this.iexec,
|
|
60
|
+
ipfsNode: this.ipfsNode,
|
|
61
|
+
ipfsGateway: this.ipfsGateway,
|
|
62
|
+
dappAddressOrENS: this.dappAddressOrENS,
|
|
63
|
+
dappWhitelistAddress: this.dappWhitelistAddress,
|
|
64
|
+
graphQLClient: this.graphQLClient,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=IExecWeb3mail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IExecWeb3mail.js","sourceRoot":"","sources":["../../src/web3mail/IExecWeb3mail.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Contact, DappAddressConsumer, DappWhitelistAddressConsumer, FetchMyContactsParams, IExecConsumer, SubgraphConsumer } from './types.js';
|
|
2
|
+
export declare const fetchMyContacts: ({ graphQLClient, iexec, dappAddressOrENS, dappWhitelistAddress, isUserStrict, }: IExecConsumer & SubgraphConsumer & DappAddressConsumer & DappWhitelistAddressConsumer & FetchMyContactsParams) => Promise<Contact[]>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { booleanSchema, throwIfMissing } from '../utils/validators.js';
|
|
2
|
+
import { fetchUserContacts } from './fetchUserContacts.js';
|
|
3
|
+
export const fetchMyContacts = async ({ graphQLClient = throwIfMissing(), iexec = throwIfMissing(), dappAddressOrENS = throwIfMissing(), dappWhitelistAddress = throwIfMissing(), isUserStrict = false, }) => {
|
|
4
|
+
const vIsUserStrict = booleanSchema()
|
|
5
|
+
.label('isUserStrict')
|
|
6
|
+
.validateSync(isUserStrict);
|
|
7
|
+
const userAddress = await iexec.wallet.getAddress();
|
|
8
|
+
return fetchUserContacts({
|
|
9
|
+
iexec,
|
|
10
|
+
graphQLClient,
|
|
11
|
+
dappAddressOrENS,
|
|
12
|
+
dappWhitelistAddress,
|
|
13
|
+
userAddress,
|
|
14
|
+
isUserStrict: vIsUserStrict,
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=fetchMyContacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchMyContacts.js","sourceRoot":"","sources":["../../src/web3mail/fetchMyContacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAU3D,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,EACpC,aAAa,GAAG,cAAc,EAAE,EAChC,KAAK,GAAG,cAAc,EAAE,EACxB,gBAAgB,GAAG,cAAc,EAAE,EACnC,oBAAoB,GAAG,cAAc,EAAE,EACvC,YAAY,GAAG,KAAK,GAKC,EAAsB,EAAE;IAC7C,MAAM,aAAa,GAAG,aAAa,EAAE;SAClC,KAAK,CAAC,cAAc,CAAC;SACrB,YAAY,CAAC,YAAY,CAAC,CAAC;IAE9B,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;IACpD,OAAO,iBAAiB,CAAC;QACvB,KAAK;QACL,aAAa;QACb,gBAAgB;QAChB,oBAAoB;QACpB,WAAW;QACX,YAAY,EAAE,aAAa;KAC5B,CAAC,CAAC;AACL,CAAC,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Contact, DappAddressConsumer, DappWhitelistAddressConsumer, FetchUserContactsParams, IExecConsumer, SubgraphConsumer } from './types.js';
|
|
2
|
+
export declare const fetchUserContacts: ({ graphQLClient, iexec, dappAddressOrENS, dappWhitelistAddress, userAddress, isUserStrict, }: IExecConsumer & SubgraphConsumer & DappAddressConsumer & DappWhitelistAddressConsumer & FetchUserContactsParams) => Promise<Contact[]>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { ANY_DATASET_ADDRESS } from '../config/config.js';
|
|
2
|
+
import { handleIfProtocolError, WorkflowError } from '../utils/errors.js';
|
|
3
|
+
import { autoPaginateRequest } from '../utils/paginate.js';
|
|
4
|
+
import { getValidContact } from '../utils/subgraphQuery.js';
|
|
5
|
+
import { addressOrEnsSchema, addressSchema, booleanSchema, isEnsTest, throwIfMissing, } from '../utils/validators.js';
|
|
6
|
+
export const fetchUserContacts = async ({ graphQLClient = throwIfMissing(), iexec = throwIfMissing(), dappAddressOrENS = throwIfMissing(), dappWhitelistAddress = throwIfMissing(), userAddress, isUserStrict = false, }) => {
|
|
7
|
+
try {
|
|
8
|
+
const vDappAddressOrENS = addressOrEnsSchema()
|
|
9
|
+
.required()
|
|
10
|
+
.label('dappAddressOrENS')
|
|
11
|
+
.validateSync(dappAddressOrENS);
|
|
12
|
+
const vDappWhitelistAddress = addressSchema()
|
|
13
|
+
.required()
|
|
14
|
+
.label('dappWhitelistAddress')
|
|
15
|
+
.validateSync(dappWhitelistAddress);
|
|
16
|
+
const vUserAddress = addressOrEnsSchema()
|
|
17
|
+
.required()
|
|
18
|
+
.label('userAddress')
|
|
19
|
+
.validateSync(userAddress);
|
|
20
|
+
const vIsUserStrict = booleanSchema()
|
|
21
|
+
.label('isUserStrict')
|
|
22
|
+
.validateSync(isUserStrict);
|
|
23
|
+
const [dappOrders, whitelistOrders] = await Promise.all([
|
|
24
|
+
fetchAllOrdersByApp({
|
|
25
|
+
iexec,
|
|
26
|
+
userAddress: vUserAddress,
|
|
27
|
+
appAddress: vDappAddressOrENS,
|
|
28
|
+
isUserStrict: vIsUserStrict,
|
|
29
|
+
}),
|
|
30
|
+
fetchAllOrdersByApp({
|
|
31
|
+
iexec,
|
|
32
|
+
userAddress: vUserAddress,
|
|
33
|
+
appAddress: vDappWhitelistAddress,
|
|
34
|
+
isUserStrict: vIsUserStrict,
|
|
35
|
+
}),
|
|
36
|
+
]);
|
|
37
|
+
const orders = dappOrders.concat(whitelistOrders);
|
|
38
|
+
const myContacts = [];
|
|
39
|
+
let web3DappResolvedAddress = vDappAddressOrENS;
|
|
40
|
+
if (isEnsTest(vDappAddressOrENS)) {
|
|
41
|
+
web3DappResolvedAddress = await iexec.ens.resolveName(vDappAddressOrENS);
|
|
42
|
+
}
|
|
43
|
+
orders.forEach((order) => {
|
|
44
|
+
if (order.order.apprestrict.toLowerCase() ===
|
|
45
|
+
web3DappResolvedAddress.toLowerCase() ||
|
|
46
|
+
order.order.apprestrict.toLowerCase() ===
|
|
47
|
+
vDappWhitelistAddress.toLowerCase()) {
|
|
48
|
+
const contact = {
|
|
49
|
+
address: order.order.dataset.toLowerCase(),
|
|
50
|
+
owner: order.signer.toLowerCase(),
|
|
51
|
+
accessGrantTimestamp: order.publicationTimestamp,
|
|
52
|
+
};
|
|
53
|
+
myContacts.push(contact);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
//getValidContact function remove duplicated contacts for the same protectedData address,
|
|
57
|
+
//keeping the most recent one
|
|
58
|
+
return await getValidContact(graphQLClient, myContacts);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
handleIfProtocolError(error);
|
|
62
|
+
throw new WorkflowError({
|
|
63
|
+
message: 'Failed to fetch user contacts',
|
|
64
|
+
errorCause: error,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
async function fetchAllOrdersByApp({ iexec, userAddress, appAddress, isUserStrict, }) {
|
|
69
|
+
const ordersFirstPage = iexec.orderbook.fetchDatasetOrderbook(ANY_DATASET_ADDRESS, {
|
|
70
|
+
app: appAddress,
|
|
71
|
+
requester: userAddress,
|
|
72
|
+
isAppStrict: true,
|
|
73
|
+
isRequesterStrict: isUserStrict,
|
|
74
|
+
// Use maxPageSize here to avoid too many round-trips (we want everything anyway)
|
|
75
|
+
pageSize: 1000,
|
|
76
|
+
});
|
|
77
|
+
const { orders: allOrders } = await autoPaginateRequest({
|
|
78
|
+
request: ordersFirstPage,
|
|
79
|
+
});
|
|
80
|
+
return allOrders;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=fetchUserContacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchUserContacts.js","sourceRoot":"","sources":["../../src/web3mail/fetchUserContacts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { DappAddressConsumer, DappWhitelistAddressConsumer, IExecConsumer, IpfsGatewayConfigConsumer, IpfsNodeConfigConsumer, SendEmailParams, SendEmailResponse, SubgraphConsumer } from './types.js';
|
|
2
|
+
export declare const sendEmail: ({ graphQLClient, iexec, workerpoolAddressOrEns, dappAddressOrENS, dappWhitelistAddress, ipfsNode, ipfsGateway, emailSubject, emailContent, contentType, label, dataMaxPrice, appMaxPrice, workerpoolMaxPrice, senderName, protectedData, }: IExecConsumer & SubgraphConsumer & DappAddressConsumer & DappWhitelistAddressConsumer & IpfsNodeConfigConsumer & IpfsGatewayConfigConsumer & SendEmailParams) => Promise<SendEmailResponse>;
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
import { DEFAULT_CONTENT_TYPE, MAX_DESIRED_APP_ORDER_PRICE, MAX_DESIRED_DATA_ORDER_PRICE, MAX_DESIRED_WORKERPOOL_ORDER_PRICE, PROD_WORKERPOOL_ADDRESS, } from '../config/config.js';
|
|
3
|
+
import { handleIfProtocolError, WorkflowError } from '../utils/errors.js';
|
|
4
|
+
import { generateSecureUniqueId } from '../utils/generateUniqueId.js';
|
|
5
|
+
import * as ipfs from '../utils/ipfs-service.js';
|
|
6
|
+
import { checkProtectedDataValidity } from '../utils/subgraphQuery.js';
|
|
7
|
+
import { addressOrEnsSchema, addressSchema, contentTypeSchema, emailContentSchema, emailSubjectSchema, labelSchema, positiveNumberSchema, senderNameSchema, throwIfMissing, } from '../utils/validators.js';
|
|
8
|
+
export const sendEmail = async ({ graphQLClient = throwIfMissing(), iexec = throwIfMissing(), workerpoolAddressOrEns = PROD_WORKERPOOL_ADDRESS, dappAddressOrENS, dappWhitelistAddress, ipfsNode, ipfsGateway, emailSubject, emailContent, contentType = DEFAULT_CONTENT_TYPE, label, dataMaxPrice = MAX_DESIRED_DATA_ORDER_PRICE, appMaxPrice = MAX_DESIRED_APP_ORDER_PRICE, workerpoolMaxPrice = MAX_DESIRED_WORKERPOOL_ORDER_PRICE, senderName, protectedData, }) => {
|
|
9
|
+
try {
|
|
10
|
+
const vDatasetAddress = addressOrEnsSchema()
|
|
11
|
+
.required()
|
|
12
|
+
.label('protectedData')
|
|
13
|
+
.validateSync(protectedData);
|
|
14
|
+
const vEmailSubject = emailSubjectSchema()
|
|
15
|
+
.required()
|
|
16
|
+
.label('emailSubject')
|
|
17
|
+
.validateSync(emailSubject);
|
|
18
|
+
const vEmailContent = emailContentSchema()
|
|
19
|
+
.required()
|
|
20
|
+
.label('emailContent')
|
|
21
|
+
.validateSync(emailContent);
|
|
22
|
+
const vContentType = contentTypeSchema()
|
|
23
|
+
.required()
|
|
24
|
+
.label('contentType')
|
|
25
|
+
.validateSync(contentType);
|
|
26
|
+
const vSenderName = senderNameSchema()
|
|
27
|
+
.label('senderName')
|
|
28
|
+
.validateSync(senderName);
|
|
29
|
+
const vLabel = labelSchema().label('label').validateSync(label);
|
|
30
|
+
const vWorkerpoolAddressOrEns = addressOrEnsSchema()
|
|
31
|
+
.required()
|
|
32
|
+
.label('WorkerpoolAddressOrEns')
|
|
33
|
+
.validateSync(workerpoolAddressOrEns);
|
|
34
|
+
const vDappAddressOrENS = addressOrEnsSchema()
|
|
35
|
+
.required()
|
|
36
|
+
.label('dappAddressOrENS')
|
|
37
|
+
.validateSync(dappAddressOrENS);
|
|
38
|
+
const vDappWhitelistAddress = addressSchema()
|
|
39
|
+
.required()
|
|
40
|
+
.label('dappWhitelistAddress')
|
|
41
|
+
.validateSync(dappWhitelistAddress);
|
|
42
|
+
const vDataMaxPrice = positiveNumberSchema()
|
|
43
|
+
.label('dataMaxPrice')
|
|
44
|
+
.validateSync(dataMaxPrice);
|
|
45
|
+
const vAppMaxPrice = positiveNumberSchema()
|
|
46
|
+
.label('appMaxPrice')
|
|
47
|
+
.validateSync(appMaxPrice);
|
|
48
|
+
const vWorkerpoolMaxPrice = positiveNumberSchema()
|
|
49
|
+
.label('workerpoolMaxPrice')
|
|
50
|
+
.validateSync(workerpoolMaxPrice);
|
|
51
|
+
// Check protected data validity through subgraph
|
|
52
|
+
const isValidProtectedData = await checkProtectedDataValidity(graphQLClient, vDatasetAddress);
|
|
53
|
+
if (!isValidProtectedData) {
|
|
54
|
+
throw new Error('ProtectedData is not valid');
|
|
55
|
+
}
|
|
56
|
+
const requesterAddress = await iexec.wallet.getAddress();
|
|
57
|
+
// Initialize IPFS storage if not already initialized
|
|
58
|
+
const isIpfsStorageInitialized = await iexec.storage.checkStorageTokenExists(requesterAddress);
|
|
59
|
+
if (!isIpfsStorageInitialized) {
|
|
60
|
+
const token = await iexec.storage.defaultStorageLogin();
|
|
61
|
+
await iexec.storage.pushStorageToken(token);
|
|
62
|
+
}
|
|
63
|
+
const [datasetorderForApp, datasetorderForWhitelist, apporder, workerpoolorder,] = await Promise.all([
|
|
64
|
+
// Fetch dataset order for web3mail app
|
|
65
|
+
iexec.orderbook
|
|
66
|
+
.fetchDatasetOrderbook(vDatasetAddress, {
|
|
67
|
+
app: dappAddressOrENS,
|
|
68
|
+
requester: requesterAddress,
|
|
69
|
+
})
|
|
70
|
+
.then((datasetOrderbook) => {
|
|
71
|
+
const desiredPriceDataOrderbook = datasetOrderbook.orders.filter((order) => order.order.datasetprice <= vDataMaxPrice);
|
|
72
|
+
return desiredPriceDataOrderbook[0]?.order; // may be undefined
|
|
73
|
+
}),
|
|
74
|
+
// Fetch dataset order for web3mail whitelist
|
|
75
|
+
iexec.orderbook
|
|
76
|
+
.fetchDatasetOrderbook(vDatasetAddress, {
|
|
77
|
+
app: vDappWhitelistAddress,
|
|
78
|
+
requester: requesterAddress,
|
|
79
|
+
})
|
|
80
|
+
.then((datasetOrderbook) => {
|
|
81
|
+
const desiredPriceDataOrderbook = datasetOrderbook.orders.filter((order) => order.order.datasetprice <= vDataMaxPrice);
|
|
82
|
+
return desiredPriceDataOrderbook[0]?.order; // may be undefined
|
|
83
|
+
}),
|
|
84
|
+
// Fetch app order
|
|
85
|
+
iexec.orderbook
|
|
86
|
+
.fetchAppOrderbook(dappAddressOrENS, {
|
|
87
|
+
minTag: ['tee', 'scone'],
|
|
88
|
+
maxTag: ['tee', 'scone'],
|
|
89
|
+
workerpool: workerpoolAddressOrEns,
|
|
90
|
+
})
|
|
91
|
+
.then((appOrderbook) => {
|
|
92
|
+
const desiredPriceAppOrderbook = appOrderbook.orders.filter((order) => order.order.appprice <= vAppMaxPrice);
|
|
93
|
+
const desiredPriceAppOrder = desiredPriceAppOrderbook[0]?.order;
|
|
94
|
+
if (!desiredPriceAppOrder) {
|
|
95
|
+
throw new Error('No App order found for the desired price');
|
|
96
|
+
}
|
|
97
|
+
return desiredPriceAppOrder;
|
|
98
|
+
}),
|
|
99
|
+
// Fetch workerpool order
|
|
100
|
+
iexec.orderbook
|
|
101
|
+
.fetchWorkerpoolOrderbook({
|
|
102
|
+
workerpool: workerpoolAddressOrEns,
|
|
103
|
+
app: dappAddressOrENS,
|
|
104
|
+
dataset: vDatasetAddress,
|
|
105
|
+
minTag: ['tee', 'scone'],
|
|
106
|
+
maxTag: ['tee', 'scone'],
|
|
107
|
+
category: 0,
|
|
108
|
+
})
|
|
109
|
+
.then((workerpoolOrderbook) => {
|
|
110
|
+
const desiredPriceWorkerpoolOrderbook = workerpoolOrderbook.orders.filter((order) => order.order.workerpoolprice <= vWorkerpoolMaxPrice);
|
|
111
|
+
const randomIndex = Math.floor(Math.random() * desiredPriceWorkerpoolOrderbook.length);
|
|
112
|
+
const desiredPriceWorkerpoolOrder = desiredPriceWorkerpoolOrderbook[randomIndex]?.order;
|
|
113
|
+
if (!desiredPriceWorkerpoolOrder) {
|
|
114
|
+
throw new Error('No Workerpool order found for the desired price');
|
|
115
|
+
}
|
|
116
|
+
return desiredPriceWorkerpoolOrder;
|
|
117
|
+
}),
|
|
118
|
+
]);
|
|
119
|
+
const datasetorder = datasetorderForApp || datasetorderForWhitelist;
|
|
120
|
+
if (!datasetorder) {
|
|
121
|
+
throw new Error('No Dataset order found for the desired price');
|
|
122
|
+
}
|
|
123
|
+
// Push requester secrets
|
|
124
|
+
const requesterSecretId = generateSecureUniqueId(16);
|
|
125
|
+
const emailContentEncryptionKey = iexec.dataset.generateEncryptionKey();
|
|
126
|
+
const encryptedFile = await iexec.dataset
|
|
127
|
+
.encrypt(Buffer.from(vEmailContent, 'utf8'), emailContentEncryptionKey)
|
|
128
|
+
.catch((e) => {
|
|
129
|
+
throw new WorkflowError({
|
|
130
|
+
message: 'Failed to encrypt email content',
|
|
131
|
+
errorCause: e,
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
const cid = await ipfs
|
|
135
|
+
.add(encryptedFile, {
|
|
136
|
+
ipfsNode: ipfsNode,
|
|
137
|
+
ipfsGateway: ipfsGateway,
|
|
138
|
+
})
|
|
139
|
+
.catch((e) => {
|
|
140
|
+
throw new WorkflowError({
|
|
141
|
+
message: 'Failed to upload encrypted email content',
|
|
142
|
+
errorCause: e,
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
const multiaddr = `/ipfs/${cid}`;
|
|
146
|
+
await iexec.secrets.pushRequesterSecret(requesterSecretId, JSON.stringify({
|
|
147
|
+
emailSubject: vEmailSubject,
|
|
148
|
+
emailContentMultiAddr: multiaddr,
|
|
149
|
+
contentType: vContentType,
|
|
150
|
+
senderName: vSenderName,
|
|
151
|
+
emailContentEncryptionKey,
|
|
152
|
+
}));
|
|
153
|
+
const requestorderToSign = await iexec.order.createRequestorder({
|
|
154
|
+
app: vDappAddressOrENS,
|
|
155
|
+
category: workerpoolorder.category,
|
|
156
|
+
dataset: vDatasetAddress,
|
|
157
|
+
datasetmaxprice: datasetorder.datasetprice,
|
|
158
|
+
appmaxprice: apporder.appprice,
|
|
159
|
+
workerpoolmaxprice: workerpoolorder.workerpoolprice,
|
|
160
|
+
tag: ['tee', 'scone'],
|
|
161
|
+
workerpool: vWorkerpoolAddressOrEns,
|
|
162
|
+
params: {
|
|
163
|
+
iexec_developer_logger: true,
|
|
164
|
+
iexec_secrets: {
|
|
165
|
+
1: requesterSecretId,
|
|
166
|
+
},
|
|
167
|
+
iexec_args: vLabel,
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
const requestorder = await iexec.order.signRequestorder(requestorderToSign);
|
|
171
|
+
// Match orders and compute task ID
|
|
172
|
+
const { dealid } = await iexec.order.matchOrders({
|
|
173
|
+
apporder: apporder,
|
|
174
|
+
datasetorder: datasetorder,
|
|
175
|
+
workerpoolorder: workerpoolorder,
|
|
176
|
+
requestorder: requestorder,
|
|
177
|
+
});
|
|
178
|
+
const taskId = await iexec.deal.computeTaskId(dealid, 0);
|
|
179
|
+
return {
|
|
180
|
+
taskId,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
handleIfProtocolError(error);
|
|
185
|
+
throw new WorkflowError({
|
|
186
|
+
message: 'Failed to sendEmail',
|
|
187
|
+
errorCause: error,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
//# sourceMappingURL=sendEmail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sendEmail.js","sourceRoot":"","sources":["../../src/web3mail/sendEmail.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { GraphQLClient } from 'graphql-request';
|
|
2
|
+
import { EnhancedWallet, IExec } from 'iexec';
|
|
3
|
+
import { IExecConfigOptions } from 'iexec/IExecConfig';
|
|
4
|
+
export type Web3SignerProvider = EnhancedWallet;
|
|
5
|
+
export type IExecConsumer = {
|
|
6
|
+
iexec: IExec;
|
|
7
|
+
};
|
|
8
|
+
export type ENS = string;
|
|
9
|
+
export type AddressOrENS = Address | ENS;
|
|
10
|
+
export type Address = string;
|
|
11
|
+
export type TimeStamp = string;
|
|
12
|
+
export type Contact = {
|
|
13
|
+
address: Address;
|
|
14
|
+
owner: Address;
|
|
15
|
+
accessGrantTimestamp: TimeStamp;
|
|
16
|
+
};
|
|
17
|
+
export type SendEmailParams = {
|
|
18
|
+
emailSubject: string;
|
|
19
|
+
emailContent: string;
|
|
20
|
+
protectedData: Address;
|
|
21
|
+
contentType?: string;
|
|
22
|
+
senderName?: string;
|
|
23
|
+
label?: string;
|
|
24
|
+
workerpoolAddressOrEns?: AddressOrENS;
|
|
25
|
+
dataMaxPrice?: number;
|
|
26
|
+
appMaxPrice?: number;
|
|
27
|
+
workerpoolMaxPrice?: number;
|
|
28
|
+
};
|
|
29
|
+
export type FetchMyContactsParams = {
|
|
30
|
+
/**
|
|
31
|
+
* Get contacts for this specific user only
|
|
32
|
+
*/
|
|
33
|
+
isUserStrict?: boolean;
|
|
34
|
+
};
|
|
35
|
+
export type FetchUserContactsParams = {
|
|
36
|
+
/**
|
|
37
|
+
* Address of the user
|
|
38
|
+
*/
|
|
39
|
+
userAddress: Address;
|
|
40
|
+
} & FetchMyContactsParams;
|
|
41
|
+
export type SendEmailResponse = {
|
|
42
|
+
taskId: string;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Internal props for querying the subgraph
|
|
46
|
+
*/
|
|
47
|
+
export type ProtectedDataQuery = {
|
|
48
|
+
id: string;
|
|
49
|
+
};
|
|
50
|
+
export type GraphQLResponse = {
|
|
51
|
+
protectedDatas: ProtectedDataQuery[];
|
|
52
|
+
};
|
|
53
|
+
export type SubgraphConsumer = {
|
|
54
|
+
graphQLClient: GraphQLClient;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Configuration options for Web3Mail.
|
|
58
|
+
*/
|
|
59
|
+
export type Web3MailConfigOptions = {
|
|
60
|
+
/**
|
|
61
|
+
* The Ethereum contract address or ENS (Ethereum Name Service) for the email sender dapp.
|
|
62
|
+
* If not provided, the default web3mail address will be used.
|
|
63
|
+
*/
|
|
64
|
+
dappAddressOrENS?: AddressOrENS;
|
|
65
|
+
/**
|
|
66
|
+
* The Ethereum contract address for the whitelist.
|
|
67
|
+
* If not provided, the default whitelist smart contract address will be used.
|
|
68
|
+
*/
|
|
69
|
+
dappWhitelistAddress?: Address;
|
|
70
|
+
/**
|
|
71
|
+
* The subgraph URL for querying data.
|
|
72
|
+
* If not provided, the default data protector subgraph URL will be used.
|
|
73
|
+
*/
|
|
74
|
+
dataProtectorSubgraph?: string;
|
|
75
|
+
/**
|
|
76
|
+
* Options specific to iExec integration.
|
|
77
|
+
* If not provided, default iexec options will be used.
|
|
78
|
+
*/
|
|
79
|
+
iexecOptions?: IExecConfigOptions;
|
|
80
|
+
/**
|
|
81
|
+
* The IPFS node URL.
|
|
82
|
+
* If not provided, the default IPFS node URL will be used.
|
|
83
|
+
*/
|
|
84
|
+
ipfsNode?: string;
|
|
85
|
+
/**
|
|
86
|
+
* The IPFS gateway URL.
|
|
87
|
+
* If not provided, the default IPFS gateway URL will be used.
|
|
88
|
+
*/
|
|
89
|
+
ipfsGateway?: string;
|
|
90
|
+
};
|
|
91
|
+
export type DappAddressConsumer = {
|
|
92
|
+
dappAddressOrENS: AddressOrENS;
|
|
93
|
+
};
|
|
94
|
+
export type IpfsNodeConfigConsumer = {
|
|
95
|
+
ipfsNode: string;
|
|
96
|
+
};
|
|
97
|
+
export type IpfsGatewayConfigConsumer = {
|
|
98
|
+
ipfsGateway: string;
|
|
99
|
+
};
|
|
100
|
+
export type DappWhitelistAddressConsumer = {
|
|
101
|
+
dappWhitelistAddress: string;
|
|
102
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/web3mail/types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED