diff --git a/flake.lock b/flake.lock index 01ea295f97..187fd34d9f 100644 --- a/flake.lock +++ b/flake.lock @@ -10,11 +10,11 @@ ] }, "locked": { - "lastModified": 1724407960, - "narHash": "sha256-pUKTVMYEtsD1AGlHFTdPourowt+tJ3htKhRu7VALFzc=", + "lastModified": 1742933373, + "narHash": "sha256-sW6ZheQeXe+GULDKLcgRJN4eucP3IXWHz0bHL9KKU1w=", "owner": "o1-labs", "repo": "describe-dune", - "rev": "be828239c05671209e979f9d5c2e3094e3be7a46", + "rev": "ba71baa26329399ca2f1d158f15e7c32bba1d072", "type": "github" }, "original": { @@ -58,11 +58,11 @@ ] }, "locked": { - "lastModified": 1723653683, - "narHash": "sha256-n7h3X1PCp+pPOu/bwUQ0Gwv0yXrdjA+h3Zp6CQSS4jQ=", + "lastModified": 1742933757, + "narHash": "sha256-FI8sVvIJuKscrnOUj/cqbZRVOxTzgBwYMyZSNcXq+58=", "owner": "o1-labs", "repo": "dune-nix", - "rev": "303e4cea2e035c84d4067754a9275a053dac1564", + "rev": "5eedc211a4cfc3bae1833c5a85542be49b4a9f6b", "type": "github" }, "original": { @@ -151,11 +151,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { @@ -266,10 +266,13 @@ "utils": "utils" }, "locked": { - "lastModified": 1751976294, - "narHash": "sha256-iQiich3yamIKYSq+zRKcs7zWNUC22/Bi33swjwcfc5g=", - "path": "src/mina", - "type": "path" + "lastModified": 1749040347, + "narHash": "sha256-bbX1ZGyILjCFvpPdUEAPUoITYIsQ2vd/pN2Uz1C4LAM=", + "rev": "569e99c95834841d64858644c5d80ac7e63d0157", + "revCount": 35642, + "submodules": true, + "type": "git", + "url": "file:src/mina" }, "original": { "submodules": true, @@ -395,11 +398,11 @@ }, "nixpkgs-mina": { "locked": { - "lastModified": 1747635552, - "narHash": "sha256-2wAd20JLiHzcqSt7MGza4hN4rdV/c6Ed/13gN7HZJ9U=", + "lastModified": 1751290243, + "narHash": "sha256-kNf+obkpJZWar7HZymXZbW+Rlk3HTEIMlpc6FCNz0Ds=", "owner": "nixos", "repo": "nixpkgs", - "rev": "74b4de8529c4ce6f17b80c97728fddd627097809", + "rev": "5ab036a8d97cb9476fbe81b09076e6e91d15e1b6", "type": "github" }, "original": { @@ -428,11 +431,11 @@ "nixpkgs-mozilla_2": { "flake": false, "locked": { - "lastModified": 1704373101, - "narHash": "sha256-+gi59LRWRQmwROrmE1E2b3mtocwueCQqZ60CwLG+gbg=", + "lastModified": 1744624473, + "narHash": "sha256-S6zT/w5SyAkJ//dYdjbrXgm+6Vkd/k7qqUl4WgZ6jjk=", "owner": "mozilla", "repo": "nixpkgs-mozilla", - "rev": "9b11a87c0cc54e308fa83aac5b4ee1816d5418a2", + "rev": "2292d4b35aa854e312ad2e95c4bb5c293656f21a", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 9c50f943d6..34e4a06be2 100644 --- a/flake.nix +++ b/flake.nix @@ -237,6 +237,7 @@ root = ./.; fileset = unions [ ./src/mina + ./scripts ./src/bindings/scripts ./src/bindings/js ./src/bindings/crypto @@ -281,6 +282,7 @@ patchPhase = '' patchShebangs ./src/bindings/scripts/ patchShebangs ./src/bindings/crypto/test-vectors/ + patchShebangs ./scripts/ ''; buildPhase = '' diff --git a/package.json b/package.json index 114ecaf30d..2dc89580bf 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,12 @@ "build:web": "./scripts/build/build-web.sh", "build:examples": "./scripts/build/build-examples.sh", "check:bindings": "./scripts/build/check-for-bindings.sh", + "build:wasm": "npm run build:wasm:web && npm run build:wasm:node", + "build:wasm:web": "./scripts/build/wasm/build-web.sh", + "build:wasm:node": "./scripts/build/wasm/build-node.sh", + "build:jsoo": "npm run build:jsoo:web && npm run build:jsoo:node", + "build:jsoo:web": "./scripts/build/jsoo/build-web.sh", + "build:jsoo:node": "./scripts/build/jsoo/build-node.sh", "build:docs": "typedoc", "prepublish:web": "./scripts/prepublish/prepublish-web.sh", "prepublish:node": "./scripts/prepublish/prepublish-node.sh", diff --git a/scripts/build/build-dev.sh b/scripts/build/build-dev.sh index da9c48b94e..8f9d91e8bc 100755 --- a/scripts/build/build-dev.sh +++ b/scripts/build/build-dev.sh @@ -15,7 +15,9 @@ npx tsc -p tsconfig.test.json ok "TypeScript compilation complete" info "Copying artifacts to dist..." -node src/build/copy-to-dist.js +mkdir -p dist/node/bindings/compiled/node_bindings/ +cp -r src/bindings/compiled/node_bindings/* dist/node/bindings/compiled/node_bindings/ +cp src/bindings.d.ts dist/node/ ok "Artifacts copied" success "Development build complete" \ No newline at end of file diff --git a/scripts/build/jsoo/build-node.sh b/scripts/build/jsoo/build-node.sh new file mode 100755 index 0000000000..7672e5a7f4 --- /dev/null +++ b/scripts/build/jsoo/build-node.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +source ./scripts/lib/ux.sh + +JSOO_PATH=./src/bindings/ocaml/jsoo_exports/ +BUILT_PATH=./_build/default/$JSOO_PATH +BINDINGS_PATH=./src/bindings/compiled/node_bindings/ + +setup_script "jsoo-build-node" "JSOO build node" + +mkdir -p $BINDINGS_PATH + +info "building JSOO artifacts for node..." +TARGETS=(\ + o1js_node.bc.js \ +) +dune build ${TARGETS[@]/#/$JSOO_PATH/} +ok "JSOO artifacts built successfully" + +info "copying artifacts into the right place..." +for target in ${TARGETS[@]}; do + cp $BUILT_PATH/$target $BINDINGS_PATH/$target + chmod 660 $BINDINGS_PATH/$target +done + +info "setting up TS declaration files..." +echo '// this file intentionally left blank' > $BINDINGS_PATH/o1js_node.bc.d.cts +ok "TS declaration created" + +info "moving some files to CommonJS format..." +run_cmd mv -f $BINDINGS_PATH/o1js_node.bc.js $BINDINGS_PATH/o1js_node.bc.cjs +ok "Node.js bindings copied" + +info "Updating WASM references in bindings..." +run_cmd sed -i 's/plonk_wasm.js/plonk_wasm.cjs/' $BINDINGS_PATH/o1js_node.bc.cjs +ok "WASM references updated" + +info "fixing JS bindings for better error handling..." +run_cmd sed -i 's/function failwith(s){throw \[0,Failure,s\]/function failwith(s){throw globalThis.Error(s.c)/' "${BINDINGS_PATH}"/o1js_node.bc.cjs +run_cmd sed -i 's/function invalid_arg(s){throw \[0,Invalid_argument,s\]/function invalid_arg(s){throw globalThis.Error(s.c)/' "${BINDINGS_PATH}"/o1js_node.bc.cjs +run_cmd sed -i 's/return \[0,Exn,t\]/return globalThis.Error(t.c)/' "${BINDINGS_PATH}"/o1js_node.bc.cjs +run_cmd sed -i 's/function raise(t){throw caml_call1(to_exn$0,t)}/function raise(t){throw Error(t?.[1]?.c ?? "Unknown error thrown by raise")}/' "${BINDINGS_PATH}"/o1js_node.bc.cjs +ok "JS bindings fixed" + +success "JSOO node build complete!" \ No newline at end of file diff --git a/scripts/build/jsoo/build-web.sh b/scripts/build/jsoo/build-web.sh new file mode 100755 index 0000000000..e90a3ae0ca --- /dev/null +++ b/scripts/build/jsoo/build-web.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +source ./scripts/lib/ux.sh + +JSOO_PATH=./src/bindings/ocaml/jsoo_exports/ +BUILT_PATH=./_build/default/$JSOO_PATH +BINDINGS_PATH=./src/bindings/compiled/web_bindings/ + +setup_script "jsoo-build-web" "JSOO build web" + +mkdir -p $BINDINGS_PATH + +info "building JSOO artifacts for web..." +TARGETS=(\ + o1js_web.bc.js\ +) +dune build ${TARGETS[@]/#/$JSOO_PATH/} +ok "initial artifacts built successfully!" + +info "copying artifacts into the right place..." +for target in ${TARGETS[@]}; do + cp $BUILT_PATH/$target $BINDINGS_PATH/$target + chmod 660 $BINDINGS_PATH/$target +done + +info "improving error messages in web bindings..." +# Transform OCaml-style exceptions to JavaScript Error objects +run_cmd sed -i 's/function failwith(s){throw \[0,Failure,s\]/function failwith(s){throw globalThis.Error(s.c)/' $BINDINGS_PATH/o1js_web.bc.js +run_cmd sed -i 's/function invalid_arg(s){throw \[0,Invalid_argument,s\]/function invalid_arg(s){throw globalThis.Error(s.c)/' $BINDINGS_PATH/o1js_web.bc.js +run_cmd sed -i 's/return \[0,Exn,t\]/return globalThis.Error(t.c)/' $BINDINGS_PATH/o1js_web.bc.js +run_cmd sed -i 's/function raise(t){throw caml_call1(to_exn$0,t)}/function raise(t){throw Error(t?.[1]?.c ?? "Unknown error thrown by raise")}/' $BINDINGS_PATH/o1js_web.bc.js +ok "error messages improved" + +info "minifying JS with esbuild..." +run_cmd npx esbuild --minify --log-level=error $BINDINGS_PATH/o1js_web.bc.js > $BINDINGS_PATH/o1js_web.bc.min.js +run_cmd mv $BINDINGS_PATH/o1js_web.bc.min.js $BINDINGS_PATH/o1js_web.bc.js +ok "JS minified" + +success "JSOO artifacts built for web" \ No newline at end of file diff --git a/scripts/build/wasm/build-node.sh b/scripts/build/wasm/build-node.sh new file mode 100755 index 0000000000..e757c16bf4 --- /dev/null +++ b/scripts/build/wasm/build-node.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +source ./scripts/lib/ux.sh + +setup_script "wasm-node-build" "wasm node build" + +MINA_PATH=./src/mina +KIMCHI_PATH=$MINA_PATH/src/lib/crypto/kimchi_bindings/js/node_js/ +BUILT_PATH=./_build/default/$KIMCHI_PATH +BINDINGS_PATH=./src/bindings/compiled/node_bindings/ + +mkdir -p $BINDINGS_PATH + +info "building Kimchi bindings for node..." + +TARGETS=(\ + plonk_wasm_bg.wasm \ + plonk_wasm_bg.wasm.d.ts \ + plonk_wasm.js \ + plonk_wasm.d.ts \ +) +dune build ${TARGETS[@]/#/$KIMCHI_PATH/} + +info "copying artifacts into the right place..." + +for target in "${TARGETS[@]}"; do + cp $BUILT_PATH/$target $BINDINGS_PATH/$target + chmod 660 $BINDINGS_PATH/$target +done + +info "moving some files to CommonJS format..." + +mv $BINDINGS_PATH/plonk_wasm.js $BINDINGS_PATH/plonk_wasm.cjs +mv $BINDINGS_PATH/plonk_wasm.d.ts $BINDINGS_PATH/plonk_wasm.d.cts + +info "autofixing wasm bindings for Node.JS..." +run_cmd node src/build/fix-wasm-bindings-node.js $BINDINGS_PATH/plonk_wasm.cjs + +success "WASM node build success!" \ No newline at end of file diff --git a/scripts/build/wasm/build-web.sh b/scripts/build/wasm/build-web.sh new file mode 100755 index 0000000000..155a26f732 --- /dev/null +++ b/scripts/build/wasm/build-web.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +source ./scripts/lib/ux.sh + +setup_script "wasm-web-build" "wasm web build" + +if ! command -v wasm-opt >/dev/null 2>&1; then + error "wasm-opt is required for web bindings optimization" + exit 1 +fi + +MINA_PATH=./src/mina +KIMCHI_PATH=$MINA_PATH/src/lib/crypto/kimchi_bindings/js/web/ +BUILT_PATH=./_build/default/$KIMCHI_PATH +BINDINGS_PATH=./src/bindings/compiled/web_bindings/ + +mkdir -p $BINDINGS_PATH + + +info "building Kimchi bindings for web..." + +TARGETS=(\ + plonk_wasm_bg.wasm \ + plonk_wasm_bg.wasm.d.ts \ + plonk_wasm.js \ + plonk_wasm.d.ts\ +) +dune build ${TARGETS[@]/#/$KIMCHI_PATH/} + +info "copying artifacts into the right place..." + +for target in "${TARGETS[@]}"; do + cp $BUILT_PATH/$target $BINDINGS_PATH/$target +done + +info "optimizing wasm with wasm-opt..." +run_cmd wasm-opt \ + --detect-features \ + --enable-mutable-globals \ + -O4 \ + -o $BINDINGS_PATH/plonk_wasm_bg.wasm.opt \ + $BINDINGS_PATH/plonk_wasm_bg.wasm +run_cmd mv $BINDINGS_PATH/plonk_wasm_bg.wasm.opt $BINDINGS_PATH/plonk_wasm_bg.wasm + +ok "wasm optimized" + +chmod 660 ${TARGETS[@]/#/$BINDINGS_PATH/} + +success "WASM web build success!" \ No newline at end of file diff --git a/scripts/prepublish/prepublish-node.sh b/scripts/prepublish/prepublish-node.sh index 6da803de08..06ce815b6a 100755 --- a/scripts/prepublish/prepublish-node.sh +++ b/scripts/prepublish/prepublish-node.sh @@ -21,10 +21,6 @@ info "Ensuring bindings are available..." run_cmd npm run check:bindings ok "Bindings ready" -info "Copying binding artifacts..." -run_cmd node src/build/copy-artifacts.js -ok "Artifacts copied" - info "Cleaning node dist directory..." run_cmd rimraf "$DIST_NODE_DIR" ok "Node dist directory cleaned" @@ -34,7 +30,9 @@ run_cmd tsc -p tsconfig.node.json ok "TypeScript compilation finished" info "Copying compiled output to dist..." -run_cmd node src/build/copy-to-dist.js +mkdir -p dist/node/bindings/compiled/node_bindings/ +cp -r src/bindings/compiled/node_bindings/* dist/node/bindings/compiled/node_bindings/ +cp src/bindings.d.ts dist/node/ ok "Copied compiled output" info "Building production node bundle..." diff --git a/src/bindings.js b/src/bindings.js index be16b43d39..9eede3ea4f 100644 --- a/src/bindings.js +++ b/src/bindings.js @@ -18,9 +18,9 @@ async function initializeBindings() { // this dynamic import makes jest respect the import order // otherwise the cjs file gets imported before its implicit esm dependencies and fails CJS: if (typeof require !== 'undefined') { - snarky = require('./bindings/compiled/_node_bindings/o1js_node.bc.cjs'); + snarky = require('./bindings/compiled/node_bindings/o1js_node.bc.cjs'); } - ESM: snarky = (await import('./bindings/compiled/_node_bindings/o1js_node.bc.cjs')).default; + ESM: snarky = (await import('./bindings/compiled/node_bindings/o1js_node.bc.cjs')).default; ({ Snarky, Ledger, Pickles, Test: Test_ } = snarky); resolve(); initializingPromise = undefined; @@ -33,12 +33,11 @@ async function Test() { } export { - Snarky, - Ledger, - Pickles, - Test, - withThreadPool, - wasm, - initializeBindings, isInitialized as areBindingsInitialized, + initializeBindings, Ledger, + Pickles, + Snarky, + Test, wasm, + withThreadPool }; + diff --git a/src/bindings/crypto/constants.ts b/src/bindings/crypto/constants.ts index 0d02cb4981..28594bb9b2 100644 --- a/src/bindings/crypto/constants.ts +++ b/src/bindings/crypto/constants.ts @@ -1,13 +1,13 @@ // @gen this file is generated from `bindings/ocaml/o1js_constants.ml` - don't edit it directly export { - prefixes, + mocks, + poseidonParamsKimchiFp, + poseidonParamsLegacyFp, prefixHashes, prefixHashesLegacy, - versionBytes, + prefixes, protocolVersions, - poseidonParamsKimchiFp, - poseidonParamsLegacyFp, - mocks, + versionBytes, }; let prefixes = { diff --git a/src/bindings/js/node/node-backend.js b/src/bindings/js/node/node-backend.js index 9b844239ac..c549fb4573 100644 --- a/src/bindings/js/node/node-backend.js +++ b/src/bindings/js/node/node-backend.js @@ -1,8 +1,8 @@ -import { isMainThread, parentPort, workerData, Worker } from 'worker_threads'; import os from 'os'; -import wasm_ from '../../compiled/_node_bindings/plonk_wasm.cjs'; import { fileURLToPath } from 'url'; +import { Worker, isMainThread, parentPort, workerData } from 'worker_threads'; import { WithThreadPool, workers } from '../../../lib/proof-system/workers.js'; +import wasm_ from '../../compiled/node_bindings/plonk_wasm.cjs'; let url = import.meta.url; let filename = url !== undefined ? fileURLToPath(url) : __filename; diff --git a/src/bindings/mina-transaction/gen/v1/transaction-bigint.ts b/src/bindings/mina-transaction/gen/v1/transaction-bigint.ts index 7a23e70235..ad4c18b3ed 100644 --- a/src/bindings/mina-transaction/gen/v1/transaction-bigint.ts +++ b/src/bindings/mina-transaction/gen/v1/transaction-bigint.ts @@ -1,35 +1,44 @@ // @generated this file is auto-generated - don't edit it directly +import { GenericLayout, SignableFromLayout } from '../../../lib/from-layout.js'; +import { GenericSignable } from '../../../lib/generic.js'; import { - PublicKey, - UInt64, - UInt32, - TokenId, - Field, + ActionState, + Actions, AuthRequired, BalanceChange, - Sign, Bool, - TransactionVersion, - ZkappUri, - TokenSymbol, - StateHash, Events, - Actions, - ActionState, + Field, MayUseToken, - VerificationKeyHash, + PublicKey, ReceiptChainHash, + Sign, + StateHash, + TokenId, + TokenSymbol, + TransactionVersion, + UInt32, + UInt64, + VerificationKeyHash, + ZkappUri, } from '../../v1/transaction-leaves-bigint.js'; -import { GenericSignable } from '../../../lib/generic.js'; -import { SignableFromLayout, GenericLayout } from '../../../lib/from-layout.js'; -import * as Json from './transaction-json.js'; import { jsLayout } from './js-layout.js'; +import * as Json from './transaction-json.js'; -export { customTypes, ZkappCommand, AccountUpdate, Account }; -export { Json }; export * from '../../v1/transaction-leaves-bigint.js'; -export { signableFromLayout, toJSONEssential, empty, Layout, TypeMap }; +export { + Account, + AccountUpdate, + Json, + Layout, + TypeMap, + ZkappCommand, + customTypes, + empty, + signableFromLayout, + toJSONEssential, +}; type TypeMap = { PublicKey: PublicKey; diff --git a/src/bindings/mina-transaction/gen/v1/transaction-json.ts b/src/bindings/mina-transaction/gen/v1/transaction-json.ts index c3ed04cbbe..34e372d729 100644 --- a/src/bindings/mina-transaction/gen/v1/transaction-json.ts +++ b/src/bindings/mina-transaction/gen/v1/transaction-json.ts @@ -1,20 +1,19 @@ // @generated this file is auto-generated - don't edit it directly import { - PublicKey, - UInt64, - UInt32, - TokenId, - Field, AuthRequired, BalanceChange, - Sign, Bool, + Field, + PublicKey, + Sign, + TokenId, + UInt32, + UInt64, } from '../../v1/transaction-leaves-json.js'; -export { ZkappCommand, AccountUpdate, Account }; export * from '../../v1/transaction-leaves-json.js'; -export { TypeMap }; +export { Account, AccountUpdate, TypeMap, ZkappCommand }; type TypeMap = { PublicKey: PublicKey; diff --git a/src/bindings/mina-transaction/gen/v1/transaction.ts b/src/bindings/mina-transaction/gen/v1/transaction.ts index cb122d73d0..7b50ddd7f1 100644 --- a/src/bindings/mina-transaction/gen/v1/transaction.ts +++ b/src/bindings/mina-transaction/gen/v1/transaction.ts @@ -1,36 +1,45 @@ // @generated this file is auto-generated - don't edit it directly +import { GenericLayout, ProvableFromLayout } from '../../../lib/from-layout.js'; +import { GenericProvableExtended } from '../../../lib/generic.js'; import { - PublicKey, - UInt64, - UInt32, - TokenId, - Field, + ActionState, + Actions, AuthRequired, BalanceChange, - Sign, Bool, - TransactionVersion, - ZkappUri, - TokenSymbol, - StateHash, Events, - Actions, - ActionState, + Field, MayUseToken, - VerificationKeyHash, + PublicKey, ReceiptChainHash, + Sign, + StateHash, + TokenId, + TokenSymbol, + TransactionVersion, + UInt32, + UInt64, + VerificationKeyHash, + ZkappUri, } from '../../v1/transaction-leaves.js'; -import { GenericProvableExtended } from '../../../lib/generic.js'; -import { ProvableFromLayout, GenericLayout } from '../../../lib/from-layout.js'; -import * as Json from './transaction-json.js'; -import * as Value from './transaction-bigint.js'; import { jsLayout } from './js-layout.js'; +import * as Value from './transaction-bigint.js'; +import * as Json from './transaction-json.js'; -export { customTypes, ZkappCommand, AccountUpdate, Account }; -export { Json }; export * from '../../v1/transaction-leaves.js'; -export { provableFromLayout, toJSONEssential, empty, Layout, TypeMap }; +export { + Account, + AccountUpdate, + Json, + Layout, + TypeMap, + ZkappCommand, + customTypes, + empty, + provableFromLayout, + toJSONEssential, +}; type TypeMap = { PublicKey: PublicKey; diff --git a/src/bindings/mina-transaction/gen/v2/js-layout.ts b/src/bindings/mina-transaction/gen/v2/js-layout.ts index d341f96928..132acdc85e 100644 --- a/src/bindings/mina-transaction/gen/v2/js-layout.ts +++ b/src/bindings/mina-transaction/gen/v2/js-layout.ts @@ -1,5 +1,4 @@ // @generated this file is auto-generated - don't edit it directly -import { BindingsType } from '../../v2/schema.js'; import { Actions, AuthRequired, @@ -10,7 +9,6 @@ import { Option, PublicKey, Range, - Sign, StateHash, TokenId, TokenSymbol, @@ -18,29 +16,30 @@ import { UInt64, ZkappUri, } from '../../v2/leaves.js'; +import { BindingsType } from '../../v2/schema.js'; export { - Types, - ZkappCommand, - ZkappFeePayer, - FeePayerBody, - ZkappAccountUpdate, + Account, + AccountPrecondition, + AccountTiming, AccountUpdateBody, AccountUpdateModification, - VerificationKeyWithHash, - Permissions, - VerificationKeyPermission, - Timing, - Preconditions, - NetworkPrecondition, + AuthorizationKindStructured, + Control, EpochDataPrecondition, EpochLedgerPrecondition, - AccountPrecondition, + FeePayerBody, MayUseToken, - AuthorizationKindStructured, - Control, - Account, - AccountTiming, + NetworkPrecondition, + Permissions, + Preconditions, + Timing, + Types, + VerificationKeyPermission, + VerificationKeyWithHash, ZkappAccount, + ZkappAccountUpdate, + ZkappCommand, + ZkappFeePayer, }; type FeePayerBody = { publicKey: PublicKey; diff --git a/src/bindings/scripts/build-o1js-node-artifacts.sh b/src/bindings/scripts/build-o1js-node-artifacts.sh index 045a8d9922..0748a0bd4a 100755 --- a/src/bindings/scripts/build-o1js-node-artifacts.sh +++ b/src/bindings/scripts/build-o1js-node-artifacts.sh @@ -8,15 +8,11 @@ source "$ROOT_DIR/scripts/lib/ux.sh" # paths MINA_PATH=src/mina -DUNE_PATH=src/bindings/ocaml/jsoo_exports # this is the path to where we build the jsoo artifacts from -BUILD_PATH=_build/default/"${DUNE_PATH}" # this is where dune puts the build artifacts -KIMCHI_BINDINGS="${MINA_PATH}"/src/lib/crypto/kimchi_bindings # path to kimchi bindings in the mina repo -BINDINGS_PATH=src/bindings/compiled/_node_bindings/ # output path for node bindings # setup setup_script "${BASH_SOURCE[0]}" "Node artifacts build" -export DUNE_USE_DEFAULT_LINKER="y" +DUNE_USE_DEFAULT_LINKER="y" bold "Building bindings artifacts" @@ -29,44 +25,14 @@ else ok "Dependencies already installed" fi -info "Checking existing build artifacts..." -if [ -f "${BUILD_PATH}"/o1js_node.bc.js ]; then - info "Found existing o1js_node.bc.js" - if [ -f "${BUILD_PATH}"/o1js_node.bc.map ]; then - info "Found o1js_node.bc.map, saving at temp location (dune will delete it)" - run_cmd cp "${BUILD_PATH}"/o1js_node.bc.map _build/o1js_node.bc.map - ok "Source map saved" - else - warn "Missing o1js_node.bc.map, removing o1js_node.bc.js to force rebuild" - run_cmd rm -f "${BUILD_PATH}"/o1js_node.bc.js - ok "Stale artifacts cleaned" - fi -else - info "No existing o1js_node.bc.js found, will build from scratch" -fi - info "Setting up Mina configuration files..." run_cmd dune b "${MINA_PATH}"/src/config.mlh run_cmd cp "${MINA_PATH}"/src/config.mlh "src" run_cmd cp -r "${MINA_PATH}"/src/config "src/config" ok "Mina config files copied" -info "Building Kimchi bindings for Node.js..." -run_cmd dune b "${KIMCHI_BINDINGS}"/js/node_js -ok "Kimchi bindings built" - -info "Building JSOO artifacts for o1js" -run_cmd dune b "${DUNE_PATH}"/o1js_node.bc.js -ok "JSOO artifacts built" - -info "Checking for updated source map..." -if [ -f "${BUILD_PATH}"/o1js_node.bc.map ]; then - info "New source map created, saving it" - run_cmd cp "${BUILD_PATH}"/o1js_node.bc.map _build/o1js_node.bc.map - ok "Source map updated" -else - info "No new source map created" -fi +npm run build:wasm:node +npm run build:jsoo:node info "Building transaction layout TypeScript definitions..." run_cmd dune b src/bindings/mina-transaction/gen/v1/js-layout.ts \ @@ -85,68 +51,4 @@ run_cmd rm -rf "src/config" run_cmd rm "src/config.mlh" ok "Config files cleaned up" -info "Setting up TypeScript declaration files..." -run_cmd mkdir -p src/bindings/compiled/node_bindings -echo '// this file exists to prevent TS from type-checking `o1js_node.bc.cjs`' \ - > src/bindings/compiled/node_bindings/o1js_node.bc.d.cts -ok "TypeScript declarations set up" - -info "Preparing bindings output directory..." -run_cmd mkdir -p "${BINDINGS_PATH}" -run_cmd chmod -R 777 "${BINDINGS_PATH}" -ok "Output directory prepared" - -info "Copying WASM bindings..." -run_cmd cp _build/default/"${KIMCHI_BINDINGS}"/js/node_js/plonk_wasm* "${BINDINGS_PATH}" -run_cmd mv -f "${BINDINGS_PATH}"/plonk_wasm.js "${BINDINGS_PATH}"/plonk_wasm.cjs -run_cmd mv -f "${BINDINGS_PATH}"/plonk_wasm.d.ts "${BINDINGS_PATH}"/plonk_wasm.d.cts -ok "WASM bindings copied and renamed" - -info "Copying Node.js bindings..." -run_cmd cp "${BUILD_PATH}"/o1js_node*.js "${BINDINGS_PATH}" -run_cmd cp src/bindings/compiled/node_bindings/o1js_node.bc.d.cts "${BINDINGS_PATH}"/ -if [ -f "_build/o1js_node.bc.map" ]; then - run_cmd cp "_build/o1js_node.bc.map" "${BINDINGS_PATH}"/o1js_node.bc.map - info "Source map copied" -else - warn "No source map found at _build/o1js_node.bc.map, skipping" -fi -run_cmd mv -f "${BINDINGS_PATH}"/o1js_node.bc.js "${BINDINGS_PATH}"/o1js_node.bc.cjs -ok "Node.js bindings copied" - -info "Updating WASM references in bindings..." -run_cmd sed -i 's/plonk_wasm.js/plonk_wasm.cjs/' "${BINDINGS_PATH}"/o1js_node.bc.cjs -ok "WASM references updated" - -info "Cleaning up temporary source map..." -if [ -f "_build/o1js_node.bc.map" ]; then - run_cmd cp _build/o1js_node.bc.map "${BUILD_PATH}"/o1js_node.bc.map - run_cmd rm -f _build/o1js_node.bc.map - ok "Temporary source map cleaned up" -else - info "No temporary source map to clean up" -fi - -info "Fixing JavaScript bindings for better error handling..." -# TODO: find a less hacky way to make adjustments to jsoo compiler output -# `s` is the jsoo representation of the error message string, and `s.c` is the actual JS string -run_cmd sed -i 's/function failwith(s){throw \[0,Failure,s\]/function failwith(s){throw globalThis.Error(s.c)/' "${BINDINGS_PATH}"/o1js_node.bc.cjs -run_cmd sed -i 's/function invalid_arg(s){throw \[0,Invalid_argument,s\]/function invalid_arg(s){throw globalThis.Error(s.c)/' "${BINDINGS_PATH}"/o1js_node.bc.cjs -run_cmd sed -i 's/return \[0,Exn,t\]/return globalThis.Error(t.c)/' "${BINDINGS_PATH}"/o1js_node.bc.cjs -# TODO: this doesn't cover all cases, maybe should rewrite to_exn instead -run_cmd sed -i 's/function raise(t){throw caml_call1(to_exn$0,t)}/function raise(t){throw Error(t?.[1]?.c ?? "Unknown error thrown by raise")}/' "${BINDINGS_PATH}"/o1js_node.bc.cjs -ok "JavaScript bindings fixed" - -info "Setting final permissions..." -run_cmd chmod 777 "${BINDINGS_PATH}"/* -ok "Permissions set" - -info "Fixing WASM bindings for Node.js..." -run_cmd node "src/build/fix-wasm-bindings-node.js" "${BINDINGS_PATH}"/plonk_wasm.cjs -ok "WASM bindings fixed" - -info "Copying final artifacts to node_bindings directory..." -run_cmd cp -R "${BINDINGS_PATH}"/* "src/bindings/compiled/node_bindings"/ -ok "Final artifacts copied" - success "Node bindings artifacts build complete" diff --git a/src/bindings/scripts/build-o1js-web.sh b/src/bindings/scripts/build-o1js-web.sh old mode 100755 new mode 100644 index 59caf6c7bb..8617d571b4 --- a/src/bindings/scripts/build-o1js-web.sh +++ b/src/bindings/scripts/build-o1js-web.sh @@ -1,32 +1,6 @@ #!/usr/bin/env bash -set -e - -if ! command -v wasm-opt >/dev/null 2>&1; then - echo "wasm-opt is required but not found" >&2 - exit 1 -fi - -MINA_PATH="src/mina" -DUNE_PATH="src/bindings/ocaml/jsoo_exports" -BUILD_PATH="_build/default/$DUNE_PATH" -KIMCHI_BINDINGS="$MINA_PATH/src/lib/crypto/kimchi_bindings" -WEB_BINDINGS="src/bindings/compiled/web_bindings" - -dune b "${DUNE_PATH}"/o1js_web.bc.js -cp _build/default/"${KIMCHI_BINDINGS}"/js/web/plonk_wasm* "${WEB_BINDINGS}"/ -cp "${BUILD_PATH}"/o1js_web*.js "${WEB_BINDINGS}"/ - -# better error messages -# `s` is the jsoo representation of the error message string, and `s.c` is the actual JS string -sed -i 's/function failwith(s){throw \[0,Failure,s\]/function failwith(s){throw globalThis.Error(s.c)/' "${WEB_BINDINGS}"/o1js_web.bc.js -sed -i 's/function invalid_arg(s){throw \[0,Invalid_argument,s\]/function invalid_arg(s){throw globalThis.Error(s.c)/' "${WEB_BINDINGS}"/o1js_web.bc.js -sed -i 's/return \[0,Exn,t\]/return globalThis.Error(t.c)/' "${WEB_BINDINGS}"/o1js_web.bc.js -sed -i 's/function raise(t){throw caml_call1(to_exn$0,t)}/function raise(t){throw Error(t?.[1]?.c ?? "some error")}/' "${WEB_BINDINGS}"/o1js_web.bc.js - -pushd "${WEB_BINDINGS}" - wasm-opt --detect-features --enable-mutable-globals -O4 plonk_wasm_bg.wasm -o plonk_wasm_bg.wasm.opt - mv plonk_wasm_bg.wasm.opt plonk_wasm_bg.wasm -popd +npm run build:wasm:web +npm run build:jsoo:web npm run build:web diff --git a/src/bindings/scripts/update-o1js-bindings.sh b/src/bindings/scripts/update-o1js-bindings.sh index edb8c9435b..91cc760673 100755 --- a/src/bindings/scripts/update-o1js-bindings.sh +++ b/src/bindings/scripts/update-o1js-bindings.sh @@ -6,63 +6,27 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(cd "$SCRIPT_DIR/../../.." && pwd)" source "$ROOT_DIR/scripts/lib/ux.sh" -# paths -MINA_PATH="src/mina" -DUNE_PATH="src/bindings/ocaml/jsoo_exports" -BUILD_PATH="_build/default/$DUNE_PATH" -KIMCHI_BINDINGS="$MINA_PATH/src/lib/crypto/kimchi_bindings" -NODE_BINDINGS="src/bindings/compiled/node_bindings" -WEB_BINDINGS="src/bindings/compiled/web_bindings" - # setup setup_script "${BASH_SOURCE[0]}" "Update bindings" # environment variables JUST_BINDINGS="${JUST_BINDINGS:-}" -PREBUILT_KIMCHI_BINDINGS_JS_WEB="${PREBUILT_KIMCHI_BINDINGS_JS_WEB:-}" -PREBUILT_KIMCHI_BINDINGS_JS_NODE_JS="${PREBUILT_KIMCHI_BINDINGS_JS_NODE_JS:-}" # steps bold "Updating o1js bindings (node + Web)" -info "Preparing output directories..." -run_cmd mkdir -p "${NODE_BINDINGS}" "${WEB_BINDINGS}" -ok "Output directories prepared" - bold "Phase 1: Building node bindings" info "Building node artifacts..." run_cmd "${SCRIPT_DIR}"/build-o1js-node-artifacts.sh ok "node artifacts built" -info "Copying additional node bindings files..." -run_cmd cp src/bindings/compiled/_node_bindings/plonk_wasm.d.cts "${NODE_BINDINGS}"/plonk_wasm.d.cts -ok "Additional bindings files copied" - info "Copying build artifacts to dist..." -run_cmd node src/build/copy-to-dist.js +mkdir -p dist/node/bindings/compiled/node_bindings/ +cp -r src/bindings/compiled/node_bindings/* dist/node/bindings/compiled/node_bindings/ +cp src/bindings.d.ts dist/node/ ok "Build artifacts copied" -info "Setting node bindings permissions..." -run_cmd chmod -R 777 "${NODE_BINDINGS}" -ok "Permissions set" - -info "Copying final node bindings from dist..." -BINDINGS_PATH=dist/node/bindings/compiled/_node_bindings -run_cmd cp "${BINDINGS_PATH}"/o1js_node.bc.cjs "${NODE_BINDINGS}"/o1js_node.bc.cjs -if [ -f "${BINDINGS_PATH}"/o1js_node.bc.map ]; then - run_cmd cp "${BINDINGS_PATH}"/o1js_node.bc.map "${NODE_BINDINGS}"/o1js_node.bc.map - info "Source map copied" -else - warn "No source map found in dist, skipping" -fi -run_cmd cp "${BINDINGS_PATH}"/plonk_wasm* "${NODE_BINDINGS}"/ -ok "Final node bindings copied" - -info "Updating WASM references in node bindings..." -run_cmd sed -i 's/plonk_wasm.js/plonk_wasm.cjs/' "${NODE_BINDINGS}"/o1js_node.bc.cjs -ok "WASM references updated" - if [ -z "${JUST_BINDINGS}" ]; then info "Running main build..." run_cmd npm run build @@ -73,104 +37,10 @@ fi bold "Phase 2: Building web bindings" -info "Checking for prebuilt bindings..." -if [ -z "${PREBUILT_KIMCHI_BINDINGS_JS_WEB}" ] || [ -z "${PREBUILT_KIMCHI_BINDINGS_JS_NODE_JS}" ]; then - info "No prebuilt bindings found, building from source..." - - info "Preserving source map during web build..." - if [ -f "$BUILD_PATH/o1js_node.bc.map" ]; then - run_cmd cp "$BUILD_PATH/o1js_node.bc.map" "_build/o1js_node.bc.map" - info "Source map backed up" - else - info "No source map to backup" - fi - - info "Building web JavaScript bytecode..." - run_cmd dune b "${DUNE_PATH}"/o1js_web.bc.js - ok "web bytecode built" - - info "Restoring source map..." - if [ -f "_build/o1js_node.bc.map" ]; then - run_cmd cp "_build/o1js_node.bc.map" "$BUILD_PATH/o1js_node.bc.map" - info "Source map restored" - fi - - info "Copying web WASM bindings..." - run_cmd cp _build/default/"${KIMCHI_BINDINGS}"/js/web/plonk_wasm* "${WEB_BINDINGS}"/ - ok "web WASM bindings copied" - - info "Copying web JavaScript bindings..." - run_cmd cp "${BUILD_PATH}"/o1js_web*.js "${WEB_BINDINGS}"/ - ok "web JavaScript bindings copied" - - info "Setting web bindings permissions..." - run_cmd chmod -R 666 "${WEB_BINDINGS}"/* - ok "web permissions set" - -else - info "Using prebuilt bindings from Nix environment..." - - info "Copying prebuilt web bindings..." - run_cmd mkdir -p "${WEB_BINDINGS}" - run_cmd cp "${PREBUILT_KIMCHI_BINDINGS_JS_WEB}"/*.js \ - "${PREBUILT_KIMCHI_BINDINGS_JS_WEB}"/*.ts \ - "${PREBUILT_KIMCHI_BINDINGS_JS_WEB}"/*.wasm \ - "${WEB_BINDINGS}" - ok "Prebuilt web bindings copied" - - info "Copying prebuilt node bindings..." - run_cmd mkdir -p "${NODE_BINDINGS}" - run_cmd cp "${PREBUILT_KIMCHI_BINDINGS_JS_NODE_JS}"/*.js \ - "${PREBUILT_KIMCHI_BINDINGS_JS_NODE_JS}"/*.ts \ - "${PREBUILT_KIMCHI_BINDINGS_JS_NODE_JS}"/*.wasm \ - "${NODE_BINDINGS}" - ok "Prebuilt node bindings copied" - - info "Cleaning up conflicting files..." - run_cmd rm "${NODE_BINDINGS}"/plonk_wasm.js \ - "${NODE_BINDINGS}"/plonk_wasm.d.ts - ok "Conflicting files removed" - - info "Building web JavaScript bytecode with prebuilt bindings..." - run_cmd dune b "${DUNE_PATH}"/o1js_web.bc.js - run_cmd cp "${BUILD_PATH}"/o1js_web*.js "${WEB_BINDINGS}"/ - ok "web JavaScript built and copied" -fi - -bold "Phase 3: Web bindings optimization" - -info "Improving error messages in web bindings..." -# Transform OCaml-style exceptions to JavaScript Error objects -run_cmd sed -i 's/function failwith(s){throw \[0,Failure,s\]/function failwith(s){throw globalThis.Error(s.c)/' "${WEB_BINDINGS}"/o1js_web.bc.js -run_cmd sed -i 's/function invalid_arg(s){throw \[0,Invalid_argument,s\]/function invalid_arg(s){throw globalThis.Error(s.c)/' "${WEB_BINDINGS}"/o1js_web.bc.js -run_cmd sed -i 's/return \[0,Exn,t\]/return globalThis.Error(t.c)/' "${WEB_BINDINGS}"/o1js_web.bc.js -run_cmd sed -i 's/function raise(t){throw caml_call1(to_exn$0,t)}/function raise(t){throw Error(t?.[1]?.c ?? "Unknown error thrown by raise")}/' "${WEB_BINDINGS}"/o1js_web.bc.js -ok "Error messages improved" - -info "Optimizing WASM and minifying JavaScript..." -# Change to web bindings directory for optimization -run_cmd pushd "${WEB_BINDINGS}" - -if ! command -v wasm-opt >/dev/null 2>&1; then - error "wasm-opt is required for web bindings optimization" - exit 1 -fi - -info "Optimizing WASM with wasm-opt..." -run_cmd wasm-opt --detect-features --enable-mutable-globals -O4 plonk_wasm_bg.wasm -o plonk_wasm_bg.wasm.opt -run_cmd mv plonk_wasm_bg.wasm.opt plonk_wasm_bg.wasm -ok "WASM optimized" - -info "Minifying JavaScript with esbuild..." -run_cmd npx esbuild --minify --log-level=error o1js_web.bc.js > o1js_web.bc.min.js -run_cmd mv o1js_web.bc.min.js o1js_web.bc.js -ok "JavaScript minified" - -run_cmd popd -ok "Optimization complete" - +npm run build:wasm:web +npm run build:jsoo:web -bold "Phase 4: Building final project" +bold "Phase 3: Building final project" if [ -z "${JUST_BINDINGS}" ]; then info "Running web build..." diff --git a/src/build/build-web.js b/src/build/build-web.js index f7dd716329..edd4dcac2e 100644 --- a/src/build/build-web.js +++ b/src/build/build-web.js @@ -182,33 +182,3 @@ function srcStringPlugin() { }, }; } - -function deferExecutionPlugin() { - return { - name: 'defer-execution-plugin', - setup(build) { - build.onResolve({ filter: /^defer:/ }, async ({ path: importPath, resolveDir }) => { - let absPath = path.resolve(resolveDir, importPath.replace('defer:', '')); - return { - path: absPath, - namespace: 'defer-execution', - }; - }); - - build.onLoad({ filter: /.*/, namespace: 'defer-execution' }, async ({ path }) => { - let code = await readFile(path, 'utf8'); - // replace direct eval, because esbuild refuses to bundle it - // code = code.replace(/eval\(/g, '(0, eval)('); - code = code.replace(/function\(\)\s*\{\s*return this\s*\}\(\)/g, 'window'); - code = code.replace(/function\(\)\s*\{\s*return this;\s*\}\(\)/g, 'window'); - let deferedCode = ` - let require = () => {}; - export default () => {\n${code}\n};`; - return { - contents: deferedCode, - loader: 'js', - }; - }); - }, - }; -} diff --git a/src/build/build.sh b/src/build/build.sh index 489c1e9d1d..724e170137 100755 --- a/src/build/build.sh +++ b/src/build/build.sh @@ -49,12 +49,6 @@ ensure_bindings() { fi } -copy_artifacts() { - bold "[2/5] Copying artifacts to dist" - node "$ROOT_DIR/src/build/copy-artifacts.js" - ok "Artifacts copied." -} - clean_dist_node() { bold "[3/5] Cleaning dist/node" if command -v npx >/dev/null 2>&1; then @@ -80,7 +74,6 @@ build_node() { # ---------- main ---------- bold "Starting build" ensure_bindings # use check:bindings first(non-fatal on error), then fallback to build:bindings-node(fatal on error) -copy_artifacts # fatal on error clean_dist_node # fatal on error build_dev # fatal on error build_node # fatal on error diff --git a/src/build/copy-artifacts.js b/src/build/copy-artifacts.js deleted file mode 100644 index f9eedb2e31..0000000000 --- a/src/build/copy-artifacts.js +++ /dev/null @@ -1,5 +0,0 @@ -// copy compiled jsoo/wasm artifacts from a folder in the source tree to the folder where they are imported from -// (these are not the same folders so that we don't automatically pollute the source tree when rebuilding artifacts) -import { copyFromTo } from './utils.js'; - -await copyFromTo(['src/bindings/compiled/node_bindings/'], 'node_bindings', '_node_bindings');