Skip to content

Commit 136a0f9

Browse files
authored
Merge branch 'main' into drand-voting
2 parents f0bb557 + ea2b7b6 commit 136a0f9

File tree

168 files changed

+63488
-110608
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

168 files changed

+63488
-110608
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import asyncio
2+
import os
3+
from enum import Enum
4+
from pathlib import Path
5+
6+
import dotenv
7+
from starknet_py.net.account.account import Account
8+
from starknet_py.net.full_node_client import FullNodeClient
9+
from starknet_py.net.models import StarknetChainId
10+
from starknet_py.net.signer.stark_curve_signer import KeyPair
11+
12+
from garaga.hints.io import to_int
13+
from garaga.starknet.cli.smart_contract_project import SmartContractProject
14+
15+
dotenv.load_dotenv(".secrets")
16+
17+
18+
class Network(Enum):
19+
SEPOLIA = "sepolia"
20+
MAINNET = "mainnet"
21+
22+
def to_starknet_chain_id(self):
23+
if self == Network.SEPOLIA:
24+
return StarknetChainId.SEPOLIA
25+
elif self == Network.MAINNET:
26+
return StarknetChainId.MAINNET
27+
else:
28+
raise ValueError(f"Unknown network: {self}")
29+
30+
31+
class Fee(Enum):
32+
ETH = "eth"
33+
STRK = "strk"
34+
35+
36+
def get_account(network: Network):
37+
rpc_url = os.getenv(f"{network.value.upper()}_RPC_URL")
38+
account_address = os.getenv(f"{network.value.upper()}_ACCOUNT_ADDRESS")
39+
account_private_key = os.getenv(f"{network.value.upper()}_ACCOUNT_PRIVATE_KEY")
40+
41+
client = FullNodeClient(node_url=rpc_url)
42+
account = Account(
43+
address=account_address,
44+
client=client,
45+
key_pair=KeyPair.from_private_key(to_int(account_private_key)),
46+
chain=network.to_starknet_chain_id(),
47+
)
48+
return account
49+
50+
51+
async def declare_contract_from_path(path: Path, network: Network, fee: Fee):
52+
contract = SmartContractProject(smart_contract_folder=path)
53+
account = get_account(network)
54+
await contract.declare_class_hash(account=account, fee=fee.value)
55+
56+
57+
async def declare_contract_from_path_both_networks(path: Path, fee: Fee):
58+
await declare_contract_from_path(path, Network.SEPOLIA, fee)
59+
await declare_contract_from_path(path, Network.MAINNET, fee)
60+
61+
62+
if __name__ == "__main__":
63+
asyncio.run(
64+
declare_contract_from_path_both_networks(
65+
Path("src/contracts/universal_ecip"), Fee.STRK
66+
)
67+
)
68+
asyncio.run(
69+
declare_contract_from_path_both_networks(
70+
Path("src/contracts/drand_quicknet"), Fee.STRK
71+
)
72+
)
73+
74+
asyncio.run(
75+
declare_contract_from_path_both_networks(
76+
Path("src/contracts/risc0_verifier_bn254"), Fee.STRK
77+
)
78+
)

.github/scripts/verify_contracts.py

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import ast
2+
import asyncio
3+
import sys
4+
from enum import Enum
5+
from pathlib import Path
6+
7+
from starknet_py.net.full_node_client import FullNodeClient
8+
9+
import garaga.hints.io as io
10+
from garaga.starknet.cli.smart_contract_project import SmartContractProject
11+
12+
13+
class Network(Enum):
14+
SEPOLIA = "sepolia"
15+
MAINNET = "mainnet"
16+
17+
18+
def get_class_hash_from_generator():
19+
try:
20+
with open(
21+
"hydra/garaga/starknet/groth16_contract_generator/generator.py", "r"
22+
) as f:
23+
tree = ast.parse(f.read())
24+
for node in ast.walk(tree):
25+
if isinstance(node, ast.Assign) and len(node.targets) == 1:
26+
if getattr(node.targets[0], "id", None) == "ECIP_OPS_CLASS_HASH":
27+
return hex(node.value.value)
28+
raise ValueError("ECIP_OPS_CLASS_HASH not found in generator.py")
29+
except Exception as e:
30+
print(f"Error parsing generator.py: {str(e)}", file=sys.stderr)
31+
sys.exit(1)
32+
33+
34+
async def verify_network(network: Network, class_hash: str):
35+
class_hash = io.to_hex_str(class_hash)
36+
print(f"\nVerifying class hash {class_hash} on {network.value}...")
37+
client = FullNodeClient(f"https://free-rpc.nethermind.io/{network.value}-juno")
38+
try:
39+
result = await client.get_class_by_hash(class_hash)
40+
if not result:
41+
print(f"Error: Contract not declared on {network.value}", file=sys.stderr)
42+
sys.exit(1)
43+
print(f"✓ Contract verified on {network.value}")
44+
except Exception as e:
45+
print(f"Error checking {network.value}: {str(e)}", file=sys.stderr)
46+
sys.exit(1)
47+
48+
49+
async def verify_ecip_contract():
50+
class_hash = get_class_hash_from_generator()
51+
print(f"Verifying ECIP contract using class hash: {class_hash}")
52+
53+
await verify_network(Network.SEPOLIA, class_hash)
54+
await verify_network(Network.MAINNET, class_hash)
55+
56+
print("\n✓ Contract verified on both networks")
57+
58+
59+
async def verify_contract_from_path(path: Path):
60+
contract = SmartContractProject(smart_contract_folder=path)
61+
class_hash = contract.get_sierra_class_hash()
62+
print(f"Verifying contract {path} with class hash {io.to_hex_str(class_hash)}")
63+
await verify_network(Network.SEPOLIA, class_hash)
64+
await verify_network(Network.MAINNET, class_hash)
65+
66+
67+
if __name__ == "__main__":
68+
asyncio.run(verify_ecip_contract())
69+
asyncio.run(verify_contract_from_path(Path("src/contracts/drand_quicknet")))
70+
asyncio.run(verify_contract_from_path(Path("src/contracts/risc0_verifier_bn254")))

