@aztec/bb.js 1.0.0-nightly.20250725 → 1.0.0-nightly.20250727

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dest/browser/barretenberg/backend.d.ts.map +1 -1
  2. package/dest/browser/barretenberg/backend.js +54 -43
  3. package/dest/browser/barretenberg/index.d.ts +10 -0
  4. package/dest/browser/barretenberg/index.d.ts.map +1 -1
  5. package/dest/browser/barretenberg/index.js +28 -1
  6. package/dest/browser/barretenberg_wasm/barretenberg_wasm_base/index.d.ts +1 -0
  7. package/dest/browser/barretenberg_wasm/barretenberg_wasm_base/index.d.ts.map +1 -1
  8. package/dest/browser/barretenberg_wasm/barretenberg_wasm_base/index.js +5 -4
  9. package/dest/browser/barretenberg_wasm/barretenberg_wasm_main/index.d.ts +2 -0
  10. package/dest/browser/barretenberg_wasm/barretenberg_wasm_main/index.d.ts.map +1 -1
  11. package/dest/browser/barretenberg_wasm/barretenberg_wasm_main/index.js +17 -1
  12. package/dest/browser/barretenberg_wasm/barretenberg_wasm_thread/index.d.ts +1 -0
  13. package/dest/browser/barretenberg_wasm/barretenberg_wasm_thread/index.d.ts.map +1 -1
  14. package/dest/browser/barretenberg_wasm/fetch_code/browser/barretenberg-threads.js +1 -1
  15. package/dest/browser/barretenberg_wasm/fetch_code/browser/barretenberg.js +1 -1
  16. package/dest/browser/cbind/generate.d.ts +5 -0
  17. package/dest/browser/cbind/generate.d.ts.map +1 -0
  18. package/dest/browser/cbind/generate.js +64 -0
  19. package/dest/browser/cbind/generated/api_types.d.ts +801 -0
  20. package/dest/browser/cbind/generated/api_types.d.ts.map +1 -0
  21. package/dest/browser/cbind/generated/api_types.js +1099 -0
  22. package/dest/browser/cbind/generated/async.d.ts +27 -0
  23. package/dest/browser/cbind/generated/async.d.ts.map +1 -0
  24. package/dest/browser/cbind/generated/async.js +184 -0
  25. package/dest/browser/cbind/generated/native.d.ts +35 -0
  26. package/dest/browser/cbind/generated/native.d.ts.map +1 -0
  27. package/dest/browser/cbind/generated/native.js +270 -0
  28. package/dest/browser/cbind/generated/sync.d.ts +27 -0
  29. package/dest/browser/cbind/generated/sync.d.ts.map +1 -0
  30. package/dest/browser/cbind/generated/sync.js +165 -0
  31. package/dest/browser/cbind/schema_compiler.d.ts +70 -0
  32. package/dest/browser/cbind/schema_compiler.d.ts.map +1 -0
  33. package/dest/browser/cbind/schema_compiler.js +683 -0
  34. package/dest/node/barretenberg/backend.d.ts.map +1 -1
  35. package/dest/node/barretenberg/backend.js +54 -43
  36. package/dest/node/barretenberg/index.d.ts +10 -0
  37. package/dest/node/barretenberg/index.d.ts.map +1 -1
  38. package/dest/node/barretenberg/index.js +28 -1
  39. package/dest/node/barretenberg_wasm/barretenberg-threads.wasm.gz +0 -0
  40. package/dest/node/barretenberg_wasm/barretenberg_wasm_base/index.d.ts +1 -0
  41. package/dest/node/barretenberg_wasm/barretenberg_wasm_base/index.d.ts.map +1 -1
  42. package/dest/node/barretenberg_wasm/barretenberg_wasm_base/index.js +5 -4
  43. package/dest/node/barretenberg_wasm/barretenberg_wasm_main/index.d.ts +2 -0
  44. package/dest/node/barretenberg_wasm/barretenberg_wasm_main/index.d.ts.map +1 -1
  45. package/dest/node/barretenberg_wasm/barretenberg_wasm_main/index.js +17 -1
  46. package/dest/node/barretenberg_wasm/barretenberg_wasm_thread/index.d.ts +1 -0
  47. package/dest/node/barretenberg_wasm/barretenberg_wasm_thread/index.d.ts.map +1 -1
  48. package/dest/node/cbind/generate.d.ts +5 -0
  49. package/dest/node/cbind/generate.d.ts.map +1 -0
  50. package/dest/node/cbind/generate.js +64 -0
  51. package/dest/node/cbind/generated/api_types.d.ts +801 -0
  52. package/dest/node/cbind/generated/api_types.d.ts.map +1 -0
  53. package/dest/node/cbind/generated/api_types.js +1099 -0
  54. package/dest/node/cbind/generated/async.d.ts +27 -0
  55. package/dest/node/cbind/generated/async.d.ts.map +1 -0
  56. package/dest/node/cbind/generated/async.js +184 -0
  57. package/dest/node/cbind/generated/native.d.ts +35 -0
  58. package/dest/node/cbind/generated/native.d.ts.map +1 -0
  59. package/dest/node/cbind/generated/native.js +270 -0
  60. package/dest/node/cbind/generated/sync.d.ts +27 -0
  61. package/dest/node/cbind/generated/sync.d.ts.map +1 -0
  62. package/dest/node/cbind/generated/sync.js +165 -0
  63. package/dest/node/cbind/schema_compiler.d.ts +70 -0
  64. package/dest/node/cbind/schema_compiler.d.ts.map +1 -0
  65. package/dest/node/cbind/schema_compiler.js +683 -0
  66. package/dest/node-cjs/barretenberg/backend.d.ts.map +1 -1
  67. package/dest/node-cjs/barretenberg/backend.js +56 -45
  68. package/dest/node-cjs/barretenberg/index.d.ts +10 -0
  69. package/dest/node-cjs/barretenberg/index.d.ts.map +1 -1
  70. package/dest/node-cjs/barretenberg/index.js +28 -1
  71. package/dest/node-cjs/barretenberg_wasm/barretenberg-threads.wasm.gz +0 -0
  72. package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_base/index.d.ts +1 -0
  73. package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_base/index.d.ts.map +1 -1
  74. package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_base/index.js +5 -4
  75. package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_main/index.d.ts +2 -0
  76. package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_main/index.d.ts.map +1 -1
  77. package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_main/index.js +17 -1
  78. package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_thread/index.d.ts +1 -0
  79. package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_thread/index.d.ts.map +1 -1
  80. package/dest/node-cjs/cbind/generate.d.ts +5 -0
  81. package/dest/node-cjs/cbind/generate.d.ts.map +1 -0
  82. package/dest/node-cjs/cbind/generate.js +66 -0
  83. package/dest/node-cjs/cbind/generated/api_types.d.ts +801 -0
  84. package/dest/node-cjs/cbind/generated/api_types.d.ts.map +1 -0
  85. package/dest/node-cjs/cbind/generated/api_types.js +1189 -0
  86. package/dest/node-cjs/cbind/generated/async.d.ts +27 -0
  87. package/dest/node-cjs/cbind/generated/async.d.ts.map +1 -0
  88. package/dest/node-cjs/cbind/generated/async.js +188 -0
  89. package/dest/node-cjs/cbind/generated/native.d.ts +35 -0
  90. package/dest/node-cjs/cbind/generated/native.d.ts.map +1 -0
  91. package/dest/node-cjs/cbind/generated/native.js +274 -0
  92. package/dest/node-cjs/cbind/generated/sync.d.ts +27 -0
  93. package/dest/node-cjs/cbind/generated/sync.d.ts.map +1 -0
  94. package/dest/node-cjs/cbind/generated/sync.js +169 -0
  95. package/dest/node-cjs/cbind/schema_compiler.d.ts +70 -0
  96. package/dest/node-cjs/cbind/schema_compiler.d.ts.map +1 -0
  97. package/dest/node-cjs/cbind/schema_compiler.js +691 -0
  98. package/package.json +4 -3
  99. package/src/barretenberg/backend.ts +60 -61
  100. package/src/barretenberg/index.ts +37 -0
  101. package/src/barretenberg_wasm/barretenberg_wasm_base/index.ts +5 -3
  102. package/src/barretenberg_wasm/barretenberg_wasm_main/index.ts +23 -0
  103. package/src/cbind/README.md +1 -0
  104. package/src/cbind/generate.ts +89 -0
  105. package/src/cbind/schema_compiler.ts +832 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@aztec/bb.js",
