@vlayer/sdk 0.1.0-nightly-20241028-591419e → 0.1.0-nightly-202410292-42360cf

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/api/email/dnsResolver.d.ts +1 -0
  2. package/dist/api/email/dnsResolver.js +6 -0
  3. package/dist/api/email/dnsResolver.test.d.ts +1 -0
  4. package/dist/api/email/dnsResolver.test.js +12 -0
  5. package/dist/api/email/parseEmail.d.ts +10 -0
  6. package/dist/api/email/parseEmail.js +38 -0
  7. package/dist/api/email/parseEmail.test.d.ts +1 -0
  8. package/dist/api/email/parseEmail.test.js +91 -0
  9. package/dist/api/email/preverify.d.ts +4 -0
  10. package/dist/api/email/preverify.js +18 -0
  11. package/dist/api/email/preverify.test.d.ts +1 -0
  12. package/dist/api/email/preverify.test.js +25 -0
  13. package/dist/api/helpers.d.ts +38 -0
  14. package/dist/api/helpers.js +72 -0
  15. package/dist/api/lib/client.d.ts +6 -0
  16. package/dist/api/lib/client.js +45 -0
  17. package/dist/api/lib/types/ethereum.d.ts +14 -0
  18. package/dist/api/lib/types/ethereum.js +12 -0
  19. package/dist/api/lib/types/index.js +3 -0
  20. package/dist/api/lib/types/viem.d.ts +8 -0
  21. package/dist/api/lib/types/viem.js +1 -0
  22. package/dist/api/lib/types/vlayer.d.ts +47 -0
  23. package/dist/api/lib/types/vlayer.js +1 -0
  24. package/dist/api/lib/types/webProofProvider.d.ts +29 -0
  25. package/dist/api/lib/types/webProofProvider.js +1 -0
  26. package/dist/api/prover.d.ts +2 -0
  27. package/dist/api/prover.js +15 -0
  28. package/dist/api/v_call.d.ts +2 -0
  29. package/dist/api/v_call.js +30 -0
  30. package/dist/api/webProof/createWebProof.d.ts +2 -0
  31. package/dist/api/webProof/createWebProof.js +7 -0
  32. package/dist/api/webProof/index.js +3 -0
  33. package/dist/api/webProof/providers/extension.d.ts +2 -0
  34. package/dist/api/webProof/providers/extension.js +32 -0
  35. package/dist/api/webProof/providers/index.js +1 -0
  36. package/dist/api/webProof/steps/expectUrl.d.ts +2 -0
  37. package/dist/api/webProof/steps/expectUrl.js +8 -0
  38. package/dist/api/webProof/steps/index.d.ts +9 -0
  39. package/dist/api/webProof/steps/index.js +9 -0
  40. package/dist/api/webProof/steps/notarize.d.ts +2 -0
  41. package/dist/api/webProof/steps/notarize.js +9 -0
  42. package/dist/api/webProof/steps/startPage.d.ts +2 -0
  43. package/dist/api/webProof/steps/startPage.js +8 -0
  44. package/dist/index.d.ts +7 -0
  45. package/dist/index.js +7 -0
  46. package/dist/testHelpers/readFile.d.ts +1 -0
  47. package/dist/testHelpers/readFile.js +2 -0
  48. package/dist/web-proof-commons/index.d.ts +3 -0
  49. package/dist/web-proof-commons/index.js +3 -0
  50. package/dist/web-proof-commons/types/message.d.ts +56 -0
  51. package/dist/web-proof-commons/types/message.js +5 -0
  52. package/dist/web-proof-commons/types/webProof.d.ts +86 -0
  53. package/dist/web-proof-commons/types/webProof.js +10 -0
  54. package/dist/web-proof-commons/utils.d.ts +7 -0
  55. package/dist/web-proof-commons/utils.js +5 -0
  56. package/package.json +16 -7
  57. package/.changeset/config.json +0 -11
  58. package/CHANGELOG.md +0 -7
  59. package/eslint.config.ts +0 -22
  60. package/src/api/email/dnsResolver.test.ts +0 -18
  61. package/src/api/email/dnsResolver.ts +0 -7
  62. package/src/api/email/parseEmail.test.ts +0 -133
  63. package/src/api/email/parseEmail.ts +0 -49
  64. package/src/api/email/preverify.test.ts +0 -37
  65. package/src/api/email/preverify.ts +0 -19
  66. package/src/api/email/testdata/test_email.txt +0 -21
  67. package/src/api/email/testdata/test_email_multiple_dkims.txt +0 -28
  68. package/src/api/email/testdata/test_email_unknown_domain.txt +0 -21
  69. package/src/api/helpers.ts +0 -173
  70. package/src/api/lib/client.ts +0 -76
  71. package/src/api/lib/types/ethereum.ts +0 -43
  72. package/src/api/lib/types/viem.ts +0 -28
  73. package/src/api/lib/types/vlayer.ts +0 -60
  74. package/src/api/lib/types/webProofProvider.ts +0 -44
  75. package/src/api/prover.ts +0 -34
  76. package/src/api/v_call.ts +0 -45
  77. package/src/api/webProof/createWebProof.ts +0 -9
  78. package/src/api/webProof/providers/extension.ts +0 -72
  79. package/src/api/webProof/steps/expectUrl.ts +0 -12
  80. package/src/api/webProof/steps/index.ts +0 -11
  81. package/src/api/webProof/steps/notarize.ts +0 -17
  82. package/src/api/webProof/steps/startPage.ts +0 -12
  83. package/src/index.ts +0 -9
  84. package/src/testHelpers/readFile.ts +0 -3
  85. package/src/web-proof-commons/index.ts +0 -3
  86. package/src/web-proof-commons/types/message.ts +0 -73
  87. package/src/web-proof-commons/types/webProof.ts +0 -111
  88. package/src/web-proof-commons/utils.ts +0 -12
  89. package/tsconfig.json +0 -24
  90. package/vite.config.ts +0 -7
  91. /package/{src/api/lib/types/index.ts → dist/api/lib/types/index.d.ts} +0 -0
  92. /package/{src/api/webProof/index.ts → dist/api/webProof/index.d.ts} +0 -0
  93. /package/{src/api/webProof/providers/index.ts → dist/api/webProof/providers/index.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ export declare function resolveDkimDns(domain: string, selector: string): Promise<string>;
@@ -0,0 +1,6 @@
1
+ import DnsResolver from "dns-over-http-resolver";
2
+ export async function resolveDkimDns(domain, selector) {
3
+ const resolver = new DnsResolver();
4
+ const address = await resolver.resolveTxt(`${selector}._domainkey.${domain}`);
5
+ return address.flat()[0];
6
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { resolveDkimDns } from "./dnsResolver";
3
+ describe("resolveDkimDns Integration", () => {
4
+ test("resolves VLayer DNS", async () => {
5
+ const resolved = await resolveDkimDns("vlayer-xyz.20230601.gappssmtp.com", "20230601");
6
+ const expected = "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3gWcOhCm99qzN+h7/2+LeP3CLsJkQQ4EP/2mrceXle5pKq8uZmBl1U4d2Vxn4w+pWFANDLmcHolLboESLFqEL5N6ae7u9b236dW4zn9AFkXAGenTzQEeif9VUFtLAZ0Qh2eV7OQgz/vPj5IaNqJ7h9hpM9gO031fe4v+J0DLCE8Rgo7hXbNgJavctc0983DaCDQaznHZ44LZ6TtZv9TBs+QFvsy4+UCTfsuOtHzoEqOOuXsVXZKLP6B882XbEnBpXEF8QzV4J26HiAJFUbO3mAqZL2UeKC0hhzoIZqZXNG0BfuzOF0VLpDa18GYMUiu+LhEJPJO9D8zhzvQIHNrpGwIDAQAB";
7
+ expect(resolved).toBe(expected);
8
+ });
9
+ test("throws error if dns not found", async () => {
10
+ await expect(resolveDkimDns("not-a-domain.com", "abcd")).rejects.toThrow();
11
+ });
12
+ });
@@ -0,0 +1,10 @@
1
+ import { Email } from "postal-mime";
2
+ export declare class DkimParsingError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export declare function parseEmail(mime: string): Promise<Email>;
6
+ export declare function getDkimSigners(mail: Email): {
7
+ domain: string;
8
+ selector: string;
9
+ }[];
10
+ export declare function parseParams(str: string): Record<string, string>;
@@ -0,0 +1,38 @@
1
+ import PostalMime from "postal-mime";
2
+ export class DkimParsingError extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "DkimParsingError";
6
+ }
7
+ }
8
+ export async function parseEmail(mime) {
9
+ return await PostalMime.parse(mime.trim());
10
+ }
11
+ export function getDkimSigners(mail) {
12
+ const dkimHeader = mail.headers.filter((h) => h.key === "dkim-signature");
13
+ if (dkimHeader.length === 0)
14
+ throw new DkimParsingError("No DKIM header found");
15
+ return dkimHeader.map(parseHeader);
16
+ }
17
+ export function parseParams(str) {
18
+ return Object.fromEntries(str.split(";").map((s) => s
19
+ .trim()
20
+ .split("=")
21
+ .map((v) => v && v.trim())));
22
+ }
23
+ function parseHeader(header) {
24
+ const params = parseParams(header.value);
25
+ if (!params) {
26
+ throw new DkimParsingError(`Invalid DKIM header ${header.value}`);
27
+ }
28
+ if (!params.d) {
29
+ throw new DkimParsingError("DKIM header missing domain");
30
+ }
31
+ if (!params.s) {
32
+ throw new DkimParsingError("DKIM header missing selector");
33
+ }
34
+ return {
35
+ domain: params.d,
36
+ selector: params.s,
37
+ };
38
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,91 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { getDkimSigners, parseEmail, parseParams } from "./parseEmail";
3
+ const emailHeaders = `From: "John Doe" <john@d.oe>
4
+ To: "Jane Doe" <jane@d.oe>
5
+ Subject: Hello World
6
+ Date: Thu, 1 Jan 1970 00:00:00 +0000
7
+ `;
8
+ const dkimHeader = "DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; h=from:to:subject; s=selector1; b=abcdef;";
9
+ const body = "Hello, World!";
10
+ const emailFixture = `${emailHeaders}${dkimHeader}\n\n${body}`;
11
+ describe("parseEmail", () => {
12
+ test("should get dkim header from email", async () => { });
13
+ test("correctly parses untrimmed email", async () => {
14
+ const untrimmed = `\n ${emailFixture} \n`;
15
+ const email = await parseEmail(untrimmed);
16
+ expect(email.headers.find((h) => h.key === "dkim-signature")).toBeDefined();
17
+ });
18
+ test("works well with multiple dkim headers", async () => {
19
+ const dkimHeader2 = "DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=second.signer; h=from:to:subject; s=selector2; b=abcdef;";
20
+ const email = await parseEmail(`${emailHeaders}${dkimHeader}\n${dkimHeader2}\n\n${body}`);
21
+ const dkim = email.headers.filter((h) => h.key === "dkim-signature");
22
+ expect(dkim).toHaveLength(2);
23
+ expect(parseParams(dkim[0].value).s).toBe("selector1");
24
+ expect(parseParams(dkim[1].value).s).toBe("selector2");
25
+ });
26
+ });
27
+ describe("getDkimSigners", () => {
28
+ test("should get dkim signers from email", async () => {
29
+ const email = await parseEmail(emailFixture);
30
+ const dkim = getDkimSigners(email);
31
+ expect(dkim).toHaveLength(1);
32
+ expect(dkim[0].domain).toBe("example.com");
33
+ expect(dkim[0].selector).toBe("selector1");
34
+ });
35
+ test("should get multiple dkim signers from email", async () => {
36
+ const dkimHeader2 = "DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=second.signer; h=from:to:subject; s=selector2; b=abcdef;";
37
+ const email = await parseEmail(`${emailHeaders}${dkimHeader}\n${dkimHeader2}\n\n${body}`);
38
+ const dkim = getDkimSigners(email);
39
+ expect(dkim).toHaveLength(2);
40
+ expect(dkim[0].domain).toBe("example.com");
41
+ expect(dkim[0].selector).toBe("selector1");
42
+ expect(dkim[1].domain).toBe("second.signer");
43
+ expect(dkim[1].selector).toBe("selector2");
44
+ });
45
+ test("should throw if no dkim header found", async () => {
46
+ const email = await parseEmail(emailHeaders);
47
+ expect(() => getDkimSigners(email)).toThrowError("No DKIM header found");
48
+ });
49
+ test("should throw if dkim header is invalid", async () => {
50
+ const email = await parseEmail(`${emailHeaders}DKIM-Signature: invalid\n\n${body}`);
51
+ expect(() => getDkimSigners(email)).toThrowError("DKIM header missing domain");
52
+ });
53
+ test("should throw if dkim header is missing domain", async () => {
54
+ const email = await parseEmail(`${emailHeaders}DKIM-Signature: v=1; s=selector\n\n${body}`);
55
+ expect(() => getDkimSigners(email)).toThrowError("DKIM header missing domain");
56
+ });
57
+ test("should throw if dkim header is missing selector", async () => {
58
+ const email = await parseEmail(`${emailHeaders}DKIM-Signature: v=1; d=example.com\n\n${body}`);
59
+ expect(() => getDkimSigners(email)).toThrowError("DKIM header missing selector");
60
+ });
61
+ });
62
+ describe("parseParams", () => {
63
+ test("should parse single parameter", () => {
64
+ const params = parseParams("a=b");
65
+ expect(params).toEqual({ a: "b" });
66
+ });
67
+ test("should parse multiple parameters", () => {
68
+ const params = parseParams("a=b; c=d; e=f");
69
+ expect(params).toEqual({ a: "b", c: "d", e: "f" });
70
+ });
71
+ test("should trim spaces around parameters", () => {
72
+ const params = parseParams(" a = b ; c = d ; e = f ");
73
+ expect(params).toEqual({ a: "b", c: "d", e: "f" });
74
+ });
75
+ test("should handle empty values", () => {
76
+ const params = parseParams("a=; b=c");
77
+ expect(params).toEqual({ a: "", b: "c" });
78
+ });
79
+ test("should handle missing values", () => {
80
+ const params = parseParams("a; b=c");
81
+ expect(params).toEqual({ a: undefined, b: "c" });
82
+ });
83
+ test("should handle empty string", () => {
84
+ const params = parseParams("");
85
+ expect(params).toEqual({});
86
+ });
87
+ test("should handle parameters with extra semicolons", () => {
88
+ const params = parseParams("a=b;; c=d;");
89
+ expect(params).toEqual({ a: "b", c: "d" });
90
+ });
91
+ });
@@ -0,0 +1,4 @@
1
+ export declare function preverifyEmail(mimeEmail: string): Promise<{
2
+ email: string;
3
+ dnsRecords: string[];
4
+ }>;
@@ -0,0 +1,18 @@
1
+ import { parseEmail, getDkimSigners } from "./parseEmail";
2
+ import { resolveDkimDns } from "./dnsResolver";
3
+ export async function preverifyEmail(mimeEmail) {
4
+ const parsedEmail = await parseEmail(mimeEmail);
5
+ const signers = getDkimSigners(parsedEmail);
6
+ if (signers.length === 0) {
7
+ throw new Error("No DKIM header found");
8
+ }
9
+ if (signers.length > 1) {
10
+ throw new Error("Multiple DKIM headers found");
11
+ }
12
+ const [{ domain, selector }] = signers;
13
+ const dnsRecord = await resolveDkimDns(domain, selector);
14
+ return {
15
+ email: mimeEmail,
16
+ dnsRecords: [dnsRecord],
17
+ };
18
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { preverifyEmail } from "./preverify";
3
+ import { readFile } from "../../testHelpers/readFile";
4
+ describe("Preverify email: integration", () => {
5
+ test("adds dns record to email mime", async () => {
6
+ const rawEmail = readFile("./src/api/email/testdata/test_email.txt");
7
+ const preverifiedEmail = await preverifyEmail(rawEmail);
8
+ expect(preverifiedEmail).toMatchObject({
9
+ email: rawEmail,
10
+ dnsRecords: [expect.stringContaining("v=DKIM1; k=rsa; p=")],
11
+ });
12
+ });
13
+ test("throws error if DKIM not found", async () => {
14
+ const emailWithNoDkimHeader = 'From: "Alice"\n\nBody';
15
+ await expect(preverifyEmail(emailWithNoDkimHeader)).rejects.toThrow("No DKIM header found");
16
+ });
17
+ test("throws error if DNS could not be resolved", async () => {
18
+ const emailWithNoDkimHeader = readFile("./src/api/email/testdata/test_email_unknown_domain.txt");
19
+ await expect(preverifyEmail(emailWithNoDkimHeader)).rejects.toThrow();
20
+ });
21
+ test("throws error if multiple DNS records found", async () => {
22
+ const emailWithNoDkimHeader = readFile("./src/api/email/testdata/test_email_multiple_dkims.txt");
23
+ await expect(preverifyEmail(emailWithNoDkimHeader)).rejects.toThrow("Multiple DKIM headers found");
24
+ });
25
+ });
@@ -0,0 +1,38 @@
1
+ import { type Abi, type Address, type Chain, type ContractFunctionArgs, type ContractFunctionName, type Hex, PublicClient, walletActions } from "viem";
2
+ import type { ContractSpec, ContractArg } from "types/ethereum";
3
+ export declare const chainIds: 31337[];
4
+ export declare function createAnvilClient(chainId?: number): ReturnType<typeof walletActions> & PublicClient;
5
+ export declare function deployContract(contractSpec: ContractSpec, args?: ContractArg[], chainId?: number): Promise<Address>;
6
+ type DeploySpec<T extends Abi> = {
7
+ abi: T;
8
+ bytecode: {
9
+ object: Hex;
10
+ };
11
+ };
12
+ type Tail<T> = T extends readonly [unknown, ...infer U] ? U : [];
13
+ export declare function deployProverVerifier<P extends Abi, V extends Abi>(proverSpec: DeploySpec<P>, verifierSpec: DeploySpec<V>, args?: {
14
+ prover?: ContractArg[];
15
+ verifier?: Tail<ContractArg>[];
16
+ }, chainId?: number): Promise<`0x${string}`[]>;
17
+ export declare function call<T extends Abi, F extends ContractFunctionName<T, "pure" | "view">>(abi: T, address: Address, functionName: F, args?: ContractFunctionArgs<T, "pure" | "view", F>, chainId?: number): Promise<import("viem").ContractFunctionReturnType<T, "pure" | "view", F, ContractFunctionArgs<T, "pure" | "view", F>>>;
18
+ export declare function writeContract<T extends Abi, F extends ContractFunctionName<T, "payable" | "nonpayable">>(address: Address, abi: T, functionName: F, args: ContractFunctionArgs<T, "payable" | "nonpayable", F>, sender?: Address, chain?: Chain): Promise<import("viem").TransactionReceipt>;
19
+ export declare const getTestAccount: () => {
20
+ address: Address;
21
+ nonceManager?: import("viem").NonceManager | undefined;
22
+ sign: (parameters: {
23
+ hash: import("viem").Hash;
24
+ }) => Promise<Hex>;
25
+ experimental_signAuthorization: (parameters: import("viem/experimental").Authorization) => Promise<import("viem/accounts").SignAuthorizationReturnType>;
26
+ signMessage: ({ message }: {
27
+ message: import("viem").SignableMessage;
28
+ }) => Promise<Hex>;
29
+ signTransaction: <serializer extends import("viem").SerializeTransactionFn<import("viem").TransactionSerializable> = import("viem").SerializeTransactionFn<import("viem").TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
30
+ serializer?: serializer | undefined;
31
+ } | undefined) => Promise<import("viem").IsNarrowable<import("viem").TransactionSerialized<import("viem").GetTransactionType<transaction>>, Hex> extends true ? import("viem").TransactionSerialized<import("viem").GetTransactionType<transaction>> : Hex>;
32
+ signTypedData: <const typedData extends import("viem").TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: import("viem").TypedDataDefinition<typedData, primaryType>) => Promise<Hex>;
33
+ publicKey: Hex;
34
+ source: "privateKey";
35
+ type: "local";
36
+ };
37
+ export declare const getTestAddresses: (chainId?: number) => Promise<Address[]>;
38
+ export {};
@@ -0,0 +1,72 @@
1
+ import { createTestClient, http, publicActions, walletActions, } from "viem";
2
+ import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
3
+ import { foundry } from "viem/chains";
4
+ const rpcUrls = new Map([[foundry.id, http()]]);
5
+ export const chainIds = [foundry.id];
6
+ export function createAnvilClient(chainId = foundry.id) {
7
+ const transport = rpcUrls.get(chainId);
8
+ if (transport == undefined) {
9
+ throw Error(`No url for chainId ${chainId}`);
10
+ }
11
+ return createTestClient({
12
+ chain: foundry,
13
+ mode: "anvil",
14
+ transport: transport,
15
+ })
16
+ .extend(publicActions)
17
+ .extend(walletActions);
18
+ }
19
+ export async function deployContract(contractSpec, args = [], chainId = foundry.id) {
20
+ const ethClient = createAnvilClient(chainId);
21
+ const [deployer] = await ethClient.getAddresses();
22
+ const txHash = await ethClient.deployContract({
23
+ abi: contractSpec.abi,
24
+ bytecode: contractSpec.bytecode.object,
25
+ account: deployer,
26
+ args,
27
+ chain: foundry,
28
+ });
29
+ const receipt = await ethClient.waitForTransactionReceipt({ hash: txHash });
30
+ if (receipt.status != "success") {
31
+ throw new Error(`Contract deployment failed with status: ${receipt.status}`);
32
+ }
33
+ return receipt.contractAddress;
34
+ }
35
+ export async function deployProverVerifier(proverSpec, verifierSpec, args = {}, chainId = foundry.id) {
36
+ console.log("Deploying prover");
37
+ const proverAddress = await deployContract(proverSpec, args.prover ?? [], chainId);
38
+ console.log(`Prover has been deployed on ${proverAddress} address`);
39
+ console.log("Deploying verifier");
40
+ const verifierAddress = await deployContract(verifierSpec, [proverAddress, ...(args.verifier ?? [])], chainId);
41
+ console.log(`Verifier has been deployed on ${verifierAddress} address`);
42
+ return [proverAddress, verifierAddress];
43
+ }
44
+ export async function call(abi, address, functionName, args, chainId = foundry.id) {
45
+ const ethClient = createAnvilClient(chainId);
46
+ return ethClient.readContract({
47
+ abi,
48
+ address,
49
+ functionName,
50
+ args,
51
+ });
52
+ }
53
+ export async function writeContract(address, abi, functionName, args, sender, chain = foundry) {
54
+ const ethClient = createAnvilClient(chain.id);
55
+ const selectedSender = sender || (await ethClient.getAddresses())[0];
56
+ const txHash = await ethClient.writeContract({
57
+ address,
58
+ abi: abi,
59
+ functionName,
60
+ args: args,
61
+ chain,
62
+ account: selectedSender,
63
+ chainOverride: undefined,
64
+ });
65
+ const txReceipt = await ethClient.waitForTransactionReceipt({ hash: txHash });
66
+ if (txReceipt.status != "success") {
67
+ throw new Error(`Transaction failed with status: ${txReceipt.status}`);
68
+ }
69
+ return txReceipt;
70
+ }
71
+ export const getTestAccount = () => privateKeyToAccount(generatePrivateKey());
72
+ export const getTestAddresses = (chainId = foundry.id) => createAnvilClient(chainId).getAddresses();
@@ -0,0 +1,6 @@
1
+ import { VlayerClient } from "types/vlayer";
2
+ import { WebProofProvider } from "types/webProofProvider";
3
+ export declare const createVlayerClient: ({ url, webProofProvider, }?: {
4
+ url?: string;
5
+ webProofProvider?: WebProofProvider;
6
+ }) => VlayerClient;
@@ -0,0 +1,45 @@
1
+ import { prove } from "../prover";
2
+ import { createExtensionWebProofProvider } from "../webProof";
3
+ import { decodeFunctionResult } from "viem";
4
+ function dropEmptyProofFromArgs(args) {
5
+ if (Array.isArray(args)) {
6
+ return args.slice(1);
7
+ }
8
+ return [];
9
+ }
10
+ function generateRandomHash() {
11
+ let hash = "0x";
12
+ for (let i = 0; i < 40; ++i) {
13
+ hash += Math.floor(Math.random() * 16).toString(16);
14
+ }
15
+ return hash;
16
+ }
17
+ export const createVlayerClient = ({ url = "http://127.0.0.1:3000", webProofProvider = createExtensionWebProofProvider(), } = {
18
+ url: "http://127.0.0.1:3000",
19
+ webProofProvider: createExtensionWebProofProvider(),
20
+ }) => {
21
+ console.log("createVlayerClient with", url, webProofProvider);
22
+ const resultHashMap = new Map();
23
+ return {
24
+ // eslint-disable-next-line @typescript-eslint/require-await
25
+ prove: async ({ address, functionName, chainId, proverAbi, args }) => {
26
+ const result_promise = prove(address, proverAbi, functionName, args, chainId, url);
27
+ const hash = generateRandomHash();
28
+ resultHashMap.set(hash, [result_promise, proverAbi, functionName]);
29
+ return { hash };
30
+ },
31
+ waitForProvingResult: async ({ hash }) => {
32
+ const savedProvingData = resultHashMap.get(hash);
33
+ if (!savedProvingData) {
34
+ throw new Error("No result found for hash " + hash);
35
+ }
36
+ const { result: { proof, evm_call_result }, } = await savedProvingData[0];
37
+ const result = dropEmptyProofFromArgs(decodeFunctionResult({
38
+ abi: savedProvingData[1],
39
+ data: evm_call_result,
40
+ functionName: savedProvingData[2],
41
+ }));
42
+ return [proof, ...result];
43
+ },
44
+ };
45
+ };
@@ -0,0 +1,14 @@
1
+ import { Abi, Address, Hex } from "viem";
2
+ import { Branded } from "../../../web-proof-commons";
3
+ export type Bytecode = {
4
+ object: Hex;
5
+ };
6
+ export type ContractSpec = {
7
+ abi: Abi;
8
+ bytecode: Bytecode;
9
+ };
10
+ export type ContractArg = number | string | boolean | bigint | number[] | string[] | boolean[] | bigint[] | Address[];
11
+ export type EthereumAddress = Branded<Hex, "EthereumAddress">;
12
+ export type EthereumTxHash = Branded<Hex, "EthereumTxHash">;
13
+ export declare function assertEthereumAddress(hash: string): asserts hash is EthereumAddress;
14
+ export declare function assertEthereumTxHash(hash: string): asserts hash is EthereumTxHash;
@@ -0,0 +1,12 @@
1
+ export function assertEthereumAddress(hash) {
2
+ const regex = /^(0x)?[0-9a-fA-F]{40}$/;
3
+ if (!regex.test(hash)) {
4
+ throw new Error(`Invalid ethereum account ${hash}`);
5
+ }
6
+ }
7
+ export function assertEthereumTxHash(hash) {
8
+ const regex = /^(0x)?[0-9a-fA-F]{64}$/;
9
+ if (!regex.test(hash)) {
10
+ throw new Error(`Invalid ethereum tx hash ${hash}`);
11
+ }
12
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./ethereum";
2
+ export * from "./vlayer";
3
+ export * from "./webProofProvider";
@@ -0,0 +1,8 @@
1
+ import { Abi, ContractFunctionName } from "viem";
2
+ import { AbiParametersToPrimitiveTypes, ExtractAbiFunction } from "abitype";
3
+ type Without<T extends readonly unknown[], P> = T extends readonly [
4
+ infer F,
5
+ ...infer R
6
+ ] ? F extends P ? Without<R, P> : readonly [F, ...Without<R, P>] : [];
7
+ export type ContractFunctionArgsWithout<abi extends Abi, functionName extends ContractFunctionName<abi>, without> = AbiParametersToPrimitiveTypes<Without<ExtractAbiFunction<abi extends Abi ? abi : Abi, functionName>["inputs"], without>, "inputs"> extends infer args ? [args] extends [never] ? readonly unknown[] : args : readonly unknown[];
8
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,47 @@
1
+ import { Abi, AbiStateMutability, Address, ContractFunctionArgs, ContractFunctionName, Hex } from "viem";
2
+ type Calldata = string;
3
+ export type CallParams = {
4
+ to: Address;
5
+ data: Calldata;
6
+ };
7
+ export type CallContext = {
8
+ chain_id: number;
9
+ };
10
+ export type Proof = {
11
+ length: bigint;
12
+ seal: {
13
+ verifierSelector: Hex;
14
+ seal: readonly [Hex, Hex, Hex, Hex, Hex, Hex, Hex, Hex];
15
+ mode: number;
16
+ };
17
+ callAssumptions: {
18
+ proverContractAddress: Address;
19
+ functionSelector: Hex;
20
+ settleBlockHash: Hex;
21
+ settleBlockNumber: bigint;
22
+ };
23
+ };
24
+ export interface VCallResult {
25
+ evm_call_result: Hex;
26
+ proof: Proof;
27
+ }
28
+ export interface VCallResponse {
29
+ jsonrpc: string;
30
+ result: VCallResult;
31
+ id: number;
32
+ }
33
+ export type VlayerClient = {
34
+ prove: <T extends Abi, F extends ContractFunctionName<T>>(args: {
35
+ address: Hex;
36
+ proverAbi: T;
37
+ functionName: F;
38
+ chainId: number;
39
+ args: ContractFunctionArgs<T, AbiStateMutability, F>;
40
+ }) => Promise<{
41
+ hash: string;
42
+ }>;
43
+ waitForProvingResult: ({ hash, }: {
44
+ hash: string;
45
+ }) => Promise<[Proof, ...unknown[]]>;
46
+ };
47
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,29 @@
1
+ import { Hex, Abi, ContractFunctionName } from "viem";
2
+ import type { ContractFunctionArgsWithout } from "./viem";
3
+ import { Branded, WebProof, WebProofStep } from "../../../web-proof-commons";
4
+ export type WebProofSetupInput = {
5
+ logoUrl: string;
6
+ steps: WebProofStep[];
7
+ };
8
+ export type WebProofSetup = Branded<WebProofSetupInput & {
9
+ isWebProof: true;
10
+ }, "webProof">;
11
+ export type ProverCallCommitment<T extends Abi, F extends ContractFunctionName<T>> = {
12
+ address: Hex;
13
+ proverAbi: T;
14
+ functionName: F;
15
+ commitmentArgs: ContractFunctionArgsWithout<T, F, {
16
+ name: "webProof";
17
+ }>;
18
+ chainId: number;
19
+ };
20
+ export type GetWebProofArgs<T extends Abi, F extends ContractFunctionName<T>> = {
21
+ proverCallCommitment: ProverCallCommitment<T, F>;
22
+ } & WebProofSetupInput;
23
+ export type WebProofProvider = {
24
+ getWebProof: <T extends Abi, F extends ContractFunctionName<T>>(args: GetWebProofArgs<T, F>) => Promise<WebProof>;
25
+ };
26
+ export type WebProofProviderSetup = {
27
+ notaryUrl?: string;
28
+ wsProxyUrl?: string;
29
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import { type Abi, AbiStateMutability, type Address, ContractFunctionArgs, ContractFunctionName } from "viem";
2
+ export declare function prove<T extends Abi, F extends ContractFunctionName<T>>(prover: Address, abi: T, functionName: F, args: ContractFunctionArgs<T, AbiStateMutability, F>, chainId?: number, url?: string): Promise<import("types/vlayer").VCallResponse>;
@@ -0,0 +1,15 @@
1
+ import { encodeFunctionData, } from "viem";
2
+ import { v_call } from "./v_call";
3
+ import { foundry } from "viem/chains";
4
+ export async function prove(prover, abi, functionName, args, chainId = foundry.id, url = "http://127.0.0.1:3000") {
5
+ const calldata = encodeFunctionData({
6
+ abi: abi,
7
+ functionName: functionName,
8
+ args: args,
9
+ });
10
+ const call = { to: prover, data: calldata };
11
+ const context = {
12
+ chain_id: chainId,
13
+ };
14
+ return v_call(call, context, url);
15
+ }
@@ -0,0 +1,2 @@
1
+ import { CallContext, CallParams, VCallResponse } from "types/vlayer";
2
+ export declare function v_call(call: CallParams, context: CallContext, url?: string): Promise<VCallResponse>;
@@ -0,0 +1,30 @@
1
+ function v_callBody(call, context) {
2
+ return {
3
+ method: "v_call",
4
+ params: [call, context],
5
+ id: 1,
6
+ jsonrpc: "2.0",
7
+ };
8
+ }
9
+ export async function v_call(call, context, url = "http://127.0.0.1:3000") {
10
+ const response = await fetch(url, {
11
+ method: "POST",
12
+ body: JSON.stringify(v_callBody(call, context)),
13
+ headers: { "Content-Type": "application/json" },
14
+ });
15
+ if (!response.ok) {
16
+ throw new Error(`HTTP error! status: ${response.status}`);
17
+ }
18
+ const response_json = await response.json();
19
+ //TODO we should launch some schema validation here
20
+ assertObject(response_json);
21
+ if ("error" in response_json) {
22
+ throw new Error(`Error response: ${response_json.error.message || "unknown error"}`);
23
+ }
24
+ return response_json;
25
+ }
26
+ function assertObject(x) {
27
+ if (typeof x !== "object") {
28
+ throw new Error("Expected object");
29
+ }
30
+ }
@@ -0,0 +1,2 @@
1
+ import { WebProofSetup, WebProofSetupInput } from "types/webProofProvider";
2
+ export declare const createWebProof: ({ logoUrl, steps }: WebProofSetupInput) => WebProofSetup;
@@ -0,0 +1,7 @@
1
+ export const createWebProof = ({ logoUrl, steps }) => {
2
+ return {
3
+ logoUrl,
4
+ steps,
5
+ isWebProof: true,
6
+ };
7
+ };
@@ -0,0 +1,3 @@
1
+ export * from "./createWebProof";
2
+ export * from "./steps";
3
+ export * from "./providers";
@@ -0,0 +1,2 @@
1
+ import { type WebProofProvider, type WebProofProviderSetup } from "../../lib/types/webProofProvider";
2
+ export declare const createExtensionWebProofProvider: ({ notaryUrl, wsProxyUrl, }?: WebProofProviderSetup) => WebProofProvider;
@@ -0,0 +1,32 @@
1
+ // this id is fixed in the extension by the key in manifest.json
2
+ const EXTENSION_ID = "jbchhcgphfokabmfacnkafoeeeppjmpl";
3
+ export const createExtensionWebProofProvider = ({ notaryUrl = "https://notary.pse.dev/v0.1.0-alpha.5/", wsProxyUrl = "wss://notary.pse.dev/proxy", } = {
4
+ notaryUrl: "https://notary.pse.dev/v0.1.0-alpha.5/",
5
+ wsProxyUrl: "wss://notary.pse.dev/proxy",
6
+ }) => {
7
+ return {
8
+ getWebProof: async function (webProofSetup) {
9
+ return new Promise((resolve, reject) => {
10
+ chrome.runtime.sendMessage(EXTENSION_ID, {
11
+ action: 0 /* ExtensionAction.RequestWebProof */,
12
+ payload: {
13
+ notaryUrl,
14
+ wsProxyUrl,
15
+ logoUrl: webProofSetup.logoUrl,
16
+ steps: webProofSetup.steps,
17
+ },
18
+ });
19
+ const port = chrome.runtime.connect(EXTENSION_ID);
20
+ // TODO: validate message in runtime
21
+ port.onMessage.addListener((message) => {
22
+ if (message.type === "ProofDone" /* ExtensionMessageType.ProofDone */) {
23
+ resolve(message.proof);
24
+ }
25
+ if (message.type === "ProofError" /* ExtensionMessageType.ProofError */) {
26
+ reject(new Error(message.error));
27
+ }
28
+ });
29
+ });
30
+ },
31
+ };
32
+ };
@@ -0,0 +1 @@
1
+ export * from "./extension";
@@ -0,0 +1,2 @@
1
+ import { WebProofStepExpectUrl } from "../../../web-proof-commons";
2
+ export declare const expectUrl: (url: string, label: string) => WebProofStepExpectUrl;