@vlayer/sdk 0.1.0-nightly-20250127-96fc5df → 0.1.0-nightly-20250128-0a32cfc
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/api/lib/client.d.ts.map +1 -1
- package/dist/api/lib/client.js.map +1 -1
- package/dist/api/prover.d.ts.map +1 -1
- package/dist/api/prover.js +1 -2
- package/dist/api/prover.js.map +1 -1
- package/dist/api/v_call.d.ts +1 -1
- package/dist/api/v_call.d.ts.map +1 -1
- package/dist/api/v_call.js +8 -2
- package/dist/api/v_call.js.map +1 -1
- package/dist/api/v_getProofReceipt.d.ts.map +1 -1
- package/dist/api/v_getProofReceipt.js.map +1 -1
- package/dist/api/webProof/createWebProofRequest.d.ts.map +1 -1
- package/dist/api/webProof/createWebProofRequest.js.map +1 -1
- package/package.json +20 -7
- package/src/api/email/dnsResolver.test.ts +19 -0
- package/src/api/email/dnsResolver.ts +87 -0
- package/src/api/email/parseEmail.test.ts +133 -0
- package/src/api/email/parseEmail.ts +55 -0
- package/src/api/email/preverify.test.ts +201 -0
- package/src/api/email/preverify.ts +70 -0
- package/src/api/email/testdata/test_email.txt +21 -0
- package/src/api/email/testdata/test_email_multiple_dkims.txt +28 -0
- package/src/api/email/testdata/test_email_subdomain.txt +21 -0
- package/src/api/email/testdata/test_email_unknown_domain.txt +21 -0
- package/src/api/lib/client.test.ts +261 -0
- package/src/api/lib/client.ts +191 -0
- package/src/api/lib/errors.ts +19 -0
- package/src/api/lib/types/ethereum.ts +45 -0
- package/src/api/lib/types/index.ts +3 -0
- package/src/api/lib/types/viem.ts +26 -0
- package/src/api/lib/types/vlayer.ts +156 -0
- package/src/api/lib/types/webProofProvider.ts +68 -0
- package/src/api/prover.ts +120 -0
- package/src/api/utils/prefixAllButNthSubstring.test.ts +24 -0
- package/src/api/utils/prefixAllButNthSubstring.ts +13 -0
- package/src/api/utils/versions.test.ts +52 -0
- package/src/api/utils/versions.ts +31 -0
- package/src/api/v_call.ts +58 -0
- package/src/api/v_getProofReceipt.ts +48 -0
- package/src/api/v_versions.ts +68 -0
- package/src/api/webProof/createWebProofRequest.ts +15 -0
- package/src/api/webProof/index.ts +3 -0
- package/src/api/webProof/providers/extension.test.ts +122 -0
- package/src/api/webProof/providers/extension.ts +197 -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 +20 -0
- package/src/api/webProof/steps/startPage.ts +12 -0
- package/src/config/createContext.ts +69 -0
- package/src/config/deploy.ts +108 -0
- package/src/config/getChainConfirmations.ts +6 -0
- package/src/config/getConfig.ts +71 -0
- package/src/config/index.ts +5 -0
- package/src/config/types.ts +26 -0
- package/src/config/writeEnvVariables.ts +28 -0
- package/src/index.ts +7 -0
- package/src/testHelpers/readFile.ts +3 -0
- package/src/web-proof-commons/index.ts +3 -0
- package/src/web-proof-commons/types/message.ts +176 -0
- package/src/web-proof-commons/types/redaction.test.ts +97 -0
- package/src/web-proof-commons/types/redaction.ts +201 -0
- package/src/web-proof-commons/utils.ts +11 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
2
|
+
import { checkVersionCompatibility } from "./versions";
|
3
|
+
|
4
|
+
describe("versions compatibility", () => {
|
5
|
+
test("throws if major version mismatches", () => {
|
6
|
+
expect(() => {
|
7
|
+
checkVersionCompatibility("1.2.3", "2.1.3");
|
8
|
+
}).toThrowError(
|
9
|
+
"SDK version 2.1.3 is incompatible with prover version 1.2.3",
|
10
|
+
);
|
11
|
+
});
|
12
|
+
|
13
|
+
test("throws if major version mismatches with metadata after dash", () => {
|
14
|
+
expect(() => {
|
15
|
+
checkVersionCompatibility("1.2.3-dev-123456-deadbeef", "2.1.3");
|
16
|
+
}).toThrowError(
|
17
|
+
"SDK version 2.1.3 is incompatible with prover version 1.2.3-dev-123456-deadbeef",
|
18
|
+
);
|
19
|
+
});
|
20
|
+
|
21
|
+
test("throws if major version is 0 and minor version mismatches", () => {
|
22
|
+
expect(() => {
|
23
|
+
checkVersionCompatibility("0.2.3", "0.1.3");
|
24
|
+
}).toThrowError(
|
25
|
+
"SDK version 0.1.3 is incompatible with prover version 0.2.3",
|
26
|
+
);
|
27
|
+
});
|
28
|
+
|
29
|
+
test("does not throw if major and minor versions match", () => {
|
30
|
+
expect(() => {
|
31
|
+
checkVersionCompatibility("1.2.3", "1.2.13");
|
32
|
+
}).not.toThrow();
|
33
|
+
});
|
34
|
+
|
35
|
+
test("does not throw if major version is >0 and minor mismatches", () => {
|
36
|
+
expect(() => {
|
37
|
+
checkVersionCompatibility("1.2.3", "1.5.8");
|
38
|
+
}).not.toThrow();
|
39
|
+
});
|
40
|
+
|
41
|
+
test("does not throw if major version is 0 and minor matches", () => {
|
42
|
+
expect(() => {
|
43
|
+
checkVersionCompatibility("0.2.3", "0.2.7");
|
44
|
+
}).not.toThrow();
|
45
|
+
});
|
46
|
+
|
47
|
+
test("works for semvers with metadata after dash", () => {
|
48
|
+
expect(() => {
|
49
|
+
checkVersionCompatibility("0.2.3-dev-123456-deadbeef", "0.2.7");
|
50
|
+
}).not.toThrow();
|
51
|
+
});
|
52
|
+
});
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import { parse, type SemVer } from "semver";
|
2
|
+
import { VersionError } from "../lib/errors";
|
3
|
+
|
4
|
+
function safeParseSemver(semverString: string): SemVer {
|
5
|
+
const parsed = parse(semverString);
|
6
|
+
if (parsed === null) {
|
7
|
+
throw new VersionError(`Invalid semver string: ${semverString}`);
|
8
|
+
}
|
9
|
+
return parsed;
|
10
|
+
}
|
11
|
+
|
12
|
+
export function checkVersionCompatibility(
|
13
|
+
proverSemver: string,
|
14
|
+
sdkSemver: string,
|
15
|
+
) {
|
16
|
+
const { major: proverMajor, minor: proverMinor } =
|
17
|
+
safeParseSemver(proverSemver);
|
18
|
+
const { major: sdkMajor, minor: sdkMinor } = safeParseSemver(sdkSemver);
|
19
|
+
|
20
|
+
if (proverMajor !== sdkMajor) {
|
21
|
+
throw new VersionError(
|
22
|
+
`SDK version ${sdkSemver} is incompatible with prover version ${proverSemver}`,
|
23
|
+
);
|
24
|
+
}
|
25
|
+
|
26
|
+
if (proverMajor === 0 && proverMinor !== sdkMinor) {
|
27
|
+
throw new VersionError(
|
28
|
+
`SDK version ${sdkSemver} is incompatible with prover version ${proverSemver}`,
|
29
|
+
);
|
30
|
+
}
|
31
|
+
}
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import {
|
2
|
+
type CallContext,
|
3
|
+
type CallParams,
|
4
|
+
type VCallResponse,
|
5
|
+
} from "./lib/types/vlayer";
|
6
|
+
import { parseVCallResponseError } from "./lib/errors";
|
7
|
+
import debug from "debug";
|
8
|
+
|
9
|
+
const log = debug("vlayer:v_call");
|
10
|
+
|
11
|
+
function v_callBody(call: CallParams, context: CallContext) {
|
12
|
+
console.log("call", call);
|
13
|
+
console.log("context", context);
|
14
|
+
return {
|
15
|
+
method: "v_call",
|
16
|
+
params: [call, context],
|
17
|
+
id: 1,
|
18
|
+
jsonrpc: "2.0",
|
19
|
+
};
|
20
|
+
}
|
21
|
+
|
22
|
+
export async function v_call(
|
23
|
+
call: CallParams,
|
24
|
+
context: CallContext,
|
25
|
+
url: string = "http://127.0.0.1:3000",
|
26
|
+
token?: string,
|
27
|
+
): Promise<VCallResponse> {
|
28
|
+
const headers: Record<string, string> = {
|
29
|
+
"Content-Type": "application/json",
|
30
|
+
};
|
31
|
+
if (token !== undefined) {
|
32
|
+
headers["Authorization"] = "Bearer " + token;
|
33
|
+
}
|
34
|
+
const response = await fetch(url, {
|
35
|
+
method: "POST",
|
36
|
+
body: JSON.stringify(v_callBody(call, context)),
|
37
|
+
headers,
|
38
|
+
});
|
39
|
+
log("response", response);
|
40
|
+
if (!response.ok) {
|
41
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
42
|
+
}
|
43
|
+
const response_json = await response.json();
|
44
|
+
log("response_json", response_json);
|
45
|
+
assertObject(response_json);
|
46
|
+
if ("error" in response_json) {
|
47
|
+
throw parseVCallResponseError(
|
48
|
+
response_json.error as { message: string | undefined },
|
49
|
+
);
|
50
|
+
}
|
51
|
+
return response_json as Promise<VCallResponse>;
|
52
|
+
}
|
53
|
+
|
54
|
+
function assertObject(x: unknown): asserts x is object {
|
55
|
+
if (typeof x !== "object") {
|
56
|
+
throw new Error("Expected object");
|
57
|
+
}
|
58
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import {
|
2
|
+
type VGetProofReceiptParams,
|
3
|
+
type VGetProofReceiptResponse,
|
4
|
+
} from "./lib/types/vlayer";
|
5
|
+
import { parseVCallResponseError } from "./lib/errors";
|
6
|
+
import { vGetProofReceiptSchema } from "./lib/types/vlayer";
|
7
|
+
import debug from "debug";
|
8
|
+
|
9
|
+
const log = debug("vlayer:v_getProofReceipt");
|
10
|
+
|
11
|
+
function v_getProofReceiptBody(params: VGetProofReceiptParams) {
|
12
|
+
return {
|
13
|
+
method: "v_getProofReceipt",
|
14
|
+
params: params,
|
15
|
+
id: 1,
|
16
|
+
jsonrpc: "2.0",
|
17
|
+
};
|
18
|
+
}
|
19
|
+
|
20
|
+
export async function v_getProofReceipt(
|
21
|
+
params: VGetProofReceiptParams,
|
22
|
+
url: string = "http://127.0.0.1:3000",
|
23
|
+
): Promise<VGetProofReceiptResponse> {
|
24
|
+
const response = await fetch(url, {
|
25
|
+
method: "POST",
|
26
|
+
body: JSON.stringify(v_getProofReceiptBody(params)),
|
27
|
+
headers: { "Content-Type": "application/json" },
|
28
|
+
});
|
29
|
+
log("response", response);
|
30
|
+
if (!response.ok) {
|
31
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
32
|
+
}
|
33
|
+
const response_json = await response.json();
|
34
|
+
log("response_json", response_json);
|
35
|
+
assertObject(response_json);
|
36
|
+
if ("error" in response_json) {
|
37
|
+
throw parseVCallResponseError(
|
38
|
+
response_json.error as { message: string | undefined },
|
39
|
+
);
|
40
|
+
}
|
41
|
+
return vGetProofReceiptSchema.parse(response_json);
|
42
|
+
}
|
43
|
+
|
44
|
+
function assertObject(x: unknown): asserts x is object {
|
45
|
+
if (typeof x !== "object") {
|
46
|
+
throw new Error("Expected object");
|
47
|
+
}
|
48
|
+
}
|
@@ -0,0 +1,68 @@
|
|
1
|
+
import debug from "debug";
|
2
|
+
|
3
|
+
const log = debug("vlayer:v_versions");
|
4
|
+
|
5
|
+
const v_versionsBody = {
|
6
|
+
method: "v_versions",
|
7
|
+
params: [],
|
8
|
+
id: 1,
|
9
|
+
jsonrpc: "2.0",
|
10
|
+
};
|
11
|
+
|
12
|
+
interface VVersionsResponseResult {
|
13
|
+
call_guest_id: string;
|
14
|
+
chain_guest_id: string;
|
15
|
+
api_version: string;
|
16
|
+
}
|
17
|
+
|
18
|
+
export interface VVersionsResponse {
|
19
|
+
jsonrpc: string;
|
20
|
+
result: VVersionsResponseResult;
|
21
|
+
id: number;
|
22
|
+
}
|
23
|
+
|
24
|
+
export async function v_versions(
|
25
|
+
url: string = "http://127.0.0.1:3000",
|
26
|
+
): Promise<VVersionsResponse> {
|
27
|
+
const response = await fetch(url, {
|
28
|
+
method: "POST",
|
29
|
+
body: JSON.stringify(v_versionsBody),
|
30
|
+
headers: { "Content-Type": "application/json" },
|
31
|
+
});
|
32
|
+
log("response", response);
|
33
|
+
if (!response.ok) {
|
34
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
35
|
+
}
|
36
|
+
const response_json = await response.json();
|
37
|
+
assertResponseObject(response_json);
|
38
|
+
return response_json;
|
39
|
+
}
|
40
|
+
|
41
|
+
function isFieldAString(
|
42
|
+
x: object,
|
43
|
+
field: keyof VVersionsResponseResult,
|
44
|
+
): boolean {
|
45
|
+
return (
|
46
|
+
field in x && typeof (x as VVersionsResponseResult)[field] === "string"
|
47
|
+
);
|
48
|
+
}
|
49
|
+
|
50
|
+
function assertResponseObject(x: unknown): asserts x is VVersionsResponse {
|
51
|
+
if (!x || typeof x !== "object") {
|
52
|
+
throw new Error("Expected object");
|
53
|
+
}
|
54
|
+
if (!("result" in x) || !x.result || typeof x.result !== "object") {
|
55
|
+
throw new Error(
|
56
|
+
`Unexpected \`v_versions\` response: ${JSON.stringify(x, null, 2)}`,
|
57
|
+
);
|
58
|
+
}
|
59
|
+
if (
|
60
|
+
!isFieldAString(x.result, "call_guest_id") ||
|
61
|
+
!isFieldAString(x.result, "chain_guest_id") ||
|
62
|
+
!isFieldAString(x.result, "api_version")
|
63
|
+
) {
|
64
|
+
throw new Error(
|
65
|
+
`Unexpected \`v_versions\` response: ${JSON.stringify(x, null, 2)}`,
|
66
|
+
);
|
67
|
+
}
|
68
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import {
|
2
|
+
type WebProofRequest,
|
3
|
+
type WebProofRequestInput,
|
4
|
+
} from "../lib/types/webProofProvider";
|
5
|
+
|
6
|
+
export const createWebProofRequest = ({
|
7
|
+
logoUrl,
|
8
|
+
steps,
|
9
|
+
}: WebProofRequestInput) => {
|
10
|
+
return {
|
11
|
+
logoUrl,
|
12
|
+
steps,
|
13
|
+
isWebProof: true,
|
14
|
+
} as WebProofRequest;
|
15
|
+
};
|
@@ -0,0 +1,122 @@
|
|
1
|
+
import { createExtensionWebProofProvider } from "./extension";
|
2
|
+
import { describe, it, expect, vi } from "vitest";
|
3
|
+
import { expectUrl, startPage, notarize } from "../steps";
|
4
|
+
import { StepValidationError } from "../../../web-proof-commons";
|
5
|
+
|
6
|
+
const chrome = {
|
7
|
+
runtime: {
|
8
|
+
disconnectCallbacks: [] as (() => void)[],
|
9
|
+
connect: vi.fn().mockImplementation(() => ({
|
10
|
+
postMessage: vi.fn().mockImplementation(() => {}),
|
11
|
+
onMessage: {
|
12
|
+
addListener: vi.fn().mockImplementation(() => {}),
|
13
|
+
},
|
14
|
+
onDisconnect: {
|
15
|
+
addListener: vi.fn().mockImplementation((callback: () => void) => {
|
16
|
+
chrome.runtime.disconnectCallbacks.push(callback);
|
17
|
+
}),
|
18
|
+
},
|
19
|
+
})),
|
20
|
+
disconnect: vi.fn().mockImplementation(() => {
|
21
|
+
chrome.runtime.disconnectCallbacks.forEach((callback) => {
|
22
|
+
callback();
|
23
|
+
});
|
24
|
+
}),
|
25
|
+
},
|
26
|
+
};
|
27
|
+
|
28
|
+
vi.stubGlobal("chrome", chrome);
|
29
|
+
|
30
|
+
const defaults = {
|
31
|
+
logoUrl: "https://example.com/logo.png",
|
32
|
+
proverCallCommitment: {
|
33
|
+
address: "0x" as `0x${string}`,
|
34
|
+
proverAbi: [],
|
35
|
+
chainId: 1,
|
36
|
+
functionName: "test",
|
37
|
+
commitmentArgs: null as never,
|
38
|
+
},
|
39
|
+
};
|
40
|
+
|
41
|
+
const invalidUrl = "http:/example.com";
|
42
|
+
const invalidUrlPattern = "http://+.test";
|
43
|
+
const validUrl = "https://example.com";
|
44
|
+
const validUrlPattern = "https://example.com/test";
|
45
|
+
const label = "test";
|
46
|
+
|
47
|
+
describe("ExtensionWebProofProvider", () => {
|
48
|
+
it("should properly validate startPage step", () => {
|
49
|
+
const provider = createExtensionWebProofProvider();
|
50
|
+
expect(() =>
|
51
|
+
provider.requestWebProof({
|
52
|
+
...defaults,
|
53
|
+
steps: [startPage(invalidUrl, label)],
|
54
|
+
}),
|
55
|
+
).toThrow(StepValidationError);
|
56
|
+
});
|
57
|
+
|
58
|
+
it("should properly validate expectUrl step", () => {
|
59
|
+
const provider = createExtensionWebProofProvider();
|
60
|
+
expect(() =>
|
61
|
+
provider.requestWebProof({
|
62
|
+
...defaults,
|
63
|
+
steps: [expectUrl(invalidUrlPattern, label)],
|
64
|
+
}),
|
65
|
+
).toThrow(StepValidationError);
|
66
|
+
});
|
67
|
+
|
68
|
+
it("should properly validate notarize step", () => {
|
69
|
+
const provider = createExtensionWebProofProvider();
|
70
|
+
expect(() =>
|
71
|
+
provider.requestWebProof({
|
72
|
+
...defaults,
|
73
|
+
steps: [notarize(invalidUrlPattern, "GET", label)],
|
74
|
+
}),
|
75
|
+
).toThrow(StepValidationError);
|
76
|
+
});
|
77
|
+
|
78
|
+
it("successfully validates all steps", () => {
|
79
|
+
const provider = createExtensionWebProofProvider();
|
80
|
+
expect(() =>
|
81
|
+
provider.requestWebProof({
|
82
|
+
...defaults,
|
83
|
+
steps: [
|
84
|
+
startPage(validUrl, label),
|
85
|
+
expectUrl(validUrlPattern, label),
|
86
|
+
notarize(validUrlPattern, "GET", label),
|
87
|
+
],
|
88
|
+
}),
|
89
|
+
).not.toThrow(StepValidationError);
|
90
|
+
});
|
91
|
+
|
92
|
+
it("should properly work backward compatible way with only urls used", () => {
|
93
|
+
const provider = createExtensionWebProofProvider();
|
94
|
+
|
95
|
+
expect(() =>
|
96
|
+
provider.requestWebProof({
|
97
|
+
...defaults,
|
98
|
+
steps: [
|
99
|
+
startPage(validUrl, label),
|
100
|
+
expectUrl(validUrl, label),
|
101
|
+
expectUrl(validUrl, label),
|
102
|
+
notarize(validUrl, "GET", label),
|
103
|
+
],
|
104
|
+
}),
|
105
|
+
).not.toThrow();
|
106
|
+
});
|
107
|
+
|
108
|
+
it("should reconnect extension on disconnect", () => {
|
109
|
+
const provider = createExtensionWebProofProvider();
|
110
|
+
provider.requestWebProof({
|
111
|
+
...defaults,
|
112
|
+
steps: [
|
113
|
+
startPage(validUrl, label),
|
114
|
+
expectUrl(validUrlPattern, label),
|
115
|
+
notarize(validUrlPattern, "GET", label),
|
116
|
+
],
|
117
|
+
});
|
118
|
+
chrome.runtime.connect.mockClear();
|
119
|
+
chrome.runtime.disconnect();
|
120
|
+
expect(chrome.runtime.connect).toHaveBeenCalled();
|
121
|
+
});
|
122
|
+
});
|
@@ -0,0 +1,197 @@
|
|
1
|
+
import {
|
2
|
+
type WebProofProvider,
|
3
|
+
type WebProofProviderSetup,
|
4
|
+
type WebProofRequestInput,
|
5
|
+
} from "../../lib/types/webProofProvider";
|
6
|
+
|
7
|
+
import {
|
8
|
+
EXTENSION_STEP,
|
9
|
+
ExtensionAction,
|
10
|
+
type ExtensionMessage,
|
11
|
+
ExtensionMessageType,
|
12
|
+
type WebProofStep,
|
13
|
+
type PresentationJSON,
|
14
|
+
ZkProvingStatus,
|
15
|
+
assertUrl,
|
16
|
+
assertUrlPattern,
|
17
|
+
type RedactionConfig,
|
18
|
+
RedactionItemsArray,
|
19
|
+
type MessageToExtension,
|
20
|
+
} from "../../../web-proof-commons";
|
21
|
+
|
22
|
+
import debug from "debug";
|
23
|
+
|
24
|
+
const log = debug("vlayer:WebProof:provider");
|
25
|
+
|
26
|
+
const EXTENSION_ID = "jbchhcgphfokabmfacnkafoeeeppjmpl";
|
27
|
+
|
28
|
+
declare let chrome: {
|
29
|
+
runtime: {
|
30
|
+
sendMessage: (
|
31
|
+
extensionId: string | undefined,
|
32
|
+
message: MessageToExtension,
|
33
|
+
) => void;
|
34
|
+
connect: (extensionId: string) => {
|
35
|
+
onMessage: {
|
36
|
+
addListener: (message: unknown) => void;
|
37
|
+
};
|
38
|
+
postMessage: (message: MessageToExtension) => void;
|
39
|
+
onDisconnect: {
|
40
|
+
addListener: (callback: () => void) => void;
|
41
|
+
};
|
42
|
+
};
|
43
|
+
};
|
44
|
+
};
|
45
|
+
|
46
|
+
class ExtensionWebProofProvider implements WebProofProvider {
|
47
|
+
private port: ReturnType<typeof chrome.runtime.connect> | null = null;
|
48
|
+
|
49
|
+
private listeners: Partial<
|
50
|
+
Record<
|
51
|
+
ExtensionMessageType,
|
52
|
+
((
|
53
|
+
args: Extract<ExtensionMessage, { type: ExtensionMessageType }>,
|
54
|
+
) => void)[]
|
55
|
+
>
|
56
|
+
> = {};
|
57
|
+
|
58
|
+
constructor(
|
59
|
+
private notaryUrl: string,
|
60
|
+
private wsProxyUrl: string,
|
61
|
+
) {}
|
62
|
+
|
63
|
+
public notifyZkProvingStatus(status: ZkProvingStatus) {
|
64
|
+
if (typeof chrome !== "undefined") {
|
65
|
+
// Chrome does not provide reliable api to check if given extension is installed
|
66
|
+
// what we could do is to use management api but
|
67
|
+
// 1) this will need to provided extra permission
|
68
|
+
// 2) still is not reliable because this api becomes defined when first extension that uses it is installed
|
69
|
+
// so still will need to try catch
|
70
|
+
try {
|
71
|
+
chrome.runtime.sendMessage(EXTENSION_ID, {
|
72
|
+
action: ExtensionAction.NotifyZkProvingStatus,
|
73
|
+
payload: { status },
|
74
|
+
});
|
75
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
76
|
+
} catch (e) {
|
77
|
+
log("Cant send message", "look that extension is not installed ");
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
private connectToExtension() {
|
83
|
+
if (!this.port) {
|
84
|
+
this.port = chrome.runtime.connect(EXTENSION_ID);
|
85
|
+
this.port.onDisconnect.addListener(() => {
|
86
|
+
this.port = null;
|
87
|
+
this.connectToExtension();
|
88
|
+
});
|
89
|
+
this.port.onMessage.addListener((message: ExtensionMessage) => {
|
90
|
+
if (message.type === ExtensionMessageType.ProofDone) {
|
91
|
+
this.listeners[ExtensionMessageType.ProofDone]?.forEach((cb) => {
|
92
|
+
cb(message);
|
93
|
+
});
|
94
|
+
}
|
95
|
+
if (message.type === ExtensionMessageType.ProofError) {
|
96
|
+
this.listeners[ExtensionMessageType.ProofError]?.forEach((cb) => {
|
97
|
+
cb(message);
|
98
|
+
});
|
99
|
+
}
|
100
|
+
});
|
101
|
+
}
|
102
|
+
return this.port;
|
103
|
+
}
|
104
|
+
|
105
|
+
public addEventListeners<T extends ExtensionMessageType>(
|
106
|
+
messageType: T,
|
107
|
+
listener: (args: Extract<ExtensionMessage, { type: T }>) => void,
|
108
|
+
) {
|
109
|
+
this.connectToExtension();
|
110
|
+
if (!this.listeners[messageType]) {
|
111
|
+
this.listeners[messageType] = [];
|
112
|
+
}
|
113
|
+
this.listeners[messageType].push(
|
114
|
+
listener as (args: ExtensionMessage) => void,
|
115
|
+
);
|
116
|
+
}
|
117
|
+
|
118
|
+
public requestWebProof(webProofRequest: WebProofRequestInput) {
|
119
|
+
validateWebProofRequest(webProofRequest);
|
120
|
+
this.connectToExtension().postMessage({
|
121
|
+
action: ExtensionAction.RequestWebProof,
|
122
|
+
payload: {
|
123
|
+
notaryUrl: this.notaryUrl,
|
124
|
+
wsProxyUrl: this.wsProxyUrl,
|
125
|
+
logoUrl: webProofRequest.logoUrl,
|
126
|
+
steps: webProofRequest.steps,
|
127
|
+
},
|
128
|
+
});
|
129
|
+
}
|
130
|
+
|
131
|
+
public async getWebProof(webProofRequest: WebProofRequestInput): Promise<{
|
132
|
+
presentationJSON: PresentationJSON;
|
133
|
+
decodedTranscript: {
|
134
|
+
sent: string;
|
135
|
+
recv: string;
|
136
|
+
};
|
137
|
+
}> {
|
138
|
+
return new Promise<{
|
139
|
+
presentationJSON: PresentationJSON;
|
140
|
+
decodedTranscript: {
|
141
|
+
sent: string;
|
142
|
+
recv: string;
|
143
|
+
};
|
144
|
+
}>((resolve, reject) => {
|
145
|
+
chrome.runtime.sendMessage(EXTENSION_ID, {
|
146
|
+
action: ExtensionAction.RequestWebProof,
|
147
|
+
payload: {
|
148
|
+
notaryUrl: this.notaryUrl,
|
149
|
+
wsProxyUrl: this.wsProxyUrl,
|
150
|
+
logoUrl: webProofRequest.logoUrl,
|
151
|
+
steps: webProofRequest.steps,
|
152
|
+
},
|
153
|
+
});
|
154
|
+
|
155
|
+
this.connectToExtension().onMessage.addListener(
|
156
|
+
(message: ExtensionMessage) => {
|
157
|
+
if (message.type === ExtensionMessageType.ProofDone) {
|
158
|
+
resolve(message.payload);
|
159
|
+
}
|
160
|
+
if (message.type === ExtensionMessageType.ProofError) {
|
161
|
+
reject(new Error(message.payload.error));
|
162
|
+
}
|
163
|
+
},
|
164
|
+
);
|
165
|
+
});
|
166
|
+
}
|
167
|
+
}
|
168
|
+
|
169
|
+
const validateSteps = (steps: WebProofStep[]) => {
|
170
|
+
steps.forEach((step) => {
|
171
|
+
if (step.step === EXTENSION_STEP.startPage) {
|
172
|
+
assertUrl(step.url);
|
173
|
+
} else {
|
174
|
+
assertUrlPattern(step.url);
|
175
|
+
}
|
176
|
+
if (step.step === EXTENSION_STEP.notarize) {
|
177
|
+
validateRedaction(step.redact ?? []);
|
178
|
+
}
|
179
|
+
});
|
180
|
+
};
|
181
|
+
|
182
|
+
const validateRedaction = (redaction: RedactionConfig) => {
|
183
|
+
RedactionItemsArray.parse(redaction);
|
184
|
+
};
|
185
|
+
|
186
|
+
export const validateWebProofRequest = (
|
187
|
+
webProofRequest: WebProofRequestInput,
|
188
|
+
) => {
|
189
|
+
validateSteps(webProofRequest.steps);
|
190
|
+
};
|
191
|
+
|
192
|
+
export const createExtensionWebProofProvider = ({
|
193
|
+
notaryUrl = "https://notary.pse.dev/v0.1.0-alpha.7",
|
194
|
+
wsProxyUrl = "wss://notary.pse.dev/proxy",
|
195
|
+
}: WebProofProviderSetup = {}): WebProofProvider => {
|
196
|
+
return new ExtensionWebProofProvider(notaryUrl, wsProxyUrl);
|
197
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from "./extension";
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import {
|
2
|
+
EXTENSION_STEP,
|
3
|
+
type WebProofStepExpectUrl,
|
4
|
+
} from "../../../web-proof-commons";
|
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,20 @@
|
|
1
|
+
import {
|
2
|
+
EXTENSION_STEP,
|
3
|
+
type WebProofStepNotarize,
|
4
|
+
type RedactionConfig,
|
5
|
+
} from "../../../web-proof-commons";
|
6
|
+
|
7
|
+
export const notarize = (
|
8
|
+
url: string,
|
9
|
+
method: string = "GET",
|
10
|
+
label: string,
|
11
|
+
redact?: RedactionConfig,
|
12
|
+
) => {
|
13
|
+
return {
|
14
|
+
url,
|
15
|
+
method,
|
16
|
+
label,
|
17
|
+
redact: redact ?? [],
|
18
|
+
step: EXTENSION_STEP.notarize,
|
19
|
+
} as WebProofStepNotarize;
|
20
|
+
};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import {
|
2
|
+
EXTENSION_STEP,
|
3
|
+
type WebProofStepStartPage,
|
4
|
+
} from "../../../web-proof-commons";
|
5
|
+
|
6
|
+
export const startPage = (url: string, label: string) => {
|
7
|
+
return {
|
8
|
+
url,
|
9
|
+
label,
|
10
|
+
step: EXTENSION_STEP.startPage,
|
11
|
+
} as WebProofStepStartPage;
|
12
|
+
};
|