3
3
  "packageManager": "yarn@4.5.2",
4
- "version": "1.0.0-nightly.20250725",
4
+ "version": "1.0.0-nightly.20250727",
5
5
  "homepage": "https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg/ts",
6
6
  "license": "MIT",
7
7
  "type": "module",
@@ -21,13 +21,14 @@
21
21
  "README.md"
22
22
  ],
23
23
  "scripts": {
24
- "clean": "rm -rf ./dest .tsbuildinfo .tsbuildinfo.cjs",
25
- "build": "yarn clean && yarn build:wasm && yarn build:esm && yarn build:cjs && yarn build:browser",
24
+ "clean": "rm -rf ./dest .tsbuildinfo .tsbuildinfo.cjs ./src/cbind/generated",
25
+ "build": "yarn clean && yarn generate && yarn build:wasm && yarn build:esm && yarn build:cjs && yarn build:browser",
26
26
  "build:wasm": "./scripts/build_wasm.sh",
27
27
  "build:esm": "tsc -b tsconfig.esm.json && chmod +x ./dest/node/main.js",
28
28
  "build:cjs": "tsc -b tsconfig.cjs.json && ./scripts/cjs_postprocess.sh",
29
29
  "build:browser": "tsc -b tsconfig.browser.json && ./scripts/browser_postprocess.sh",
30
30
  "build:bindings": "cd .. && ./scripts/bindgen.sh",
31
+ "generate": "NODE_OPTIONS='--loader ts-node/esm' NODE_NO_WARNINGS=1 ts-node src/cbind/generate.ts",
31
32
  "formatting": "prettier --check ./src && eslint --max-warnings 0 ./src",
32
33
  "formatting:fix": "prettier -w ./src",
33
34
  "test": "NODE_OPTIONS='--loader ts-node/esm' NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --passWithNoTests",
@@ -8,8 +8,10 @@ import {
8
8
  splitHonkProof,
9
9
  PAIRING_POINTS_SIZE,
10
10
  } from '../proof/index.js';
11
- import { Encoder } from 'msgpackr/pack';
11
+ import { fromClientIVCProof, toClientIVCProof } from '../cbind/generated/api_types.js';
12
12
  import { ungzip } from 'pako';
13
+ import { Buffer } from 'buffer';
14
+ import { Decoder, Encoder } from 'msgpackr';
13
15
 
14
16
  export class AztecClientBackendError extends Error {
15
17
  constructor(message: string) {
@@ -17,23 +19,6 @@ export class AztecClientBackendError extends Error {
17
19
  }
18
20
  }
19
21
 
20
- // Utility for parsing gate counts from buffer
21
- // TODO: Where should this logic live? Should go away with move to msgpack.
22
- function parseBigEndianU32Array(buffer: Uint8Array): number[] {
23
- const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
24
-
25
- let offset = 0;
26
- const count = buffer.byteLength >>> 2; // default is entire buffer length / 4
27
-
28
- const out: number[] = new Array(count);
29
- for (let i = 0; i < count; i++) {
30
- out[i] = dv.getUint32(offset, false);
31
- offset += 4;
32
- }
33
-
34
- return out;
35
- }
36
-
37
22
  /**
38
23
  * Options for the UltraHonkBackend.
39
24
  */
@@ -219,39 +204,6 @@ export class UltraHonkBackend {
219
204
  await this.api.destroy();
220
205
  }
221
206
  }
222
- interface AztecClientExecutionStep {
223
- functionName: string;
224
- gateCount?: number;
225
- // Note: not gzipped like in native code
226
- bytecode: Uint8Array;
227
- // Note: not gzipped like in native code. Already bincoded.
228
- witness: Uint8Array;
229
- /* TODO(https://github.com/AztecProtocol/barretenberg/issues/1328) this should get its own proper class. */
230
- vk: Uint8Array;
231
- }
232
-
233
- function serializeAztecClientExecutionSteps(
234
- acirBuf: Uint8Array[],
235
- witnessBuf: Uint8Array[],
236
- vksBuf: Uint8Array[],
237
- ): Uint8Array {
238
- const steps: AztecClientExecutionStep[] = [];
239
- for (let i = 0; i < acirBuf.length; i++) {
240
- const bytecode = acirBuf[i];
241
- // Witnesses are not provided at all for gates info.
242
- const witness = witnessBuf[i] || Buffer.from([]);
243
- // VKs are optional for proving (deprecated feature) or not provided at all for gates info.
244
- const vk = vksBuf[i] || Buffer.from([]);
245
- const functionName = `unknown_wasm_${i}`;
246
- steps.push({
247
- bytecode,
248
- witness,
249
- vk,
250
- functionName,
251
- });
252
- }
253
- return new Encoder({ useRecords: false }).pack(steps);
254
- }
255
207
 
256
208
  export class AztecClientBackend {
257
209
  // These type assertions are used so that we don't
@@ -284,26 +236,73 @@ export class AztecClientBackend {
284
236
  throw new AztecClientBackendError('Witness and VKs must have the same stack depth!');
285
237
  }
286
238
  await this.instantiate();
287
- const ivcInputsBuf = serializeAztecClientExecutionSteps(this.acirBuf, witnessBuf, vksBuf);
288
- const proofAndVk = await this.api.acirProveAztecClient(ivcInputsBuf);
289
- const [proof, vk] = proofAndVk;
290
- if (!(await this.verify(proof, vk))) {
239
+
240
+ // Queue IVC start with the number of circuits
241
+ this.api.clientIvcStart({ numCircuits: this.acirBuf.length });
242
+
243
+ // Queue load and accumulate for each circuit
244
+ for (let i = 0; i < this.acirBuf.length; i++) {
245
+ const bytecode = this.acirBuf[i];
246
+ const witness = witnessBuf[i] || Buffer.from([]);
247
+ const vk = vksBuf[i] || Buffer.from([]);
248
+ const functionName = `unknown_wasm_${i}`;
249
+
250
+ // Load the circuit
251
+ this.api.clientIvcLoad({
252
+ circuit: {
253
+ name: functionName,
254
+ bytecode: Buffer.from(bytecode),
255
+ verificationKey: Buffer.from(vk),
256
+ }
257
+ });
258
+
259
+ // Accumulate with witness
260
+ this.api.clientIvcAccumulate({
261
+ witness: Buffer.from(witness),
262
+ });
263
+ }
264
+
265
+ // Generate the proof (and wait for all previous steps to finish)
266
+ const proveResult = await this.api.clientIvcProve({});
267
+
268
+ // The API currently expects a msgpack-encoded API.
269
+ const proof = new Encoder({useRecords: false}).encode(fromClientIVCProof(proveResult.proof));
270
+ // Generate the VK
271
+ const vkResult = await this.api.clientIvcComputeIvcVk({ circuit: {
272
+ name: 'tail',
273
+ bytecode: this.acirBuf[this.acirBuf.length - 1],
274
+ } });
275
+
276
+ // Note: Verification may not work correctly until we properly serialize the proof
277
+ if (!(await this.verify(proof, vkResult.bytes))) {
291
278
  throw new AztecClientBackendError('Failed to verify the private (ClientIVC) transaction proof!');
292
279
  }
293
- return proofAndVk;
280
+ return [proof, vkResult.bytes];
294
281
  }
295
282
 
296
283
  async verify(proof: Uint8Array, vk: Uint8Array): Promise<boolean> {
297
284
  await this.instantiate();
298
- return this.api.acirVerifyAztecClient(proof, vk);
285
+ const result = await this.api.clientIvcVerify({
286
+ proof: toClientIVCProof(new Decoder({useRecords: false}).decode(proof)),
287
+ vk: Buffer.from(vk),
288
+ });
289
+ return result.valid;
299
290
  }
300
291
 
301
292
  async gates(): Promise<number[]> {
302
- // call function on API
303
293
  await this.instantiate();
304
- const ivcInputsBuf = serializeAztecClientExecutionSteps(this.acirBuf, [], []);
305
- const resultBuffer = await this.api.acirGatesAztecClient(ivcInputsBuf);
306
- return parseBigEndianU32Array(resultBuffer);
294
+ const circuitSizes: number[] = [];
295
+ for (const buf of this.acirBuf) {
296
+ const gates = await this.api.clientIvcGates({
297
+ circuit: {
298
+ name: 'circuit',
299
+ bytecode: buf,
300
+ },
301
+ includeGatesPerOpcode: false
302
+ });
303
+ circuitSizes.push(gates.circuitSize);
304
+ }
305
+ return circuitSizes;
307
306
  }
308
307
 
309
308
  async destroy(): Promise<void> {
@@ -7,6 +7,8 @@ import { Crs, GrumpkinCrs } from '../crs/index.js';
7
7
  import { RawBuffer } from '../types/raw_buffer.js';
8
8
  import { fetchModuleAndThreads } from '../barretenberg_wasm/index.js';
9
9
  import { createDebugLogger } from '../log/index.js';
10
+ import { AsyncApi } from '../cbind/generated/async.js';
11
+ import { BbApiBase } from '../cbind/generated/api_types.js';
10
12
 
11
13
  export { BarretenbergVerifier } from './verifier.js';
12
14
  export { UltraHonkBackend, AztecClientBackend } from './backend.js';
@@ -39,6 +41,7 @@ export type CircuitOptions = {
39
41
  */
40
42
  export class Barretenberg extends BarretenbergApi {
41
43
  private options: BackendOptions;
44
+ private bbApi: BbApiBase;
42
45
 
43
46
  private constructor(
44
47
  private worker: any,
@@ -47,6 +50,7 @@ export class Barretenberg extends BarretenbergApi {
47
50
  ) {
48
51
  super(wasm);
49
52
  this.options = options;
53
+ this.bbApi = new AsyncApi(wasm);
50
54
  }
51
55
 
52
56
  /**
@@ -114,6 +118,39 @@ export class Barretenberg extends BarretenbergApi {
114
118
  getWasm() {
115
119
  return this.wasm;
116
120
  }
121
+
122
+ getBbApi(): BbApiBase {
123
+ return this.bbApi;
124
+ }
125
+
126
+ // Wrap ClientIVC methods used by AztecClientBackend
127
+ async clientIvcStart(command: Parameters<BbApiBase['clientIvcStart']>[0]) {
128
+ return this.bbApi.clientIvcStart(command);
129
+ }
130
+
131
+ async clientIvcLoad(command: Parameters<BbApiBase['clientIvcLoad']>[0]) {
132
+ return this.bbApi.clientIvcLoad(command);
133
+ }
134
+
135
+ async clientIvcAccumulate(command: Parameters<BbApiBase['clientIvcAccumulate']>[0]) {
136
+ return this.bbApi.clientIvcAccumulate(command);
137
+ }
138
+
139
+ async clientIvcProve(command: Parameters<BbApiBase['clientIvcProve']>[0]) {
140
+ return this.bbApi.clientIvcProve(command);
141
+ }
142
+
143
+ async clientIvcVerify(command: Parameters<BbApiBase['clientIvcVerify']>[0]) {
144
+ return this.bbApi.clientIvcVerify(command);
145
+ }
146
+
147
+ async clientIvcComputeIvcVk(command: Parameters<BbApiBase['clientIvcComputeIvcVk']>[0]) {
148
+ return this.bbApi.clientIvcComputeIvcVk(command);
149
+ }
150
+
151
+ async clientIvcGates(command: Parameters<BbApiBase['clientIvcGates']>[0]) {
152
+ return this.bbApi.clientIvcGates(command);
153
+ }
117
154
  }
118
155
 
119
156
  let barretenbergSyncSingletonPromise: Promise<BarretenbergSync>;
@@ -49,9 +49,11 @@ export class BarretenbergWasmBase {
49
49
  const m = this.getMemory();
50
50
  const str2 = `${str} (mem: ${(m.length / (1024 * 1024)).toFixed(2)}MiB)`;
51
51
  this.logger(str2);
52
- // if (str2.startsWith('WARNING:')) {
53
- // this.logger(new Error().stack!);
54
- // }
52
+ },
53
+
54
+ throw_or_abort_impl: (addr: number) => {
55
+ const str = this.stringFromAddress(addr);
56
+ throw new Error(str);
55
57
  },
56
58
 
57
59
  get_data: (keyAddr: number, outBufAddr: number) => {
@@ -136,6 +136,29 @@ export class BarretenbergWasmMain extends BarretenbergWasmBase {
136
136
  return this.getMemorySlice(ptr + 4, ptr + 4 + length);
137
137
  });
138
138
  }
139
+
140
+ cbindCall(cbind: string, inputBuffer: Uint8Array): any {
141
+ const outputSizePtr = this.call('bbmalloc', 4);
142
+ const outputMsgpackPtr = this.call('bbmalloc', 4);
143
+
144
+ const inputPtr = this.call('bbmalloc', inputBuffer.length);
145
+ this.writeMemory(inputPtr, inputBuffer);
146
+ this.call(cbind, inputPtr, inputBuffer.length, outputMsgpackPtr, outputSizePtr);
147
+
148
+ const readPtr32 = (ptr32: number) => {
149
+ const dataView = new DataView(this.getMemorySlice(ptr32, ptr32 + 4).buffer);
150
+ return dataView.getUint32(0, true);
151
+ };
152
+
153
+ const encodedResult = this.getMemorySlice(
154
+ readPtr32(outputMsgpackPtr),
155
+ readPtr32(outputMsgpackPtr) + readPtr32(outputSizePtr),
156
+ );
157
+ this.call('bbfree', inputPtr);
158
+ this.call('bbfree', outputSizePtr);
159
+ this.call('bbfree', outputMsgpackPtr);
160
+ return encodedResult;
161
+ }
139
162
  }
140
163
 
141
164
  /**
@@ -0,0 +1 @@
1
+ Derive bindings from the reported scheme of msgpack from bb. Currently redundant with bindgen, until that is supplanted.
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Generate TypeScript bindings from msgpack schema
3
+ */
4
+
5
+ import { writeFileSync, mkdirSync } from 'fs';
6
+ import { dirname, join } from 'path';
7
+ import { exec } from 'child_process';
8
+ import { promisify } from 'util';
9
+ import { fileURLToPath } from 'url';
10
+ import {
11
+ createSharedTypesCompiler,
12
+ createSyncApiCompiler,
13
+ createAsyncApiCompiler,
14
+ createNativeApiCompiler,
15
+ type SchemaCompiler,
16
+ } from './schema_compiler.js';
17
+
18
+ const execAsync = promisify(exec);
19
+
20
+ interface GeneratorConfig {
21
+ name: string;
22
+ outputFile: string;
23
+ createCompiler: () => SchemaCompiler;
24
+ }
25
+
26
+ const GENERATORS: GeneratorConfig[] = [
27
+ {
28
+ name: 'Shared types',
29
+ outputFile: 'generated/api_types.ts',
30
+ createCompiler: createSharedTypesCompiler,
31
+ },
32
+ {
33
+ name: 'Sync API',
34
+ outputFile: 'generated/sync.ts',
35
+ createCompiler: createSyncApiCompiler,
36
+ },
37
+ {
38
+ name: 'Async API',
39
+ outputFile: 'generated/async.ts',
40
+ createCompiler: createAsyncApiCompiler,
41
+ },
42
+ {
43
+ name: 'Native API',
44
+ outputFile: 'generated/native.ts',
45
+ createCompiler: createNativeApiCompiler,
46
+ },
47
+ ];
48
+
49
+ // @ts-ignore
50
+ const __dirname = dirname(fileURLToPath(import.meta.url));
51
+
52
+ async function generate() {
53
+ const bbBuildPath = process.env.BB_BINARY_PATH || join(__dirname, '../../../cpp/build/bin/bb');
54
+
55
+ // Get schema from bb
56
+ console.log('Fetching msgpack schema from bb...');
57
+ const { stdout } = await execAsync(`${bbBuildPath} msgpack schema`);
58
+ const schema = JSON.parse(stdout.trim());
59
+
60
+ if (!schema.commands || !schema.responses) {
61
+ throw new Error('Invalid schema: missing commands or responses');
62
+ }
63
+
64
+ console.log('Generating TypeScript bindings...\n');
65
+
66
+ // Ensure output directory exists
67
+ const outputDir = join(__dirname, 'generated');
68
+ mkdirSync(outputDir, { recursive: true });
69
+
70
+ // Generate each output file
71
+ for (const config of GENERATORS) {
72
+ const compiler = config.createCompiler();
73
+ compiler.processApiSchema(schema.commands, schema.responses);
74
+
75
+ const outputPath = join(__dirname, config.outputFile);
76
+ const content = compiler.compile();
77
+ writeFileSync(outputPath, content);
78
+
79
+ console.log(`✓ ${config.name}: ${outputPath}`);
80
+ }
81
+
82
+ console.log('\nGeneration complete!');
83
+ }
84
+
85
+ // Run the generator
86
+ generate().catch(error => {
87
+ console.error('Generation failed:', error);
88
+ process.exit(1);
89
+ });