Sol.College

Full lesson

zk-lokomotive-core

The only true metadata leak-free, platform-less end-to-end decentralized data transfer protocol

What it does

From the project README:

zk-lokomotive is an advanced, zero-knowledge proof-based file transfer system designed to operate seamlessly across multiple blockchain networks, including EVM-compatible chains, Solana, and Sui. By leveraging state-of-the-art zero-knowledge cryptography, Arweave for decentralized storage, and Wormhole for cross-chain interoperability, zk-lokomotive provides an unparalleled solution for secure, private, and efficient file transfers in a trustless environment.
Original
zklambda/zk-lokomotive-core
SuperStack fork
Blockchains/zk-lokomotive-core @ 3da6216
Stars
31
Last push (original)
2024-12-24
Languages
JavaScript, Makefile, TypeScript, Move, SCSS, Rust
Detected stack
AnchorNext.jsweb3.js
Categories
Infrastructure & Tooling
Licence
MIT
Homepage
https://zk-lokomotive.xyz/

Architecture

977 source files. By extension: .js ×898, .ts ×32, .tsx ×20, .sol ×10, .rs ×10, .move ×7.

Top-level directorySource files
zk-lok-enc-nonet-master283
zk-lok-enc-solana-master283
static266
ui36
zkl-messenger15
zkl-eswm-ES6-main15
zkl-old-arweave12
pages8

On-chain programs: anchor-cli/programs/lokomotive, zkl-messenger/chains/solana/programs/solana

❌ Does not build as-is, checked 2026-11-02 Tested on 2026-11-02: full log results.json

Build it yourself: step-by-step guide

Every command below was run on 2026-11-02 by tests/run_fork.py against the pinned commit, and the results come from that run. The full output is in the committed log.

1. Prerequisites (versions we tested with)

cargo install --git https://github.com/coral-xyz/anchor avm --locked
avm install 0.32.1 && avm use 0.32.1
sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"

2. Clone at the tested commit

git clone https://github.com/Blockchains/zk-lokomotive-core.git && cd zk-lokomotive-core
git checkout 3da6216e112b150fb657c2dbc968b9b8c369aea4

3. Configure

The repo reads these environment variables. Copy the example file and fill in your own values. Never commit real keys.

4. Install dependencies

DirectoryCommandResultTime
.npx -y yarn@1 install --ignore-engines --network-timeout 600000❌ exit 2160s
uinpm install --no-audit --no-fund --legacy-peer-deps✅ pass5s
zkl-evm-tokenbridgenpm install --no-audit --no-fund --legacy-peer-deps✅ pass6s
zk-lok-enc-nonet-masternpx -y yarn@1 install --ignore-engines --network-timeout 600000✅ pass4s
zkl-messengernpx -y yarn@1 install --ignore-engines --network-timeout 600000✅ pass5s
zkl-eswm-ES6-mainnpm install --no-audit --no-fund --legacy-peer-deps✅ pass17s
zkl-crypto-mainpnpm install --no-frozen-lockfile✅ pass2s
zkl-wormhole-local-validatornpm install --no-audit --no-fund --legacy-peer-deps✅ pass3s
zkl-ccir-main pnpm install --no-frozen-lockfile✅ pass1s
zk-lok-enc-solana-masternpx -y yarn@1 install --ignore-engines --network-timeout 600000✅ pass3s
zkl-roadhog-mainpnpm install --no-frozen-lockfile✅ pass1s
zkl-kds-mainpnpm install --no-frozen-lockfile✅ pass1s
zkl-old-arweavenpx -y yarn@1 install --ignore-engines --network-timeout 600000✅ pass17s
anchor-clinpm install --no-audit --no-fund --legacy-peer-deps✅ pass2s
zkl-messenger/chains/solananpx -y yarn@1 install --ignore-engines --network-timeout 600000✅ pass3s
anchor-clinpm install --no-audit --no-fund --legacy-peer-deps✅ pass0s
zkl-messenger/chains/solananpx -y yarn@1 install --ignore-engines --network-timeout 600000✅ pass1s
Output tail: npx -y yarn@1 install --ignore-engines --network-timeout 600000
prebuild ERR! build     at Object..js (node:internal/modules/cjs/loader:2060:10)
prebuild ERR! build     at Module.load (node:internal/modules/cjs/loader:1651:32)
prebuild ERR! build     at Module._load (node:internal/modules/cjs/loader:1443:12)
prebuild ERR! build     at wrapModuleLoad (node:internal/modules/cjs/loader:261:19)
prebuild ERR! build     at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5)
prebuild ERR! build     at node:internal/main/run_main_module:33:47

5. Build

