@vlayer/sdk 0.1.0-nightly-20241001-f254bee → 0.1.0-nightly-20241002-5b36661
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +4 -4
- 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-5b36661",
|
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
|
},
|
@@ -20,8 +20,8 @@
|
|
20
20
|
},
|
21
21
|
"dependencies": {
|
22
22
|
"dns-over-http-resolver": "^3.0.3",
|
23
|
-
"mailparser": "^3.7.1",
|
24
23
|
"postal-mime": "^2.3.2",
|
25
|
-
"viem": "^2.21.0"
|
24
|
+
"viem": "^2.21.0",
|
25
|
+
"zod": "^3.23.8"
|
26
26
|
}
|
27
27
|
}
|
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 can't assume that developer is using vite
|
35
|
+
// VITE_EXTENSION_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";
|