Merge branch 'mainnet' into testnet-beta

This commit is contained in:
Pranav Gaddamadugu 2024-07-07 19:06:24 -07:00
commit 5998a00863
61 changed files with 752 additions and 299 deletions

View File

@ -21,6 +21,7 @@ fi
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env
# Publicly mint 100 tokens for Alice.
@ -55,6 +56,7 @@ leo run mint_public aleo13ssze66adjjkt795z9u5wpq8h6kn0y2657726h4h3e3wfnez4vqsm30
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp2RWGDcde3efb89rjhME1VYA8QMxcxep5DShNBR6n8Yjh
ENDPOINT=https://localhost:3030
" > .env
# Privately mint 100 tokens for Bob.
@ -89,6 +91,7 @@ leo run mint_private aleo17vy26rpdhqx4598y5gp7nvaa9rk7tnvl6ufhvvf4calsrrqdaqyshd
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env
# Publicly transfer 10 tokens from Alice to Bob.
@ -123,6 +126,7 @@ leo run transfer_public aleo17vy26rpdhqx4598y5gp7nvaa9rk7tnvl6ufhvvf4calsrrqdaqy
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp2RWGDcde3efb89rjhME1VYA8QMxcxep5DShNBR6n8Yjh
ENDPOINT=https://localhost:3030
" > .env
# Privately transfer 20 tokens from Bob to Alice.
@ -161,6 +165,7 @@ leo run transfer_private "{
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env
# Convert 30 public tokens from Alice into 30 private tokens for Bob.
@ -196,6 +201,7 @@ leo run transfer_public_to_private aleo17vy26rpdhqx4598y5gp7nvaa9rk7tnvl6ufhvvf4
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp2RWGDcde3efb89rjhME1VYA8QMxcxep5DShNBR6n8Yjh
ENDPOINT=https://localhost:3030
" > .env
# Convert 40 private tokens from Bob into 40 public tokens for Alice.
@ -237,4 +243,5 @@ leo run transfer_private_to_public "{
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env

226
Cargo.lock generated
View File