DirectoryCommandResultTime
anchor-clianchor@0.29.0 build❌ exit 11s
zkl-messenger/chains/solanaanchor@0.32.1 build❌ exit 12s
zkl-wormhole-local-validator/solana-accountsanchor@0.32.1 build❌ exit 10s
.npx -y yarn@1 run build❌ exit 17s
uinpm run build❌ exit 13s
zk-lok-enc-nonet-masternpx -y yarn@1 run build✅ pass9s
zkl-eswm-ES6-mainnpm run build✅ pass5s
zk-lok-enc-solana-masternpx -y yarn@1 run build✅ pass10s
zkl-old-arweavenpx -y yarn@1 run build❌ exit 14s
Output tail: anchor@0.29.0 build
      = note: to use the edition 2021 resolver, specify `workspace.resolver = "2"` in the workspace root's manifest
      = note: for more details see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions
        Updating crates.io index
    error: no matching package named `ipfs-http-client` found
    location searched: crates.io index
    required by package `lokomotive v0.1.0 (/tmp/scbuild/zk-lokomotive-core/anchor-cli/programs/lokomotive)`
Output tail: anchor@0.32.1 build
496 -                 let proc_macro::LineColumn { line, column } = s.end();
496 +                 let LineColumn { line, column } = s.end();
    |
For more information about this error, try `rustc --explain E0422`.
error: could not compile `proc-macro2` (lib) due to 2 previous errors
warning: build failed, waiting for other jobs to finish...
Output tail: anchor@0.32.1 build
Error: Unable to deserialize config: TOML parse error at line 36, column 1
   |
36 | [[test.genesis]]
   | ^^^^^^^^^^^^^^^^
missing field `program`
Output tail: npx -y yarn@1 run build
Import trace for requested module:
./pages/index.js
./pages/share/[guid].js
Module not found: Can't resolve 'server' in '/tmp/scbuild/zk-lokomotive-core/pages/share'
> Build failed because of webpack errors
error Command failed with exit code 1.
Output tail: npm run build
  200 |         ) : (
> 201 |           <TwitterProfile tweets={profileTweets} wallet={wallet} />
      |            ^
  202 |         )}
  203 |       </div>
  204 |     </div>
Output tail: npx -y yarn@1 run build
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}
Node.js v24.22.1
error Command failed with exit code 1.

6. Test

DirectoryCommandResultTime
zkl-evm-tokenbridgenpm run test❌ exit 15s
zkl-eswm-ES6-mainnpm run test -- --watchAll=false 2>&1 || npm run test✅ pass1s
zkl-old-arweavenpx -y yarn@1 run test❌ exit 12s
Output tail: npm run test
    at main (file:///tmp/scbuild/zk-lokomotive-core/zkl-evm-tokenbridge/treasury.js:211:19)
    at file:///tmp/scbuild/zk-lokomotive-core/zkl-evm-tokenbridge/treasury.js:341:1
    at ModuleJob.run (node:internal/modules/esm/module_job:561:25)
    at async node:internal/modules/esm/loader:647:26
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5)
Node.js v24.22.1
Output tail: npx -y yarn@1 run test
  testMatch: /tmp/scbuild/zk-lokomotive-core/zkl-old-arweave/src/**/__tests__/**/*.{js,jsx,ts,tsx}, /tmp/scbuild/zk-lokomotive-core/zkl-old-arweave/src/**/*.{spec,test}.{js,jsx,ts,tsx} - 0 matches
  testPathIgnorePatterns: /node_modules/ - 15 matches
  testRegex:  - 0 matches
Pattern:  - 0 matches
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 1.

7. Deploy to a local validator

solana-test-validator --reset   # separate terminal
solana config set -ul && solana airdrop 100
anchor deploy --provider.cluster localnet

Deploy to devnet (free)

solana config set --url devnet
solana airdrop 2   # or https://faucet.solana.com
anchor deploy --provider.cluster devnet   # native: solana program deploy target/deploy/<name>.so
# point the frontend RPC env var at https://api.devnet.solana.com

How it works

Every instruction handler in the program, with the accounts struct it validates. Each link points to the line at the pinned commit.

InstructionAccountsWhere
Initializenative instruction variantzkl-messenger/chains/solana/programs/solana/src/wormhole.rs:27
PostMessagenative instruction variantzkl-messenger/chains/solana/programs/solana/src/wormhole.rs:28
PostVAAnative instruction variantzkl-messenger/chains/solana/programs/solana/src/wormhole.rs:29
SetFeesnative instruction variantzkl-messenger/chains/solana/programs/solana/src/wormhole.rs:30
TransferFeesnative instruction variantzkl-messenger/chains/solana/programs/solana/src/wormhole.rs:31
UpgradeContractnative instruction variantzkl-messenger/chains/solana/programs/solana/src/wormhole.rs:32
UpgradeGuardianSetnative instruction variantzkl-messenger/chains/solana/programs/solana/src/wormhole.rs:33
VerifySignaturesnative instruction variantzkl-messenger/chains/solana/programs/solana/src/wormhole.rs:34
initializeInitializezkl-messenger/chains/solana/programs/solana/src/lib.rs:36
register_chainRegisterChainzkl-messenger/chains/solana/programs/solana/src/lib.rs:42
send_msgSendMsgzkl-messenger/chains/solana/programs/solana/src/lib.rs:48
confirm_msgConfirmMsgzkl-messenger/chains/solana/programs/solana/src/lib.rs:115

