@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,191 @@
|
|
1
|
+
import { type VlayerClient, type BrandedHash } from "./types/vlayer";
|
2
|
+
import { type WebProofProvider } from "./types/webProofProvider";
|
3
|
+
import { prove, waitForProof } from "../prover";
|
4
|
+
import { createExtensionWebProofProvider } from "../webProof";
|
5
|
+
import {
|
6
|
+
type Abi,
|
7
|
+
type AbiStateMutability,
|
8
|
+
type ContractFunctionArgs,
|
9
|
+
type ContractFunctionName,
|
10
|
+
type ContractFunctionReturnType,
|
11
|
+
decodeFunctionResult,
|
12
|
+
} from "viem";
|
13
|
+
import {
|
14
|
+
ExtensionMessageType,
|
15
|
+
ZkProvingStatus,
|
16
|
+
type PresentationJSON,
|
17
|
+
} from "../../web-proof-commons";
|
18
|
+
import { type ContractFunctionArgsWithout } from "./types/viem";
|
19
|
+
import { type ProveArgs } from "./types/vlayer";
|
20
|
+
|
21
|
+
function dropEmptyProofFromArgs(args: unknown) {
|
22
|
+
if (Array.isArray(args)) {
|
23
|
+
return args.slice(1) as unknown[];
|
24
|
+
}
|
25
|
+
return [];
|
26
|
+
}
|
27
|
+
|
28
|
+
export const createVlayerClient = (
|
29
|
+
{
|
30
|
+
url = "http://127.0.0.1:3000",
|
31
|
+
webProofProvider = createExtensionWebProofProvider(),
|
32
|
+
}: {
|
33
|
+
url?: string;
|
34
|
+
webProofProvider?: WebProofProvider;
|
35
|
+
} = {
|
36
|
+
url: "http://127.0.0.1:3000",
|
37
|
+
webProofProvider: createExtensionWebProofProvider(),
|
38
|
+
},
|
39
|
+
): VlayerClient => {
|
40
|
+
const resultHashMap = new Map<string, [Abi, string]>();
|
41
|
+
|
42
|
+
return {
|
43
|
+
prove: async <T extends Abi, F extends ContractFunctionName<T>>({
|
44
|
+
address,
|
45
|
+
proverAbi,
|
46
|
+
functionName,
|
47
|
+
chainId,
|
48
|
+
gasLimit,
|
49
|
+
token,
|
50
|
+
args,
|
51
|
+
}: ProveArgs<T, F>) => {
|
52
|
+
webProofProvider.notifyZkProvingStatus(ZkProvingStatus.Proving);
|
53
|
+
|
54
|
+
const hash = await prove(
|
55
|
+
address,
|
56
|
+
proverAbi,
|
57
|
+
functionName,
|
58
|
+
args,
|
59
|
+
chainId,
|
60
|
+
url,
|
61
|
+
gasLimit,
|
62
|
+
token,
|
63
|
+
).catch((e) => {
|
64
|
+
webProofProvider.notifyZkProvingStatus(ZkProvingStatus.Error);
|
65
|
+
throw e;
|
66
|
+
});
|
67
|
+
|
68
|
+
resultHashMap.set(hash.hash, [proverAbi, functionName]);
|
69
|
+
return hash;
|
70
|
+
},
|
71
|
+
|
72
|
+
waitForProvingResult: async <
|
73
|
+
T extends Abi,
|
74
|
+
F extends ContractFunctionName<T>,
|
75
|
+
>({
|
76
|
+
hash,
|
77
|
+
numberOfRetries = 240,
|
78
|
+
sleepDuration = 1000,
|
79
|
+
}: {
|
80
|
+
hash: BrandedHash<T, F>;
|
81
|
+
numberOfRetries?: number;
|
82
|
+
sleepDuration?: number;
|
83
|
+
}): Promise<ContractFunctionReturnType<T, AbiStateMutability, F>> => {
|
84
|
+
try {
|
85
|
+
const { data } = await waitForProof(
|
86
|
+
hash,
|
87
|
+
url,
|
88
|
+
numberOfRetries,
|
89
|
+
sleepDuration,
|
90
|
+
);
|
91
|
+
const savedProvingData = resultHashMap.get(hash.hash);
|
92
|
+
if (!savedProvingData) {
|
93
|
+
throw new Error("No result found for hash " + hash.hash);
|
94
|
+
}
|
95
|
+
const [proverAbi, functionName] = savedProvingData;
|
96
|
+
|
97
|
+
const result = dropEmptyProofFromArgs(
|
98
|
+
decodeFunctionResult({
|
99
|
+
abi: proverAbi,
|
100
|
+
data: data.evm_call_result,
|
101
|
+
functionName,
|
102
|
+
}),
|
103
|
+
);
|
104
|
+
|
105
|
+
webProofProvider.notifyZkProvingStatus(ZkProvingStatus.Done);
|
106
|
+
|
107
|
+
return [data.proof, ...result] as ContractFunctionReturnType<
|
108
|
+
T,
|
109
|
+
AbiStateMutability,
|
110
|
+
F
|
111
|
+
>;
|
112
|
+
} catch (e) {
|
113
|
+
webProofProvider.notifyZkProvingStatus(ZkProvingStatus.Error);
|
114
|
+
throw e;
|
115
|
+
}
|
116
|
+
},
|
117
|
+
|
118
|
+
proveWeb: async function ({
|
119
|
+
address,
|
120
|
+
proverAbi,
|
121
|
+
functionName,
|
122
|
+
chainId,
|
123
|
+
gasLimit,
|
124
|
+
token,
|
125
|
+
args,
|
126
|
+
}) {
|
127
|
+
const webProofPlaceholder = args[0];
|
128
|
+
const commitmentArgs = args.slice(1) as ContractFunctionArgsWithout<
|
129
|
+
typeof proverAbi,
|
130
|
+
typeof functionName,
|
131
|
+
{ name: "webProof" }
|
132
|
+
>;
|
133
|
+
|
134
|
+
const webProofPromise: Promise<{
|
135
|
+
presentationJSON: PresentationJSON;
|
136
|
+
decodedTranscript: {
|
137
|
+
sent: string;
|
138
|
+
recv: string;
|
139
|
+
};
|
140
|
+
}> = new Promise((resolve, reject) => {
|
141
|
+
webProofProvider.addEventListeners(
|
142
|
+
ExtensionMessageType.ProofDone,
|
143
|
+
({ payload: { presentationJSON, decodedTranscript } }) => {
|
144
|
+
resolve({ presentationJSON, decodedTranscript });
|
145
|
+
},
|
146
|
+
);
|
147
|
+
|
148
|
+
webProofProvider.addEventListeners(
|
149
|
+
ExtensionMessageType.ProofError,
|
150
|
+
({ payload: { error } }) => {
|
151
|
+
reject(new Error(error));
|
152
|
+
},
|
153
|
+
);
|
154
|
+
});
|
155
|
+
|
156
|
+
webProofProvider.requestWebProof({
|
157
|
+
proverCallCommitment: {
|
158
|
+
address,
|
159
|
+
proverAbi,
|
160
|
+
functionName,
|
161
|
+
commitmentArgs,
|
162
|
+
chainId,
|
163
|
+
},
|
164
|
+
logoUrl: webProofPlaceholder.logoUrl,
|
165
|
+
steps: webProofPlaceholder.steps,
|
166
|
+
});
|
167
|
+
|
168
|
+
const webProof = await webProofPromise;
|
169
|
+
|
170
|
+
const hash = await this.prove({
|
171
|
+
address,
|
172
|
+
functionName,
|
173
|
+
chainId,
|
174
|
+
gasLimit,
|
175
|
+
proverAbi,
|
176
|
+
token,
|
177
|
+
args: [
|
178
|
+
{
|
179
|
+
webProofJson: JSON.stringify(webProof.presentationJSON),
|
180
|
+
},
|
181
|
+
...commitmentArgs,
|
182
|
+
] as ContractFunctionArgs<
|
183
|
+
typeof proverAbi,
|
184
|
+
AbiStateMutability,
|
185
|
+
typeof functionName
|
186
|
+
>,
|
187
|
+
});
|
188
|
+
return hash;
|
189
|
+
},
|
190
|
+
};
|
191
|
+
};
|
@@ -0,0 +1,19 @@
|
|
1
|
+
export class VersionError extends Error {
|
2
|
+
constructor(message: string) {
|
3
|
+
super(message);
|
4
|
+
this.name = "VersionError";
|
5
|
+
}
|
6
|
+
}
|
7
|
+
|
8
|
+
export function parseVCallResponseError({
|
9
|
+
message,
|
10
|
+
}: {
|
11
|
+
message: string | undefined;
|
12
|
+
}): Error {
|
13
|
+
if (message?.startsWith("Unsupported CallGuestID")) {
|
14
|
+
return new VersionError(`${message}
|
15
|
+
vlayer uses the daily release cycle, and SDK version must match the proving server version.
|
16
|
+
Please run "vlayer update" to update the SDK to the latest version.`);
|
17
|
+
}
|
18
|
+
return new Error(`Error response: ${message ?? "unknown error"}`);
|
19
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import { type Abi, type Address, type Hex } from "viem";
|
2
|
+
import { type Branded } from "../../../web-proof-commons";
|
3
|
+
|
4
|
+
export type Bytecode = {
|
5
|
+
object: Hex;
|
6
|
+
};
|
7
|
+
|
8
|
+
export type ContractSpec = {
|
9
|
+
abi: Abi;
|
10
|
+
bytecode: Bytecode;
|
11
|
+
};
|
12
|
+
|
13
|
+
export type ContractArg =
|
14
|
+
| number
|
15
|
+
| string
|
16
|
+
| boolean
|
17
|
+
| bigint
|
18
|
+
| number[]
|
19
|
+
| string[]
|
20
|
+
| boolean[]
|
21
|
+
| bigint[]
|
22
|
+
| Address[]
|
23
|
+
| (string | bigint)[]
|
24
|
+
| (string | bigint)[][];
|
25
|
+
|
26
|
+
export type EthereumAddress = Branded<Hex, "EthereumAddress">;
|
27
|
+
export type EthereumTxHash = Branded<Hex, "EthereumTxHash">;
|
28
|
+
|
29
|
+
export function assertEthereumAddress(
|
30
|
+
hash: string,
|
31
|
+
): asserts hash is EthereumAddress {
|
32
|
+
const regex = /^(0x)?[0-9a-fA-F]{40}$/;
|
33
|
+
if (!regex.test(hash)) {
|
34
|
+
throw new Error(`Invalid ethereum account ${hash}`);
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
export function assertEthereumTxHash(
|
39
|
+
hash: string,
|
40
|
+
): asserts hash is EthereumTxHash {
|
41
|
+
const regex = /^(0x)?[0-9a-fA-F]{64}$/;
|
42
|
+
if (!regex.test(hash)) {
|
43
|
+
throw new Error(`Invalid ethereum tx hash ${hash}`);
|
44
|
+
}
|
45
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { type Abi, type ContractFunctionName } from "viem";
|
2
|
+
import {
|
3
|
+
type AbiParametersToPrimitiveTypes,
|
4
|
+
type ExtractAbiFunction,
|
5
|
+
} from "abitype";
|
6
|
+
|
7
|
+
type Without<T extends readonly unknown[], P> = T extends readonly [
|
8
|
+
infer F,
|
9
|
+
...infer R,
|
10
|
+
]
|
11
|
+
? F extends P
|
12
|
+
? Without<R, P>
|
13
|
+
: readonly [F, ...Without<R, P>]
|
14
|
+
: [];
|
15
|
+
|
16
|
+
export type ContractFunctionArgsWithout<
|
17
|
+
abi extends Abi,
|
18
|
+
functionName extends ContractFunctionName<abi>,
|
19
|
+
without,
|
20
|
+
> = AbiParametersToPrimitiveTypes<
|
21
|
+
Without<
|
22
|
+
ExtractAbiFunction<abi extends Abi ? abi : Abi, functionName>["inputs"],
|
23
|
+
without
|
24
|
+
>,
|
25
|
+
"inputs"
|
26
|
+
>;
|
@@ -0,0 +1,156 @@
|
|
1
|
+
import { type Branded } from "../../../web-proof-commons/utils";
|
2
|
+
import {
|
3
|
+
type Abi,
|
4
|
+
type AbiStateMutability,
|
5
|
+
type Address,
|
6
|
+
type ContractFunctionArgs,
|
7
|
+
type ContractFunctionName,
|
8
|
+
type ContractFunctionReturnType,
|
9
|
+
type Hex,
|
10
|
+
} from "viem";
|
11
|
+
import { type WebProofRequest } from "./webProofProvider";
|
12
|
+
import { type ContractFunctionArgsWithout } from "./viem";
|
13
|
+
import { z } from "zod";
|
14
|
+
|
15
|
+
type Calldata = string;
|
16
|
+
|
17
|
+
export type CallParams = {
|
18
|
+
to: Address;
|
19
|
+
data: Calldata;
|
20
|
+
gas_limit: number;
|
21
|
+
};
|
22
|
+
|
23
|
+
export type CallContext = {
|
24
|
+
chain_id: number;
|
25
|
+
};
|
26
|
+
|
27
|
+
export type BrandedHash<T, F> = Branded<{ hash: string }, [T, F]>;
|
28
|
+
|
29
|
+
export type Proof = {
|
30
|
+
seal: {
|
31
|
+
verifierSelector: Hex;
|
32
|
+
seal: readonly [Hex, Hex, Hex, Hex, Hex, Hex, Hex, Hex];
|
33
|
+
mode: number;
|
34
|
+
};
|
35
|
+
callGuestId: Hex;
|
36
|
+
length: bigint;
|
37
|
+
callAssumptions: {
|
38
|
+
proverContractAddress: Address;
|
39
|
+
functionSelector: Hex;
|
40
|
+
settleBlockHash: Hex;
|
41
|
+
settleBlockNumber: bigint;
|
42
|
+
};
|
43
|
+
};
|
44
|
+
|
45
|
+
export type VCallResult = Hex;
|
46
|
+
|
47
|
+
export interface VCallResponse {
|
48
|
+
jsonrpc: string;
|
49
|
+
result: VCallResult;
|
50
|
+
id: number;
|
51
|
+
}
|
52
|
+
|
53
|
+
export type VGetProofReceiptParams = {
|
54
|
+
hash: Hex;
|
55
|
+
};
|
56
|
+
|
57
|
+
export enum ProofState {
|
58
|
+
Queued = "queued",
|
59
|
+
ChainProof = "chain_proof",
|
60
|
+
Preflight = "preflight",
|
61
|
+
Proving = "proving",
|
62
|
+
Done = "done",
|
63
|
+
}
|
64
|
+
|
65
|
+
export type ProofData = {
|
66
|
+
evm_call_result: Hex;
|
67
|
+
proof: Proof;
|
68
|
+
};
|
69
|
+
|
70
|
+
export type Metrics = {
|
71
|
+
gas: number;
|
72
|
+
cycles: number;
|
73
|
+
times: {
|
74
|
+
preflight: number;
|
75
|
+
proving: number;
|
76
|
+
};
|
77
|
+
};
|
78
|
+
|
79
|
+
export type ProofDataWithMetrics = {
|
80
|
+
data: ProofData;
|
81
|
+
metrics: Metrics;
|
82
|
+
};
|
83
|
+
|
84
|
+
export type ProveArgs<T extends Abi, F extends ContractFunctionName<T>> = {
|
85
|
+
address: Hex;
|
86
|
+
proverAbi: T;
|
87
|
+
functionName: F;
|
88
|
+
chainId?: number;
|
89
|
+
gasLimit?: number;
|
90
|
+
token?: string;
|
91
|
+
args: ContractFunctionArgs<T, AbiStateMutability, F>;
|
92
|
+
};
|
93
|
+
|
94
|
+
export type VlayerClient = {
|
95
|
+
prove: <T extends Abi, F extends ContractFunctionName<T>>(
|
96
|
+
args: ProveArgs<T, F>,
|
97
|
+
) => Promise<BrandedHash<T, F>>;
|
98
|
+
|
99
|
+
waitForProvingResult: <
|
100
|
+
T extends Abi,
|
101
|
+
F extends ContractFunctionName<T>,
|
102
|
+
>(args: {
|
103
|
+
hash: BrandedHash<T, F>;
|
104
|
+
numberOfRetries?: number;
|
105
|
+
sleepDuration?: number;
|
106
|
+
}) => Promise<ContractFunctionReturnType<T, AbiStateMutability, F>>;
|
107
|
+
|
108
|
+
proveWeb: <T extends Abi, F extends ContractFunctionName<T>>(args: {
|
109
|
+
address: Hex;
|
110
|
+
proverAbi: T;
|
111
|
+
functionName: F;
|
112
|
+
chainId: number;
|
113
|
+
gasLimit?: number;
|
114
|
+
token?: string;
|
115
|
+
args: [
|
116
|
+
WebProofRequest,
|
117
|
+
...ContractFunctionArgsWithout<T, F, { name: "webProof" }>,
|
118
|
+
];
|
119
|
+
}) => Promise<BrandedHash<T, F>>;
|
120
|
+
};
|
121
|
+
|
122
|
+
export const proofReceiptSchema = z.discriminatedUnion("status", [
|
123
|
+
z.object({
|
124
|
+
status: z.literal(0),
|
125
|
+
error: z.string(),
|
126
|
+
data: z.undefined(),
|
127
|
+
metrics: z.custom<Metrics>(),
|
128
|
+
state: z.enum([
|
129
|
+
ProofState.ChainProof,
|
130
|
+
ProofState.Preflight,
|
131
|
+
ProofState.Proving,
|
132
|
+
]),
|
133
|
+
}),
|
134
|
+
z.object({
|
135
|
+
status: z.literal(1),
|
136
|
+
error: z.undefined(),
|
137
|
+
state: z.enum([
|
138
|
+
ProofState.Done,
|
139
|
+
ProofState.ChainProof,
|
140
|
+
ProofState.Preflight,
|
141
|
+
ProofState.Proving,
|
142
|
+
ProofState.Queued,
|
143
|
+
]),
|
144
|
+
data: z.custom<ProofData>(),
|
145
|
+
metrics: z.custom<Metrics>(),
|
146
|
+
}),
|
147
|
+
]);
|
148
|
+
|
149
|
+
export const vGetProofReceiptSchema = z.object({
|
150
|
+
jsonrpc: z.string(),
|
151
|
+
result: proofReceiptSchema,
|
152
|
+
id: z.number(),
|
153
|
+
});
|
154
|
+
|
155
|
+
export type ProofReceipt = z.infer<typeof proofReceiptSchema>;
|
156
|
+
export type VGetProofReceiptResponse = z.infer<typeof vGetProofReceiptSchema>;
|
@@ -0,0 +1,68 @@
|
|
1
|
+
import { type Hex, type Abi, type ContractFunctionName } from "viem";
|
2
|
+
import type { ContractFunctionArgsWithout } from "./viem";
|
3
|
+
import {
|
4
|
+
type Branded,
|
5
|
+
type ExtensionMessageType,
|
6
|
+
type ExtensionMessage,
|
7
|
+
type PresentationJSON,
|
8
|
+
type WebProofStep,
|
9
|
+
type ZkProvingStatus,
|
10
|
+
} from "../../../web-proof-commons";
|
11
|
+
|
12
|
+
export type WebProofRequestInput = {
|
13
|
+
logoUrl: string;
|
14
|
+
steps: WebProofStep[];
|
15
|
+
};
|
16
|
+
|
17
|
+
export type WebProofRequest = Branded<
|
18
|
+
WebProofRequestInput & {
|
19
|
+
isWebProof: true;
|
20
|
+
},
|
21
|
+
"webProof"
|
22
|
+
>;
|
23
|
+
|
24
|
+
export type ProverCallCommitment<
|
25
|
+
T extends Abi,
|
26
|
+
F extends ContractFunctionName<T>,
|
27
|
+
> = {
|
28
|
+
address: Hex;
|
29
|
+
proverAbi: T;
|
30
|
+
functionName: F;
|
31
|
+
commitmentArgs: ContractFunctionArgsWithout<T, F, { name: "webProof" }>;
|
32
|
+
chainId: number;
|
33
|
+
};
|
34
|
+
|
35
|
+
export type GetWebProofArgs<
|
36
|
+
T extends Abi,
|
37
|
+
F extends ContractFunctionName<T>,
|
38
|
+
> = {
|
39
|
+
proverCallCommitment: ProverCallCommitment<T, F>;
|
40
|
+
} & WebProofRequestInput;
|
41
|
+
|
42
|
+
export type WebProofProvider = {
|
43
|
+
getWebProof: <T extends Abi, F extends ContractFunctionName<T>>(
|
44
|
+
args: GetWebProofArgs<T, F>,
|
45
|
+
) => Promise<{
|
46
|
+
presentationJSON: PresentationJSON;
|
47
|
+
decodedTranscript: {
|
48
|
+
sent: string;
|
49
|
+
recv: string;
|
50
|
+
};
|
51
|
+
}>;
|
52
|
+
|
53
|
+
requestWebProof: <T extends Abi, F extends ContractFunctionName<T>>(
|
54
|
+
args: GetWebProofArgs<T, F>,
|
55
|
+
) => void;
|
56
|
+
|
57
|
+
notifyZkProvingStatus: (status: ZkProvingStatus) => void;
|
58
|
+
|
59
|
+
addEventListeners: <T extends ExtensionMessageType>(
|
60
|
+
messageType: T,
|
61
|
+
listener: (args: Extract<ExtensionMessage, { type: T }>) => void,
|
62
|
+
) => void;
|
63
|
+
};
|
64
|
+
|
65
|
+
export type WebProofProviderSetup = {
|
66
|
+
notaryUrl?: string;
|
67
|
+
wsProxyUrl?: string;
|
68
|
+
};
|
@@ -0,0 +1,120 @@
|
|
1
|
+
import {
|
2
|
+
type Abi,
|
3
|
+
type AbiStateMutability,
|
4
|
+
type Address,
|
5
|
+
type ContractFunctionArgs,
|
6
|
+
type ContractFunctionName,
|
7
|
+
encodeFunctionData,
|
8
|
+
type Hex,
|
9
|
+
} from "viem";
|
10
|
+
import {
|
11
|
+
type CallContext,
|
12
|
+
type CallParams,
|
13
|
+
type BrandedHash,
|
14
|
+
type ProofDataWithMetrics,
|
15
|
+
type ProofReceipt,
|
16
|
+
ProofState,
|
17
|
+
type VGetProofReceiptParams,
|
18
|
+
type VGetProofReceiptResponse,
|
19
|
+
} from "./lib/types/vlayer";
|
20
|
+
import { match } from "ts-pattern";
|
21
|
+
import { v_call } from "./v_call";
|
22
|
+
import { v_getProofReceipt } from "./v_getProofReceipt";
|
23
|
+
import { foundry } from "viem/chains";
|
24
|
+
import { v_versions } from "./v_versions";
|
25
|
+
import { checkVersionCompatibility } from "./utils/versions";
|
26
|
+
import meta from "../../package.json" with { type: "json" };
|
27
|
+
const sdkVersion = meta.version;
|
28
|
+
|
29
|
+
export interface ProveOptions {
|
30
|
+
preverifyVersions?: boolean;
|
31
|
+
}
|
32
|
+
|
33
|
+
async function preverifyVersions(url: string, shouldPreverify: boolean) {
|
34
|
+
if (shouldPreverify) {
|
35
|
+
const proverVersions = await v_versions(url);
|
36
|
+
checkVersionCompatibility(proverVersions.result.api_version, sdkVersion);
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
export async function prove<T extends Abi, F extends ContractFunctionName<T>>(
|
41
|
+
prover: Address,
|
42
|
+
abi: T,
|
43
|
+
functionName: F,
|
44
|
+
args: ContractFunctionArgs<T, AbiStateMutability, F>,
|
45
|
+
chainId: number = foundry.id,
|
46
|
+
url: string = "http://127.0.0.1:3000",
|
47
|
+
gasLimit: number = 10_000_000,
|
48
|
+
token?: string,
|
49
|
+
options: ProveOptions = { preverifyVersions: false },
|
50
|
+
): Promise<BrandedHash<T, F>> {
|
51
|
+
await preverifyVersions(url, !!options.preverifyVersions);
|
52
|
+
const calldata = encodeFunctionData({
|
53
|
+
abi: abi as Abi,
|
54
|
+
functionName: functionName as string,
|
55
|
+
args: args as readonly unknown[],
|
56
|
+
});
|
57
|
+
const call: CallParams = { to: prover, data: calldata, gas_limit: gasLimit };
|
58
|
+
const context: CallContext = {
|
59
|
+
chain_id: chainId,
|
60
|
+
};
|
61
|
+
const resp = await v_call(call, context, url, token);
|
62
|
+
return { hash: resp.result } as BrandedHash<T, F>;
|
63
|
+
}
|
64
|
+
|
65
|
+
export async function getProofReceipt<
|
66
|
+
T extends Abi,
|
67
|
+
F extends ContractFunctionName<T>,
|
68
|
+
>(
|
69
|
+
hash: BrandedHash<T, F>,
|
70
|
+
url: string = "http://127.0.0.1:3000",
|
71
|
+
): Promise<ProofReceipt> {
|
72
|
+
const params: VGetProofReceiptParams = {
|
73
|
+
hash: hash.hash as Hex,
|
74
|
+
};
|
75
|
+
const resp = await v_getProofReceipt(params, url);
|
76
|
+
handleErrors(resp);
|
77
|
+
return resp.result;
|
78
|
+
}
|
79
|
+
|
80
|
+
const handleErrors = (resp: VGetProofReceiptResponse) => {
|
81
|
+
const { status, state, error } = resp.result;
|
82
|
+
if (status === 0) {
|
83
|
+
match(state)
|
84
|
+
.with(ProofState.ChainProof, () => {
|
85
|
+
throw new Error("Waiting for chain proof failed with error: " + error);
|
86
|
+
})
|
87
|
+
.with(ProofState.Preflight, () => {
|
88
|
+
throw new Error("Preflight failed with error: " + error);
|
89
|
+
})
|
90
|
+
.with(ProofState.Proving, () => {
|
91
|
+
throw new Error("Proving failed with error: " + error);
|
92
|
+
})
|
93
|
+
.exhaustive();
|
94
|
+
}
|
95
|
+
};
|
96
|
+
|
97
|
+
export async function waitForProof<
|
98
|
+
T extends Abi,
|
99
|
+
F extends ContractFunctionName<T>,
|
100
|
+
>(
|
101
|
+
hash: BrandedHash<T, F>,
|
102
|
+
url: string,
|
103
|
+
numberOfRetries: number = 240,
|
104
|
+
sleepDuration: number = 1000,
|
105
|
+
): Promise<ProofDataWithMetrics> {
|
106
|
+
for (let retry = 0; retry < numberOfRetries; retry++) {
|
107
|
+
const { state, data, metrics } = await getProofReceipt(hash, url);
|
108
|
+
if (state === ProofState.Done) {
|
109
|
+
return { data, metrics };
|
110
|
+
}
|
111
|
+
await sleep(sleepDuration);
|
112
|
+
}
|
113
|
+
throw new Error(
|
114
|
+
`Timed out waiting for ZK proof generation after ${numberOfRetries * sleepDuration}ms. Consider increasing numberOfRetries.`,
|
115
|
+
);
|
116
|
+
}
|
117
|
+
|
118
|
+
async function sleep(ms: number): Promise<void> {
|
119
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
120
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
2
|
+
import { prefixAllButNthSubstring } from "./prefixAllButNthSubstring";
|
3
|
+
|
4
|
+
describe("prefixAllButNthSubstring", () => {
|
5
|
+
test("adds 'X-' prefix to all matches except n-th (indexed from 0)", () => {
|
6
|
+
const str = "abc 123 abc 456 abc 789";
|
7
|
+
expect(prefixAllButNthSubstring(str, /abc/gi, 3, 0)).toBe(
|
8
|
+
"abc 123 X-abc 456 X-abc 789",
|
9
|
+
);
|
10
|
+
expect(prefixAllButNthSubstring(str, /abc/gi, 3, 1)).toBe(
|
11
|
+
"X-abc 123 abc 456 X-abc 789",
|
12
|
+
);
|
13
|
+
expect(prefixAllButNthSubstring(str, /abc/gi, 3, 2)).toBe(
|
14
|
+
"X-abc 123 X-abc 456 abc 789",
|
15
|
+
);
|
16
|
+
});
|
17
|
+
|
18
|
+
test("does not add prefix to substrings past total substring count", () => {
|
19
|
+
const str = "abc 123 abc 456 abc 789 abc abc";
|
20
|
+
expect(prefixAllButNthSubstring(str, /abc/gi, 3, 1)).toBe(
|
21
|
+
"X-abc 123 abc 456 X-abc 789 abc abc",
|
22
|
+
);
|
23
|
+
});
|
24
|
+
});
|
@@ -0,0 +1,13 @@
|
|
1
|
+
export function prefixAllButNthSubstring(
|
2
|
+
str: string,
|
3
|
+
pattern: RegExp,
|
4
|
+
substringsCount: number,
|
5
|
+
skippedIndex: number,
|
6
|
+
) {
|
7
|
+
let occurrence = 0;
|
8
|
+
return str.replace(pattern, (match) => {
|
9
|
+
return occurrence++ === skippedIndex || occurrence > substringsCount
|
10
|
+
? match
|
11
|
+
: `X-${match}`;
|
12
|
+
});
|
13
|
+
}
|