@corpus-core/colibri-stateless 2.0.3 → 2.0.5
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 +15 -1
- package/c4w.js +1 -1
- package/c4w.wasm +0 -0
- package/cjs/http.js +5 -32
- package/cjs/index.js +44 -54
- package/cjs/index.node.js +53 -0
- package/cjs/runtime.js +53 -0
- package/cjs/runtime_node.js +113 -0
- package/cjs/runtime_wasm.js +132 -0
- package/cjs/wasm.js +10 -0
- package/cjs/wasm_cjs.js +10 -0
- package/http.d.ts +25 -1
- package/http.js +5 -32
- package/index.d.ts +9 -2
- package/index.js +40 -51
- package/index.node.d.ts +24 -0
- package/index.node.js +35 -0
- package/package.json +13 -3
- package/prebuilds/darwin-arm64/colibri_native.node +0 -0
- package/prebuilds/darwin-x64/colibri_native.node +0 -0
- package/prebuilds/linux-arm64/colibri_native.node +0 -0
- package/prebuilds/linux-x64/colibri_native.node +0 -0
- package/prebuilds/win32-x64/colibri_native.node +0 -0
- package/runtime.d.ts +88 -0
- package/runtime.js +49 -0
- package/runtime_node.d.ts +28 -0
- package/runtime_node.js +110 -0
- package/runtime_wasm.d.ts +28 -0
- package/runtime_wasm.js +129 -0
- package/types.d.ts +4 -1
- package/wasm.d.ts +7 -0
- package/wasm.js +11 -0
- package/wasm_cjs.d.ts +7 -0
- package/wasm_cjs.js +9 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 corpus.core
|
|
4
|
+
*
|
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
* this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
* the Software without restriction, including without limitation the rights to
|
|
8
|
+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
* subject to the following conditions:
|
|
11
|
+
*
|
|
12
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
* copies or substantial portions of the Software.
|
|
14
|
+
*
|
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
*
|
|
22
|
+
* SPDX-License-Identifier: MIT
|
|
23
|
+
*/
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.getWasmRuntime = getWasmRuntime;
|
|
26
|
+
const wasm_js_1 = require("./wasm.js");
|
|
27
|
+
const wasm_shared_js_1 = require("./wasm_shared.js");
|
|
28
|
+
// The WASM runtime wraps the pointer-level Emscripten API (`C4W`) behind the
|
|
29
|
+
// value-level `C4Runtime` interface. The module is loaded once via `getC4w()`.
|
|
30
|
+
// Note: the historical c4w_* exports say "proof_ctx" where the core C API
|
|
31
|
+
// (and this interface) say "prover" (c4_prover_create etc.).
|
|
32
|
+
function createRuntime(c4w) {
|
|
33
|
+
return {
|
|
34
|
+
kind: 'wasm',
|
|
35
|
+
getMethodType(chainId, method, paramsJson, flags) {
|
|
36
|
+
const free_buffers = [];
|
|
37
|
+
const type = c4w._c4w_get_method_type(chainId, (0, wasm_shared_js_1.as_char_ptr)(method, c4w, free_buffers), paramsJson ? (0, wasm_shared_js_1.as_char_ptr)(paramsJson, c4w, free_buffers) : 0, flags);
|
|
38
|
+
free_buffers.forEach(ptr => c4w._free(ptr));
|
|
39
|
+
return type;
|
|
40
|
+
},
|
|
41
|
+
createProverCtx(method, argsJson, chainId, flags) {
|
|
42
|
+
const free_buffers = [];
|
|
43
|
+
const ctx = c4w._c4w_create_proof_ctx((0, wasm_shared_js_1.as_char_ptr)(method, c4w, free_buffers), (0, wasm_shared_js_1.as_char_ptr)(argsJson, c4w, free_buffers), chainId, flags);
|
|
44
|
+
free_buffers.forEach(ptr => c4w._free(ptr));
|
|
45
|
+
return ctx;
|
|
46
|
+
},
|
|
47
|
+
executeProverCtx(ctx) {
|
|
48
|
+
const state = (0, wasm_shared_js_1.as_json)(c4w._c4w_execute_proof_ctx(ctx), c4w, true);
|
|
49
|
+
// On success the JSON carries the proof as heap pointer + length
|
|
50
|
+
// (owned by the prover ctx); materialize it as bytes.
|
|
51
|
+
if (state.status === 'success')
|
|
52
|
+
state.result = (0, wasm_shared_js_1.as_bytes)(state.result, state.result_len, c4w);
|
|
53
|
+
return state;
|
|
54
|
+
},
|
|
55
|
+
freeProverCtx(ctx) {
|
|
56
|
+
c4w._c4w_free_proof_ctx(ctx);
|
|
57
|
+
},
|
|
58
|
+
createVerifyCtx(proof, method, argsJson, chainId, trustedCheckpoint, witnessKeys, flags, minLatestBlockTs) {
|
|
59
|
+
const free_buffers = [];
|
|
60
|
+
const ctx = c4w._c4w_create_verify_ctx((0, wasm_shared_js_1.copy_to_c)(proof, c4w, free_buffers), proof.length, (0, wasm_shared_js_1.as_char_ptr)(method, c4w, free_buffers), (0, wasm_shared_js_1.as_char_ptr)(argsJson, c4w, free_buffers), chainId, trustedCheckpoint ? (0, wasm_shared_js_1.as_char_ptr)(trustedCheckpoint, c4w, free_buffers) : 0, witnessKeys ? (0, wasm_shared_js_1.as_char_ptr)(witnessKeys, c4w, free_buffers) : 0, flags, minLatestBlockTs);
|
|
61
|
+
free_buffers.forEach(ptr => c4w._free(ptr));
|
|
62
|
+
return ctx;
|
|
63
|
+
},
|
|
64
|
+
verifyProof(ctx) {
|
|
65
|
+
return (0, wasm_shared_js_1.as_json)(c4w._c4w_verify_proof(ctx), c4w, true);
|
|
66
|
+
},
|
|
67
|
+
freeVerifyCtx(ctx) {
|
|
68
|
+
c4w._c4w_free_verify_ctx(ctx);
|
|
69
|
+
},
|
|
70
|
+
createRpcCtx(method, paramsJson, chainId, proverFlags, verifyFlags, proverMode) {
|
|
71
|
+
const free_buffers = [];
|
|
72
|
+
const ctx = c4w._c4w_create_rpc_ctx((0, wasm_shared_js_1.as_char_ptr)(method, c4w, free_buffers), (0, wasm_shared_js_1.as_char_ptr)(paramsJson, c4w, free_buffers), chainId, proverFlags, verifyFlags, proverMode);
|
|
73
|
+
free_buffers.forEach(ptr => c4w._free(ptr));
|
|
74
|
+
return ctx;
|
|
75
|
+
},
|
|
76
|
+
executeRpcCtx(ctx) {
|
|
77
|
+
return (0, wasm_shared_js_1.as_json)(c4w._c4w_execute_rpc_ctx(ctx), c4w, true);
|
|
78
|
+
},
|
|
79
|
+
freeRpcCtx(ctx) {
|
|
80
|
+
c4w._c4w_free_rpc_ctx(ctx);
|
|
81
|
+
},
|
|
82
|
+
rpcCtxSetProxyUrls(ctx, rpcUrls, beaconUrls) {
|
|
83
|
+
const free_buffers = [];
|
|
84
|
+
c4w._c4w_rpc_ctx_set_proxy_urls(ctx, (0, wasm_shared_js_1.as_char_ptr)(rpcUrls, c4w, free_buffers), (0, wasm_shared_js_1.as_char_ptr)(beaconUrls, c4w, free_buffers));
|
|
85
|
+
free_buffers.forEach(ptr => c4w._free(ptr));
|
|
86
|
+
},
|
|
87
|
+
rpcCtxSetWitnessKeys(ctx, keys) {
|
|
88
|
+
const free_buffers = [];
|
|
89
|
+
c4w._c4w_rpc_ctx_set_witness_keys(ctx, (0, wasm_shared_js_1.as_char_ptr)(keys, c4w, free_buffers));
|
|
90
|
+
free_buffers.forEach(ptr => c4w._free(ptr));
|
|
91
|
+
},
|
|
92
|
+
rpcCtxSetMinLatestBlockTs(ctx, ts) {
|
|
93
|
+
c4w._c4w_rpc_ctx_set_min_latest_block_ts(ctx, ts);
|
|
94
|
+
},
|
|
95
|
+
setCheckpoint(chainId, checkpoint) {
|
|
96
|
+
const free_buffers = [];
|
|
97
|
+
c4w._c4w_set_checkpoint(chainId, (0, wasm_shared_js_1.as_char_ptr)(checkpoint, c4w, free_buffers));
|
|
98
|
+
free_buffers.forEach(ptr => c4w._free(ptr));
|
|
99
|
+
},
|
|
100
|
+
reqSetResponse(req, data, nodeIndex) {
|
|
101
|
+
// ownership of the copied bytes is transferred to the C context
|
|
102
|
+
c4w._c4w_req_set_response(req.req_ptr, (0, wasm_shared_js_1.copy_to_c)(data, c4w), data.length, nodeIndex);
|
|
103
|
+
},
|
|
104
|
+
reqSetError(req, error, nodeIndex) {
|
|
105
|
+
const free_buffers = [];
|
|
106
|
+
c4w._c4w_req_set_error(req.req_ptr, (0, wasm_shared_js_1.as_char_ptr)(error, c4w, free_buffers), nodeIndex);
|
|
107
|
+
free_buffers.forEach(ptr => c4w._free(ptr));
|
|
108
|
+
},
|
|
109
|
+
decodeProof(proof) {
|
|
110
|
+
const free_buffers = [];
|
|
111
|
+
const ptr = (0, wasm_shared_js_1.copy_to_c)(proof, c4w, free_buffers);
|
|
112
|
+
const resultPtr = c4w._c4w_decode_proof(ptr, proof.length);
|
|
113
|
+
free_buffers.forEach(p => c4w._free(p));
|
|
114
|
+
if (!resultPtr)
|
|
115
|
+
throw new Error('Unknown proof format');
|
|
116
|
+
return (0, wasm_shared_js_1.as_json)(resultPtr, c4w, true);
|
|
117
|
+
},
|
|
118
|
+
registerStorage(storage) {
|
|
119
|
+
c4w.storage = storage;
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
let runtime = null;
|
|
124
|
+
/**
|
|
125
|
+
* Returns the (cached) WASM-backed runtime.
|
|
126
|
+
* @return Initialized WASM runtime
|
|
127
|
+
*/
|
|
128
|
+
function getWasmRuntime() {
|
|
129
|
+
if (!runtime)
|
|
130
|
+
runtime = (0, wasm_js_1.getC4w)().then(createRuntime);
|
|
131
|
+
return runtime;
|
|
132
|
+
}
|
package/cjs/wasm.js
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.decode_proof = exports.set_trusted_checkpoint = exports.get_prover_config_hex = exports.getC4w = exports.loadC4WModule = exports.set_wasm_url = exports.get_default_storage = exports.copy_to_c = exports.as_json = exports.as_char_ptr = exports.as_bytes = void 0;
|
|
26
|
+
exports.module_dir = module_dir;
|
|
26
27
|
// This file is used only for the CommonJS build output. It must not use
|
|
27
28
|
// `import.meta` because that is a parse error in CommonJS environments (e.g. Jest).
|
|
28
29
|
const node_path_1 = require("node:path");
|
|
@@ -64,3 +65,12 @@ exports.getC4w = api.getC4w;
|
|
|
64
65
|
exports.get_prover_config_hex = api.get_prover_config_hex;
|
|
65
66
|
exports.set_trusted_checkpoint = api.set_trusted_checkpoint;
|
|
66
67
|
exports.decode_proof = api.decode_proof;
|
|
68
|
+
/**
|
|
69
|
+
* Returns the directory of the compiled module. Used in Node to locate
|
|
70
|
+
* packaged assets (e.g. native addon prebuilds) relative to the package root.
|
|
71
|
+
* This CJS variant replaces `wasm.ts` (ESM, `import.meta.url`) at build time.
|
|
72
|
+
* @return Absolute directory path of this module
|
|
73
|
+
*/
|
|
74
|
+
async function module_dir() {
|
|
75
|
+
return __dirname;
|
|
76
|
+
}
|
package/cjs/wasm_cjs.js
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.decode_proof = exports.set_trusted_checkpoint = exports.get_prover_config_hex = exports.getC4w = exports.loadC4WModule = exports.set_wasm_url = exports.get_default_storage = exports.copy_to_c = exports.as_json = exports.as_char_ptr = exports.as_bytes = void 0;
|
|
26
|
+
exports.module_dir = module_dir;
|
|
26
27
|
// This file is used only for the CommonJS build output. It must not use
|
|
27
28
|
// `import.meta` because that is a parse error in CommonJS environments (e.g. Jest).
|
|
28
29
|
const node_path_1 = require("node:path");
|
|
@@ -64,3 +65,12 @@ exports.getC4w = api.getC4w;
|
|
|
64
65
|
exports.get_prover_config_hex = api.get_prover_config_hex;
|
|
65
66
|
exports.set_trusted_checkpoint = api.set_trusted_checkpoint;
|
|
66
67
|
exports.decode_proof = api.decode_proof;
|
|
68
|
+
/**
|
|
69
|
+
* Returns the directory of the compiled module. Used in Node to locate
|
|
70
|
+
* packaged assets (e.g. native addon prebuilds) relative to the package root.
|
|
71
|
+
* This CJS variant replaces `wasm.ts` (ESM, `import.meta.url`) at build time.
|
|
72
|
+
* @return Absolute directory path of this module
|
|
73
|
+
*/
|
|
74
|
+
async function module_dir() {
|
|
75
|
+
return __dirname;
|
|
76
|
+
}
|
package/http.d.ts
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 corpus.core
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
5
|
+
* this software and associated documentation files (the "Software"), to deal in
|
|
6
|
+
* the Software without restriction, including without limitation the rights to
|
|
7
|
+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
8
|
+
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
9
|
+
* subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
16
|
+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
17
|
+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
18
|
+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
19
|
+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
20
|
+
*
|
|
21
|
+
* SPDX-License-Identifier: MIT
|
|
22
|
+
*/
|
|
23
|
+
import type { C4Runtime } from './runtime.js';
|
|
1
24
|
import { Config as C4Config, DataRequest } from './types.js';
|
|
2
25
|
export type AcceptKind = 'json' | 'octet';
|
|
3
26
|
/**
|
|
@@ -17,7 +40,8 @@ export declare function fetch_rpc(urls: string[], payload: any, as_proof?: boole
|
|
|
17
40
|
/**
|
|
18
41
|
* Handles a C4 data request by fetching from configured servers, setting the
|
|
19
42
|
* response or error back into the C context, and leveraging cache if present.
|
|
43
|
+
* @param runtime The active runtime the request originated from
|
|
20
44
|
* @param req DataRequest descriptor from C
|
|
21
45
|
* @param conf Colibri configuration
|
|
22
46
|
*/
|
|
23
|
-
export declare function handle_request(req: DataRequest, conf: C4Config): Promise<void>;
|
|
47
|
+
export declare function handle_request(runtime: C4Runtime, req: DataRequest, conf: C4Config): Promise<void>;
|
package/http.js
CHANGED
|
@@ -1,26 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2025 corpus.core
|
|
3
|
-
*
|
|
4
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
5
|
-
* this software and associated documentation files (the "Software"), to deal in
|
|
6
|
-
* the Software without restriction, including without limitation the rights to
|
|
7
|
-
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
8
|
-
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
9
|
-
* subject to the following conditions:
|
|
10
|
-
*
|
|
11
|
-
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
-
* copies or substantial portions of the Software.
|
|
13
|
-
*
|
|
14
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
16
|
-
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
17
|
-
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
18
|
-
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
19
|
-
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
20
|
-
*
|
|
21
|
-
* SPDX-License-Identifier: MIT
|
|
22
|
-
*/
|
|
23
|
-
import { getC4w, as_char_ptr, copy_to_c } from './wasm.js';
|
|
24
1
|
function joinPath(base, path) {
|
|
25
2
|
if (!path)
|
|
26
3
|
return base;
|
|
@@ -158,11 +135,11 @@ export async function fetch_rpc(urls, payload, as_proof = false, fetchFn = globa
|
|
|
158
135
|
/**
|
|
159
136
|
* Handles a C4 data request by fetching from configured servers, setting the
|
|
160
137
|
* response or error back into the C context, and leveraging cache if present.
|
|
138
|
+
* @param runtime The active runtime the request originated from
|
|
161
139
|
* @param req DataRequest descriptor from C
|
|
162
140
|
* @param conf Colibri configuration
|
|
163
141
|
*/
|
|
164
|
-
export async function handle_request(req, conf) {
|
|
165
|
-
const free_buffers = [];
|
|
142
|
+
export async function handle_request(runtime, req, conf) {
|
|
166
143
|
// Honor a requested delay before (re-)executing (e.g. oblivious-node retry backoff).
|
|
167
144
|
if (req.delay && req.delay > 0)
|
|
168
145
|
await new Promise(resolve => setTimeout(resolve, req.delay));
|
|
@@ -185,7 +162,6 @@ export async function handle_request(req, conf) {
|
|
|
185
162
|
servers = conf.rpcs || [...((conf.prover || []).map(p => p + (p.endsWith('/') ? '' : '/') + 'unverified_rpc'))];
|
|
186
163
|
break;
|
|
187
164
|
}
|
|
188
|
-
const c4w = await getC4w();
|
|
189
165
|
let path = (req.type == 'eth_rpc' && req.payload)
|
|
190
166
|
? `rpc: ${req.payload?.method}(${req.payload?.params.join(',')})`
|
|
191
167
|
: req.url;
|
|
@@ -195,7 +171,7 @@ export async function handle_request(req, conf) {
|
|
|
195
171
|
if (data) {
|
|
196
172
|
if (conf.debug)
|
|
197
173
|
log(`::: ${path} (len=${data.length} bytes) CACHED`);
|
|
198
|
-
|
|
174
|
+
runtime.reqSetResponse(req, data, 0);
|
|
199
175
|
if (conf.onTransfer)
|
|
200
176
|
conf.onTransfer(data.length, req);
|
|
201
177
|
return;
|
|
@@ -205,7 +181,7 @@ export async function handle_request(req, conf) {
|
|
|
205
181
|
const accept = req.encoding == 'json' ? 'json' : 'octet';
|
|
206
182
|
const fetchFn = conf.fetch || globalThis.fetch;
|
|
207
183
|
const { data, nodeIndex } = await fetch_from_servers(servers, req.url || '', req.method, req.payload, accept, req.exclude_mask, fetchFn, req.ttl);
|
|
208
|
-
|
|
184
|
+
runtime.reqSetResponse(req, data, nodeIndex);
|
|
209
185
|
if (conf.onTransfer)
|
|
210
186
|
conf.onTransfer(data.length, req);
|
|
211
187
|
if (conf.debug)
|
|
@@ -215,11 +191,8 @@ export async function handle_request(req, conf) {
|
|
|
215
191
|
}
|
|
216
192
|
catch (e) {
|
|
217
193
|
const last_error = (e instanceof Error) ? e.message : String(e);
|
|
218
|
-
|
|
194
|
+
runtime.reqSetError(req, last_error, 0);
|
|
219
195
|
if (conf.debug)
|
|
220
196
|
log(`::: ${path} (Error: ${last_error})`);
|
|
221
197
|
}
|
|
222
|
-
finally {
|
|
223
|
-
free_buffers.forEach(ptr => c4w._free(ptr));
|
|
224
|
-
}
|
|
225
198
|
}
|
package/index.d.ts
CHANGED
|
@@ -20,12 +20,19 @@
|
|
|
20
20
|
*
|
|
21
21
|
* SPDX-License-Identifier: MIT
|
|
22
22
|
*/
|
|
23
|
-
import { Storage as C4Storage } from
|
|
23
|
+
import { type Storage as C4Storage } from './runtime.js';
|
|
24
24
|
import { ProviderRpcError, RequestArguments, Cache, Config as C4Config, DataRequest, MethodType as C4MethodType, ProviderMessage, ProverMode } from './types.js';
|
|
25
25
|
import { EthSubscribeSubscriptionType, EthNewFilterType } from './subscriptionManager.js';
|
|
26
26
|
import Strategy from './strategy.js';
|
|
27
27
|
export { Strategy };
|
|
28
|
-
export { set_wasm_url
|
|
28
|
+
export { set_wasm_url } from "./wasm.js";
|
|
29
|
+
export { getRuntime, type C4Runtime, type RuntimeStatus } from './runtime.js';
|
|
30
|
+
/**
|
|
31
|
+
* Decodes a serialized proof into its JSON representation using the active runtime.
|
|
32
|
+
* @param proof The proof bytes
|
|
33
|
+
* @return The decoded proof as JSON
|
|
34
|
+
*/
|
|
35
|
+
export declare function decode_proof(proof: Uint8Array): Promise<any>;
|
|
29
36
|
export { ProviderRpcError, RequestArguments, Cache, C4Config, DataRequest, C4MethodType as MethodType, ProviderMessage, EthSubscribeSubscriptionType, EthNewFilterType, ProverMode };
|
|
30
37
|
export { TransactionVerifier, PrototypeProtection } from './transactionVerifier.js';
|
|
31
38
|
export default class C4Client {
|
package/index.js
CHANGED
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
*
|
|
21
21
|
* SPDX-License-Identifier: MIT
|
|
22
22
|
*/
|
|
23
|
-
//
|
|
24
|
-
import {
|
|
23
|
+
// Runtime abstraction: WASM (browser/default) or native addon (Node.js entry)
|
|
24
|
+
import { getRuntime } from './runtime.js';
|
|
25
25
|
import { EventEmitter } from './eventEmitter.js';
|
|
26
26
|
import { ConnectionState } from './connectionState.js';
|
|
27
27
|
import { ProviderRpcError, MethodType as C4MethodType } from './types.js';
|
|
@@ -32,7 +32,17 @@ import { TransactionVerifier, PrototypeProtection } from './transactionVerifier.
|
|
|
32
32
|
import { fetch_rpc, handle_request } from './http.js';
|
|
33
33
|
export { Strategy };
|
|
34
34
|
// Public helper for controlling WASM loading behavior in Node/bundlers.
|
|
35
|
-
export { set_wasm_url
|
|
35
|
+
export { set_wasm_url } from "./wasm.js";
|
|
36
|
+
// Runtime introspection (e.g. to check whether the native addon is active in Node).
|
|
37
|
+
export { getRuntime } from './runtime.js';
|
|
38
|
+
/**
|
|
39
|
+
* Decodes a serialized proof into its JSON representation using the active runtime.
|
|
40
|
+
* @param proof The proof bytes
|
|
41
|
+
* @return The decoded proof as JSON
|
|
42
|
+
*/
|
|
43
|
+
export async function decode_proof(proof) {
|
|
44
|
+
return (await getRuntime()).decodeProof(proof);
|
|
45
|
+
}
|
|
36
46
|
// Re-export types needed by consumers of the C4Client module
|
|
37
47
|
export { ProviderRpcError, C4MethodType as MethodType };
|
|
38
48
|
// Re-export transaction verification utilities
|
|
@@ -126,12 +136,9 @@ class C4Client {
|
|
|
126
136
|
* @returns The method type
|
|
127
137
|
*/
|
|
128
138
|
async getMethodSupport(method, args) {
|
|
129
|
-
const
|
|
130
|
-
const free_buffers = [];
|
|
139
|
+
const runtime = await getRuntime();
|
|
131
140
|
const paramsStr = args ? JSON.stringify(args) : null;
|
|
132
|
-
|
|
133
|
-
free_buffers.forEach(ptr => c4w._free(ptr));
|
|
134
|
-
return method_type;
|
|
141
|
+
return runtime.getMethodType(BigInt(this.config.chainId), method, paramsStr, this.verify_flags);
|
|
135
142
|
}
|
|
136
143
|
/**
|
|
137
144
|
* Creates a proof for the given method and arguments.
|
|
@@ -140,30 +147,27 @@ class C4Client {
|
|
|
140
147
|
* @returns The proof
|
|
141
148
|
*/
|
|
142
149
|
async createProof(method, args) {
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
let ctx = 0;
|
|
150
|
+
const runtime = await getRuntime();
|
|
151
|
+
let ctx = null;
|
|
146
152
|
try {
|
|
147
|
-
|
|
148
|
-
ctx = c4w._c4w_create_proof_ctx(as_char_ptr(method, c4w, free_buffers), as_char_ptr(JSON.stringify(args), c4w, free_buffers), BigInt(this.config.chainId), this.flags);
|
|
153
|
+
ctx = runtime.createProverCtx(method, JSON.stringify(args), BigInt(this.config.chainId), this.flags);
|
|
149
154
|
while (true) {
|
|
150
|
-
const state =
|
|
155
|
+
const state = runtime.executeProverCtx(ctx);
|
|
151
156
|
switch (state.status) {
|
|
152
157
|
case "success":
|
|
153
|
-
return
|
|
158
|
+
return state.result;
|
|
154
159
|
case "error":
|
|
155
160
|
throw new Error(state.error);
|
|
156
161
|
case "pending": {
|
|
157
|
-
await Promise.all(state.requests.map((req) => handle_request(req, this.config)));
|
|
162
|
+
await Promise.all(state.requests.map((req) => handle_request(runtime, req, this.config)));
|
|
158
163
|
break;
|
|
159
164
|
}
|
|
160
165
|
}
|
|
161
166
|
}
|
|
162
167
|
}
|
|
163
168
|
finally {
|
|
164
|
-
free_buffers.forEach(ptr => c4w._free(ptr));
|
|
165
169
|
if (ctx)
|
|
166
|
-
|
|
170
|
+
runtime.freeProverCtx(ctx);
|
|
167
171
|
}
|
|
168
172
|
}
|
|
169
173
|
/**
|
|
@@ -174,20 +178,12 @@ class C4Client {
|
|
|
174
178
|
* @returns The result
|
|
175
179
|
*/
|
|
176
180
|
async verifyProof(method, args, proof) {
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
let ctx = 0;
|
|
181
|
+
const runtime = await getRuntime();
|
|
182
|
+
let ctx = null;
|
|
180
183
|
try {
|
|
181
|
-
|
|
182
|
-
const checkpoint_ptr = this.config.trusted_checkpoint
|
|
183
|
-
? as_char_ptr(this.config.trusted_checkpoint, c4w, free_buffers)
|
|
184
|
-
: 0;
|
|
185
|
-
const witness_keys_ptr = this.config.checkpoint_witness_keys
|
|
186
|
-
? as_char_ptr(this.config.checkpoint_witness_keys, c4w, free_buffers)
|
|
187
|
-
: 0;
|
|
188
|
-
ctx = c4w._c4w_create_verify_ctx(copy_to_c(proof, c4w, free_buffers), proof.length, as_char_ptr(method, c4w, free_buffers), as_char_ptr(JSON.stringify(args), c4w, free_buffers), BigInt(this.config.chainId), checkpoint_ptr, witness_keys_ptr, this.verify_flags, this.get_min_latest_block_ts());
|
|
184
|
+
ctx = runtime.createVerifyCtx(proof, method, JSON.stringify(args), BigInt(this.config.chainId), this.config.trusted_checkpoint || null, this.config.checkpoint_witness_keys || null, this.verify_flags, this.get_min_latest_block_ts());
|
|
189
185
|
while (true) {
|
|
190
|
-
const state =
|
|
186
|
+
const state = runtime.verifyProof(ctx);
|
|
191
187
|
switch (state.status) {
|
|
192
188
|
case "success":
|
|
193
189
|
return state.result;
|
|
@@ -196,16 +192,15 @@ class C4Client {
|
|
|
196
192
|
case "error":
|
|
197
193
|
throw new Error(state.error);
|
|
198
194
|
case "pending": {
|
|
199
|
-
await Promise.all(state.requests.map((req) => handle_request(req, this.config)));
|
|
195
|
+
await Promise.all(state.requests.map((req) => handle_request(runtime, req, this.config)));
|
|
200
196
|
break;
|
|
201
197
|
}
|
|
202
198
|
}
|
|
203
199
|
}
|
|
204
200
|
}
|
|
205
201
|
finally {
|
|
206
|
-
free_buffers.forEach(ptr => c4w._free(ptr));
|
|
207
202
|
if (ctx)
|
|
208
|
-
|
|
203
|
+
runtime.freeVerifyCtx(ctx);
|
|
209
204
|
}
|
|
210
205
|
}
|
|
211
206
|
/**
|
|
@@ -227,9 +222,8 @@ class C4Client {
|
|
|
227
222
|
method_type = await this.getMethodSupport(method, args);
|
|
228
223
|
if (method_type === C4MethodType.PROOFABLE && this.config.verify && !this.config.verify(method, args))
|
|
229
224
|
return await fetch_rpc(this.config.rpcs, { method, params: args }, false, this.config.fetch);
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
let ctx = 0;
|
|
225
|
+
const runtime = await getRuntime();
|
|
226
|
+
let ctx = null;
|
|
233
227
|
try {
|
|
234
228
|
const prover_mode_map = { local: 0, remote: 1, hybrid: 2, proxy: 3, light_client: 4 };
|
|
235
229
|
const resolved_mode = this.config.prover_mode ?? (this.config.prover?.length ? 'remote' : 'local');
|
|
@@ -237,19 +231,16 @@ class C4Client {
|
|
|
237
231
|
let prover_flags = this.flags;
|
|
238
232
|
if (this.config.zk_proof)
|
|
239
233
|
prover_flags |= (1 << 7);
|
|
240
|
-
ctx =
|
|
241
|
-
if (resolved_mode === 'proxy')
|
|
242
|
-
|
|
243
|
-
const beacon_csv = this.config.beacon_apis.join(',');
|
|
244
|
-
c4w._c4w_rpc_ctx_set_proxy_urls(ctx, as_char_ptr(rpc_csv, c4w, free_buffers), as_char_ptr(beacon_csv, c4w, free_buffers));
|
|
245
|
-
}
|
|
234
|
+
ctx = runtime.createRpcCtx(method, JSON.stringify(args || []), BigInt(this.config.chainId), prover_flags, this.verify_flags, native_mode);
|
|
235
|
+
if (resolved_mode === 'proxy')
|
|
236
|
+
runtime.rpcCtxSetProxyUrls(ctx, this.config.rpcs.join(','), this.config.beacon_apis.join(','));
|
|
246
237
|
if (this.config.trusted_checkpoint)
|
|
247
|
-
|
|
238
|
+
runtime.setCheckpoint(BigInt(this.config.chainId), this.config.trusted_checkpoint);
|
|
248
239
|
if (this.config.checkpoint_witness_keys)
|
|
249
|
-
|
|
250
|
-
|
|
240
|
+
runtime.rpcCtxSetWitnessKeys(ctx, this.config.checkpoint_witness_keys);
|
|
241
|
+
runtime.rpcCtxSetMinLatestBlockTs(ctx, this.get_min_latest_block_ts());
|
|
251
242
|
while (true) {
|
|
252
|
-
const state =
|
|
243
|
+
const state = runtime.executeRpcCtx(ctx);
|
|
253
244
|
switch (state.status) {
|
|
254
245
|
case "success":
|
|
255
246
|
return state.result;
|
|
@@ -263,20 +254,18 @@ class C4Client {
|
|
|
263
254
|
}
|
|
264
255
|
throw new Error(state.error);
|
|
265
256
|
case "pending":
|
|
266
|
-
await Promise.all(state.requests.map((req) => handle_request(req, this.config)));
|
|
257
|
+
await Promise.all(state.requests.map((req) => handle_request(runtime, req, this.config)));
|
|
267
258
|
break;
|
|
268
259
|
}
|
|
269
260
|
}
|
|
270
261
|
}
|
|
271
262
|
finally {
|
|
272
|
-
free_buffers.forEach(ptr => c4w._free(ptr));
|
|
273
263
|
if (ctx)
|
|
274
|
-
|
|
264
|
+
runtime.freeRpcCtx(ctx);
|
|
275
265
|
}
|
|
276
266
|
}
|
|
277
267
|
static async register_storage(storage) {
|
|
278
|
-
|
|
279
|
-
c4w.storage = storage;
|
|
268
|
+
(await getRuntime()).registerStorage(storage);
|
|
280
269
|
}
|
|
281
270
|
async request(args) {
|
|
282
271
|
if (!this.connectionState.initialConnectionAttempted) {
|
package/index.node.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 corpus.core
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
5
|
+
* this software and associated documentation files (the "Software"), to deal in
|
|
6
|
+
* the Software without restriction, including without limitation the rights to
|
|
7
|
+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
8
|
+
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
9
|
+
* subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
16
|
+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
17
|
+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
18
|
+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
19
|
+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
20
|
+
*
|
|
21
|
+
* SPDX-License-Identifier: MIT
|
|
22
|
+
*/
|
|
23
|
+
export * from './index.js';
|
|
24
|
+
export { default } from './index.js';
|
package/index.node.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 corpus.core
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
5
|
+
* this software and associated documentation files (the "Software"), to deal in
|
|
6
|
+
* the Software without restriction, including without limitation the rights to
|
|
7
|
+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
8
|
+
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
9
|
+
* subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
16
|
+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
17
|
+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
18
|
+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
19
|
+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
20
|
+
*
|
|
21
|
+
* SPDX-License-Identifier: MIT
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Node.js entry point (selected via `package.json` conditional exports).
|
|
25
|
+
*
|
|
26
|
+
* Uses the native N-API addon when a prebuild for the current platform is
|
|
27
|
+
* available (blst with platform-optimized assembly, ~10x faster BLS pairing)
|
|
28
|
+
* and transparently falls back to the WASM build otherwise. Browser bundlers
|
|
29
|
+
* never see this file.
|
|
30
|
+
*/
|
|
31
|
+
import { setRuntimeProvider } from './runtime.js';
|
|
32
|
+
import { getNodeRuntime } from './runtime_node.js';
|
|
33
|
+
setRuntimeProvider(getNodeRuntime);
|
|
34
|
+
export * from './index.js';
|
|
35
|
+
export { default } from './index.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@corpus-core/colibri-stateless",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "Colibri is a stateless and trustless ethereum client, which is optimized for the mobile apps or embedded devices, because it does not hols the state, but verifies on demand.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -8,13 +8,20 @@
|
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./index.d.ts",
|
|
11
|
+
"browser": "./index.js",
|
|
12
|
+
"node": {
|
|
13
|
+
"import": "./index.node.js",
|
|
14
|
+
"require": "./cjs/index.node.js"
|
|
15
|
+
},
|
|
11
16
|
"import": "./index.js",
|
|
12
17
|
"require": "./cjs/index.js"
|
|
13
|
-
}
|
|
18
|
+
},
|
|
19
|
+
"./package.json": "./package.json"
|
|
14
20
|
},
|
|
15
21
|
"scripts": {
|
|
16
22
|
"test": "npm run test:node && npm run test:webpack",
|
|
17
|
-
"test:node": "node --test test/rpc.test.mjs test/cjs_bridge.test.mjs",
|
|
23
|
+
"test:node": "node --test test/rpc.test.mjs test/cjs_bridge.test.mjs test/runtime_selection.test.mjs",
|
|
24
|
+
"test:node:native": "node --test test/native.test.mjs",
|
|
18
25
|
"test:integration": "C4_RUN_INTEGRATION=1 node --test test/integration.test.mjs",
|
|
19
26
|
"test:ccip": "C4_RUN_INTEGRATION=1 node --test test/ens_ccip.test.mjs",
|
|
20
27
|
"test:webpack": "npm run webpack:install && npm run webpack:build",
|
|
@@ -57,6 +64,9 @@
|
|
|
57
64
|
"devDependencies": {
|
|
58
65
|
"ethers": "^6.16.0"
|
|
59
66
|
},
|
|
67
|
+
"overrides": {
|
|
68
|
+
"ws": "^8.21.3"
|
|
69
|
+
},
|
|
60
70
|
"publishConfig": {
|
|
61
71
|
"access": "public"
|
|
62
72
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|