Extend it

  1. Add an integration test that runs the main flow end to end and asserts every account state change.
  2. Add a negative test: call each instruction with the wrong signer or account and check that it fails.
  3. Add an event (emit!) to each state-changing instruction and subscribe to it from the client.
  4. Replace any unchecked AccountInfo with typed accounts plus has_one/seeds constraints.
  5. Make the frontend read the cluster from an env var, deploy it to GitHub Pages and point it at your devnet program.
  6. Wire the build into CI by copying this site's verify-forks workflow.

Key code, explained

Excerpts chosen automatically where the code uses the most Solana concepts, pinned to the fork's commit.

zklambda/zk-lokomotive-core · zkl-messenger/chains/solana/programs/solana/src/context.rs L1–24 @ 3da6216 · MIT · original
use anchor_lang::prelude::*;use crate::constant::*;use crate::account::*;use std::str::FromStr;use anchor_lang::solana_program::sysvar::{rent, clock};use crate::wormhole::*;use hex::decode; #[derive(Accounts)]pub struct Initialize<'info> {    #[account(        init,        seeds=[b"config".as_ref()],        payer=owner,        bump,        space=8+32+32+1024    )]    pub config: Account<'info, Config>,    #[account(mut)]    pub owner: Signer<'info>,    pub system_program: Program<'info, System>} #[derive(Accounts)]
  1. Line 12 init,: Creates and pays for a new account. Space and payer must be specified.
  2. Line 13 seeds=[b"config".as_ref()],: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match.
  3. Line 15 bump,: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
  4. Line 20 pub owner: Signer<'info>,: Requires this account to have signed the transaction.
zklambda/zk-lokomotive-core · zkl-messenger/chains/solana/programs/solana/src/lib.rs L121–144 @ 3da6216 · MIT · original
        h.write(serialized_vaa.as_slice()).unwrap();        let vaa_hash: [u8; 32] = h.finalize().into();         let (vaa_key, _) = Pubkey::find_program_address(&[            b"PostedVAA",            &vaa_hash        ], &Pubkey::from_str(CORE_BRIDGE_ADDRESS).unwrap());         if ctx.accounts.core_bridge_vaa.key() != vaa_key {            return err!(MessengerError::VAAKeyMismatch);        }         msg!("Checking emitter chain and address");        // Already checked that the SignedVaa is owned by core bridge in account constraint logic        //Check that the emitter chain and address match up with the vaa        if vaa.emitter_chain != ctx.accounts.emitter_acc.chain_id ||           vaa.emitter_address != &decode(&ctx.accounts.emitter_acc.emitter_addr.as_str()).unwrap()[..] {            return err!(MessengerError::VAAEmitterMismatch)        }         ctx.accounts.config.current_msg = String::from_utf8(vaa.payload).unwrap();        Ok(())    }}
  1. Line 124 let (vaa_key, _) = Pubkey::find_program_address(&[: Derives a PDA from seeds and the program ID and returns the address with its canonical bump.
  2. Line 130 return err!(MessengerError::VAAKeyMismatch);: An explicit validation that aborts the instruction with an error.
  3. Line 133 msg!("Checking emitter chain and address");: Logs to the program log, which is visible in explorers and the test output.

How to run, build and test

These commands come from the repo's own manifests (package.json scripts, Anchor.toml, Cargo, go.mod, Makefile). Check the README for prerequisites and environment variables.

DirectoryCommandRuns
.npm run devnext dev
.npm run startnext start
.npm run buildnext build
zkl-arweave-uploader/ausnpm run devnext dev
zkl-arweave-uploader/ausnpm run startnext start
zkl-arweave-uploader/ausnpm run buildnext build
zkl-arweave-uploader/ausnpm run lintnext lint
uinpm run devnext dev
uinpm run startnext start
uinpm run buildnext build
uinpm run lintnext lint
zkl-aus-main /ausnpm run devnext dev
zkl-aus-main /ausnpm run startnext start
zkl-aus-main /ausnpm run buildnext build
zkl-aus-main /ausnpm run lintnext lint
zkl-crypto-mainnpm run testecho "Error: no test specified" && exit 1

What you could build from it

Used in lessons