.github/workflows/cairo.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
- uses: actions/checkout@v3
2828
- uses: software-mansion/setup-scarb@v1
2929
with:
30-
scarb-version: "2.8.2"
30+
scarb-version: "2.9.1"
3131
- run: scarb fmt --check
3232
working-directory: src/
3333
- run: cd src/ && scarb test

.github/workflows/e2e.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
- name: Setup Scarb
3939
uses: software-mansion/setup-scarb@v1
4040
with:
41-
scarb-version: "2.8.2"
41+
scarb-version: "2.9.1"
4242
- name: Install dependencies
4343
run: make setup
4444

.github/workflows/hydra.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
- name: Set up Scarb
5555
uses: software-mansion/setup-scarb@v1
5656
with:
57-
scarb-version: "2.8.2"
57+
scarb-version: "2.9.1"
5858
- name: Run make rewrite and check for unstaged changes
5959
run: |
6060
source venv/bin/activate

.github/workflows/maturin.yml

+26-14
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
# This file is autogenerated by maturin v1.7.0
2-
# To update, run
3-
#
4-
# maturin generate-ci github
5-
#
61
name: CI
7-
82
on:
93
push:
104
branches:
@@ -40,7 +34,7 @@ jobs:
4034
- uses: actions/checkout@v4
4135
- uses: actions/setup-python@v5
4236
with:
43-
python-version: 3.x
37+
python-version: "3.10.x"
4438
- name: Build wheels
4539
uses: PyO3/maturin-action@v1
4640
with:
@@ -71,7 +65,7 @@ jobs:
7165
- uses: actions/checkout@v4
7266
- uses: actions/setup-python@v5
7367
with:
74-
python-version: 3.x
68+
python-version: "3.10.x"
7569
- name: Build wheels
7670
uses: PyO3/maturin-action@v1
7771
with:
@@ -98,7 +92,7 @@ jobs:
9892
- uses: actions/checkout@v4
9993
- uses: actions/setup-python@v5
10094
with:
101-
python-version: 3.x
95+
python-version: 3.10.x
10296
architecture: ${{ matrix.platform.target }}
10397
- name: Build wheels
10498
uses: PyO3/maturin-action@v1
@@ -117,16 +111,15 @@ jobs:
117111
strategy:
118112
matrix:
119113
platform:
120-
- runner: macos-12
114+
- runner: macos-14
121115
target: x86_64
122116
- runner: macos-14
123117
target: aarch64
124118
steps:
125119
- uses: actions/checkout@v4
126120
- uses: actions/setup-python@v5
127121
with:
128-
# Workaround to ensure python 3.10 is available on x86_64
129-
python-version: ${{ matrix.platform.target == 'x86_64' && '3.10' || '3.x' }}
122+
python-version: "3.10.x"
130123
- name: Build wheels
131124
uses: PyO3/maturin-action@v1
132125
with:
@@ -157,10 +150,29 @@ jobs:
157150
release:
158151
name: Release
159152
runs-on: ubuntu-latest
160-
# Note this will only run when a new tag is pushed
161-
if: "startsWith(github.ref, 'refs/tags/')"
153+
if: "startsWith(github.ref, 'refs/tags/')" # Only run on tag pushes
162154
needs: [linux, musllinux, windows, macos, sdist]
163155
steps:
156+
- uses: actions/checkout@v4
157+
- name: Set up Rust
158+
uses: actions-rs/toolchain@v1
159+
with:
160+
toolchain: stable
161+
override: true
162+
profile: minimal
163+
components: rustfmt
164+
165+
- uses: software-mansion/setup-scarb@v1
166+
with:
167+
scarb-version: "2.9.1"
168+
- name: Set up Python 3.10
169+
uses: actions/setup-python@v5
170+
with:
171+
python-version: "3.10.x"
172+
- name: Install dependencies
173+
run: make setup
174+
- name: Verify Contract Declaration
175+
run: source venv/bin/activate && python .github/scripts/verify_contracts.py
164176
- uses: actions/download-artifact@v4
165177
- name: Publish to PyPI
166178
uses: PyO3/maturin-action@v1