@ -196,6 +196,15 @@ version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
[[package]]
name = "arbitrary"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
dependencies = [
"derive_arbitrary",
]
[[package]]
name = "arrayref"
version = "0.3.7"
@ -429,9 +438,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.7"
version = "4.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f"
checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d"
dependencies = [
"clap_builder",
"clap_derive",
@ -439,9 +448,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.7"
version = "4.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f"
checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708"
dependencies = [
"anstream",
"anstyle",
@ -451,9 +460,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.5"
version = "4.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085"
dependencies = [
"heck",
"proc-macro2",
@ -741,6 +750,30 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "derive_arbitrary"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
dependencies = [
"proc-macro2",
"quote 1.0.36",
"syn 2.0.66",
]
[[package]]
name = "dialoguer"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de"
dependencies = [
"console",
"shell-words",
"tempfile",
"thiserror",
"zeroize",
]
[[package]]
name = "difflib"
version = "0.4.0"
@ -799,6 +832,17 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "displaydoc"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote 1.0.36",
"syn 2.0.66",
]
[[package]]
name = "doc-comment"
version = "0.3.3"
@ -857,6 +901,26 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "enum-iterator"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c280b9e6b3ae19e152d8e31cf47f18389781e119d4013a2a2bb0180e5facc635"
dependencies = [
"enum-iterator-derive",
]
[[package]]
name = "enum-iterator-derive"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b"
dependencies = [
"proc-macro2",
"quote 1.0.36",
"syn 2.0.66",
]
[[package]]
name = "enum_index"
version = "0.2.0"
@ -1470,9 +1534,9 @@ dependencies = [
[[package]]
name = "lazy_static"
version = "1.4.0"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "leo-abnf"
@ -1560,6 +1624,7 @@ dependencies = [
"colored",
"console",
"crossterm",
"dialoguer",
"dirs 5.0.1",
"dotenvy",
"indexmap 1.9.3",
@ -1578,7 +1643,7 @@ dependencies = [
"reqwest 0.12.5",
"rpassword",
"rusty-hook",
"self_update 0.40.0",
"self_update 0.41.0",
"serde",
"serde_json",
"serial_test",
@ -1598,6 +1663,7 @@ name = "leo-package"
version = "1.12.0"
dependencies = [
"aleo-std",
"dialoguer",
"indexmap 1.9.3",
"lazy_static",
"leo-errors",
@ -2629,9 +2695,9 @@ dependencies = [
[[package]]
name = "self_update"
version = "0.40.0"
version = "0.41.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4997484b55df069a4773d822715695b2cc27b23829eca2a4b41690e948bdeb"
checksum = "469a3970061380c19852269f393e74c0fe607a4e23d85267382cf25486aa8de5"
dependencies = [
"hyper 1.3.1",
"indicatif",
@ -2764,6 +2830,12 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "shell-words"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
[[package]]
name = "signal-hook"
version = "0.3.17"
@ -2834,7 +2906,7 @@ dependencies = [
[[package]]
name = "snarkvm"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"anstyle",
"anyhow",
@ -2863,7 +2935,7 @@ dependencies = [
[[package]]
name = "snarkvm-algorithms"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"aleo-std",
"anyhow",
@ -2893,7 +2965,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-circuit-account",
"snarkvm-circuit-algorithms",
@ -2907,7 +2979,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-account"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-circuit-algorithms",
"snarkvm-circuit-network",
@ -2918,7 +2990,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-algorithms"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-circuit-types",
"snarkvm-console-algorithms",
@ -2928,7 +3000,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-collections"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-circuit-algorithms",
"snarkvm-circuit-types",
@ -2938,7 +3010,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-environment"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"indexmap 2.2.6",
"itertools 0.11.0",
@ -2956,12 +3028,12 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-environment-witness"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
[[package]]
name = "snarkvm-circuit-network"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-circuit-algorithms",
"snarkvm-circuit-collections",
@ -2972,7 +3044,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-program"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"paste",
"snarkvm-circuit-account",
@ -2987,7 +3059,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-types"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-circuit-environment",
"snarkvm-circuit-types-address",
@ -3002,7 +3074,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-types-address"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-circuit-environment",
"snarkvm-circuit-types-boolean",
@ -3015,7 +3087,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-types-boolean"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-circuit-environment",
"snarkvm-console-types-boolean",
@ -3024,7 +3096,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-types-field"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-circuit-environment",
"snarkvm-circuit-types-boolean",
@ -3034,7 +3106,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-types-group"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-circuit-environment",
"snarkvm-circuit-types-boolean",
@ -3046,7 +3118,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-types-integers"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-circuit-environment",
"snarkvm-circuit-types-boolean",
@ -3058,7 +3130,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-types-scalar"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-circuit-environment",
"snarkvm-circuit-types-boolean",
@ -3069,7 +3141,7 @@ dependencies = [
[[package]]
name = "snarkvm-circuit-types-string"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-circuit-environment",
"snarkvm-circuit-types-boolean",
@ -3081,7 +3153,7 @@ dependencies = [
[[package]]
name = "snarkvm-console"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-console-account",
"snarkvm-console-algorithms",
@ -3094,7 +3166,7 @@ dependencies = [
[[package]]
name = "snarkvm-console-account"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"bs58",
"snarkvm-console-network",
@ -3105,7 +3177,7 @@ dependencies = [
[[package]]
name = "snarkvm-console-algorithms"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"blake2s_simd",
"smallvec",
@ -3118,7 +3190,7 @@ dependencies = [
[[package]]
name = "snarkvm-console-collections"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"aleo-std",
"rayon",
@ -3129,7 +3201,7 @@ dependencies = [
[[package]]
name = "snarkvm-console-network"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"anyhow",
"indexmap 2.2.6",
@ -3152,7 +3224,7 @@ dependencies = [
[[package]]
name = "snarkvm-console-network-environment"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"anyhow",
"bech32",
@ -3170,8 +3242,9 @@ dependencies = [
[[package]]
name = "snarkvm-console-program"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"enum-iterator",
"enum_index",
"enum_index_derive",
"indexmap 2.2.6",
@ -3191,7 +3264,7 @@ dependencies = [
[[package]]
name = "snarkvm-console-types"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-console-network-environment",
"snarkvm-console-types-address",
@ -3206,7 +3279,7 @@ dependencies = [
[[package]]
name = "snarkvm-console-types-address"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-console-network-environment",
"snarkvm-console-types-boolean",
@ -3217,7 +3290,7 @@ dependencies = [
[[package]]
name = "snarkvm-console-types-boolean"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-console-network-environment",
]
@ -3225,7 +3298,7 @@ dependencies = [
[[package]]
name = "snarkvm-console-types-field"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-console-network-environment",
"snarkvm-console-types-boolean",
@ -3235,7 +3308,7 @@ dependencies = [
[[package]]
name = "snarkvm-console-types-group"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-console-network-environment",
"snarkvm-console-types-boolean",
@ -3246,7 +3319,7 @@ dependencies = [
[[package]]
name = "snarkvm-console-types-integers"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-console-network-environment",
"snarkvm-console-types-boolean",
@ -3257,7 +3330,7 @@ dependencies = [
[[package]]
name = "snarkvm-console-types-scalar"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-console-network-environment",
"snarkvm-console-types-boolean",
@ -3268,7 +3341,7 @@ dependencies = [
[[package]]
name = "snarkvm-console-types-string"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-console-network-environment",
"snarkvm-console-types-boolean",
@ -3279,7 +3352,7 @@ dependencies = [
[[package]]
name = "snarkvm-curves"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"rand",
"rayon",
@ -3293,7 +3366,7 @@ dependencies = [
[[package]]
name = "snarkvm-fields"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"aleo-std",
"anyhow",
@ -3310,7 +3383,7 @@ dependencies = [
[[package]]
name = "snarkvm-ledger"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"aleo-std",
"anyhow",
@ -3334,7 +3407,7 @@ dependencies = [
[[package]]
name = "snarkvm-ledger-authority"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"anyhow",
"rand",
@ -3346,7 +3419,7 @@ dependencies = [
[[package]]
name = "snarkvm-ledger-block"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"indexmap 2.2.6",
"rayon",
@ -3365,7 +3438,7 @@ dependencies = [
[[package]]
name = "snarkvm-ledger-committee"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"indexmap 2.2.6",
"rayon",
@ -3377,7 +3450,7 @@ dependencies = [
[[package]]
name = "snarkvm-ledger-narwhal"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-ledger-narwhal-batch-certificate",
"snarkvm-ledger-narwhal-batch-header",
@ -3390,7 +3463,7 @@ dependencies = [
[[package]]
name = "snarkvm-ledger-narwhal-batch-certificate"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"indexmap 2.2.6",
"rayon",
@ -3403,7 +3476,7 @@ dependencies = [
[[package]]
name = "snarkvm-ledger-narwhal-batch-header"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"indexmap 2.2.6",
"rayon",
@ -3415,7 +3488,7 @@ dependencies = [
[[package]]
name = "snarkvm-ledger-narwhal-data"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"bytes",
"serde_json",
@ -3426,7 +3499,7 @@ dependencies = [
[[package]]
name = "snarkvm-ledger-narwhal-subdag"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"indexmap 2.2.6",
"rayon",
@ -3441,7 +3514,7 @@ dependencies = [
[[package]]
name = "snarkvm-ledger-narwhal-transmission"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"bytes",
"serde_json",
@ -3454,7 +3527,7 @@ dependencies = [
[[package]]
name = "snarkvm-ledger-narwhal-transmission-id"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"snarkvm-console",
"snarkvm-ledger-puzzle",
@ -3463,7 +3536,7 @@ dependencies = [
[[package]]
name = "snarkvm-ledger-puzzle"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"aleo-std",
"anyhow",
@ -3483,22 +3556,28 @@ dependencies = [
[[package]]
name = "snarkvm-ledger-puzzle-epoch"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"aleo-std",
"anyhow",
"colored",
"indexmap 2.2.6",
"lru",
"parking_lot",
"rand",
"rand_chacha",
"rayon",
"snarkvm-circuit",
"snarkvm-console",
"snarkvm-ledger-puzzle",
"snarkvm-synthesizer-process",
"snarkvm-synthesizer-program",
]
[[package]]
name = "snarkvm-ledger-query"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"async-trait",
"reqwest 0.11.27",
@ -3511,7 +3590,7 @@ dependencies = [
[[package]]
name = "snarkvm-ledger-store"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"aleo-std-storage",
"anyhow",
@ -3534,7 +3613,7 @@ dependencies = [
[[package]]
name = "snarkvm-parameters"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"aleo-std",
"anyhow",
@ -3559,7 +3638,7 @@ dependencies = [
[[package]]
name = "snarkvm-synthesizer"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"aleo-std",
"anyhow",
@ -3569,6 +3648,7 @@ dependencies = [
"parking_lot",
"rand",
"rayon",
"serde_json",
"snarkvm-algorithms",
"snarkvm-circuit",
"snarkvm-console",
@ -3588,7 +3668,7 @@ dependencies = [
[[package]]
name = "snarkvm-synthesizer-process"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"aleo-std",
"colored",
@ -3611,7 +3691,7 @@ dependencies = [
[[package]]
name = "snarkvm-synthesizer-program"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"indexmap 2.2.6",
"paste",
@ -3625,7 +3705,7 @@ dependencies = [
[[package]]
name = "snarkvm-synthesizer-snark"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"bincode",
"once_cell",
@ -3638,7 +3718,7 @@ dependencies = [
[[package]]
name = "snarkvm-utilities"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"aleo-std",
"anyhow",
@ -3659,7 +3739,7 @@ dependencies = [
[[package]]
name = "snarkvm-utilities-derives"
version = "0.16.19"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=fddd8b9#fddd8b92b4c6417e37d62722b3b937534dc4fb26"
source = "git+https://github.com/AleoNet/snarkVM.git?rev=d170a9f#d170a9f7c5ef980f9392301dc899dee355599ca6"
dependencies = [
"proc-macro2",
"quote 1.0.36",
@ -4579,13 +4659,17 @@ dependencies = [
[[package]]
name = "zip"
version = "0.6.6"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
checksum = "775a2b471036342aa69bc5a602bc889cb0a06cda00477d0c69566757d5553d39"
dependencies = [
"byteorder",
"arbitrary",
"crc32fast",
"crossbeam-utils",
"displaydoc",
"indexmap 2.2.6",
"memchr",
"thiserror",
"time",
]

View File

@ -46,7 +46,7 @@ members = [
[workspace.dependencies.snarkvm]
#version = "0.16.19"
git = "https://github.com/AleoNet/snarkVM.git"
rev = "fddd8b9"
rev = "d170a9f"
[lib]
path = "leo/lib.rs"
@ -61,6 +61,7 @@ ci_skip = [ "leo-compiler/ci_skip" ]
noconfig = [ ]
[dependencies]
dialoguer = "0.11.0"
num-format = "0.4.4"
text-tables = "0.3.1"
ureq = "2.9.7"
@ -124,7 +125,7 @@ version = "1.9"
features = [ "serde" ]
[dependencies.lazy_static]
version = "1.4.0"
version = "1.5.0"
[dependencies.rand]
version = "0.8"
@ -141,7 +142,7 @@ version = "0.12.5"
features = [ "blocking", "json", "multipart" ]
[dependencies.self_update]
version = "0.40.0"
version = "0.41.0"
features = [ "archive-zip" ]
[dependencies.serde]

View File

@ -121,6 +121,7 @@ pub fn setup_build_directory(
program_name: &str,
bytecode: &String,
handler: &Handler,
endpoint: String,
) -> Result<Package<CurrentNetwork>, ()> {
// Initialize a temporary directory.
let directory = temp_dir();
@ -137,7 +138,7 @@ pub fn setup_build_directory(
let _manifest_file = Manifest::create(&directory, &program_id).unwrap();
// Create the environment file.
Env::<CurrentNetwork>::new().unwrap().write_to(&directory).unwrap();
Env::<CurrentNetwork>::new(None, endpoint).unwrap().write_to(&directory);
if Env::<CurrentNetwork>::exists_at(&directory) {
println!(".env file created at {:?}", &directory);
}
@ -283,14 +284,3 @@ pub fn compile_and_process<'a>(parsed: &'a mut Compiler<'a, CurrentNetwork>) ->
Ok(bytecode)
}
/// Returns the private key from the .env file specified in the directory.
#[allow(unused)]
pub fn dotenv_private_key(directory: &Path) -> Result<PrivateKey<CurrentNetwork>> {
use std::str::FromStr;
dotenvy::from_path(directory.join(".env")).map_err(|_| anyhow!("Missing a '.env' file in the test directory."))?;
// Load the private key from the environment.
let private_key = dotenvy::var("PRIVATE_KEY").map_err(|e| anyhow!("Missing PRIVATE_KEY - {e}"))?;
// Parse the private key.
PrivateKey::<CurrentNetwork>::from_str(&private_key)
}

View File

@ -41,7 +41,7 @@ features = [ "derive" ]
version = "1.9"
[dependencies.lazy_static]
version = "1.3.0"
version = "1.5.0"
[dependencies.serde]
version = "1.0"

View File

@ -39,7 +39,7 @@ pub(crate) struct ParserContext<'a, N: Network> {
/// The previous token, i.e., if `p.tokens = ['3', *, '4']`,
/// then after two `p.bump()`s, we'll have `p.token = '*'` and `p.prev_token = '3'`.
pub(crate) prev_token: SpannedToken,
/// true if parsing an expression for if and loop statements -- means struct inits are not legal
/// True if parsing an expression for if and loop statements -- means struct inits are not legal.
pub(crate) disallow_struct_construction: bool,
/// The name of the program being parsed.
pub(crate) program_name: Option<Symbol>,
@ -95,7 +95,7 @@ impl<'a, N: Network> ParserContext<'a, N> {
&self.token.token == tok
}
/// Checks whether the current token is a `Token::Int(_)`.
/// Checks whether the current token is a `Token::Integer(_)`.
pub(super) fn check_int(&self) -> bool {
matches!(&self.token.token, Token::Integer(_))
}
@ -142,7 +142,7 @@ impl<'a, N: Network> ParserContext<'a, N> {
Identifier { name, span, id: self.node_builder.next_id() }
}
/// Eats the next token if its an identifier and returns it.
/// Eats the next token if it is an identifier and returns it.
pub(super) fn eat_identifier(&mut self) -> Option<Identifier> {
if let Token::Identifier(name) = self.token.token {
self.bump();

View File

@ -75,11 +75,12 @@ impl<N: Network> ParserContext<'_, N> {
// Parse `foo`.
let import_name = self.expect_identifier()?;
// Parse `.aleo`.
// Parse `.`.
self.expect(&Token::Dot)?;
// Parse network, which currently must be `aleo`.
if !self.eat(&Token::Aleo) {
// Throw error for non-aleo files.
// Throw error for non-aleo networks.
return Err(ParserError::invalid_network(self.token.span).into());
}
@ -100,10 +101,10 @@ impl<N: Network> ParserContext<'_, N> {
// Set the program name in the context.
self.program_name = Some(name.name);
// Parse the program network.
// Parse the `.`.
self.expect(&Token::Dot)?;
// Otherwise throw parser error
// Parse the program network, which must be `aleo`, otherwise throw parser error.
self.expect(&Token::Aleo).map_err(|_| ParserError::invalid_network(self.token.span))?;
// Construct the program id.

View File

@ -14,10 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
//! The parser to convert Leo code text into an [`Program`] AST type.
//! The parser to convert Leo code text into a [`Program`] AST type.
//!
//! This module contains the [`parse()`] method which calls the underlying [`tokenize()`]
//! method to create a new program ast.
//! This module contains the [`parse()`] function which calls the underlying [`tokenize()`]
//! method to create a new program AST.
use crate::{tokenizer::*, Token};

View File

@ -154,8 +154,15 @@ impl Token {
// }
// }
/// Returns a tuple: [(integer length, integer token)] if an integer can be eaten, otherwise returns [`None`].
/// An integer can be eaten if its bytes are at the front of the given `input` string.
/// Returns a tuple: [(integer length, integer token)] if an integer can be eaten.
/// An integer can be eaten if its characters are at the front of the given `input` string.
/// If there is no input, this function returns an error.
/// If there is input but no integer, this function returns the tuple consisting of
/// length 0 and a dummy integer token that contains an empty string.
/// However, this function is always called when the next character is a digit.
/// This function eats a sequence of one or more digits and underscores
/// (starting from a digit, as explained above, given when it is called),
/// which corresponds to a numeral in the ABNF grammar.
fn eat_integer(input: &mut Peekable<impl Iterator<Item = char>>) -> Result<(usize, Token)> {
if input.peek().is_none() {
return Err(ParserError::lexer_empty_input().into());
@ -178,7 +185,7 @@ impl Token {
}
/// Returns a tuple: [(token length, token)] if the next token can be eaten, otherwise returns an error.
/// The next token can be eaten if the bytes at the front of the given `input` string can be scanned into a token.
/// The next token can be eaten if the characters at the front of the given `input` string can be scanned into a token.
pub(crate) fn eat(input: &str) -> Result<(usize, Token)> {
if input.is_empty() {
return Err(ParserError::lexer_empty_input().into());
@ -221,13 +228,13 @@ impl Token {
// See the example with the different combinations for Mul, MulAssign, Pow, PowAssign below.
let match_four = |
input: &mut Peekable<_>,
first_token, // Mul '*'
second_char, // '='
second_token, // MulAssign '*='
third_char, // '*'
third_token, // Pow '**'
fourth_char, // '='
fourth_token // PowAssign '**='
first_token, // e.e. Mul '*'
second_char, // e.g. '='
second_token, // e.g. MulAssign '*='
third_char, // e.g. '*'
third_token, // e.g. Pow '**'
fourth_char, // e.g. '='
fourth_token // e.g. PowAssign '**='
| {
input.next();
Ok(if input.next_if_eq(&second_char).is_some() {
@ -252,7 +259,7 @@ impl Token {
// Find end string quotation mark.
// Instead of checking each `char` and pushing, we can avoid reallocations.
// This works because the code 34 of double quote cannot appear as a byte
// in middle of a multi-byte UTF-8 encoding of a character,
// in the middle of a multi-byte UTF-8 encoding of a character,
// because those bytes all have the high bit set to 1;
// in UTF-8, the byte 34 can only appear as the single-byte encoding of double quote.
let rest = &input_str[1..];
@ -306,7 +313,7 @@ impl Token {
if input.next_if_eq(&'/').is_some() {
// Find the end of the comment line.
// This works because the code 10 of line feed cannot appear as a byte
// in middle of a multi-byte UTF-8 encoding of a character,
// in the middle of a multi-byte UTF-8 encoding of a character,
// because those bytes all have the high bit set to 1;
// in UTF-8, the byte 10 can only appear as the single-byte encoding of line feed.
let comment = match input_str.as_bytes().iter().position(|c| *c == b'\n') {
@ -416,8 +423,8 @@ impl Token {
"record" => Token::Record,
"return" => Token::Return,
"scalar" => Token::Scalar,
"signature" => Token::Signature,
"self" => Token::SelfLower,
"signature" => Token::Signature,
"string" => Token::String,
"struct" => Token::Struct,
"transition" => Token::Transition,

View File

@ -29,20 +29,24 @@ use leo_span::{sym, Symbol};
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum Token {
// Comments
CommentLine(String),
CommentBlock(String),
CommentLine(String), // the string includes the starting '//' and the ending line feed
CommentBlock(String), // the string includes the starting '/*' and the ending '*/'
// Whitespace (we do not distinguish among different kinds here)
WhiteSpace,
// Literals (= atomic literals and numerals in the ABNF grammar)
// The string in Integer(String) consists of digits optionally followed by a type
// The string in AddressLit(String) has the form `aleo1...`
// The string in Integer(String) consists of digits
// The string in AddressLit(String) has the form `aleo1...`.
True,
False,
Integer(String), // = numeric literal or numeral in the ABNF grammar
Integer(String), // = numeral (including tuple index) in the ABNF grammar
AddressLit(String),
StaticString(String),
// The numeric literals in the ABNF grammar, which consist of numerals followed by types,
// are represented not as single tokens here,
// but as two separate tokens (one for the numeral and one for the type),
// enforcing, during parsing, the absence of whitespace or comments between those two tokens.
// Identifiers
Identifier(Symbol),

View File

@ -32,7 +32,7 @@ pub use self::traits::*;
// Right now for cleanliness of calling error functions we say each argument implements one of the follow types rather than giving a specific type.
// This allows us to just pass many types rather doing conversions cleaning up the code.
// The args can be made cleaneronce https://github.com/rust-lang/rust/issues/41517 or https://github.com/rust-lang/rust/issues/63063 hits stable.
// The args can be made cleaner once https://github.com/rust-lang/rust/issues/41517 or https://github.com/rust-lang/rust/issues/63063 hits stable.
// Either of why would allows to generate a type alias for these trait implementing types.
// pub(crate) type DisplayArg = impl std::fmt::Display;
// pub(crate) type DebugArg = impl std::fmt::Debug;

View File

@ -264,4 +264,60 @@ create_messages!(
msg: format!("{error}"),
help: None,
}
@backtraced
failed_to_get_endpoint_from_env {
args: (),
msg: "Failed to get an endpoint.".to_string(),
help: Some("Either make sure you have a `.env` file in current project directory with an `ENDPOINT` variable set, or set the `--endpoint` flag when invoking the CLI command.\n Example: `ENDPOINT=https://api.explorer.aleo.org/v1` or `leo build --endpoint \"https://api.explorer.aleo.org/v1\"`.".to_string()),
}
@backtraced
failed_to_get_private_key_from_env {
args: (),
msg: "Failed to get a private key.".to_string(),
help: Some("Either make sure you have a `.env` file in current project directory with a `PRIVATE_KEY` variable set, or set the `--private-key` flag when invoking the CLI command.\n Example: `PRIVATE_KEY=0x1234...` or `leo deploy --private-key \"APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH\"`.".to_string()),
}
@backtraced
failed_to_get_network_from_env {
args: (),
msg: "Failed to get a network.".to_string(),
help: Some("Either make sure you have a `.env` file in current project directory with a `NETWORK` variable set, or set the `--network` flag when invoking the CLI command.\n Example: `NETWORK=testnet` or `leo build --network testnet`.".to_string()),
}
@backtraced
constraint_limit_exceeded {
args: (program: impl Display, limit: u64, network: impl Display),
msg: format!("Program `{program}` exceeds the constraint limit {limit} for deployment on network {network}."),
help: Some("Reduce the number of constraints in the program by reducing the number of instructions in transition functions.".to_string()),
}
@backtraced
variable_limit_exceeded {
args: (program: impl Display, limit: u64, network: impl Display),
msg: format!("Program `{program}` exceeds the variable limit {limit} for deployment on network {network}."),
help: Some("Reduce the number of variables in the program by reducing the number of instructions in transition functions.".to_string()),
}
@backtraced
confirmation_failed {
args: (),
msg: "Failed to confirm transaction".to_string(),
help: None,
}
@backtraced
invalid_balance {
args: (account: impl Display),
msg: format!("Invalid public balance for account: {account}"),
help: Some("Make sure the account has enough balance to pay for the deployment.".to_string()),
}
@backtraced
table_render_failed {
args: (error: impl Display),
msg: format!("Failed to render table.\nError: {error}"),
help: None,
}
);

View File

@ -60,16 +60,16 @@ pub enum LeoError {
/// Represents an AST Error in a Leo Error.
#[error(transparent)]
AstError(#[from] AstError),
/// Represents an CLI Error in a Leo Error.
/// Represents a CLI Error in a Leo Error.
#[error(transparent)]
CliError(#[from] CliError),
/// Represents an Compiler Error in a Leo Error.
/// Represents a Compiler Error in a Leo Error.
#[error(transparent)]
CompilerError(#[from] CompilerError),
/// Represents an Package Error in a Leo Error.
/// Represents a Package Error in a Leo Error.
#[error(transparent)]
PackageError(#[from] PackageError),
/// Represents an Parser Error in a Leo Error.
/// Represents a Parser Error in a Leo Error.
#[error(transparent)]
ParserError(#[from] ParserError),
/// Represents a Type Checker Error in a Leo Error.
@ -85,7 +85,7 @@ pub enum LeoError {
/// not re-displaying an error.
#[error("")]
LastErrorCode(i32),
/// Represents a Utils Error in a Leo Error
/// Represents a Utils Error in a Leo Error.
#[error(transparent)]
UtilError(#[from] UtilError),
/// Anyhow errors.
@ -109,7 +109,7 @@ impl LeoError {
FlattenError(error) => error.error_code(),
UtilError(error) => error.error_code(),
LastErrorCode(_) => unreachable!(),
Anyhow(_) => unimplemented!(), // todo: implement error codes for snarkvm errors.
Anyhow(_) => "SnarkVM Error".to_string(), // todo: implement error codes for snarkvm errors.
}
}
@ -128,19 +128,19 @@ impl LeoError {
FlattenError(error) => error.exit_code(),
UtilError(error) => error.exit_code(),
LastErrorCode(code) => *code,
Anyhow(_) => unimplemented!(), // todo: implement exit codes for snarkvm errors.
Anyhow(_) => 11000, // todo: implement exit codes for snarkvm errors.
}
}
}
/// The LeoWarning type that contains all sub error types.
/// This allows a unified error type throughout the Leo crates.
/// The LeoWarning type that contains all sub warning types.
/// This allows a unified warning type throughout the Leo crates.
#[derive(Debug, Error)]
pub enum LeoWarning {
/// Represents an Parser Error in a Leo Error.
/// Represents an Parser Warning in a Leo Warning.
#[error(transparent)]
ParserWarning(#[from] ParserWarning),
/// Represents a Type Checker Error in a Leo Error.
/// Represents a Type Checker Warning in a Leo Warning.
#[error(transparent)]
TypeCheckerWarning(#[from] TypeCheckerWarning),
}

View File

@ -418,4 +418,18 @@ create_messages!(
msg: format!("❌ Execution error: {error}"),
help: Some("Make sure that you are using the right `--network` options.".to_string()),
}
@backtraced
snarkvm_error {
args: (error: impl Display),
msg: format!("[snarkVM Error] {error}"),
help: None,
}
@backtraced
failed_to_load_package {
args: (path: impl Display),
msg: format!("Failed to load leo project at path {path}"),
help: Some("Make sure that the path is correct and that the project exists.".to_string()),
}
);

View File

@ -193,4 +193,11 @@ create_messages!(
msg: format!("Invalid field: {field}."),
help: Some("Field element must be numerical string with optional \"field\" suffix.".to_string()),
}
@backtraced
invalid_bound {
args: (bound: impl Display),
msg: format!("Invalid bound: {bound}."),
help: Some("Bound must be a valid u32.".to_string()),
}
);

View File

@ -21,7 +21,7 @@
#[macro_use]
extern crate thiserror;
/// Contains the common functionalities for defining errors..
/// Contains the common functionalities for defining errors.
#[macro_use]
pub mod common;
pub use self::common::*;
@ -29,6 +29,6 @@ pub use self::common::*;
/// Contains traits and types for channels through which errors go.
pub mod emitter;
/// Contains the errors and warnings for the Leo lang.
/// Contains the errors and warnings for the Leo language.
pub mod errors;
pub use self::errors::*;

View File

@ -1,4 +1,4 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -40,6 +40,7 @@ echo "
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env
# Have the first bidder place a bid of 10.
@ -62,6 +63,7 @@ leo run place_bid aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9p
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp2RWGDcde3efb89rjhME1VYA8QMxcxep5DShNBR6n8Yjh
ENDPOINT=https://localhost:3030
" > .env
# Have the second bidder place a bid of 90.
@ -84,6 +86,7 @@ leo run place_bid aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem2u4
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp2GUmKbVsuc1NSj28pa1WTQuZaK5f1DQJAT6vPcHyWokG
ENDPOINT=https://localhost:3030
" > .env
# Have the auctioneer select the winning bid.
@ -141,6 +144,7 @@ leo run finish "{
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env

View File

@ -1,4 +1,4 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -20,6 +20,7 @@ fi
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env
# Have the bank issue 100 tokens to the user.
@ -70,6 +71,7 @@ leo run issue aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem2u4t 10
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp2RWGDcde3efb89rjhME1VYA8QMxcxep5DShNBR6n8Yjh
ENDPOINT=https://localhost:3030
" > .env
# Have the user deposit 50 tokens into the bank.
@ -164,6 +166,7 @@ echo "
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env
# Have the bank withdraw all of the user's tokens with compound interest over 15 periods at 12.34%.

View File

@ -1,3 +1,4 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp2RWGDcde3efb89rjhME1VYA8QMxcxep5DShNBR6n8Yjh
ENDPOINT=https://localhost:3030

View File

@ -19,6 +19,7 @@ echo "
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env
echo "✅ Successfully initialized Player 1."
@ -69,6 +70,7 @@ echo "
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp2RWGDcde3efb89rjhME1VYA8QMxcxep5DShNBR6n8Yjh
ENDPOINT=https://localhost:3030
" > .env
leo run initialize_board 31u64 2207646875648u64 224u64 9042383626829824u64 aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem2u4t || exit
@ -117,6 +119,7 @@ echo "
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env
leo run play '{
@ -152,6 +155,7 @@ echo "
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp2RWGDcde3efb89rjhME1VYA8QMxcxep5DShNBR6n8Yjh
ENDPOINT=https://localhost:3030
" > .env
leo run play '{
@ -187,6 +191,7 @@ echo "
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env
leo run play '{
@ -222,6 +227,7 @@ echo "
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp2RWGDcde3efb89rjhME1VYA8QMxcxep5DShNBR6n8Yjh
ENDPOINT=https://localhost:3030
" > .env
leo run play '{
@ -250,4 +256,5 @@ echo "
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,3 +1,4 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,4 +1,4 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -20,6 +20,7 @@ fi
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env
# Publicly mint 100 tokens for Alice.
@ -54,6 +55,7 @@ leo run mint_public aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp2RWGDcde3efb89rjhME1VYA8QMxcxep5DShNBR6n8Yjh
ENDPOINT=https://localhost:3030
" > .env
# Privately mint 100 tokens for Bob.
@ -88,6 +90,7 @@ leo run mint_private aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env
# Publicly transfer 10 tokens from Alice to Bob.
@ -122,6 +125,7 @@ leo run transfer_public aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5p
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp2RWGDcde3efb89rjhME1VYA8QMxcxep5DShNBR6n8Yjh
ENDPOINT=https://localhost:3030
" > .env
# Privately transfer 20 tokens from Bob to Alice.
@ -160,6 +164,7 @@ leo run transfer_private "{
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env
# Convert 30 public tokens from Alice into 30 private tokens for Bob.
@ -195,6 +200,7 @@ leo run transfer_public_to_private aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0x
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp2RWGDcde3efb89rjhME1VYA8QMxcxep5DShNBR6n8Yjh
ENDPOINT=https://localhost:3030
" > .env
# Convert 40 private tokens from Bob into 40 public tokens for Alice.
@ -236,4 +242,5 @@ leo run transfer_private_to_public "{
echo "
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030
" > .env

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -1,2 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=https://localhost:3030

View File

@ -315,6 +315,7 @@ mod test_helpers {
use std::path::Path;
const NETWORK: &str = "testnet";
const ENDPOINT: &str = "https://api.explorer.aleo.org/v1";
pub(crate) fn sample_nested_package(temp_dir: &Path) {
let name = "nested";
@ -329,7 +330,9 @@ mod test_helpers {
let new = CLI {
debug: false,
quiet: false,
command: Commands::New { command: New { name: name.to_string(), network: NETWORK.to_string() } },
command: Commands::New {
command: New { name: name.to_string(), network: NETWORK.to_string(), endpoint: ENDPOINT.to_string() },
},
path: Some(project_directory.clone()),
home: None,
};
@ -430,7 +433,13 @@ function external_nested_function:
let create_grandparent_project = CLI {
debug: false,
quiet: false,
command: Commands::New { command: New { name: "grandparent".to_string(), network: NETWORK.to_string() } },
command: Commands::New {
command: New {
name: "grandparent".to_string(),
network: NETWORK.to_string(),
endpoint: ENDPOINT.to_string(),
},
},
path: Some(grandparent_directory.clone()),
home: None,
};
@ -438,7 +447,13 @@ function external_nested_function:
let create_parent_project = CLI {
debug: false,
quiet: false,
command: Commands::New { command: New { name: "parent".to_string(), network: NETWORK.to_string() } },
command: Commands::New {
command: New {
name: "parent".to_string(),
network: NETWORK.to_string(),
endpoint: ENDPOINT.to_string(),
},
},
path: Some(parent_directory.clone()),
home: None,
};
@ -446,7 +461,13 @@ function external_nested_function:
let create_child_project = CLI {
debug: false,
quiet: false,
command: Commands::New { command: New { name: "child".to_string(), network: NETWORK.to_string() } },
command: Commands::New {
command: New {
name: "child".to_string(),
network: NETWORK.to_string(),
endpoint: ENDPOINT.to_string(),
},
},
path: Some(child_directory.clone()),
home: None,
};
@ -561,7 +582,13 @@ program child.aleo {
let create_outer_project = CLI {
debug: false,
quiet: false,
command: Commands::New { command: New { name: "outer".to_string(), network: NETWORK.to_string() } },
command: Commands::New {
command: New {
name: "outer".to_string(),
network: NETWORK.to_string(),
endpoint: ENDPOINT.to_string(),
},
},
path: Some(outer_directory.clone()),
home: None,
};
@ -569,7 +596,13 @@ program child.aleo {
let create_inner_1_project = CLI {
debug: false,
quiet: false,
command: Commands::New { command: New { name: "inner_1".to_string(), network: NETWORK.to_string() } },
command: Commands::New {
command: New {
name: "inner_1".to_string(),
network: NETWORK.to_string(),
endpoint: ENDPOINT.to_string(),
},
},
path: Some(inner_1_directory.clone()),
home: None,
};
@ -577,7 +610,13 @@ program child.aleo {
let create_inner_2_project = CLI {
debug: false,
quiet: false,
command: Commands::New { command: New { name: "inner_2".to_string(), network: NETWORK.to_string() } },
command: Commands::New {
command: New {
name: "inner_2".to_string(),
network: NETWORK.to_string(),
endpoint: ENDPOINT.to_string(),
},
},
path: Some(inner_2_directory.clone()),
home: None,
};
@ -699,7 +738,13 @@ program outer.aleo {
let create_outer_project = CLI {
debug: false,
quiet: false,
command: Commands::New { command: New { name: "outer_2".to_string(), network: NETWORK.to_string() } },
command: Commands::New {
command: New {
name: "outer_2".to_string(),
network: NETWORK.to_string(),
endpoint: ENDPOINT.to_string(),
},
},
path: Some(outer_directory.clone()),
home: None,
};
@ -707,7 +752,13 @@ program outer.aleo {
let create_inner_1_project = CLI {
debug: false,
quiet: false,
command: Commands::New { command: New { name: "inner_1".to_string(), network: NETWORK.to_string() } },
command: Commands::New {
command: New {
name: "inner_1".to_string(),
network: NETWORK.to_string(),
endpoint: ENDPOINT.to_string(),
},
},
path: Some(inner_1_directory.clone()),
home: None,
};
@ -715,7 +766,13 @@ program outer.aleo {
let create_inner_2_project = CLI {
debug: false,
quiet: false,
command: Commands::New { command: New { name: "inner_2".to_string(), network: NETWORK.to_string() } },
command: Commands::New {
command: New {
name: "inner_2".to_string(),
network: NETWORK.to_string(),
endpoint: ENDPOINT.to_string(),
},
},
path: Some(inner_2_directory.clone()),
home: None,
};

View File

@ -26,7 +26,7 @@ use crossterm::ExecutableCommand;
use leo_retriever::NetworkName;
use rand::SeedableRng;
use rand_chacha::ChaChaRng;
use snarkvm::prelude::{MainnetV0, Network, TestnetV0};
use snarkvm::prelude::{CanaryV0, MainnetV0, Network, TestnetV0};
use std::{
io::{self, Read, Write},
path::PathBuf,
@ -49,6 +49,13 @@ pub enum Account {
discreet: bool,
#[clap(short = 'n', long, help = "Name of the network to use", default_value = "testnet")]
network: String,
#[clap(
short = 'e',
long,
help = "Endpoint to retrieve network state from.",
default_value = "https://api.explorer.aleo.org/v1"
)]
endpoint: String,
},
/// Derive an Aleo account from a private key.
Import {
@ -62,6 +69,13 @@ pub enum Account {
discreet: bool,
#[clap(short = 'n', long, help = "Name of the network to use", default_value = "testnet")]
network: String,
#[clap(
short = 'e',
long,
help = "Endpoint to retrieve network state from.",
default_value = "https://api.explorer.aleo.org/v1"
)]
endpoint: String,
},
/// Sign a message using your Aleo private key.
Sign {
@ -118,20 +132,22 @@ impl Command for Account {
Self: Sized,
{
match self {
Account::New { seed, write, discreet, network } => {
Account::New { seed, write, discreet, network, endpoint } => {
// Parse the network.
let network = NetworkName::try_from(network.as_str())?;
match network {
NetworkName::MainnetV0 => generate_new_account::<MainnetV0>(seed, write, discreet, &ctx),
NetworkName::TestnetV0 => generate_new_account::<TestnetV0>(seed, write, discreet, &ctx),
NetworkName::MainnetV0 => generate_new_account::<MainnetV0>(seed, write, discreet, &ctx, endpoint),
NetworkName::TestnetV0 => generate_new_account::<TestnetV0>(seed, write, discreet, &ctx, endpoint),
NetworkName::CanaryV0 => generate_new_account::<CanaryV0>(seed, write, discreet, &ctx, endpoint),
}?
}
Account::Import { private_key, write, discreet, network } => {
Account::Import { private_key, write, discreet, network, endpoint } => {
// Parse the network.
let network = NetworkName::try_from(network.as_str())?;
match network {
NetworkName::MainnetV0 => import_account::<MainnetV0>(private_key, write, discreet, &ctx),
NetworkName::TestnetV0 => import_account::<TestnetV0>(private_key, write, discreet, &ctx),
NetworkName::MainnetV0 => import_account::<MainnetV0>(private_key, write, discreet, &ctx, endpoint),
NetworkName::TestnetV0 => import_account::<TestnetV0>(private_key, write, discreet, &ctx, endpoint),
NetworkName::CanaryV0 => import_account::<CanaryV0>(private_key, write, discreet, &ctx, endpoint),
}?
}
Self::Sign { message, seed, raw, private_key, private_key_file, network } => {
@ -144,6 +160,9 @@ impl Command for Account {
NetworkName::TestnetV0 => {
sign_message::<TestnetV0>(message, seed, raw, private_key, private_key_file)
}
NetworkName::CanaryV0 => {
sign_message::<MainnetV0>(message, seed, raw, private_key, private_key_file)
}
}?;
println!("{result}")
}
@ -153,6 +172,7 @@ impl Command for Account {
let result = match network {
NetworkName::MainnetV0 => verify_message::<MainnetV0>(address, signature, message, raw),
NetworkName::TestnetV0 => verify_message::<TestnetV0>(address, signature, message, raw),
NetworkName::CanaryV0 => verify_message::<CanaryV0>(address, signature, message, raw),
}?;
println!("{result}")
}
@ -164,7 +184,13 @@ impl Command for Account {
// Helper functions
// Generate a new account.
fn generate_new_account<N: Network>(seed: Option<u64>, write: bool, discreet: bool, ctx: &Context) -> Result<()> {
fn generate_new_account<N: Network>(
seed: Option<u64>,
write: bool,
discreet: bool,
ctx: &Context,
endpoint: String,
) -> Result<()> {
// Sample a new Aleo account.
let private_key = match seed {
// Recover the field element deterministically.
@ -179,13 +205,19 @@ fn generate_new_account<N: Network>(seed: Option<u64>, write: bool, discreet: bo
// Save key data to .env file.
if write {
write_to_env_file(private_key, ctx)?;
write_to_env_file(private_key, ctx, endpoint)?;
}
Ok(())
}
// Import an account.
fn import_account<N: Network>(private_key: Option<String>, write: bool, discreet: bool, ctx: &Context) -> Result<()> {
fn import_account<N: Network>(
private_key: Option<String>,
write: bool,
discreet: bool,
ctx: &Context,
endpoint: String,
) -> Result<()> {
let priv_key = match discreet {
true => {
let private_key_input = rpassword::prompt_password("Please enter your private key: ").unwrap();
@ -207,7 +239,7 @@ fn import_account<N: Network>(private_key: Option<String>, write: bool, discreet
// Save key data to .env file.
if write {
write_to_env_file::<N>(priv_key, ctx)?;
write_to_env_file::<N>(priv_key, ctx, endpoint)?;
}
Ok(())
@ -323,9 +355,9 @@ pub(crate) fn verify_message<N: Network>(
}
// Write the network and private key to the .env file in project directory.
fn write_to_env_file<N: Network>(private_key: PrivateKey<N>, ctx: &Context) -> Result<()> {
fn write_to_env_file<N: Network>(private_key: PrivateKey<N>, ctx: &Context, endpoint: String) -> Result<()> {
let program_dir = ctx.dir()?;
Env::<N>::from(private_key).write_to(&program_dir)?;
Env::<N>::new(Some(private_key), endpoint)?.write_to(&program_dir)?;
tracing::info!("✅ Private Key written to {}", program_dir.join(".env").display());
Ok(())
}

View File

@ -29,6 +29,7 @@ use snarkvm::{
};
use indexmap::IndexMap;
use snarkvm::prelude::CanaryV0;
use std::{
io::Write,
path::{Path, PathBuf},
@ -93,10 +94,11 @@ impl Command for Build {
fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
// Parse the network.
let network = NetworkName::try_from(self.options.network.as_str())?;
let network = NetworkName::try_from(context.get_network(&self.options.network)?)?;
match network {
NetworkName::MainnetV0 => handle_build::<MainnetV0>(&self, context),
NetworkName::TestnetV0 => handle_build::<TestnetV0>(&self, context),
NetworkName::CanaryV0 => handle_build::<CanaryV0>(&self, context),
}
}
}
@ -123,8 +125,13 @@ fn handle_build<N: Network>(command: &Build, context: Context) -> Result<<Build
// Retrieve all local dependencies in post order
let main_sym = Symbol::intern(&program_id.name().to_string());
let mut retriever = Retriever::<N>::new(main_sym, &package_path, &home_path, command.options.endpoint.clone())
.map_err(|err| UtilError::failed_to_retrieve_dependencies(err, Default::default()))?;
let mut retriever = Retriever::<N>::new(
main_sym,
&package_path,
&home_path,
context.get_endpoint(&command.options.endpoint)?.to_string(),
)
.map_err(|err| UtilError::failed_to_retrieve_dependencies(err, Default::default()))?;
let mut local_dependencies =
retriever.retrieve().map_err(|err| UtilError::failed_to_retrieve_dependencies(err, Default::default()))?;

View File

@ -16,23 +16,23 @@
use super::*;
use aleo_std::StorageMode;
use dialoguer::{theme::ColorfulTheme, Confirm};
use leo_retriever::NetworkName;
use snarkvm::{
circuit::{Aleo, AleoTestnetV0, AleoV0},
cli::helpers::dotenv_private_key,
circuit::{Aleo, AleoCanaryV0, AleoTestnetV0, AleoV0},
ledger::query::Query as SnarkVMQuery,
package::Package as SnarkVMPackage,
prelude::{
deployment_cost,
store::{helpers::memory::ConsensusMemory, ConsensusStore},
CanaryV0,
MainnetV0,
PrivateKey,
ProgramOwner,
TestnetV0,
VM,
},
};
use std::{path::PathBuf, str::FromStr};
use std::path::PathBuf;
use text_tables;
/// Deploys an Aleo program.
@ -71,10 +71,12 @@ impl Command for Deploy {
fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
// Parse the network.
let network = NetworkName::try_from(self.options.network.as_str())?;
let network = NetworkName::try_from(context.get_network(&self.options.network)?)?;
let endpoint = context.get_endpoint(&self.options.endpoint)?;
match network {
NetworkName::MainnetV0 => handle_deploy::<AleoV0, MainnetV0>(&self, context),
NetworkName::TestnetV0 => handle_deploy::<AleoTestnetV0, TestnetV0>(&self, context),
NetworkName::MainnetV0 => handle_deploy::<AleoV0, MainnetV0>(&self, context, network, &endpoint),
NetworkName::TestnetV0 => handle_deploy::<AleoTestnetV0, TestnetV0>(&self, context, network, &endpoint),
NetworkName::CanaryV0 => handle_deploy::<AleoCanaryV0, CanaryV0>(&self, context, network, &endpoint),
}
}
}
@ -83,20 +85,18 @@ impl Command for Deploy {
fn handle_deploy<A: Aleo<Network = N, BaseField = N::Field>, N: Network>(
command: &Deploy,
context: Context,
network: NetworkName,
endpoint: &str,
) -> Result<<Deploy as Command>::Output> {
// Get the program name.
let project_name = context.open_manifest::<N>()?.program_id().to_string();
// Get the private key.
let private_key = match &command.fee_options.private_key {
Some(key) => PrivateKey::from_str(key)?,
None => PrivateKey::from_str(
&dotenv_private_key().map_err(CliError::failed_to_read_environment_private_key)?.to_string(),
)?,
};
let private_key = context.get_private_key(&command.fee_options.private_key)?;
let address = Address::try_from(&private_key)?;
// Specify the query
let query = SnarkVMQuery::from(&command.options.endpoint);
let query = SnarkVMQuery::from(endpoint);
let mut all_paths: Vec<(String, PathBuf)> = Vec::new();
@ -120,6 +120,15 @@ fn handle_deploy<A: Aleo<Network = N, BaseField = N::Field>, N: Network>(
// Generate the deployment
let deployment = package.deploy::<A>(None)?;
// Check if the number of variables and constraints are within the limits.
if deployment.num_combined_variables()? > N::MAX_DEPLOYMENT_VARIABLES {
return Err(CliError::variable_limit_exceeded(name, N::MAX_DEPLOYMENT_VARIABLES, network).into());
}
if deployment.num_combined_constraints()? > N::MAX_DEPLOYMENT_CONSTRAINTS {
return Err(CliError::constraint_limit_exceeded(name, N::MAX_DEPLOYMENT_CONSTRAINTS, network).into());
}
let deployment_id = deployment.to_deployment_id()?;
let store = ConsensusStore::<N, ConsensusMemory<N>>::open(StorageMode::Production)?;
@ -139,7 +148,7 @@ fn handle_deploy<A: Aleo<Network = N, BaseField = N::Field>, N: Network>(
synthesis_cost as f64 / 1_000_000.0,
namespace_cost as f64 / 1_000_000.0,
command.fee_options.priority_fee as f64 / 1_000_000.0,
);
)?;
// Initialize an RNG.
let rng = &mut rand::thread_rng();
@ -160,13 +169,7 @@ fn handle_deploy<A: Aleo<Network = N, BaseField = N::Field>, N: Network>(
}
None => {
// Make sure the user has enough public balance to pay for the deployment.
check_balance(
&private_key,
&command.options.endpoint,
&command.options.network,
context.clone(),
total_cost,
)?;
check_balance(&private_key, endpoint, &network.to_string(), context.clone(), total_cost)?;
let fee_authorization = vm.authorize_fee_public(
&private_key,
total_cost,
@ -185,18 +188,32 @@ fn handle_deploy<A: Aleo<Network = N, BaseField = N::Field>, N: Network>(
// Determine if the transaction should be broadcast, stored, or displayed to the user.
if !command.fee_options.dry_run {
println!("✅ Created deployment transaction for '{}'", name.bold());
handle_broadcast(
&format!("{}/{}/transaction/broadcast", command.options.endpoint, command.options.network),
transaction,
name,
)?;
if !command.fee_options.yes {
let prompt = format!(
"Do you want to submit deployment of program `{name}.aleo` to network {} via endpoint {} using address {}?",
network, endpoint, address
);
let confirmation =
Confirm::with_theme(&ColorfulTheme::default()).with_prompt(prompt).default(false).interact();
// Check if the user confirmed the transaction.
if let Ok(confirmation) = confirmation {
if !confirmation {
println!("✅ Successfully aborted the execution transaction for '{}'\n", name.bold());
return Ok(());
}
} else {
return Err(CliError::confirmation_failed().into());
}
}
println!("✅ Created deployment transaction for '{}'\n", name.bold());
handle_broadcast(&format!("{}/{}/transaction/broadcast", endpoint, network), transaction, name)?;
// Wait between successive deployments to prevent out of order deployments.
if index < all_paths.len() - 1 {
std::thread::sleep(std::time::Duration::from_secs(command.wait));
}
} else {
println!("✅ Successful dry run deployment for '{}'", name.bold());
println!("✅ Successful dry run deployment for '{}'\n", name.bold());
}
}
@ -211,8 +228,8 @@ fn deploy_cost_breakdown(
synthesis_cost: f64,
namespace_cost: f64,
priority_fee: f64,
) {
println!("Base deployment cost for '{}' is {} credits.", name.bold(), total_cost);
) -> Result<()> {
println!("\nBase deployment cost for '{}' is {} credits.\n", name.bold(), total_cost);
// Display the cost breakdown in a table.
let data = [
[name, "Cost (credits)"],
@ -223,6 +240,7 @@ fn deploy_cost_breakdown(
["Total", &format!("{:.6}", total_cost)],
];
let mut out = Vec::new();
text_tables::render(&mut out, data).unwrap();
println!("{}", ::std::str::from_utf8(&out).unwrap());
text_tables::render(&mut out, data).map_err(CliError::table_render_failed)?;
println!("{}", ::std::str::from_utf8(&out).map_err(CliError::table_render_failed)?);
Ok(())
}

View File

@ -25,6 +25,13 @@ pub struct Example {
pub(crate) name: String,
#[clap(short = 'n', long, help = "Name of the network to use", default_value = "testnet")]
pub(crate) network: String,
#[clap(
short = 'e',
long,
help = "Endpoint to retrieve network state from.",
default_value = "https://api.explorer.aleo.org/v1"
)]
pub(crate) endpoint: String,
}
impl Command for Example {
@ -33,7 +40,8 @@ impl Command for Example {
fn prelude(&self, context: Context) -> Result<Self::Input> {
// Run leo new <name> --network <network>
(New { name: self.name.clone(), network: self.network.clone() }).execute(context)
(New { name: self.name.clone(), network: self.network.clone(), endpoint: self.endpoint.clone() })
.execute(context)
}
fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output>

View File

@ -24,9 +24,10 @@ use snarkvm::{
use std::collections::HashMap;
use crate::cli::query::QueryCommands;
use dialoguer::{theme::ColorfulTheme, Confirm};
use leo_retriever::NetworkName;
use snarkvm::{
circuit::{Aleo, AleoTestnetV0, AleoV0},
circuit::{Aleo, AleoCanaryV0, AleoTestnetV0, AleoV0},
cli::LOCALE,
ledger::Transaction::Execute as ExecuteTransaction,
package::Package as SnarkVMPackage,
@ -66,6 +67,8 @@ pub struct Execute {
compiler_options: BuildOptions,
#[arg(short, long, help = "The inputs to the program, from a file. Overrides the INPUTS argument.")]
file: Option<String>,
#[clap(long, help = "Disables building of the project before execution.", default_value = "false")]
pub(crate) no_build: bool,
}
impl Command for Execute {
@ -78,7 +81,7 @@ impl Command for Execute {
fn prelude(&self, context: Context) -> Result<Self::Input> {
// No need to build if we are executing an external program.
if self.program.is_some() {
if self.program.is_some() || self.no_build {
return Ok(());
}
(Build { options: self.compiler_options.clone() }).execute(context)
@ -86,16 +89,23 @@ impl Command for Execute {
fn apply(self, context: Context, _input: Self::Input) -> Result<Self::Output> {
// Parse the network.
let network = NetworkName::try_from(self.compiler_options.network.as_str())?;
let network = NetworkName::try_from(context.get_network(&self.compiler_options.network)?)?;
let endpoint = context.get_endpoint(&self.compiler_options.endpoint)?;
match network {
NetworkName::MainnetV0 => handle_execute::<AleoV0>(self, context),
NetworkName::TestnetV0 => handle_execute::<AleoTestnetV0>(self, context),
NetworkName::MainnetV0 => handle_execute::<AleoV0>(self, context, network, &endpoint),
NetworkName::TestnetV0 => handle_execute::<AleoTestnetV0>(self, context, network, &endpoint),
NetworkName::CanaryV0 => handle_execute::<AleoCanaryV0>(self, context, network, &endpoint),
}
}
}
// A helper function to handle the `execute` command.
fn handle_execute<A: Aleo>(command: Execute, context: Context) -> Result<<Execute as Command>::Output> {
fn handle_execute<A: Aleo>(
command: Execute,
context: Context,
network: NetworkName,
endpoint: &str,
) -> Result<<Execute as Command>::Output> {
// If input values are provided, then run the program with those inputs.
// Otherwise, use the input file.
let mut inputs = command.inputs.clone();
@ -133,13 +143,14 @@ fn handle_execute<A: Aleo>(command: Execute, context: Context) -> Result<<Execut
&dotenv_private_key().map_err(CliError::failed_to_read_environment_private_key)?.to_string(),
)?,
};
let address = Address::try_from(&private_key)?;
// If the `broadcast` flag is set, then broadcast the transaction.
if command.broadcast {
// Get the program name.
let program_name = match (command.program.clone(), command.local) {
(Some(name), true) => {
let local = context.open_manifest::<A::Network>()?.program_id().to_string();
let local = context.open_manifest::<A::Network>()?.program_id().name().to_string();
// Throw error if local name doesn't match the specified name.
if name == local {
local
@ -148,13 +159,12 @@ fn handle_execute<A: Aleo>(command: Execute, context: Context) -> Result<<Execut
}
}
(Some(name), false) => name.clone(),
(None, true) => context.open_manifest::<A::Network>()?.program_id().to_string(),
(None, true) => context.open_manifest::<A::Network>()?.program_id().name().to_string(),
(None, false) => return Err(PackageError::missing_on_chain_program_name().into()),
};
// Specify the query
let query =
SnarkVMQuery::<A::Network, BlockMemory<A::Network>>::from(command.compiler_options.endpoint.clone());
let query = SnarkVMQuery::<A::Network, BlockMemory<A::Network>>::from(endpoint);
// Initialize the storage.
let store = ConsensusStore::<A::Network, ConsensusMemory<A::Network>>::open(StorageMode::Production)?;
@ -164,8 +174,7 @@ fn handle_execute<A: Aleo>(command: Execute, context: Context) -> Result<<Execut
// Load the main program, and all of its imports.
let program_id = &ProgramID::<A::Network>::from_str(&format!("{}.aleo", program_name))?;
// TODO: X
load_program_from_network(&command, context.clone(), &mut vm.process().write(), program_id)?;
load_program_from_network(context.clone(), &mut vm.process().write(), program_id, network, endpoint)?;
let fee_record = if let Some(record) = command.fee_options.record {
Some(parse_record(&private_key, &record)?)
@ -176,7 +185,7 @@ fn handle_execute<A: Aleo>(command: Execute, context: Context) -> Result<<Execut
// Create a new transaction.
let transaction = vm.execute(
&private_key,
(program_id, command.name),
(program_id, command.name.clone()),
inputs.iter(),
fee_record.clone(),
command.fee_options.priority_fee,
@ -200,32 +209,38 @@ fn handle_execute<A: Aleo>(command: Execute, context: Context) -> Result<<Execut
storage_cost as f64 / 1_000_000.0,
finalize_cost as f64 / 1_000_000.0,
command.fee_options.priority_fee as f64 / 1_000_000.0,
);
)?;
// Check if the public balance is sufficient.
if fee_record.is_none() {
check_balance::<A::Network>(
&private_key,
&command.compiler_options.endpoint,
&command.compiler_options.network,
context,
total_cost,
)?;
check_balance::<A::Network>(&private_key, endpoint, &network.to_string(), context, total_cost)?;
}
// Broadcast the execution transaction.
if !command.fee_options.dry_run {
println!("✅ Created execution transaction for '{}'", program_id.to_string().bold());
handle_broadcast(
&format!(
"{}/{}/transaction/broadcast",
command.compiler_options.endpoint, command.compiler_options.network
),
transaction,
&program_name,
)?;
if !command.fee_options.yes {
let prompt = format!(
"Do you want to submit execution of function `{}` on program `{program_name}.aleo` to network {} via endpoint {} using address {}?",
&command.name, network, endpoint, address
);
// Ask the user for confirmation of the transaction.
let confirmation =
Confirm::with_theme(&ColorfulTheme::default()).with_prompt(prompt).default(false).interact();
// Check if the user confirmed the transaction.
if let Ok(confirmation) = confirmation {
if !confirmation {
println!("✅ Successfully aborted the execution transaction for '{}'\n", program_name.bold());
return Ok(());
}
} else {
return Err(CliError::confirmation_failed().into());
}
}
println!("✅ Created execution transaction for '{}'\n", program_id.to_string().bold());
handle_broadcast(&format!("{}/{}/transaction/broadcast", endpoint, network), transaction, &program_name)?;
} else {
println!("✅ Successful dry run execution for '{}'", program_id.to_string().bold());
println!("✅ Successful dry run execution for '{}'\n", program_id.to_string().bold());
}
return Ok(());
@ -241,14 +256,18 @@ fn handle_execute<A: Aleo>(command: Execute, context: Context) -> Result<<Execut
// Load the package.
let package = SnarkVMPackage::open(&path)?;
// Convert the inputs.
let inputs = inputs.iter().map(|input| Value::from_str(input).unwrap()).collect::<Vec<Value<A::Network>>>();
let mut parsed_inputs: Vec<Value<A::Network>> = Vec::new();
for input in inputs.iter() {
let value = Value::from_str(input)?;
parsed_inputs.push(value);
}
// Execute the request.
let (response, execution, metrics) = package
.execute::<A, _>(
command.compiler_options.endpoint.clone(),
endpoint.to_string(),
&private_key,
Identifier::try_from(command.name.clone())?,
&inputs,
&parsed_inputs,
rng,
)
.map_err(PackageError::execution_error)?;
@ -318,25 +337,22 @@ fn handle_execute<A: Aleo>(command: Execute, context: Context) -> Result<<Execut
/// A helper function to recursively load the program and all of its imports into the process. Lifted from snarkOS.
fn load_program_from_network<N: Network>(
command: &Execute,
context: Context,
process: &mut Process<N>,
program_id: &ProgramID<N>,
network: NetworkName,
endpoint: &str,
) -> Result<()> {
// Fetch the program.
let program_src = Query {
endpoint: command.compiler_options.endpoint.clone(),
network: command.compiler_options.network.clone(),
endpoint: Some(endpoint.to_string()),
network: Some(network.to_string()),
command: QueryCommands::Program {
command: crate::cli::commands::query::Program {
name: program_id.to_string(),
mappings: false,
mapping_value: None,
},
command: query::Program { name: program_id.to_string(), mappings: false, mapping_value: None },
},
}
.execute(Context::new(context.path.clone(), context.home.clone(), true)?)?;
let program = SnarkVMProgram::<N>::from_str(&program_src).unwrap();
let program = SnarkVMProgram::<N>::from_str(&program_src)?;
// Return early if the program is already loaded.
if process.contains_program(program.id()) {
@ -348,7 +364,7 @@ fn load_program_from_network<N: Network>(
// Add the imports to the process if does not exist yet.
if !process.contains_program(import_program_id) {
// Recursively load the program and its imports.
load_program_from_network(command, context.clone(), process, import_program_id)?;
load_program_from_network(context.clone(), process, import_program_id, network, endpoint)?;
}
}
@ -361,8 +377,14 @@ fn load_program_from_network<N: Network>(
}
// A helper function to display a cost breakdown of the execution.
fn execution_cost_breakdown(name: &String, total_cost: f64, storage_cost: f64, finalize_cost: f64, priority_fee: f64) {
println!("Base execution cost for '{}' is {} credits.", name.bold(), total_cost);
fn execution_cost_breakdown(
name: &String,
total_cost: f64,
storage_cost: f64,
finalize_cost: f64,
priority_fee: f64,
) -> Result<()> {
println!("\nBase execution cost for '{}' is {} credits.\n", name.bold(), total_cost);
// Display the cost breakdown in a table.
let data = [
[name, "Cost (credits)"],
@ -372,6 +394,7 @@ fn execution_cost_breakdown(name: &String, total_cost: f64, storage_cost: f64, f
["Total", &format!("{:.6}", total_cost)],
];
let mut out = Vec::new();
text_tables::render(&mut out, data).unwrap();
println!("{}", ::std::str::from_utf8(&out).unwrap());
text_tables::render(&mut out, data).map_err(CliError::table_render_failed)?;
println!("{}", std::str::from_utf8(&out).map_err(CliError::table_render_failed)?);
Ok(())
}

View File

@ -133,14 +133,10 @@ pub trait Command {
/// require Build command output as their input.
#[derive(Parser, Clone, Debug)]
pub struct BuildOptions {
#[clap(
long,
help = "Endpoint to retrieve network state from.",
default_value = "https://api.explorer.aleo.org/v1"
)]
pub endpoint: String,
#[clap(long, help = "Network to broadcast to. Defaults to testnet.", default_value = "testnet")]
pub(crate) network: String,
#[clap(long, help = "Endpoint to retrieve network state from. Overrides setting in `.env`.")]
pub endpoint: Option<String>,
#[clap(long, help = "Network to broadcast to. Overrides setting in `.env`.")]
pub(crate) network: Option<String>,
#[clap(long, help = "Does not recursively compile dependencies.")]
pub non_recursive: bool,
#[clap(long, help = "Enables offline mode.")]
@ -182,8 +178,8 @@ pub struct BuildOptions {
impl Default for BuildOptions {
fn default() -> Self {
Self {
endpoint: "http://api.explorer.aleo.org/v1".to_string(),
network: "testnet".to_string(),
endpoint: None,
network: None,
non_recursive: false,
offline: false,
enable_symbol_table_spans: false,
@ -210,6 +206,8 @@ impl Default for BuildOptions {
/// Used by Execute and Deploy commands.
#[derive(Parser, Clone, Debug, Default)]
pub struct FeeOptions {
#[clap(short, long, help = "Don't ask for confirmation.", default_value = "false")]
pub(crate) yes: bool,
#[clap(short, long, help = "Performs a dry-run of transaction generation")]
pub(crate) dry_run: bool,
#[clap(long, help = "Priority fee in microcredits. Defaults to 0.", default_value = "0")]
@ -250,8 +248,8 @@ fn check_balance<N: Network>(
let address = Address::<N>::try_from(ViewKey::try_from(private_key)?)?;
// Query the public balance of the address on the `account` mapping from `credits.aleo`.
let mut public_balance = Query {
endpoint: endpoint.to_string(),
network: network.to_string(),
endpoint: Some(endpoint.to_string()),
network: Some(network.to_string()),
command: QueryCommands::Program {
command: crate::cli::commands::query::Program {
name: "credits".to_string(),
@ -263,17 +261,24 @@ fn check_balance<N: Network>(
.execute(Context::new(context.path.clone(), context.home.clone(), true)?)?;
// Remove the last 3 characters since they represent the `u64` suffix.
public_balance.truncate(public_balance.len() - 3);
// Make sure the balance is valid.
let balance = if let Ok(credits) = public_balance.parse::<u64>() {
credits
} else {
return Err(CliError::invalid_balance(address).into());
};
// Compare balance.
if public_balance.parse::<u64>().unwrap() < total_cost {
if balance < total_cost {
Err(PackageError::insufficient_balance(address, public_balance, total_cost).into())
} else {
println!("Your current public balance is {} credits.\n", balance as f64 / 1_000_000.0);
Ok(())
}
}
/// Determine if the transaction should be broadcast or displayed to user.
fn handle_broadcast<N: Network>(endpoint: &String, transaction: Transaction<N>, operation: &String) -> Result<()> {
println!("Broadcasting transaction to {}...", endpoint.clone());
println!("Broadcasting transaction to {}...\n", endpoint.clone());
// Get the transaction id.
let transaction_id = transaction.id();
@ -287,20 +292,20 @@ fn handle_broadcast<N: Network>(endpoint: &String, transaction: Transaction<N>,
match transaction {
Transaction::Deploy(..) => {
println!(
"⌛ Deployment {transaction_id} ('{}') has been broadcast to {}.",
"⌛ Deployment {transaction_id} ('{}') has been broadcast to {}.\n",
operation.bold(),
endpoint
)
}
Transaction::Execute(..) => {
println!(
"⌛ Execution {transaction_id} ('{}') has been broadcast to {}.",
"⌛ Execution {transaction_id} ('{}') has been broadcast to {}.\n",
operation.bold(),
endpoint
)
}
Transaction::Fee(..) => {
println!("❌ Failed to broadcast fee '{}' to the {}.", operation.bold(), endpoint)
println!("❌ Failed to broadcast fee '{}' to the {}.\n", operation.bold(), endpoint)
}
}
Ok(())

View File

@ -15,7 +15,7 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use super::*;
use snarkvm::prelude::{MainnetV0, TestnetV0};
use snarkvm::prelude::{CanaryV0, MainnetV0, TestnetV0};
use leo_retriever::NetworkName;
@ -26,6 +26,13 @@ pub struct New {
pub(crate) name: String,
#[clap(short = 'n', long, help = "Name of the network to use", default_value = "testnet")]
pub(crate) network: String,
#[clap(
short = 'e',
long,
help = "Endpoint to retrieve network state from.",
default_value = "https://api.explorer.aleo.org/v1"
)]
pub(crate) endpoint: String,
}
impl Command for New {
@ -53,8 +60,9 @@ impl Command for New {
// Initialize the package.
match network {
NetworkName::MainnetV0 => Package::initialize::<MainnetV0>(&self.name, &package_path),
NetworkName::TestnetV0 => Package::initialize::<TestnetV0>(&self.name, &package_path),
NetworkName::MainnetV0 => Package::initialize::<MainnetV0>(&self.name, &package_path, self.endpoint),
NetworkName::TestnetV0 => Package::initialize::<TestnetV0>(&self.name, &package_path, self.endpoint),
NetworkName::CanaryV0 => Package::initialize::<CanaryV0>(&self.name, &package_path, self.endpoint),
}?;
Ok(())

View File

@ -69,8 +69,11 @@ impl Command for Block {
is_valid_numerical_input(&range[0])?;
is_valid_numerical_input(&range[1])?;
// Parse the range values.
let end = &range[1].parse::<u32>().map_err(|_| UtilError::invalid_bound(&range[1]))?;
let start = &range[0].parse::<u32>().map_err(|_| UtilError::invalid_bound(&range[0]))?;
// Make sure the range is not too large.
if range[1].parse::<u32>().unwrap() - range[0].parse::<u32>().unwrap() > 50 {
if end - start > 50 {
return Err(UtilError::invalid_range().into());
}
format!("blocks?start={}&end={}", range[0], range[1])

View File

@ -15,7 +15,7 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use super::*;
use snarkvm::prelude::{MainnetV0, TestnetV0};
use snarkvm::prelude::{CanaryV0, MainnetV0, TestnetV0};
mod block;
use block::Block;
@ -47,16 +47,10 @@ use leo_retriever::{fetch_from_network, verify_valid_program, NetworkName};
/// Query live data from the Aleo network.
#[derive(Parser, Debug)]
pub struct Query {
#[clap(
short,
long,
global = true,
help = "Endpoint to retrieve network state from. Defaults to https://api.explorer.aleo.org/v1.",
default_value = "https://api.explorer.aleo.org/v1"
)]
pub endpoint: String,
#[clap(short, long, global = true, help = "Network to use. Defaults to testnet.", default_value = "testnet")]
pub(crate) network: String,
#[clap(short, long, global = true, help = "Endpoint to retrieve network state from. Defaults to entry in `.env`.")]
pub endpoint: Option<String>,
#[clap(short, long, global = true, help = "Network to use. Defaults to entry in `.env`.")]
pub(crate) network: Option<String>,
#[clap(subcommand)]
pub command: QueryCommands,
}
@ -75,16 +69,23 @@ impl Command for Query {
fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
// Parse the network.
let network = NetworkName::try_from(self.network.as_str())?;
let network = NetworkName::try_from(context.get_network(&self.network)?)?;
let endpoint = context.get_endpoint(&self.endpoint)?;
match network {
NetworkName::MainnetV0 => handle_query::<MainnetV0>(self, context),
NetworkName::TestnetV0 => handle_query::<TestnetV0>(self, context),
NetworkName::MainnetV0 => handle_query::<MainnetV0>(self, context, &network.to_string(), &endpoint),
NetworkName::TestnetV0 => handle_query::<TestnetV0>(self, context, &network.to_string(), &endpoint),
NetworkName::CanaryV0 => handle_query::<CanaryV0>(self, context, &network.to_string(), &endpoint),
}
}
}
// A helper function to handle the `query` command.
fn handle_query<N: Network>(query: Query, context: Context) -> Result<<Query as Command>::Output> {
fn handle_query<N: Network>(
query: Query,
context: Context,
network: &str,
endpoint: &str,
) -> Result<<Query as Command>::Output> {
let recursive = context.recursive;
let (program, output) = match query.command {
QueryCommands::Block { command } => (None, command.apply(context, ())?),
@ -98,7 +99,7 @@ fn handle_query<N: Network>(query: Query, context: Context) -> Result<<Query as
QueryCommands::Stateroot { command } => (None, command.apply(context, ())?),
QueryCommands::Committee { command } => (None, command.apply(context, ())?),
QueryCommands::Mempool { command } => {
if query.endpoint == "https://api.explorer.aleo.org/v1" {
if endpoint == "https://api.explorer.aleo.org/v1" {
tracing::warn!(
"⚠️ `leo query mempool` is only valid when using a custom endpoint. Specify one using `--endpoint`."
);
@ -106,7 +107,7 @@ fn handle_query<N: Network>(query: Query, context: Context) -> Result<<Query as
(None, command.apply(context, ())?)
}
QueryCommands::Peers { command } => {
if query.endpoint == "https://api.explorer.aleo.org/v1" {
if endpoint == "https://api.explorer.aleo.org/v1" {
tracing::warn!(
"⚠️ `leo query peers` is only valid when using a custom endpoint. Specify one using `--endpoint`."
);
@ -116,7 +117,7 @@ fn handle_query<N: Network>(query: Query, context: Context) -> Result<<Query as
};
// Make GET request to retrieve on-chain state.
let url = format!("{}/{}/{output}", query.endpoint, query.network);
let url = format!("{}/{}/{output}", endpoint, network);
let result = fetch_from_network(&url)?;
if !recursive {
tracing::info!("✅ Successfully retrieved data from '{url}'.\n");

View File

@ -19,7 +19,7 @@ use super::*;
use leo_retriever::NetworkName;
use snarkvm::{
cli::Run as SnarkVMRun,
prelude::{MainnetV0, Network, Parser as SnarkVMParser, TestnetV0},
prelude::{CanaryV0, MainnetV0, Network, Parser as SnarkVMParser, TestnetV0},
};
/// Build, Prove and Run Leo program with inputs
@ -52,10 +52,11 @@ impl Command for Run {
fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
// Parse the network.
let network = NetworkName::try_from(self.compiler_options.network.as_str())?;
let network = NetworkName::try_from(context.get_network(&self.compiler_options.network)?)?;
match network {
NetworkName::MainnetV0 => handle_run::<MainnetV0>(self, context),
NetworkName::TestnetV0 => handle_run::<TestnetV0>(self, context),
NetworkName::CanaryV0 => handle_run::<CanaryV0>(self, context),
}
}
}

View File

@ -23,12 +23,13 @@ use snarkvm::file::Manifest;
use aleo_std::aleo_dir;
use indexmap::IndexMap;
use snarkvm::prelude::Network;
use snarkvm::prelude::{Network, PrivateKey};
use std::{
env::current_dir,
fs::File,
io::Write,
path::{Path, PathBuf},
str::FromStr,
};
/// Project context, manifest, current directory etc
@ -140,4 +141,54 @@ impl Context {
Ok(list)
}
/// Returns the private key from the .env file specified in the directory.
pub fn dotenv_private_key<N: Network>(&self) -> Result<PrivateKey<N>> {
dotenvy::from_path(self.dir()?.join(".env")).map_err(|_| CliError::failed_to_get_private_key_from_env())?;
// Load the private key from the environment.
let private_key = dotenvy::var("PRIVATE_KEY").map_err(|_| CliError::failed_to_get_private_key_from_env())?;
// Parse the private key.
Ok(PrivateKey::<N>::from_str(&private_key)?)
}
/// Returns the endpoint from the .env file specified in the directory.
pub fn dotenv_endpoint(&self) -> Result<String> {
dotenvy::from_path(self.dir()?.join(".env")).map_err(|_| CliError::failed_to_get_endpoint_from_env())?;
// Load the endpoint from the environment.
Ok(dotenvy::var("ENDPOINT").map_err(|_| CliError::failed_to_get_endpoint_from_env())?)
}
/// Returns the network from the .env file specified in the directory.
pub fn dotenv_network(&self) -> Result<String> {
dotenvy::from_path(self.dir()?.join(".env")).map_err(|_| CliError::failed_to_get_network_from_env())?;
// Load the network from the environment.
Ok(dotenvy::var("NETWORK").map_err(|_| CliError::failed_to_get_network_from_env())?)
}
/// Returns the endpoint to interact with the network.
/// If the `--endpoint` options is not provided, it will default to the one in the `.env` file.
pub fn get_endpoint(&self, endpoint: &Option<String>) -> Result<String> {
match endpoint {
Some(endpoint) => Ok(endpoint.clone()),
None => Ok(self.dotenv_endpoint()?),
}
}
/// Returns the network name.
/// If the `--network` options is not provided, it will default to the one in the `.env` file.
pub fn get_network(&self, network: &Option<String>) -> Result<String> {
match network {
Some(network) => Ok(network.clone()),
None => Ok(self.dotenv_network()?),
}
}
/// Returns the private key.
/// If the `--private-key` options is not provided, it will default to the one in the `.env` file.
pub fn get_private_key<N: Network>(&self, private_key: &Option<String>) -> Result<PrivateKey<N>> {
match private_key {
Some(private_key) => Ok(PrivateKey::<N>::from_str(private_key)?),
None => self.dotenv_private_key(),
}
}
}

View File

@ -37,6 +37,9 @@ default-features = false
version = "1.9"
features = [ "serde" ]
[dependencies.dialoguer]
version = "0.11.0"
[dependencies.num-format]
version = "0.4.4"
@ -60,7 +63,7 @@ version = "0.8"
version = "0.1"
[dev-dependencies.lazy_static]
version = "1.3.0"
version = "1.5.0"
[dev-dependencies.snarkvm]
workspace = true

View File

@ -22,8 +22,8 @@ use leo_errors::{PackageError, Result};
use leo_retriever::{Manifest, NetworkName};
use serde::Deserialize;
use snarkvm::prelude::Network;
use std::path::Path;
use snarkvm::prelude::{Network, PrivateKey};
use std::{path::Path, str::FromStr};
#[derive(Deserialize)]
pub struct Package {
@ -125,7 +125,7 @@ impl Package {
}
/// Creates a Leo package at the given path
pub fn initialize<N: Network>(package_name: &str, path: &Path) -> Result<()> {
pub fn initialize<N: Network>(package_name: &str, path: &Path, endpoint: String) -> Result<()> {
// Construct the path to the package directory.
let path = path.join(package_name);
@ -147,7 +147,12 @@ impl Package {
Gitignore::new().write_to(&path)?;
// Create the .env file.
Env::<N>::new()?.write_to(&path)?;
// Include the private key of validator 0 for ease of use with local devnets, as it will automatically be seeded with funds.
Env::<N>::new(
Some(PrivateKey::<N>::from_str("APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH")?),
endpoint,
)?
.write_to(&path)?;
// Create a manifest.
let manifest = Manifest::default(package_name);

View File

@ -30,17 +30,21 @@ pub static ENV_FILENAME: &str = ".env";
pub struct Env<N: Network> {
#[serde(bound(deserialize = ""))]
private_key: PrivateKey<N>,
endpoint: String,
}
impl<N: Network> Env<N> {
pub fn new() -> Result<Self> {
pub fn new(private_key: Option<PrivateKey<N>>, endpoint: String) -> Result<Self> {
// Initialize an RNG.
let rng = &mut rand::thread_rng();
// Generate a development private key.
let private_key = PrivateKey::<N>::new(rng)?;
let private_key = match private_key {
Some(private_key) => private_key,
None => PrivateKey::<N>::new(rng)?,
};
Ok(Self { private_key })
Ok(Self { private_key, endpoint })
}
pub fn exists_at(path: &Path) -> bool {
@ -63,12 +67,6 @@ impl<N: Network> Env<N> {
}
}
impl<N: Network> From<PrivateKey<N>> for Env<N> {
fn from(private_key: PrivateKey<N>) -> Self {
Self { private_key }
}
}
impl<N: Network> ToString for Env<N> {
fn to_string(&self) -> String {
// Get the network name.
@ -78,6 +76,6 @@ impl<N: Network> ToString for Env<N> {
_ => unimplemented!("Unsupported network"),
};
// Return the formatted string.
format!("NETWORK={network}\nPRIVATE_KEY={}\n", self.private_key)
format!("NETWORK={network}\nPRIVATE_KEY={}\nENDPOINT={}\n", self.private_key, self.endpoint)
}
}

View File

@ -87,7 +87,7 @@ impl Manifest {
pub fn read_from_dir(path: &Path) -> Result<Self, PackageError> {
// Read the manifest file.
let contents = std::fs::read_to_string(path.join("program.json"))
.map_err(|err| PackageError::failed_to_read_file(path.to_str().unwrap(), err))?;
.map_err(|_| PackageError::failed_to_load_package(path.to_str().unwrap()))?;
// Deserialize the manifest.
serde_json::from_str(&contents)
.map_err(|err| PackageError::failed_to_deserialize_manifest_file(path.to_str().unwrap(), err))

View File

@ -15,7 +15,7 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use leo_errors::{CliError, LeoError};
use snarkvm::prelude::{MainnetV0, Network, TestnetV0};
use snarkvm::prelude::{CanaryV0, MainnetV0, Network, TestnetV0};
use serde::{Deserialize, Serialize};
use std::fmt;
@ -27,6 +27,8 @@ pub enum NetworkName {
TestnetV0,
#[serde(rename = "mainnet")]
MainnetV0,
#[serde(rename = "canary")]
CanaryV0,
}
impl NetworkName {
@ -34,6 +36,7 @@ impl NetworkName {
match self {
NetworkName::TestnetV0 => TestnetV0::ID,
NetworkName::MainnetV0 => MainnetV0::ID,
NetworkName::CanaryV0 => CanaryV0::ID,
}
}
}
@ -45,16 +48,33 @@ impl TryFrom<&str> for NetworkName {
match network {
"testnet" => Ok(NetworkName::TestnetV0),
"mainnet" => Ok(NetworkName::MainnetV0),
"canary" => Ok(NetworkName::CanaryV0),
_ => Err(LeoError::CliError(CliError::invalid_network_name(network))),
}
}
}
impl TryFrom<String> for NetworkName {
type Error = LeoError;
fn try_from(network: String) -> Result<Self, LeoError> {
if network == "testnet" {
Ok(NetworkName::TestnetV0)
} else if network == "mainnet" {
Ok(NetworkName::MainnetV0)
} else if network == "canary" {
Ok(NetworkName::CanaryV0)
} else {
Err(LeoError::CliError(CliError::invalid_network_name(&network)))
}
}
}
impl fmt::Display for NetworkName {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
NetworkName::TestnetV0 => write!(f, "testnet"),
NetworkName::MainnetV0 => write!(f, "mainnet"),
NetworkName::CanaryV0 => write!(f, "canary"),
}
}
}