@midnight-ntwrk/wallet-sdk-prover-client 2.0.0-beta.2 → 2.0.0-beta.4
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/README.md +37 -0
- package/dist/effect/HttpProverClient.js +23 -6
- package/dist/effect/KeyMaterial.d.ts +122 -0
- package/dist/effect/KeyMaterial.js +187 -0
- package/dist/effect/ProverClient.d.ts +17 -3
- package/dist/effect/WasmProver.d.ts +70 -1
- package/dist/effect/WasmProver.js +74 -56
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -57,6 +57,43 @@ class HttpProverClient {
|
|
|
57
57
|
}
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
### Proving providers, per ledger version
|
|
61
|
+
|
|
62
|
+
A proof preimage is produced by the ledger version that built the transaction, and the request carrying it has to be
|
|
63
|
+
framed and read back by that same version. `HttpProverClient` therefore offers one provider per ledger version:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
const client = await Effect.runPromise(HttpProverClient.create({ url: proofServerUrl }));
|
|
67
|
+
|
|
68
|
+
client.asV9ProvingProvider(); // frames with @midnightntwrk/ledger-v9; asProvingProvider() is the same provider
|
|
69
|
+
client.asV8ProvingProvider(); // frames with @midnight-ntwrk/ledger-v8
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`WasmProver` offers both names too, and returns the same provider for each: the in-process prover drives a zkir runtime
|
|
73
|
+
over bytes and never looks at a ledger version. Its key material, though, is per ledger version: each ledger version's
|
|
74
|
+
circuits were generated as their own generation, and a node rejects a proof made with another's. Create the prover with
|
|
75
|
+
the key material of the ledger version it proves for:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
WasmProver.makeV9KeyMaterialProvider(); // ledger-v9: circuit generation 10
|
|
79
|
+
WasmProver.makeV8KeyMaterialProvider(); // ledger-v8: circuit generation 9
|
|
80
|
+
WasmProver.makeDefaultKeyMaterialProvider(); // the same as makeV9KeyMaterialProvider()
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Each reads from `https://srs.midnight.network/`, the host the ledger's own data provider reads, and checks every file
|
|
84
|
+
against the SHA-256 its ledger release declares before handing it back; a file that does not match is refused with
|
|
85
|
+
`KeyMaterialIntegrityError`. To serve the files yourself — a mirror, or your page's own origin, since that host sends no
|
|
86
|
+
CORS headers — pass `{ source }`; the files are checked all the same:
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
WasmProver.makeV9KeyMaterialProvider({ source: 'https://example.com/midnight-keys/' });
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Checking needs Web Crypto (`crypto.subtle`): Node 19 or later, or a browser page served from a secure context.
|
|
93
|
+
|
|
94
|
+
> This package depends on both ledger runtimes, `@midnight-ntwrk/ledger-v8` and `@midnightntwrk/ledger-v9`. Both are
|
|
95
|
+
> WASM modules, so a direct consumer bundling this package ships both.
|
|
96
|
+
|
|
60
97
|
## Exports
|
|
61
98
|
|
|
62
99
|
### Default Export
|
|
@@ -15,9 +15,20 @@ import { FetchHttpClient, HttpBody, HttpClient, HttpClientRequest } from '@effec
|
|
|
15
15
|
import { ProverClient } from './ProverClient.js';
|
|
16
16
|
import { ClientError, HttpURL, ServerError, } from '@midnight-ntwrk/wallet-sdk-utilities/networking';
|
|
17
17
|
import { BlobOps, EitherOps } from '@midnight-ntwrk/wallet-sdk-utilities';
|
|
18
|
-
import * as
|
|
18
|
+
import * as ledgerV8 from '@midnight-ntwrk/ledger-v8';
|
|
19
|
+
import * as ledgerV9 from '@midnightntwrk/ledger-v9';
|
|
19
20
|
const PROVE_TX_PATH = '/prove';
|
|
20
21
|
const CHECK_TX_PATH = '/check';
|
|
22
|
+
const v9Framing = {
|
|
23
|
+
createProvingPayload: (preimage, binding) => ledgerV9.createProvingPayload(preimage, binding),
|
|
24
|
+
createCheckPayload: (preimage) => ledgerV9.createCheckPayload(preimage),
|
|
25
|
+
parseCheckResult: (result) => ledgerV9.parseCheckResult(result),
|
|
26
|
+
};
|
|
27
|
+
const v8Framing = {
|
|
28
|
+
createProvingPayload: (preimage, binding) => ledgerV8.createProvingPayload(preimage, binding),
|
|
29
|
+
createCheckPayload: (preimage) => ledgerV8.createCheckPayload(preimage),
|
|
30
|
+
parseCheckResult: (result) => ledgerV8.parseCheckResult(result),
|
|
31
|
+
};
|
|
21
32
|
/**
|
|
22
33
|
* Creates a layer for a {@link ProverClient} that sends requests to a Proof Server over HTTP.
|
|
23
34
|
*
|
|
@@ -65,15 +76,15 @@ class HttpProverClientImpl {
|
|
|
65
76
|
ResponseError: (err) => Effect.orElseSucceed(err.response.text, () => 'Unknown server error').pipe(Effect.flatMap((message) => new ServerError({ message }))),
|
|
66
77
|
}), Effect.provide(FetchHttpClient.layer));
|
|
67
78
|
}
|
|
68
|
-
serverProverProvider = () => ({
|
|
69
|
-
check: async (serializedPreimage, _keyLocation) => pipe(Effect.succeed(
|
|
70
|
-
prove: async (serializedPreimage, _keyLocation, overwriteBindingInput) => pipe(Effect.succeed(
|
|
79
|
+
serverProverProvider = (framing) => ({
|
|
80
|
+
check: async (serializedPreimage, _keyLocation) => pipe(Effect.succeed(framing.createCheckPayload(serializedPreimage)), Effect.flatMap((tx) => this.request(CHECK_TX_PATH, tx, 'Failed to check')), Effect.map((response) => framing.parseCheckResult(response)), Effect.runPromise),
|
|
81
|
+
prove: async (serializedPreimage, _keyLocation, overwriteBindingInput) => pipe(Effect.succeed(framing.createProvingPayload(serializedPreimage, overwriteBindingInput)), Effect.flatMap((tx) => this.request(PROVE_TX_PATH, tx, 'Failed to prove')), Effect.runPromise),
|
|
71
82
|
// The proof server holds its own key material and resolves circuits from the
|
|
72
83
|
// preimage's key location, so there is never local key material to provide.
|
|
73
84
|
lookupKey: (_keyLocation) => Promise.resolve(undefined),
|
|
74
85
|
});
|
|
75
86
|
proveTransaction(transaction, costModel) {
|
|
76
|
-
return pipe(Effect.succeed(this.serverProverProvider()), Effect.flatMap((provider) => Effect.tryPromise({
|
|
87
|
+
return pipe(Effect.succeed(this.serverProverProvider(v9Framing)), Effect.flatMap((provider) => Effect.tryPromise({
|
|
77
88
|
try: () => transaction.prove(provider, costModel),
|
|
78
89
|
catch: (error) => error instanceof ClientError || error instanceof ServerError
|
|
79
90
|
? error
|
|
@@ -81,6 +92,12 @@ class HttpProverClientImpl {
|
|
|
81
92
|
})));
|
|
82
93
|
}
|
|
83
94
|
asProvingProvider() {
|
|
84
|
-
return this.serverProverProvider();
|
|
95
|
+
return this.serverProverProvider(v9Framing);
|
|
96
|
+
}
|
|
97
|
+
asV9ProvingProvider() {
|
|
98
|
+
return this.asProvingProvider();
|
|
99
|
+
}
|
|
100
|
+
asV8ProvingProvider() {
|
|
101
|
+
return this.serverProverProvider(v8Framing);
|
|
85
102
|
}
|
|
86
103
|
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The key material each ledger version's circuits were generated with, and a provider that reads it and checks it.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* A node verifies a proof against the verifier keys of the circuit generation its ledger version was built with, so a
|
|
6
|
+
* proof has to be made with that generation's key material, byte for byte. Which generation that is, and what every
|
|
7
|
+
* file of it hashes to, is declared by the ledger release itself (`midnight-ledger`: `static/version`,
|
|
8
|
+
* `ledger/static/dust/*.sha256`, `zswap/static/*.sha256`, and the parameter hashes in `base-crypto`'s data provider);
|
|
9
|
+
* the descriptors below are copies of those declarations, one per ledger version. Nothing at runtime can re-derive
|
|
10
|
+
* them: the published ledger packages neither expose the generation nor embed the Dust spend verifier key.
|
|
11
|
+
*/
|
|
12
|
+
import type { KeyMaterialProvider } from '@midnight-ntwrk/zkir-v2';
|
|
13
|
+
import { Cause, Schedule } from 'effect';
|
|
14
|
+
/** The host the ledger's own data provider reads key material from: its `MIDNIGHT_PARAM_SOURCE` default. */
|
|
15
|
+
export declare const DefaultKeyMaterialSource = "https://srs.midnight.network/";
|
|
16
|
+
/** A circuit whose key material the ledger resolves by location, named as the host lays it out. */
|
|
17
|
+
export type Circuit = 'zswap/spend' | 'zswap/output' | 'zswap/sign' | 'dust/spend';
|
|
18
|
+
/** The three files a circuit's key material is made of. */
|
|
19
|
+
type KeyFileKind = 'prover' | 'verifier' | 'bzkir';
|
|
20
|
+
/** One file of one circuit's key material, named as the ledger names its hash (`<family>/<name>.<kind>`). */
|
|
21
|
+
export type KeyFile = `${Circuit}.${KeyFileKind}`;
|
|
22
|
+
/** A SHA-256 digest, as lowercase hex. */
|
|
23
|
+
type Sha256 = string;
|
|
24
|
+
/**
|
|
25
|
+
* The key material one ledger version's circuits were generated with.
|
|
26
|
+
*
|
|
27
|
+
* @remarks
|
|
28
|
+
* A copy of what one ledger release declares. `ledgerRelease` records which: the pins hold for that release, and a test
|
|
29
|
+
* compares it with the ledger package installed, so that a ledger upgrade cannot leave them behind unnoticed.
|
|
30
|
+
*/
|
|
31
|
+
export type KeyMaterialDescriptor = Readonly<{
|
|
32
|
+
/** The ledger release the pins were copied from: its npm package and version, and its `midnight-ledger` tag. */
|
|
33
|
+
ledgerRelease: Readonly<{
|
|
34
|
+
packageName: string;
|
|
35
|
+
version: string;
|
|
36
|
+
tag: string;
|
|
37
|
+
}>;
|
|
38
|
+
/** The circuit generation the ledger's key locations resolve to (`static/version`). */
|
|
39
|
+
generation: number;
|
|
40
|
+
/** What each file of each circuit hashes to. */
|
|
41
|
+
files: Readonly<Record<KeyFile, Sha256>>;
|
|
42
|
+
/** What the public parameters for each size `k` hash to. */
|
|
43
|
+
params: Readonly<Record<number, Sha256>>;
|
|
44
|
+
}>;
|
|
45
|
+
/** Ledger-v9's key material: circuit generation 10, as `midnight-ledger` `ledger-9.1.0.0-rc.5` declares it. */
|
|
46
|
+
export declare const V9KeyMaterial: KeyMaterialDescriptor;
|
|
47
|
+
/** Ledger-v8's key material: circuit generation 9, as `midnight-ledger` `ledger-8.1.0` declares it. */
|
|
48
|
+
export declare const V8KeyMaterial: KeyMaterialDescriptor;
|
|
49
|
+
declare const KeyMaterialIntegrityError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
50
|
+
readonly _tag: "@midnight-ntwrk/wallet-sdk-prover-client/effect/KeyMaterial/KeyMaterialIntegrityError";
|
|
51
|
+
} & Readonly<A>;
|
|
52
|
+
/** Raised when a key material file does not hash to what the ledger release declares for it. */
|
|
53
|
+
export declare class KeyMaterialIntegrityError extends KeyMaterialIntegrityError_base<{
|
|
54
|
+
readonly message: string;
|
|
55
|
+
/** The file whose bytes did not match. */
|
|
56
|
+
readonly url: string;
|
|
57
|
+
/** What the ledger release declares the file hashes to. */
|
|
58
|
+
readonly expected: string;
|
|
59
|
+
/** What the bytes received hash to. */
|
|
60
|
+
readonly actual: string;
|
|
61
|
+
}> {
|
|
62
|
+
}
|
|
63
|
+
declare const KeyMaterialFetchError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
64
|
+
readonly _tag: "@midnight-ntwrk/wallet-sdk-prover-client/effect/KeyMaterial/KeyMaterialFetchError";
|
|
65
|
+
} & Readonly<A>;
|
|
66
|
+
/** Raised when the host answers a request for key material with anything but success. */
|
|
67
|
+
export declare class KeyMaterialFetchError extends KeyMaterialFetchError_base<{
|
|
68
|
+
readonly message: string;
|
|
69
|
+
/** The file that was asked for. */
|
|
70
|
+
readonly url: string;
|
|
71
|
+
/** The HTTP status the host answered with. */
|
|
72
|
+
readonly status: number;
|
|
73
|
+
}> {
|
|
74
|
+
}
|
|
75
|
+
declare const KeyMaterialTransferError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
76
|
+
readonly _tag: "@midnight-ntwrk/wallet-sdk-prover-client/effect/KeyMaterial/KeyMaterialTransferError";
|
|
77
|
+
} & Readonly<A>;
|
|
78
|
+
/**
|
|
79
|
+
* Raised when no complete answer arrives for a request for key material: the host was unreachable, or the transfer
|
|
80
|
+
* broke off.
|
|
81
|
+
*/
|
|
82
|
+
export declare class KeyMaterialTransferError extends KeyMaterialTransferError_base<{
|
|
83
|
+
readonly message: string;
|
|
84
|
+
/** The file that was asked for. */
|
|
85
|
+
readonly url: string;
|
|
86
|
+
readonly cause: unknown;
|
|
87
|
+
}> {
|
|
88
|
+
}
|
|
89
|
+
declare const UnknownPublicParametersError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
90
|
+
readonly _tag: "@midnight-ntwrk/wallet-sdk-prover-client/effect/KeyMaterial/UnknownPublicParametersError";
|
|
91
|
+
} & Readonly<A>;
|
|
92
|
+
/** Raised when public parameters are asked for at a size `k` the ledger does not publish. */
|
|
93
|
+
export declare class UnknownPublicParametersError extends UnknownPublicParametersError_base<{
|
|
94
|
+
readonly message: string;
|
|
95
|
+
/** The size that was asked for. */
|
|
96
|
+
readonly k: number;
|
|
97
|
+
}> {
|
|
98
|
+
}
|
|
99
|
+
/** Everything reading key material can fail with. */
|
|
100
|
+
export type KeyMaterialError = KeyMaterialIntegrityError | KeyMaterialFetchError | KeyMaterialTransferError | UnknownPublicParametersError;
|
|
101
|
+
/** How a provider reads key material. */
|
|
102
|
+
export type KeyMaterialProviderOptions = Readonly<{
|
|
103
|
+
/** Where to read from. A path is kept: `https://example.com/keys` reads `https://example.com/keys/dust/…`. */
|
|
104
|
+
source: URL | string;
|
|
105
|
+
/** How often, and how far apart, to ask again after a failure that may pass. */
|
|
106
|
+
retrySchedule?: Schedule.Schedule<unknown, unknown>;
|
|
107
|
+
}>;
|
|
108
|
+
/**
|
|
109
|
+
* A key material provider for the ledger version a descriptor describes.
|
|
110
|
+
*
|
|
111
|
+
* @remarks
|
|
112
|
+
* Every file is checked against the descriptor before it is handed back, and kept once it has been: a circuit or a
|
|
113
|
+
* parameter size is read once per provider, however often and however concurrently it is asked for. A failure is not
|
|
114
|
+
* kept. Checking needs Web Crypto (`crypto.subtle`): Node 19 or later, or a browser page served from a secure
|
|
115
|
+
* context.
|
|
116
|
+
* @param descriptor The key material to read, and what each file must hash to.
|
|
117
|
+
* @param options Where to read from, and how to retry.
|
|
118
|
+
* @returns A provider for the zkir runtime. Its lookups reject with a {@link KeyMaterialError}.
|
|
119
|
+
* @throws TypeError if `options.source` is not a URL.
|
|
120
|
+
*/
|
|
121
|
+
export declare const makeKeyMaterialProvider: (descriptor: KeyMaterialDescriptor, options: KeyMaterialProviderOptions) => KeyMaterialProvider;
|
|
122
|
+
export {};
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { Cache, Cause, Data, Duration, Effect, Exit, Option, Record as ERecord, Schedule, pipe } from 'effect';
|
|
2
|
+
/** The host the ledger's own data provider reads key material from: its `MIDNIGHT_PARAM_SOURCE` default. */
|
|
3
|
+
export const DefaultKeyMaterialSource = 'https://srs.midnight.network/';
|
|
4
|
+
/** The public parameters `bls_midnight_2p<k>`, as `base-crypto` declares them; no ledger release has changed them. */
|
|
5
|
+
const publicParameters = {
|
|
6
|
+
0: '59b30b3114a34ccbbfb599376e178fb8d9b3366cae2174c2f1da20e75847f823',
|
|
7
|
+
1: 'bbe04fe3c70d0c138447cb086b4baddc30cb8bb2a004114bc02e6f739516280e',
|
|
8
|
+
2: '80e15568fa1a0117db893239be7fa5e34a6bcc3a8c3bfa7709534b9cb88eb6c1',
|
|
9
|
+
3: '4be827a6472193df80d8f08b4b25a85baef436fdd1965d89b6af89f4ec4e99e2',
|
|
10
|
+
4: '232f401fad10c7ddf8828d2aa4c85c6506c5da09795998cecaeb9f75fc8f6ada',
|
|
11
|
+
5: '0a1c9229f315fc1868ff25f668fb83aec4d09f4f23a706b5197c692c619d72c6',
|
|
12
|
+
6: 'cf2ad6be7d0fedf5bec2aaa35f6be4aca33053d74268fdf5aa54fcb2891ea6df',
|
|
13
|
+
7: 'e82ae890c080188355f37feaffe91372584cd810615082d9143d4dec0453fd9d',
|
|
14
|
+
8: '909b707551eaaea79828e883cde6fc46ab15986c3b1d791bed462c9e2805c933',
|
|
15
|
+
9: 'b9009f1098bcefffec3c461ab3a5e3a17f7e5599f0f08c70fcdc55a89227bcbd',
|
|
16
|
+
10: '46b2290933cbed4c378889e4ba971f1a92888331ffb09466acd4ff61a1e2cb42',
|
|
17
|
+
11: '9901589d7956ff58be0d85569b2f455b77b58c3758026ffb5bbe4807000b96d1',
|
|
18
|
+
12: 'ef08eb3fcf62df8f72c515cffa027e681808b530cb016eea104115545ef6d5c8',
|
|
19
|
+
13: 'd3324910969c4cc54143b8045b649e5c3a4bd5fb7b8f85fe1b770f640ce1c803',
|
|
20
|
+
14: 'fc253016885ec830e97808c9ec920bb5cab5c21af590380a6cb5eb0538e2b244',
|
|
21
|
+
15: '724c7c3d779148bb113c7ee9c034b2f27db16e6bdf315fde90105a9bad00b1de',
|
|
22
|
+
16: '09c877216d6589b370263e18af40a030a901b41a7a7c37ef58c9901db41f05c6',
|
|
23
|
+
17: '4a9ef6c7c0619aab74eede44b13e753e3ba54508a02dd3b7106a949aabb73b74',
|
|
24
|
+
18: 'e8436dc5d8b598f169c127c745135d889744007e6d384ff126df8d1332522f86',
|
|
25
|
+
19: '8e8dc15c4362f05c912f1e770559a3945db3e58a374def416ed5d3e65ad5b10e',
|
|
26
|
+
20: '1cc62978558fdc1e445cd70cfd9a86ec3c2e2151b6d74811232d37faf9133ff1',
|
|
27
|
+
21: '9cf1644a87f0f027ae5fc6278f91d823a6334ff3e338a29e2f2ef57d071ed64d',
|
|
28
|
+
22: 'e8ad5eed936d657a0fb59d2a55ba19f81a3083bb3554ef88f464f5377e9b2c2f',
|
|
29
|
+
23: '09399d05f9f50875dfdd87dc9903d40c897eaafa9ec8cbb08bace853ecc36c0c',
|
|
30
|
+
24: 'b0e6fa7a4ab4a79a1e6560966f267556409db44bab6d5fab3711ad6c6b623207',
|
|
31
|
+
25: '3289a751c938988cd2f54154d8722d1eda2cd11593064afdde82099b24ff4a58',
|
|
32
|
+
};
|
|
33
|
+
/** Zswap's key material: the same bytes in circuit generations 9 and 10. */
|
|
34
|
+
const zswapFiles = {
|
|
35
|
+
'zswap/spend.prover': '19d234b5c68b7212ad6b0ec9334a95594748154128f3704eb576bcc843cc5c45',
|
|
36
|
+
'zswap/spend.verifier': '544554effd7ae9fb9063be52a9ec2a986756301071fcd97bb4598fb45a335658',
|
|
37
|
+
'zswap/spend.bzkir': '7cb5bbcf67cb212a3336fb439a77e8f32f0aa8a56185c8e1247d6cbfc7300205',
|
|
38
|
+
'zswap/output.prover': 'd992b04f13c3fd432f55fb8bfe6466d87bc181f1a2acf233ec228030bbdd4ed8',
|
|
39
|
+
'zswap/output.verifier': '72e8074856f2f5c504ade25a86a2b8902c64aeb9497c4c8e6b26dea842a0ab08',
|
|
40
|
+
'zswap/output.bzkir': '91dc8b401dd8385e8d29eaac018c70b578505f48c7952452ef319bc397fa1f1b',
|
|
41
|
+
'zswap/sign.prover': 'fe7268dd2bdd107f862f881ac3c5bc71a6df77ce80bfed51cf71514648e660e0',
|
|
42
|
+
'zswap/sign.verifier': 'e39a727caa0de167e6dd6122a9e3b758fecf48f9093ab77c0309648de8ce07e1',
|
|
43
|
+
'zswap/sign.bzkir': '37ea2094516e145a738126307cf92bd293f7cb524b1ccd49fa6f3225a9ec3a50',
|
|
44
|
+
};
|
|
45
|
+
/** Ledger-v9's key material: circuit generation 10, as `midnight-ledger` `ledger-9.1.0.0-rc.5` declares it. */
|
|
46
|
+
export const V9KeyMaterial = {
|
|
47
|
+
ledgerRelease: { packageName: '@midnightntwrk/ledger-v9', version: '1.0.0-rc.5', tag: 'ledger-9.1.0.0-rc.5' },
|
|
48
|
+
generation: 10,
|
|
49
|
+
files: {
|
|
50
|
+
...zswapFiles,
|
|
51
|
+
'dust/spend.prover': '3dff9f54add761350ad02621a425d67fe3d656c8145fef8ef147870489ffdc81',
|
|
52
|
+
'dust/spend.verifier': 'd15a1295780549f534287a39c938005e1faa3232be21861573bd0cdb148949cb',
|
|
53
|
+
'dust/spend.bzkir': 'd211cacb22391b9db60f945787d98c16d344cbb4790246132117084c080399c1',
|
|
54
|
+
},
|
|
55
|
+
params: publicParameters,
|
|
56
|
+
};
|
|
57
|
+
/** Ledger-v8's key material: circuit generation 9, as `midnight-ledger` `ledger-8.1.0` declares it. */
|
|
58
|
+
export const V8KeyMaterial = {
|
|
59
|
+
ledgerRelease: { packageName: '@midnight-ntwrk/ledger-v8', version: '8.1.0', tag: 'ledger-8.1.0' },
|
|
60
|
+
generation: 9,
|
|
61
|
+
files: {
|
|
62
|
+
...zswapFiles,
|
|
63
|
+
'dust/spend.prover': '996602da7ca386284e656c78ea03e55bffdba29475e6a67965c50de05e13efc2',
|
|
64
|
+
'dust/spend.verifier': '3f1569ebcab0655c5c145b28947c74edc4e3f5c6b276e4404b661cf0905b49d3',
|
|
65
|
+
'dust/spend.bzkir': '904181287e75b0fb596ba5fcc116c882ee5d28e3115304c93ebd913722ce5841',
|
|
66
|
+
},
|
|
67
|
+
params: publicParameters,
|
|
68
|
+
};
|
|
69
|
+
/** Raised when a key material file does not hash to what the ledger release declares for it. */
|
|
70
|
+
export class KeyMaterialIntegrityError extends Data.TaggedError('@midnight-ntwrk/wallet-sdk-prover-client/effect/KeyMaterial/KeyMaterialIntegrityError') {
|
|
71
|
+
}
|
|
72
|
+
/** Raised when the host answers a request for key material with anything but success. */
|
|
73
|
+
export class KeyMaterialFetchError extends Data.TaggedError('@midnight-ntwrk/wallet-sdk-prover-client/effect/KeyMaterial/KeyMaterialFetchError') {
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Raised when no complete answer arrives for a request for key material: the host was unreachable, or the transfer
|
|
77
|
+
* broke off.
|
|
78
|
+
*/
|
|
79
|
+
export class KeyMaterialTransferError extends Data.TaggedError('@midnight-ntwrk/wallet-sdk-prover-client/effect/KeyMaterial/KeyMaterialTransferError') {
|
|
80
|
+
}
|
|
81
|
+
/** Raised when public parameters are asked for at a size `k` the ledger does not publish. */
|
|
82
|
+
export class UnknownPublicParametersError extends Data.TaggedError('@midnight-ntwrk/wallet-sdk-prover-client/effect/KeyMaterial/UnknownPublicParametersError') {
|
|
83
|
+
}
|
|
84
|
+
/** Four more attempts after the first, one, two, four and eight seconds apart. */
|
|
85
|
+
const defaultRetrySchedule = pipe(Schedule.exponential(Duration.seconds(1), 2), Schedule.intersect(Schedule.recurs(4)));
|
|
86
|
+
/** Room for every circuit and every parameter size a descriptor names. */
|
|
87
|
+
const cacheCapacity = 64;
|
|
88
|
+
const circuitsByKeyLocation = {
|
|
89
|
+
'midnight/zswap/spend': 'zswap/spend',
|
|
90
|
+
'midnight/zswap/output': 'zswap/output',
|
|
91
|
+
'midnight/zswap/sign': 'zswap/sign',
|
|
92
|
+
'midnight/dust/spend': 'dust/spend',
|
|
93
|
+
};
|
|
94
|
+
/** A failure that asking again may cure: no complete answer, a server error, or being asked to slow down. */
|
|
95
|
+
const mayPass = (error) => error instanceof KeyMaterialTransferError || error.status >= 500 || error.status === 429;
|
|
96
|
+
/** Resolves a path against the source, keeping any path the source has. */
|
|
97
|
+
const sourceBase = (source) => {
|
|
98
|
+
const href = source.toString();
|
|
99
|
+
return new URL(href.endsWith('/') ? href : `${href}/`);
|
|
100
|
+
};
|
|
101
|
+
const fetchBytes = (url) => pipe(Effect.tryPromise({
|
|
102
|
+
try: (signal) => globalThis.fetch(url, { signal }),
|
|
103
|
+
catch: (cause) => new KeyMaterialTransferError({
|
|
104
|
+
message: `Could not fetch ${url.href}: ${String(cause)}`,
|
|
105
|
+
url: url.href,
|
|
106
|
+
cause,
|
|
107
|
+
}),
|
|
108
|
+
}), Effect.filterOrFail((response) => response.ok, (response) => new KeyMaterialFetchError({
|
|
109
|
+
message: `${url.href} answered ${response.status}${response.statusText === '' ? '' : ` ${response.statusText}`}`,
|
|
110
|
+
url: url.href,
|
|
111
|
+
status: response.status,
|
|
112
|
+
})), Effect.flatMap((response) => Effect.tryPromise({
|
|
113
|
+
try: () => response.arrayBuffer(),
|
|
114
|
+
catch: (cause) => new KeyMaterialTransferError({
|
|
115
|
+
message: `The transfer of ${url.href} broke off: ${String(cause)}`,
|
|
116
|
+
url: url.href,
|
|
117
|
+
cause,
|
|
118
|
+
}),
|
|
119
|
+
})), Effect.map((buffer) => new Uint8Array(buffer)));
|
|
120
|
+
const sha256Of = (bytes) => pipe(Effect.promise(() => globalThis.crypto.subtle.digest('SHA-256', bytes)), Effect.map((digest) => Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, '0')).join('')));
|
|
121
|
+
/** Reads one file, asking again while the failure may pass, and hands it back only if it hashes to `expected`. */
|
|
122
|
+
const fetchVerified = (url, expected, retrySchedule) => pipe(fetchBytes(url), Effect.tapError((error) => mayPass(error) ? Effect.logWarning(`${error.message} (asking again while retries remain)`) : Effect.void), Effect.retry({ schedule: retrySchedule, while: mayPass }), Effect.flatMap((bytes) => pipe(sha256Of(bytes), Effect.filterOrFail((actual) => actual === expected, (actual) => new KeyMaterialIntegrityError({
|
|
123
|
+
message: `${url.href} hashes to ${actual}, but the ledger release declares ${expected}`,
|
|
124
|
+
url: url.href,
|
|
125
|
+
expected,
|
|
126
|
+
actual,
|
|
127
|
+
})), Effect.as(bytes))));
|
|
128
|
+
/**
|
|
129
|
+
* Runs a read at the Promise boundary the zkir runtime calls through, rejecting with the error itself rather than
|
|
130
|
+
* Effect's wrapper around it.
|
|
131
|
+
*/
|
|
132
|
+
const runAtBoundary = (effect) => Effect.runPromiseExit(effect).then(Exit.match({
|
|
133
|
+
onSuccess: (value) => Promise.resolve(value),
|
|
134
|
+
onFailure: (cause) => {
|
|
135
|
+
const error = Cause.squash(cause);
|
|
136
|
+
return Promise.reject(error instanceof Error ? error : new Error(String(error)));
|
|
137
|
+
},
|
|
138
|
+
}));
|
|
139
|
+
/**
|
|
140
|
+
* Reads through a cache that keeps what was read for good but forgets a failure at once, so that the next request reads
|
|
141
|
+
* again. The failure is dropped explicitly: a cache entry that expires "now" can still be served within the same
|
|
142
|
+
* instant.
|
|
143
|
+
*/
|
|
144
|
+
const readThrough = (cache, key) => pipe(cache.get(key), Effect.tapError(() => cache.invalidate(key)));
|
|
145
|
+
/**
|
|
146
|
+
* A key material provider for the ledger version a descriptor describes.
|
|
147
|
+
*
|
|
148
|
+
* @remarks
|
|
149
|
+
* Every file is checked against the descriptor before it is handed back, and kept once it has been: a circuit or a
|
|
150
|
+
* parameter size is read once per provider, however often and however concurrently it is asked for. A failure is not
|
|
151
|
+
* kept. Checking needs Web Crypto (`crypto.subtle`): Node 19 or later, or a browser page served from a secure
|
|
152
|
+
* context.
|
|
153
|
+
* @param descriptor The key material to read, and what each file must hash to.
|
|
154
|
+
* @param options Where to read from, and how to retry.
|
|
155
|
+
* @returns A provider for the zkir runtime. Its lookups reject with a {@link KeyMaterialError}.
|
|
156
|
+
* @throws TypeError if `options.source` is not a URL.
|
|
157
|
+
*/
|
|
158
|
+
export const makeKeyMaterialProvider = (descriptor, options) => {
|
|
159
|
+
const base = sourceBase(options.source);
|
|
160
|
+
const retrySchedule = options.retrySchedule ?? defaultRetrySchedule;
|
|
161
|
+
const readFile = (circuit, kind) => {
|
|
162
|
+
const file = `${circuit}.${kind}`;
|
|
163
|
+
const path = `${circuit.replace('/', `/${descriptor.generation}/`)}.${kind}`;
|
|
164
|
+
return fetchVerified(new URL(path, base), descriptor.files[file], retrySchedule);
|
|
165
|
+
};
|
|
166
|
+
const readCircuit = (circuit) => Effect.all({
|
|
167
|
+
proverKey: readFile(circuit, 'prover'),
|
|
168
|
+
verifierKey: readFile(circuit, 'verifier'),
|
|
169
|
+
ir: readFile(circuit, 'bzkir'),
|
|
170
|
+
});
|
|
171
|
+
const readParams = (k) => Option.match(Option.fromNullable(descriptor.params[k]), {
|
|
172
|
+
onNone: () => Effect.fail(new UnknownPublicParametersError({
|
|
173
|
+
message: `The ledger publishes no public parameters for k = ${k}`,
|
|
174
|
+
k,
|
|
175
|
+
})),
|
|
176
|
+
onSome: (expected) => fetchVerified(new URL(`bls_midnight_2p${k}`, base), expected, retrySchedule),
|
|
177
|
+
});
|
|
178
|
+
const circuits = Effect.runSync(Cache.make({ capacity: cacheCapacity, timeToLive: Duration.infinity, lookup: readCircuit }));
|
|
179
|
+
const params = Effect.runSync(Cache.make({ capacity: cacheCapacity, timeToLive: Duration.infinity, lookup: readParams }));
|
|
180
|
+
return {
|
|
181
|
+
lookupKey: (keyLocation) => Option.match(ERecord.get(circuitsByKeyLocation, keyLocation), {
|
|
182
|
+
onNone: () => Promise.resolve(undefined),
|
|
183
|
+
onSome: (circuit) => runAtBoundary(readThrough(circuits, circuit)),
|
|
184
|
+
}),
|
|
185
|
+
getParams: (k) => runAtBoundary(readThrough(params, k)),
|
|
186
|
+
};
|
|
187
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Effect, Context } from 'effect';
|
|
2
|
-
import type * as
|
|
2
|
+
import type * as ledgerV8 from '@midnight-ntwrk/ledger-v8';
|
|
3
|
+
import type * as ledgerV9 from '@midnightntwrk/ledger-v9';
|
|
3
4
|
import { type ClientError, type ServerError } from '@midnight-ntwrk/wallet-sdk-utilities/networking';
|
|
4
5
|
import type { KeyMaterialProvider } from '@midnight-ntwrk/zkir-v2';
|
|
5
6
|
declare const ProverClient_base: Context.TagClass<ProverClient, "@midnight-ntwrk/prover-client#ProverClient", ProverClient.Service>;
|
|
@@ -25,8 +26,21 @@ export declare namespace ProverClient {
|
|
|
25
26
|
* @returns An `Effect` that yields with a serialized transaction representing the proven version of `transaction`;
|
|
26
27
|
* or fails with a client or server side error.
|
|
27
28
|
*/
|
|
28
|
-
proveTransaction<S extends
|
|
29
|
-
|
|
29
|
+
proveTransaction<S extends ledgerV9.Signaturish, B extends ledgerV9.Bindingish>(tx: ledgerV9.Transaction<S, ledgerV9.PreProof, B>, costModel?: ledgerV9.CostModel): Effect.Effect<ledgerV9.Transaction<S, ledgerV9.Proof, B>, ClientError | ServerError>;
|
|
30
|
+
/** A proving provider that frames its requests with ledger-v9. */
|
|
31
|
+
asProvingProvider(): ledgerV9.ProvingProvider;
|
|
32
|
+
/** The same provider as {@link asProvingProvider}, named for the ledger version it frames with. */
|
|
33
|
+
asV9ProvingProvider(): ledgerV9.ProvingProvider;
|
|
34
|
+
/**
|
|
35
|
+
* A proving provider that frames its requests with ledger-v8.
|
|
36
|
+
*
|
|
37
|
+
* @remarks
|
|
38
|
+
* A preimage is produced by the ledger version that built the transaction, and has to be framed and read back by
|
|
39
|
+
* that same version — so a client serving a ledger-v8 transaction is asked for this provider rather than the
|
|
40
|
+
* other. An in-process prover frames nothing: it works on bytes, and offers the same provider for both. What it
|
|
41
|
+
* proves for is decided by the key material it was created with, which is per ledger version.
|
|
42
|
+
*/
|
|
43
|
+
asV8ProvingProvider(): ledgerV8.ProvingProvider;
|
|
30
44
|
}
|
|
31
45
|
}
|
|
32
46
|
export {};
|
|
@@ -44,4 +44,73 @@ export declare const GetParamsOperationResultSchema: Schema.Struct<{
|
|
|
44
44
|
k: typeof Schema.Number;
|
|
45
45
|
result: typeof Schema.Uint8Array;
|
|
46
46
|
}>;
|
|
47
|
-
export
|
|
47
|
+
export { DefaultKeyMaterialSource, KeyMaterialFetchError, KeyMaterialIntegrityError, KeyMaterialTransferError, UnknownPublicParametersError, type KeyMaterialError, } from './KeyMaterial.js';
|
|
48
|
+
/** Where the bundled key material providers read from. */
|
|
49
|
+
export type KeyMaterialConfig = {
|
|
50
|
+
/**
|
|
51
|
+
* The host to read key material from, in place of {@link DefaultKeyMaterialSource}.
|
|
52
|
+
*
|
|
53
|
+
* @remarks
|
|
54
|
+
* For serving the files yourself — a mirror, or the page's own origin in a browser, since the default host sends no
|
|
55
|
+
* CORS headers. The files are laid out as the default host lays them out (`dust/10/spend.prover`,
|
|
56
|
+
* `bls_midnight_2p14`, …), and a path is kept: `https://example.com/keys` reads `https://example.com/keys/dust/…`.
|
|
57
|
+
* Whatever the host, every file is checked against the hash its ledger release declares.
|
|
58
|
+
*/
|
|
59
|
+
readonly source?: URL | string;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* The key material ledger-v9's circuits were generated with: circuit generation 10.
|
|
63
|
+
*
|
|
64
|
+
* @remarks
|
|
65
|
+
* Every file is read from the host the ledger's own data provider reads (or from `config.source`) and checked against
|
|
66
|
+
* the SHA-256 the ledger release declares before it is handed back; a file that does not match is refused with
|
|
67
|
+
* {@link KeyMaterialIntegrityError}, since a proof made with it would be rejected by a node. Each circuit and each
|
|
68
|
+
* parameter size is read once per provider. Checking needs Web Crypto (`crypto.subtle`): Node 19 or later, or a
|
|
69
|
+
* browser page served from a secure context.
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* const prover = yield* WasmProver.create({ keyMaterialProvider: WasmProver.makeV9KeyMaterialProvider() });
|
|
73
|
+
* const proven = yield* prover.proveTransaction(unprovenV9Transaction, ledger.CostModel.initialCostModel());
|
|
74
|
+
* ```;
|
|
75
|
+
*
|
|
76
|
+
* @param config Where to read from; the default host when left out.
|
|
77
|
+
* @returns A provider for {@link create} whose prover proves ledger-v9 transactions.
|
|
78
|
+
* @throws TypeError if `config.source` is not a URL.
|
|
79
|
+
*/
|
|
80
|
+
export declare const makeV9KeyMaterialProvider: (config?: KeyMaterialConfig) => KeyMaterialProvider;
|
|
81
|
+
/**
|
|
82
|
+
* The key material ledger-v8's circuits were generated with: circuit generation 9.
|
|
83
|
+
*
|
|
84
|
+
* @remarks
|
|
85
|
+
* The ledger-v8 twin of {@link makeV9KeyMaterialProvider}, read and checked the same way. A prover created with it
|
|
86
|
+
* proves ledger-v8 transactions, through `asV8ProvingProvider()`; ledger-v9's Dust spend circuit is a different
|
|
87
|
+
* generation, and a node rejects a Dust spend proved with the other version's key material.
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const prover = yield* WasmProver.create({ keyMaterialProvider: WasmProver.makeV8KeyMaterialProvider() });
|
|
91
|
+
* const proven = yield* Effect.promise(() =>
|
|
92
|
+
* unprovenV8Transaction.prove(prover.asV8ProvingProvider(), ledgerV8.CostModel.initialCostModel()),
|
|
93
|
+
* );
|
|
94
|
+
* ```;
|
|
95
|
+
*
|
|
96
|
+
* @param config Where to read from; the default host when left out.
|
|
97
|
+
* @returns A provider for {@link create} whose prover proves ledger-v8 transactions.
|
|
98
|
+
* @throws TypeError if `config.source` is not a URL.
|
|
99
|
+
*/
|
|
100
|
+
export declare const makeV8KeyMaterialProvider: (config?: KeyMaterialConfig) => KeyMaterialProvider;
|
|
101
|
+
/**
|
|
102
|
+
* The same provider as {@link makeV9KeyMaterialProvider}.
|
|
103
|
+
*
|
|
104
|
+
* @remarks
|
|
105
|
+
* Ledger-v9's, because ledger-v9 is what this prover's own surface — `proveTransaction`, `asProvingProvider` — is typed
|
|
106
|
+
* with. A prover that proves ledger-v8 transactions wants {@link makeV8KeyMaterialProvider} instead.
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* const prover = yield* WasmProver.create({ keyMaterialProvider: WasmProver.makeDefaultKeyMaterialProvider() });
|
|
110
|
+
* ```;
|
|
111
|
+
*
|
|
112
|
+
* @param config Where to read from; the default host when left out.
|
|
113
|
+
* @returns A provider for {@link create} whose prover proves ledger-v9 transactions.
|
|
114
|
+
* @throws TypeError if `config.source` is not a URL.
|
|
115
|
+
*/
|
|
116
|
+
export declare const makeDefaultKeyMaterialProvider: (config?: KeyMaterialConfig) => KeyMaterialProvider;
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import Worker from 'web-worker';
|
|
14
14
|
import { Effect, Layer, Schema, pipe } from 'effect';
|
|
15
15
|
import { ClientError } from '@midnight-ntwrk/wallet-sdk-utilities/networking';
|
|
16
|
+
import { DefaultKeyMaterialSource, makeKeyMaterialProvider, V8KeyMaterial, V9KeyMaterial } from './KeyMaterial.js';
|
|
16
17
|
import { ProverClient } from './ProverClient.js';
|
|
17
18
|
/**
|
|
18
19
|
* Creates a layer for a {@link ProverClient} that sends requests to a Wasm Prover.
|
|
@@ -142,60 +143,77 @@ class WasmProverImpl {
|
|
|
142
143
|
asProvingProvider() {
|
|
143
144
|
return this.wasmProverProvider();
|
|
144
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* The same provider {@link asProvingProvider} returns.
|
|
148
|
+
*
|
|
149
|
+
* @remarks
|
|
150
|
+
* The in-process prover drives a zkir runtime over bytes and never looks at a ledger version, so the provider is the
|
|
151
|
+
* same under both names — but the key material it proves with is not interchangeable. Each ledger version's
|
|
152
|
+
* circuits were generated as their own generation, and a node rejects a proof made with another's, so a prover
|
|
153
|
+
* proves for the ledger version whose key material it was created with: {@link makeV9KeyMaterialProvider} for
|
|
154
|
+
* ledger-v9, {@link makeV8KeyMaterialProvider} for ledger-v8.
|
|
155
|
+
*/
|
|
156
|
+
asV9ProvingProvider() {
|
|
157
|
+
return this.wasmProverProvider();
|
|
158
|
+
}
|
|
159
|
+
asV8ProvingProvider() {
|
|
160
|
+
return this.wasmProverProvider();
|
|
161
|
+
}
|
|
145
162
|
}
|
|
146
|
-
export
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
163
|
+
export { DefaultKeyMaterialSource, KeyMaterialFetchError, KeyMaterialIntegrityError, KeyMaterialTransferError, UnknownPublicParametersError, } from './KeyMaterial.js';
|
|
164
|
+
/**
|
|
165
|
+
* The key material ledger-v9's circuits were generated with: circuit generation 10.
|
|
166
|
+
*
|
|
167
|
+
* @remarks
|
|
168
|
+
* Every file is read from the host the ledger's own data provider reads (or from `config.source`) and checked against
|
|
169
|
+
* the SHA-256 the ledger release declares before it is handed back; a file that does not match is refused with
|
|
170
|
+
* {@link KeyMaterialIntegrityError}, since a proof made with it would be rejected by a node. Each circuit and each
|
|
171
|
+
* parameter size is read once per provider. Checking needs Web Crypto (`crypto.subtle`): Node 19 or later, or a
|
|
172
|
+
* browser page served from a secure context.
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* const prover = yield* WasmProver.create({ keyMaterialProvider: WasmProver.makeV9KeyMaterialProvider() });
|
|
176
|
+
* const proven = yield* prover.proveTransaction(unprovenV9Transaction, ledger.CostModel.initialCostModel());
|
|
177
|
+
* ```;
|
|
178
|
+
*
|
|
179
|
+
* @param config Where to read from; the default host when left out.
|
|
180
|
+
* @returns A provider for {@link create} whose prover proves ledger-v9 transactions.
|
|
181
|
+
* @throws TypeError if `config.source` is not a URL.
|
|
182
|
+
*/
|
|
183
|
+
export const makeV9KeyMaterialProvider = (config) => makeKeyMaterialProvider(V9KeyMaterial, { source: config?.source ?? DefaultKeyMaterialSource });
|
|
184
|
+
/**
|
|
185
|
+
* The key material ledger-v8's circuits were generated with: circuit generation 9.
|
|
186
|
+
*
|
|
187
|
+
* @remarks
|
|
188
|
+
* The ledger-v8 twin of {@link makeV9KeyMaterialProvider}, read and checked the same way. A prover created with it
|
|
189
|
+
* proves ledger-v8 transactions, through `asV8ProvingProvider()`; ledger-v9's Dust spend circuit is a different
|
|
190
|
+
* generation, and a node rejects a Dust spend proved with the other version's key material.
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* const prover = yield* WasmProver.create({ keyMaterialProvider: WasmProver.makeV8KeyMaterialProvider() });
|
|
194
|
+
* const proven = yield* Effect.promise(() =>
|
|
195
|
+
* unprovenV8Transaction.prove(prover.asV8ProvingProvider(), ledgerV8.CostModel.initialCostModel()),
|
|
196
|
+
* );
|
|
197
|
+
* ```;
|
|
198
|
+
*
|
|
199
|
+
* @param config Where to read from; the default host when left out.
|
|
200
|
+
* @returns A provider for {@link create} whose prover proves ledger-v8 transactions.
|
|
201
|
+
* @throws TypeError if `config.source` is not a URL.
|
|
202
|
+
*/
|
|
203
|
+
export const makeV8KeyMaterialProvider = (config) => makeKeyMaterialProvider(V8KeyMaterial, { source: config?.source ?? DefaultKeyMaterialSource });
|
|
204
|
+
/**
|
|
205
|
+
* The same provider as {@link makeV9KeyMaterialProvider}.
|
|
206
|
+
*
|
|
207
|
+
* @remarks
|
|
208
|
+
* Ledger-v9's, because ledger-v9 is what this prover's own surface — `proveTransaction`, `asProvingProvider` — is typed
|
|
209
|
+
* with. A prover that proves ledger-v8 transactions wants {@link makeV8KeyMaterialProvider} instead.
|
|
210
|
+
* @example
|
|
211
|
+
* ```typescript
|
|
212
|
+
* const prover = yield* WasmProver.create({ keyMaterialProvider: WasmProver.makeDefaultKeyMaterialProvider() });
|
|
213
|
+
* ```;
|
|
214
|
+
*
|
|
215
|
+
* @param config Where to read from; the default host when left out.
|
|
216
|
+
* @returns A provider for {@link create} whose prover proves ledger-v9 transactions.
|
|
217
|
+
* @throws TypeError if `config.source` is not a URL.
|
|
218
|
+
*/
|
|
219
|
+
export const makeDefaultKeyMaterialProvider = (config) => makeV9KeyMaterialProvider(config);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midnight-ntwrk/wallet-sdk-prover-client",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -30,10 +30,11 @@
|
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@effect/platform": "^0.
|
|
33
|
+
"@effect/platform": "^0.97.0",
|
|
34
|
+
"@midnight-ntwrk/ledger-v8": "^8.1.0",
|
|
34
35
|
"@midnight-ntwrk/zkir-v2": "^2.1.0",
|
|
35
|
-
"@midnightntwrk/ledger-v9": "1.0.0-rc.
|
|
36
|
-
"@midnight-ntwrk/wallet-sdk-utilities": "1.2.0",
|
|
36
|
+
"@midnightntwrk/ledger-v9": "1.0.0-rc.5",
|
|
37
|
+
"@midnight-ntwrk/wallet-sdk-utilities": "1.2.2-beta.0",
|
|
37
38
|
"effect": "^3.19.19",
|
|
38
39
|
"web-worker": "^1.5.0"
|
|
39
40
|
},
|