@vlayer/sdk 0.1.0-nightly-20241001-aa0406f → 0.1.0-nightly-20241002-4630acc
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +6 -4
- package/src/api/email/dnsResolver.ts +4 -11
- package/src/api/email/parseEmail.test.ts +44 -16
- package/src/api/email/parseEmail.ts +25 -21
- package/src/api/email/preverify.test.ts +1 -1
- package/src/api/helpers.ts +2 -6
- package/src/api/lib/client.ts +6 -5
- package/src/api/lib/types/index.ts +3 -0
- package/src/api/lib/types/viem.ts +28 -0
- package/src/api/lib/types/vlayer.ts +25 -3
- package/src/api/lib/types/webProof.ts +11 -6
- package/src/api/lib/types/webProofProvider.ts +93 -0
- package/src/api/prover.ts +5 -24
- package/src/api/webProof/createWebProof.ts +9 -0
- package/src/api/webProof/index.ts +3 -0
- package/src/api/webProof/providers/extension.ts +73 -0
- package/src/api/webProof/providers/index.ts +1 -0
- package/src/api/webProof/steps/expectUrl.ts +12 -0
- package/src/api/webProof/steps/index.ts +11 -0
- package/src/api/webProof/steps/notarize.ts +17 -0
- package/src/api/webProof/steps/startPage.ts +12 -0
- package/src/index.ts +3 -0
package/package.json
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
"name": "@vlayer/sdk",
|
3
3
|
"type": "module",
|
4
4
|
"module": "src/index.ts",
|
5
|
-
"version": "0.1.0-nightly-
|
5
|
+
"version": "0.1.0-nightly-20241002-4630acc",
|
6
|
+
"types": "src/index.ts",
|
6
7
|
"scripts": {
|
7
8
|
"build": "npm run gen:types",
|
8
9
|
"test": "vitest --run",
|
@@ -11,7 +12,6 @@
|
|
11
12
|
"devDependencies": {
|
12
13
|
"@changesets/cli": "^2.27.7",
|
13
14
|
"@types/bun": "latest",
|
14
|
-
"@types/mailparser": "^3.4.4",
|
15
15
|
"abitype": "^1.0.6",
|
16
16
|
"vitest": "^2.1.1"
|
17
17
|
},
|
@@ -19,7 +19,9 @@
|
|
19
19
|
"typescript": "^5.0.0"
|
20
20
|
},
|
21
21
|
"dependencies": {
|
22
|
-
"
|
23
|
-
"
|
22
|
+
"dns-over-http-resolver": "^3.0.3",
|
23
|
+
"postal-mime": "^2.3.2",
|
24
|
+
"viem": "^2.21.0",
|
25
|
+
"zod": "^3.23.8"
|
24
26
|
}
|
25
27
|
}
|
@@ -1,14 +1,7 @@
|
|
1
|
-
import
|
1
|
+
import DnsResolver from "dns-over-http-resolver";
|
2
2
|
|
3
3
|
export async function resolveDkimDns(domain: string, selector: string) {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
reject(err);
|
8
|
-
return;
|
9
|
-
}
|
10
|
-
|
11
|
-
resolve(addresses.flat()[0]);
|
12
|
-
});
|
13
|
-
});
|
4
|
+
const resolver = new DnsResolver();
|
5
|
+
const address = await resolver.resolveTxt(`${selector}._domainkey.${domain}`);
|
6
|
+
return address.flat()[0];
|
14
7
|
}
|
@@ -1,7 +1,5 @@
|
|
1
|
-
import assert from "node:assert";
|
2
1
|
import { describe, expect, test } from "vitest";
|
3
|
-
import { getDkimSigners, parseEmail } from "./parseEmail.ts";
|
4
|
-
import { StructuredHeader } from "mailparser";
|
2
|
+
import { getDkimSigners, parseEmail, parseParams } from "./parseEmail.ts";
|
5
3
|
|
6
4
|
const emailHeaders = `From: "John Doe" <john@d.oe>
|
7
5
|
To: "Jane Doe" <jane@d.oe>
|
@@ -17,18 +15,12 @@ const body = "Hello, World!";
|
|
17
15
|
const emailFixture = `${emailHeaders}${dkimHeader}\n\n${body}`;
|
18
16
|
|
19
17
|
describe("parseEmail", () => {
|
20
|
-
test("should get dkim header from email", async () => {
|
21
|
-
const email = await parseEmail(emailFixture);
|
22
|
-
const dkim = email.headers.get("dkim-signature")!;
|
23
|
-
assert(typeof dkim === "object" && "params" in dkim);
|
24
|
-
expect(dkim.params.d).toBe("example.com");
|
25
|
-
expect(dkim.params.s).toBe("selector1");
|
26
|
-
});
|
18
|
+
test("should get dkim header from email", async () => {});
|
27
19
|
|
28
20
|
test("correctly parses untrimmed email", async () => {
|
29
21
|
const untrimmed = `\n ${emailFixture} \n`;
|
30
22
|
const email = await parseEmail(untrimmed);
|
31
|
-
expect(email.headers.
|
23
|
+
expect(email.headers.find((h) => h.key === "dkim-signature")).toBeDefined();
|
32
24
|
});
|
33
25
|
|
34
26
|
test("works well with multiple dkim headers", async () => {
|
@@ -38,12 +30,11 @@ describe("parseEmail", () => {
|
|
38
30
|
const email = await parseEmail(
|
39
31
|
`${emailHeaders}${dkimHeader}\n${dkimHeader2}\n\n${body}`,
|
40
32
|
);
|
41
|
-
const dkim = email.headers.
|
42
|
-
|
43
|
-
)! as unknown as StructuredHeader[];
|
33
|
+
const dkim = email.headers.filter((h) => h.key === "dkim-signature")!;
|
34
|
+
|
44
35
|
expect(dkim).toHaveLength(2);
|
45
|
-
expect(dkim[0].
|
46
|
-
expect(dkim[1].
|
36
|
+
expect(parseParams(dkim[0].value).s).toBe("selector1");
|
37
|
+
expect(parseParams(dkim[1].value).s).toBe("selector2");
|
47
38
|
});
|
48
39
|
});
|
49
40
|
|
@@ -103,3 +94,40 @@ describe("getDkimSigners", () => {
|
|
103
94
|
);
|
104
95
|
});
|
105
96
|
});
|
97
|
+
|
98
|
+
describe("parseParams", () => {
|
99
|
+
test("should parse single parameter", () => {
|
100
|
+
const params = parseParams("a=b");
|
101
|
+
expect(params).toEqual({ a: "b" });
|
102
|
+
});
|
103
|
+
|
104
|
+
test("should parse multiple parameters", () => {
|
105
|
+
const params = parseParams("a=b; c=d; e=f");
|
106
|
+
expect(params).toEqual({ a: "b", c: "d", e: "f" });
|
107
|
+
});
|
108
|
+
|
109
|
+
test("should trim spaces around parameters", () => {
|
110
|
+
const params = parseParams(" a = b ; c = d ; e = f ");
|
111
|
+
expect(params).toEqual({ a: "b", c: "d", e: "f" });
|
112
|
+
});
|
113
|
+
|
114
|
+
test("should handle empty values", () => {
|
115
|
+
const params = parseParams("a=; b=c");
|
116
|
+
expect(params).toEqual({ a: "", b: "c" });
|
117
|
+
});
|
118
|
+
|
119
|
+
test("should handle missing values", () => {
|
120
|
+
const params = parseParams("a; b=c");
|
121
|
+
expect(params).toEqual({ a: undefined, b: "c" });
|
122
|
+
});
|
123
|
+
|
124
|
+
test("should handle empty string", () => {
|
125
|
+
const params = parseParams("");
|
126
|
+
expect(params).toEqual({});
|
127
|
+
});
|
128
|
+
|
129
|
+
test("should handle parameters with extra semicolons", () => {
|
130
|
+
const params = parseParams("a=b;; c=d;");
|
131
|
+
expect(params).toEqual({ a: "b", c: "d" });
|
132
|
+
});
|
133
|
+
});
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import PostalMime, { Email, Header } from "postal-mime";
|
2
2
|
|
3
3
|
export class DkimParsingError extends Error {
|
4
4
|
constructor(message: string) {
|
@@ -8,38 +8,42 @@ export class DkimParsingError extends Error {
|
|
8
8
|
}
|
9
9
|
|
10
10
|
export async function parseEmail(mime: string) {
|
11
|
-
return
|
12
|
-
skipHtmlToText: true,
|
13
|
-
skipTextToHtml: true,
|
14
|
-
skipTextLinks: true,
|
15
|
-
skipImageLinks: true,
|
16
|
-
});
|
11
|
+
return await PostalMime.parse(mime.trim());
|
17
12
|
}
|
18
13
|
|
19
|
-
export function getDkimSigners(mail:
|
20
|
-
const dkimHeader = mail.headers.
|
21
|
-
if (
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
14
|
+
export function getDkimSigners(mail: Email) {
|
15
|
+
const dkimHeader = mail.headers.filter((h) => h.key === "dkim-signature");
|
16
|
+
if (dkimHeader.length === 0)
|
17
|
+
throw new DkimParsingError("No DKIM header found");
|
18
|
+
return dkimHeader.map(parseHeader);
|
19
|
+
}
|
20
|
+
|
21
|
+
export function parseParams(str: string) {
|
22
|
+
return Object.fromEntries(
|
23
|
+
str.split(";").map((s) =>
|
24
|
+
s
|
25
|
+
.trim()
|
26
|
+
.split("=")
|
27
|
+
.map((v) => v && v.trim()),
|
28
|
+
),
|
29
|
+
);
|
26
30
|
}
|
27
31
|
|
28
|
-
function parseHeader(header:
|
29
|
-
|
32
|
+
function parseHeader(header: Header) {
|
33
|
+
const params = parseParams(header.value);
|
34
|
+
if (!params) {
|
30
35
|
throw new DkimParsingError(`Invalid DKIM header ${header}`);
|
31
36
|
}
|
32
37
|
|
33
|
-
if (!
|
38
|
+
if (!params.d) {
|
34
39
|
throw new DkimParsingError("DKIM header missing domain");
|
35
40
|
}
|
36
41
|
|
37
|
-
if (!
|
42
|
+
if (!params.s) {
|
38
43
|
throw new DkimParsingError("DKIM header missing selector");
|
39
44
|
}
|
40
|
-
|
41
45
|
return {
|
42
|
-
domain:
|
43
|
-
selector:
|
46
|
+
domain: params.d,
|
47
|
+
selector: params.s,
|
44
48
|
};
|
45
49
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { describe, expect, test } from "vitest";
|
2
2
|
import { preverifyEmail } from "./preverify.ts";
|
3
|
-
import { readFile } from "testHelpers/readFile";
|
3
|
+
import { readFile } from "../../testHelpers/readFile";
|
4
4
|
|
5
5
|
describe("Preverify email: integration", () => {
|
6
6
|
test("adds dns record to email mime", async () => {
|
package/src/api/helpers.ts
CHANGED
@@ -18,14 +18,10 @@ import { foundry } from "viem/chains";
|
|
18
18
|
import type { ContractSpec, ContractArg } from "types/ethereum";
|
19
19
|
|
20
20
|
export const testChainId1 = 100001;
|
21
|
-
export const testChainId2 = 100002;
|
22
21
|
|
23
|
-
const rpcUrls: Map<number, HttpTransport> = new Map([
|
24
|
-
[testChainId1, http()],
|
25
|
-
[testChainId2, http("http://127.0.0.1:8546")],
|
26
|
-
]);
|
22
|
+
const rpcUrls: Map<number, HttpTransport> = new Map([[testChainId1, http()]]);
|
27
23
|
|
28
|
-
export const chainIds = [testChainId1
|
24
|
+
export const chainIds = [testChainId1];
|
29
25
|
|
30
26
|
export function client(
|
31
27
|
chainId: number = testChainId1,
|
package/src/api/lib/client.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import { VlayerClient } from "types/vlayer";
|
2
|
-
import { WebProofProvider } from "types/
|
2
|
+
import { WebProofProvider } from "types/webProofProvider";
|
3
3
|
|
4
|
+
import { prove } from "../prover";
|
4
5
|
export const createVlayerClient = ({
|
5
6
|
url,
|
6
7
|
webProofProvider,
|
@@ -8,11 +9,11 @@ export const createVlayerClient = ({
|
|
8
9
|
url: string;
|
9
10
|
webProofProvider: WebProofProvider;
|
10
11
|
}): VlayerClient => {
|
12
|
+
// TODO : implement high level api
|
13
|
+
console.log("createVlayerClient with", url, webProofProvider);
|
11
14
|
return {
|
12
|
-
prove: async () => {
|
13
|
-
|
14
|
-
console.log("url", url);
|
15
|
-
console.log("webProofProvider", webProofProvider);
|
15
|
+
prove: async ({ address, functionName, chainId, proverAbi, args }) => {
|
16
|
+
return prove(address, proverAbi, functionName, args, chainId);
|
16
17
|
},
|
17
18
|
};
|
18
19
|
};
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { Abi, ContractFunctionName } from "viem";
|
2
|
+
import { AbiParametersToPrimitiveTypes, ExtractAbiFunction } from "abitype";
|
3
|
+
|
4
|
+
type Without<T extends readonly unknown[], P> = T extends readonly [
|
5
|
+
infer F,
|
6
|
+
...infer R,
|
7
|
+
]
|
8
|
+
? F extends P
|
9
|
+
? Without<R, P>
|
10
|
+
: readonly [F, ...Without<R, P>]
|
11
|
+
: [];
|
12
|
+
|
13
|
+
export type ContractFunctionArgsWithout<
|
14
|
+
abi extends Abi,
|
15
|
+
functionName extends ContractFunctionName<abi>,
|
16
|
+
without,
|
17
|
+
> =
|
18
|
+
AbiParametersToPrimitiveTypes<
|
19
|
+
Without<
|
20
|
+
ExtractAbiFunction<abi extends Abi ? abi : Abi, functionName>["inputs"],
|
21
|
+
without
|
22
|
+
>,
|
23
|
+
"inputs"
|
24
|
+
> extends infer args
|
25
|
+
? [args] extends [never]
|
26
|
+
? readonly unknown[]
|
27
|
+
: args
|
28
|
+
: readonly unknown[];
|
@@ -1,4 +1,14 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
Abi,
|
3
|
+
AbiFunction,
|
4
|
+
AbiStateMutability,
|
5
|
+
Address,
|
6
|
+
ContractFunctionArgs,
|
7
|
+
ContractFunctionName,
|
8
|
+
Hex,
|
9
|
+
} from "viem";
|
10
|
+
|
11
|
+
import { type ProverCallCommitment } from "types/webProofProvider.ts";
|
2
12
|
|
3
13
|
type Calldata = string;
|
4
14
|
|
@@ -30,7 +40,7 @@ export interface Proof {
|
|
30
40
|
bigint,
|
31
41
|
bigint,
|
32
42
|
];
|
33
|
-
|
43
|
+
assumptions: {
|
34
44
|
proverContractAddress: Address;
|
35
45
|
functionSelector: Hex;
|
36
46
|
settleBlockHash: Hex;
|
@@ -51,5 +61,17 @@ export interface VCallResponse {
|
|
51
61
|
|
52
62
|
// Add more methods here
|
53
63
|
export type VlayerClient = {
|
54
|
-
prove:
|
64
|
+
prove: <
|
65
|
+
T extends readonly [AbiFunction, ...Abi[number][]],
|
66
|
+
F extends ContractFunctionName<T>,
|
67
|
+
>(
|
68
|
+
args: VlayerClientProveArgs<T, F>,
|
69
|
+
) => void;
|
70
|
+
};
|
71
|
+
|
72
|
+
export type VlayerClientProveArgs<
|
73
|
+
T extends readonly [AbiFunction, ...Abi[number][]],
|
74
|
+
F extends ContractFunctionName<T>,
|
75
|
+
> = ProverCallCommitment<T, F> & {
|
76
|
+
args: ContractFunctionArgs<T, AbiStateMutability, F>;
|
55
77
|
};
|
@@ -1,6 +1,6 @@
|
|
1
|
-
//NOTE : this is copied from tlsn-js 5.4
|
2
|
-
// for some reason newest
|
3
|
-
//
|
1
|
+
// NOTE : this is copied from tlsn-js 5.4
|
2
|
+
// for some reason newest versions doesn't export this type (clarification is in progress)
|
3
|
+
// probably it should be reexported from tlsn-js
|
4
4
|
|
5
5
|
export interface WebProof {
|
6
6
|
session: Session;
|
@@ -100,7 +100,12 @@ export interface Range {
|
|
100
100
|
start: number;
|
101
101
|
end: number;
|
102
102
|
}
|
103
|
-
|
104
|
-
|
105
|
-
|
103
|
+
export const assertWebProof = function (candidate: {
|
104
|
+
notaryUrl?: string;
|
105
|
+
}): asserts candidate is WebProof {
|
106
|
+
//for now only thing we check is notary url
|
107
|
+
//TODO: implement later once we known the conteact with tlsn-js
|
108
|
+
if (!candidate.notaryUrl) {
|
109
|
+
throw new Error("Missing required parameter");
|
110
|
+
}
|
106
111
|
};
|
@@ -0,0 +1,93 @@
|
|
1
|
+
import { WebProof } from "types/webProof.ts";
|
2
|
+
import { AbiFunction, Hex, Abi, ContractFunctionName } from "viem";
|
3
|
+
import { Branded } from "types/utils.ts";
|
4
|
+
import type { ContractFunctionArgsWithout } from "./viem";
|
5
|
+
|
6
|
+
export const EXTENSION_STEP = {
|
7
|
+
expectUrl: "expectUrl",
|
8
|
+
startPage: "startPage",
|
9
|
+
notarize: "notarize",
|
10
|
+
} as const;
|
11
|
+
|
12
|
+
export const EXTENSION_ACTION = {
|
13
|
+
requestWebProof: "requestWebProof",
|
14
|
+
} as const;
|
15
|
+
|
16
|
+
export const EXTENSION_MESSAGE = {
|
17
|
+
proofDone: "proofDone",
|
18
|
+
proofError: "proofError",
|
19
|
+
} as const;
|
20
|
+
|
21
|
+
export type ExtensionStep =
|
22
|
+
(typeof EXTENSION_STEP)[keyof typeof EXTENSION_STEP];
|
23
|
+
|
24
|
+
export type WebProofStepNotarize = Branded<
|
25
|
+
{
|
26
|
+
url: string;
|
27
|
+
method: string;
|
28
|
+
label: string;
|
29
|
+
step: typeof EXTENSION_STEP.notarize;
|
30
|
+
},
|
31
|
+
"notarize"
|
32
|
+
>;
|
33
|
+
|
34
|
+
export type WebProofStepExpectUrl = Branded<
|
35
|
+
{
|
36
|
+
url: string;
|
37
|
+
label: string;
|
38
|
+
step: typeof EXTENSION_STEP.expectUrl;
|
39
|
+
},
|
40
|
+
"expectUrl"
|
41
|
+
>;
|
42
|
+
|
43
|
+
export type WebProofStepStartPage = Branded<
|
44
|
+
{
|
45
|
+
url: string;
|
46
|
+
label: string;
|
47
|
+
step: typeof EXTENSION_STEP.startPage;
|
48
|
+
},
|
49
|
+
"startPage"
|
50
|
+
>;
|
51
|
+
|
52
|
+
export type WebProofSetupInput = {
|
53
|
+
logoUrl: string;
|
54
|
+
steps: [WebProofStepExpectUrl, WebProofStepStartPage, WebProofStepStartPage];
|
55
|
+
};
|
56
|
+
|
57
|
+
export type WebProofSetup = Branded<
|
58
|
+
WebProofSetupInput & {
|
59
|
+
isWebProof: true;
|
60
|
+
},
|
61
|
+
"webProof"
|
62
|
+
>;
|
63
|
+
|
64
|
+
export type ProverCallCommitment<
|
65
|
+
T extends readonly [AbiFunction, ...Abi[number][]],
|
66
|
+
F extends ContractFunctionName<T>,
|
67
|
+
> = {
|
68
|
+
address: Hex;
|
69
|
+
proverAbi: T;
|
70
|
+
functionName: F;
|
71
|
+
commitmentArgs: ContractFunctionArgsWithout<T, F, { name: "webProof" }>;
|
72
|
+
chainId: number;
|
73
|
+
};
|
74
|
+
export type GetWebProofArgs<
|
75
|
+
T extends readonly [AbiFunction, ...Abi[number][]],
|
76
|
+
F extends ContractFunctionName<T>,
|
77
|
+
> = {
|
78
|
+
proverCallCommitment: ProverCallCommitment<T, F>;
|
79
|
+
} & WebProofSetupInput;
|
80
|
+
|
81
|
+
export type WebProofProvider = {
|
82
|
+
getWebProof: <
|
83
|
+
T extends readonly [AbiFunction, ...Abi[number][]],
|
84
|
+
F extends ContractFunctionName<T>,
|
85
|
+
>(
|
86
|
+
args: GetWebProofArgs<T, F>,
|
87
|
+
) => Promise<WebProof>;
|
88
|
+
};
|
89
|
+
|
90
|
+
export type WebProofProviderSetup = {
|
91
|
+
notaryUrl?: string;
|
92
|
+
wsProxyUrl?: string;
|
93
|
+
};
|
package/src/api/prover.ts
CHANGED
@@ -9,7 +9,7 @@ import {
|
|
9
9
|
encodeFunctionData,
|
10
10
|
} from "viem";
|
11
11
|
|
12
|
-
import { type CallContext, type CallParams
|
12
|
+
import { type CallContext, type CallParams } from "types/vlayer";
|
13
13
|
import { v_call } from "./v_call";
|
14
14
|
import { testChainId1 } from "./helpers";
|
15
15
|
import { ContractSpec } from "types/ethereum";
|
@@ -43,31 +43,12 @@ export async function prove<
|
|
43
43
|
result: { proof, evm_call_result },
|
44
44
|
} = await v_call(call, context);
|
45
45
|
|
46
|
-
const returnValue = decodeFunctionResult({
|
46
|
+
const [, ...returnValue] = decodeFunctionResult({
|
47
47
|
abi: abi as Abi,
|
48
48
|
data: evm_call_result,
|
49
49
|
functionName: functionName as string,
|
50
|
-
|
51
|
-
|
52
|
-
addDynamicParamsOffsets(abi, functionName, proof);
|
53
|
-
|
54
|
-
return { proof, returnValue: returnValue as `0x${string}`[] };
|
55
|
-
}
|
56
|
-
|
57
|
-
function addDynamicParamsOffsets(
|
58
|
-
abi: Abi,
|
59
|
-
functionName: string | undefined,
|
60
|
-
proof: Proof,
|
61
|
-
) {
|
62
|
-
const proverFunction = abi.find(
|
63
|
-
(f) => f.type === "function" && f.name === functionName,
|
64
|
-
) as AbiFunction;
|
65
|
-
|
66
|
-
if (proverFunction?.outputs && proverFunction.outputs.length > 0) {
|
67
|
-
const secondVerifyMethodParamType = proverFunction.outputs[0].type;
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
51
|
+
}) as any[];
|
68
52
|
|
69
|
-
|
70
|
-
proof.dynamicParamsOffsets[0] = BigInt(32);
|
71
|
-
}
|
72
|
-
}
|
53
|
+
return { proof, returnValue };
|
73
54
|
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
import {
|
2
|
+
EXTENSION_ACTION,
|
3
|
+
EXTENSION_MESSAGE,
|
4
|
+
type WebProofProvider,
|
5
|
+
type WebProofProviderSetup,
|
6
|
+
type WebProofSetupInput,
|
7
|
+
} from "../../lib/types/webProofProvider";
|
8
|
+
|
9
|
+
import { WebProof } from "../../lib/types/webProof";
|
10
|
+
|
11
|
+
// NOTE @types/chrome and webextension-polyfill work only in the extension context
|
12
|
+
// and looks that there is no community driven package providing typings for chrome.runtime
|
13
|
+
// or polyfill logic for the browser APIs available in the browser context
|
14
|
+
// we intentionally use chrome here instead of browser as we support only chrome for now
|
15
|
+
// and there could be some differences in the API between browsers
|
16
|
+
|
17
|
+
declare const chrome: {
|
18
|
+
runtime: {
|
19
|
+
sendMessage: (extensionId: string | undefined, message: unknown) => void;
|
20
|
+
connect: (extensionId: string) => {
|
21
|
+
onMessage: {
|
22
|
+
addListener: (message: unknown) => void;
|
23
|
+
};
|
24
|
+
};
|
25
|
+
};
|
26
|
+
};
|
27
|
+
|
28
|
+
export const createExtensionWebProofProvider = ({
|
29
|
+
notaryUrl = "https://notary.pse.dev/v0.1.0-alpha.5/",
|
30
|
+
wsProxyUrl = "wss://notary.pse.dev/proxy",
|
31
|
+
}: WebProofProviderSetup): WebProofProvider => {
|
32
|
+
return {
|
33
|
+
getWebProof: async function (webProofSetup: WebProofSetupInput) {
|
34
|
+
// TODO: we cant assume that developer is using vite
|
35
|
+
// EXTESION_ID value should be injected by the build system
|
36
|
+
|
37
|
+
return new Promise<WebProof>((resolve, reject) => {
|
38
|
+
chrome.runtime.sendMessage(import.meta.env.VITE_EXTENSION_ID, {
|
39
|
+
action: EXTENSION_ACTION.requestWebProof,
|
40
|
+
payload: {
|
41
|
+
notaryUrl,
|
42
|
+
wsProxyUrl,
|
43
|
+
logoUrl: webProofSetup.logoUrl,
|
44
|
+
steps: webProofSetup.steps,
|
45
|
+
},
|
46
|
+
});
|
47
|
+
const EXTENSION_ID = import.meta.env.VITE_EXTENSION_ID as string;
|
48
|
+
const port = chrome.runtime.connect(EXTENSION_ID);
|
49
|
+
//TODO : validate message in runtime
|
50
|
+
port.onMessage.addListener(
|
51
|
+
(
|
52
|
+
message:
|
53
|
+
| {
|
54
|
+
type: typeof EXTENSION_MESSAGE.proofDone;
|
55
|
+
proof: WebProof;
|
56
|
+
}
|
57
|
+
| {
|
58
|
+
type: typeof EXTENSION_MESSAGE.proofError;
|
59
|
+
error: { message: string };
|
60
|
+
},
|
61
|
+
) => {
|
62
|
+
if (message.type === EXTENSION_MESSAGE.proofDone) {
|
63
|
+
resolve(message.proof);
|
64
|
+
}
|
65
|
+
if (message.type === EXTENSION_MESSAGE.proofError) {
|
66
|
+
reject(message.error);
|
67
|
+
}
|
68
|
+
},
|
69
|
+
);
|
70
|
+
});
|
71
|
+
},
|
72
|
+
};
|
73
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from "./extension";
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import {
|
2
|
+
EXTENSION_STEP,
|
3
|
+
WebProofStepExpectUrl,
|
4
|
+
} from "../../../api/lib/types/webProofProvider";
|
5
|
+
|
6
|
+
export const expectUrl = (url: string, label: string) => {
|
7
|
+
return {
|
8
|
+
url,
|
9
|
+
label,
|
10
|
+
step: EXTENSION_STEP.expectUrl,
|
11
|
+
} as WebProofStepExpectUrl;
|
12
|
+
};
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import {
|
2
|
+
EXTENSION_STEP,
|
3
|
+
WebProofStepNotarize,
|
4
|
+
} from "../../../api/lib/types/webProofProvider";
|
5
|
+
|
6
|
+
export const notarize = (
|
7
|
+
url: string,
|
8
|
+
method: string = "GET",
|
9
|
+
label: string,
|
10
|
+
) => {
|
11
|
+
return {
|
12
|
+
url,
|
13
|
+
method,
|
14
|
+
label,
|
15
|
+
step: EXTENSION_STEP.notarize,
|
16
|
+
} as WebProofStepNotarize;
|
17
|
+
};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import {
|
2
|
+
EXTENSION_STEP,
|
3
|
+
WebProofStepStartPage,
|
4
|
+
} from "../../../api/lib/types/webProofProvider";
|
5
|
+
|
6
|
+
export const startPage = (url: string, label: string) => {
|
7
|
+
return {
|
8
|
+
url,
|
9
|
+
label,
|
10
|
+
step: EXTENSION_STEP.startPage,
|
11
|
+
} as WebProofStepStartPage;
|
12
|
+
};
|
package/src/index.ts
CHANGED
@@ -6,3 +6,6 @@ export { getContractSpec, prove } from "./api/prover";
|
|
6
6
|
export * as testHelpers from "./api/helpers";
|
7
7
|
export { client as createTestClient } from "./api/helpers";
|
8
8
|
export { preverifyEmail } from "./api/email/preverify.ts";
|
9
|
+
|
10
|
+
export * from "./api/webProof";
|
11
|
+
export * from "./api/lib/types";
|