-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* dev: add cli packages * feat: add basic cli * dev: remove figlet * feat: add error handling and flag conflicts * doc: add telegram group to README * chore: downgrade trunk check to python 3.10 for consistency with tests action * doc: add CLI usage to README * chore: move Usage after Cairo presentation * doc: add cli usage example * doc: add state of builtins implem * fix: use Op1Src enum for instruction initialization * chore: remove unused local variable * feat: add package build script * chore: add types to print trace variables * chore: remove empty cli file * chore: rename memory error to avoid export conflicts * feat: add build script with type declaration transforms * refactor: export argument json validation to argument argParser * doc: update doc for local dependency use * feat: rename cli to cairo * refactor: rename relocateOffset to offset * doc: use updated cli command name * chore: remove unused scripts * chore: format RunOptions * refactor: wrap cli action in a global try catch clause
- Loading branch information
Showing
15 changed files
with
357 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
node_modules | ||
dist | ||
|
||
cairo_programs/**/*.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,13 @@ | ||
# TypeScript Cairo VM | ||
# Cairo VM Typescript | ||
|
||
<div align="center"> | ||
<h1><code>TypeScript Cairo VM</code></h1> | ||
<h1><code>Cairo VM TypeScript</code></h1> | ||
|
||
<strong>An implementation of the Cairo VM in TypeScript, focusing on | ||
education</strong> | ||
|
||
[Github](https://github.com/kkrt-labs/cairo-vm-ts) | ||
[Github](https://github.com/kkrt-labs/cairo-vm-ts) · | ||
[Telegram](https://t.me/cairovmts) | ||
|
||
<sub>Built with 🥕 by <a href="https://twitter.com/KakarotZkEvm">KKRT | ||
Labs</a></sub> | ||
|
@@ -92,13 +93,44 @@ performance and safety. While the ones of our TypeScript implementation is | |
- Deliberate design choices to further improve readability and simplicity | ||
- Extensive documentation: JSDoc, diagrams, explainers, etc. | ||
|
||
## Usage | ||
|
||
### CLI | ||
|
||
You can install the CLI `cairo-vm-ts` by doing the following: | ||
|
||
1. Clone this repo: `git clone [email protected]:kkrt-labs/cairo-vm-ts.git` | ||
2. Go to the cloned directory: `cd cairo-vm-ts` | ||
3. Install the dependencies: `bun install` | ||
4. Register the package as a _linkable_ package: `bun link` | ||
|
||
Example usage: | ||
|
||
```bash | ||
cairo run fibonacci.json --export-memory fib_mem.bin --print-memory --print-output | ||
``` | ||
|
||
### As a dependency | ||
|
||
No package release has been done yet. | ||
|
||
You can still add it as a dependency with a local copy: | ||
|
||
1. Clone this repo: `git clone [email protected]:kkrt-labs/cairo-vm-ts.git` | ||
2. Go to the cloned directory: `cd cairo-vm-ts` | ||
3. Install the dependencies: `bun install` | ||
4. Build the project: `bun run build` | ||
5. Go to your project `cd ~/my-project` | ||
6. Add `cairo-vm-ts` to your project dependency: | ||
`<bun | yarn | npm> add ~/path/to/cairo-vm-ts` | ||
|
||
## State of the VM | ||
|
||
| Goals | Done? | | ||
| ---------------------------- | ------- | | ||
| Run basic Cairo Zero program | ☑ | | ||
| Run basic Cairo program | ☐ | | ||
| Add [builtins](#builtins) | ☐ | | ||
| Add [builtins](#builtins) | ☑ | | ||
| Add [hints](#hints) | ☐ | | ||
| Run StarkNet contracts | ☐ | | ||
| Benchmark against other VMs | ☐ | | ||
|
@@ -107,7 +139,20 @@ performance and safety. While the ones of our TypeScript implementation is | |
|
||
### Builtins | ||
|
||
<!-- Add a table with the builtin list and state done/to be done --> | ||
| Builtin | Done? | | ||
| -------------------------------------------------------------------- | ------- | | ||
| [Output](https://github.com/kkrt-labs/cairo-vm-ts/issues/65) | ☑ | | ||
| [Pedersen](https://github.com/kkrt-labs/cairo-vm-ts/issues/70) | ☑ | | ||
| [Range Check](https://github.com/kkrt-labs/cairo-vm-ts/issues/68) | ☑ | | ||
| [ECDSA](https://github.com/kkrt-labs/cairo-vm-ts/issues/67) | ☑ | | ||
| [Bitwise](https://github.com/kkrt-labs/cairo-vm-ts/issues/62) | ☑ | | ||
| [EcOp](https://github.com/kkrt-labs/cairo-vm-ts/issues/66) | ☑ | | ||
| [Keccak](https://github.com/kkrt-labs/cairo-vm-ts/issues/69) | ☑ | | ||
| [Poseidon](https://github.com/kkrt-labs/cairo-vm-ts/issues/71) | ☑ | | ||
| [Range Check 96](https://github.com/kkrt-labs/cairo-vm-ts/issues/81) | ☑ | | ||
| Segment Arena | ☐ | | ||
| AddMod | ☐ | | ||
| MulMod | ☐ | | ||
|
||
### Hints | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,18 +2,27 @@ | |
"name": "cairo-vm-ts", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"start": "echo \"Error: no entrypoint yet\" && exit 1" | ||
}, | ||
"keywords": [], | ||
"author": "Clément Walter <[email protected]>", | ||
"license": "Apache-2.0", | ||
"devDependencies": { | ||
"bun-types": "^1.1.12", | ||
"typescript": "^5.2.2" | ||
"main": "dist/index.js", | ||
"types": "dist/types/index.d.ts", | ||
"scripts": { | ||
"clean": "rimraf dist", | ||
"prebuild": "bun run clean", | ||
"build": "bun build --target=node ./src/index.ts --outfile=dist/index.js && bun run build:declaration", | ||
"build:declaration": "tspc --emitDeclarationOnly --project tsconfig.types.json", | ||
"postbuild": "rimraf tsconfig.types.tsbuildinfo" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/kkrt-labs/cairo-vm-ts" | ||
}, | ||
"files": [ | ||
"src/**/*.ts", | ||
"dist/*.js", | ||
"dist/types/**/*.d.ts" | ||
], | ||
"prettier": { | ||
"proseWrap": "always", | ||
"trailingComma": "es5", | ||
|
@@ -23,8 +32,21 @@ | |
"printWidth": 80 | ||
}, | ||
"dependencies": { | ||
"@commander-js/extra-typings": "^12.1.0", | ||
"@noble/curves": "^1.4.0", | ||
"@scure/starknet": "^1.0.0", | ||
"commander": "^12.1.0", | ||
"consola": "^3.2.3", | ||
"rimraf": "^5.0.7", | ||
"zod": "canary" | ||
}, | ||
"devDependencies": { | ||
"bun-types": "^1.1.12", | ||
"ts-patch": "^3.2.0", | ||
"typescript": "^5.2.2", | ||
"typescript-transform-paths": "^3.4.7" | ||
}, | ||
"bin": { | ||
"cairo": "./src/cli.ts" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
#! /usr/bin/env bun | ||
|
||
import * as fs from 'fs'; | ||
import { Command, Option } from '@commander-js/extra-typings'; | ||
|
||
import { consola } from 'consola'; | ||
import { parseProgram } from 'vm/program'; | ||
import { CairoRunner, RunOptions } from 'runners/cairoRunner'; | ||
import { TraceEntry } from 'vm/virtualMachine'; | ||
import { Argument } from 'commander'; | ||
|
||
consola.options = { | ||
...consola.options, | ||
formatOptions: { | ||
date: false, | ||
}, | ||
}; | ||
|
||
const VERSION_CLI = '0.1.0'; | ||
|
||
const program = new Command().name('cairo').version(VERSION_CLI); | ||
|
||
program | ||
.command('run', { isDefault: true }) | ||
.description('Run a compiled Cairo program') | ||
.addArgument( | ||
new Argument( | ||
'<program.json>', | ||
'path to Cairo compilation artifacts' | ||
).argParser((path) => { | ||
if (!path.match(/\.json$/)) | ||
throw new Error('Provided file is not a JSON'); | ||
return path; | ||
}) | ||
) | ||
.option('--no-relocate', 'do not relocate memory') | ||
.addOption( | ||
new Option( | ||
'--offset <OFFSET>', | ||
'start address of the relocated memory\nStarkWare verifier expects offset to be 1' | ||
) | ||
.default(0, '0') | ||
.argParser(parseInt) | ||
) | ||
.option( | ||
'--export-trace <TRACE_FILENAME>', | ||
'export the trace, little-endian encoded' | ||
) | ||
.option( | ||
'--export-memory <MEMORY_FILENAME>', | ||
'export the relocated memory, little-endian encoded' | ||
) | ||
.option('--print-trace', 'print the trace') | ||
.option('--print-memory', 'print the non-relocated memory') | ||
.option('--print-relocated-memory', 'print the relocated memory') | ||
.option('--print-output', 'print the output segment') | ||
.action(async (path, options) => { | ||
try { | ||
const { | ||
relocate, | ||
offset, | ||
exportMemory, | ||
exportTrace, | ||
printOutput, | ||
printMemory, | ||
printRelocatedMemory, | ||
printTrace, | ||
} = options; | ||
|
||
if ( | ||
(!relocate && !!offset) || | ||
(!relocate && exportMemory) || | ||
(!relocate && printRelocatedMemory) | ||
) { | ||
consola.log( | ||
"option '--no-relocate' cannot be used with options '--offset <OFFSET>', '--export-memory <MEMORY_FILENAME>' or '--print-relocated-memory'" | ||
); | ||
process.exit(1); | ||
} | ||
|
||
consola.info(`Cairo VM TS ${VERSION_CLI} - Execution Mode`); | ||
|
||
const program = parseProgram(fs.readFileSync(String(path), 'utf-8')); | ||
const runner = new CairoRunner(program); | ||
const config: RunOptions = { relocate: relocate, offset: offset }; | ||
runner.run(config); | ||
consola.success('Execution finished!'); | ||
|
||
if (exportMemory) { | ||
consola.info('Exporting memory...'); | ||
runner.exportMemory(exportMemory, offset); | ||
consola.success(`Memory exported to ${exportMemory}`); | ||
} | ||
if (exportTrace) { | ||
consola.info('Exporting trace...'); | ||
runner.exportTrace(exportTrace); | ||
consola.success(`Trace exported to ${exportTrace}`); | ||
} | ||
|
||
if (printMemory) consola.log(runner.vm.memory.toString()); | ||
if (printRelocatedMemory) | ||
consola.log(runner.vm.relocatedMemoryToString()); | ||
if (printTrace) | ||
consola.log( | ||
'\nTRACE:', | ||
runner.vm.trace | ||
.map((entry: TraceEntry, index: number) => | ||
[ | ||
`\nSTEP: ${index}`, | ||
`pc: ${entry.pc.toString()}`, | ||
`ap: ${entry.ap.toString()}`, | ||
`fp: ${entry.fp.toString()}\n`, | ||
].join('\n') | ||
) | ||
.join('\n') | ||
); | ||
if (printOutput) { | ||
const output = runner.getOutput(); | ||
if (output.length) { | ||
consola.log('Program output: '); | ||
output.forEach((value) => consola.log(value.toString())); | ||
} else { | ||
consola.log('Output segment is empty'); | ||
} | ||
} | ||
} catch (err) { | ||
consola.fail(`Execution failed`); | ||
throw err; | ||
} | ||
}); | ||
|
||
program.addHelpText( | ||
'beforeAll', | ||
'\nGitHub: https://github.com/kkrt-labs/cairo-vm-ts\nTelegram: https://t.me/cairovmts\n' | ||
); | ||
program.showHelpAfterError(); | ||
program.parse(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
class CairoRunnerError extends Error {} | ||
|
||
export class EmptyRelocatedMemory extends CairoRunnerError {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
export * as PrimitiveErrors from 'errors/primitives'; | ||
export * as MemoryErrors from 'errors/memory'; | ||
export * as InstructionErrors from 'errors/instruction'; | ||
export * as VirtualMachineErrors from 'errors/virtualMachine'; | ||
export * as BuiltinErrors from 'errors/builtins'; | ||
export * as CairoRunnerErrors from 'errors/cairoRunner'; | ||
|
||
export { Felt } from 'primitives/felt'; | ||
export { Relocatable } from 'primitives/relocatable'; | ||
export { SegmentValue, isFelt, isRelocatable } from 'primitives/segmentValue'; | ||
|
||
export { Memory } from 'memory/memory'; | ||
export { | ||
Instruction, | ||
Register, | ||
Op1Src, | ||
ResLogic, | ||
Opcode, | ||
PcUpdate, | ||
ApUpdate, | ||
FpUpdate, | ||
} from 'vm/instruction'; | ||
export { | ||
VirtualMachine, | ||
TraceEntry, | ||
RelocatedMemory, | ||
RelocatedTraceEntry, | ||
} from 'vm/virtualMachine'; | ||
export { parseProgram, Program, Identifier } from 'vm/program'; | ||
|
||
export { BuiltinHandler, getBuiltin } from 'builtins/builtin'; | ||
export { outputHandler } from 'builtins/output'; | ||
export { pedersenHandler } from 'builtins/pedersen'; | ||
export { rangeCheckHandler } from 'builtins/rangeCheck'; | ||
export { ecdsaHandler, EcdsaSegment, EcdsaSignature } from 'builtins/ecdsa'; | ||
export { bitwiseHandler } from 'builtins/bitwise'; | ||
export { ecOpHandler } from 'builtins/ecop'; | ||
export { keccakHandler } from 'builtins/keccak'; | ||
export { poseidonHandler } from 'builtins/poseidon'; | ||
|
||
export { CairoRunner, RunOptions } from 'runners/cairoRunner'; |
Oops, something went wrong.