.github/workflows/wasm.yml

+21-3
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,29 @@ jobs:
7676
release:
7777
name: Release
7878
runs-on: ubuntu-latest
79-
# Note this will only run when a new tag is pushed
80-
if: "startsWith(github.ref, 'refs/tags/')"
79+
if: "startsWith(github.ref, 'refs/tags/')" # Only run on tag pushes
8180
needs: [build, test, test-integration]
8281
steps:
82+
- uses: actions/checkout@v4
83+
- name: Set up Rust
84+
uses: actions-rs/toolchain@v1
85+
with:
86+
toolchain: stable
87+
override: true
88+
profile: minimal
89+
components: rustfmt
90+
91+
- uses: software-mansion/setup-scarb@v1
92+
with:
93+
scarb-version: "2.9.1"
94+
- name: Set up Python 3.10.14
95+
uses: actions/setup-python@v5
96+
with:
97+
python-version: 3.10.14
98+
- name: Install dependencies
99+
run: make setup
100+
- name: Verify Contract Declaration
101+
run: source venv/bin/activate && python .github/scripts/verify_contracts.py
83102
- uses: actions/setup-node@v4
84103
with:
85104
node-version: 'lts/*'
@@ -90,7 +109,6 @@ jobs:
90109
name: npm-package
91110
- name: Publish to npm
92111
run: |
93-
npm login
94112
npm publish --access=public *.tgz
95113
env:
96114
NODE_AUTH_TOKEN: ${{ secrets.NPM_API_TOKEN }}

README.md

+4-7
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,7 @@ Garaga currently supports:
3535
- Scalar & Multi-scalar multiplication for any Weirstrass curve, including BN254, BLS12_381, SECP256/R1, and ED25519. You can add the one you need by specifying the curve parameters.
3636
- Pairing operations for BN254 and BLS12_381.
3737
- Groth16 smart contract verifiers generators for BN254 and BLS12_381.
38-
39-
Following supported schemes will be
40-
- BLS signatures contract generators.
41-
- Plonk based SNARKs verifier, especially Noir.
38+
- Noir smart contract verifiers generators for ultra keccak honk flavour.
4239

4340

4441
## Architecture overview
@@ -62,9 +59,9 @@ Currently, only Groth16 on BN254 and BLS12_381 is supported with automatic suppo
6259
6. Run the `garaga declare` command in your terminal to declare the smart contract on Starknet and obtain its class hash. Note that this is an expensive operation.
6360
7. Run the `garaga deploy` command in your terminal using the class hash obtained in the previous step to get the contract address.
6461

65-
7. Run the `garaga verify-onchain` command in your terminal using the contract address, the verification key, the proof and the public inputs to verify the proof against the SNARK verifier contract.
62+
8. Run the `garaga verify-onchain` command in your terminal using the contract address, the verification key, the proof and the public inputs to verify the proof against the SNARK verifier contract.
6663

67-
For more details, please refer to the [documentation](https://felt.gitbook.io/garaga/).
64+
For more details, please refer to the [documentation](https://garaga.gitbook.io/garaga/).
6865

6966
## Developer setup
7067

@@ -74,7 +71,7 @@ To get started with Garaga, you'll need to have some tools and dependencies inst
7471

7572
Ensure you have the following installed:
7673
- [Python 3.10](https://www.python.org/downloads/) - /!\ Make sure `python3.10` is a valid command in your terminal. The core language used for development. Make sure you have the correct dependencies installed (in particular, GMP) for the `fastecdsa` python package. See [here](https://pypi.org/project/fastecdsa/#installing) for linux and [here](https://github.com/AntonKueltz/fastecdsa/issues/74) for macos.
77-
- [Scarb 2.8.2](https://docs.swmansion.com/scarb/download.html) - The Cairo package manager. Comes with Cairo inside. Requires [Rust](https://www.rust-lang.org/tools/install).
74+
- [Scarb 2.9.1](https://docs.swmansion.com/scarb/download.html) - The Cairo package manager. Comes with Cairo inside. Requires [Rust](https://www.rust-lang.org/tools/install).
7875

7976
##### Optionally :
8077

0 commit comments

Comments
 (0)