Skip to content

Commit

Permalink
feat: init command support for starknet
Browse files Browse the repository at this point in the history
  • Loading branch information
xJonathanLEI committed Apr 11, 2024
1 parent 43a8245 commit f02addd
Show file tree
Hide file tree
Showing 22 changed files with 739 additions and 7 deletions.
76 changes: 76 additions & 0 deletions cmd/substreams/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var (
devInitProtocol = os.Getenv("SUBSTREAMS_DEV_INIT_PROTOCOL")
devInitEthereumTrackedContract = os.Getenv("SUBSTREAMS_DEV_INIT_ETHEREUM_TRACKED_CONTRACT")
devInitEthereumChain = os.Getenv("SUBSTREAMS_DEV_INIT_ETHEREUM_CHAIN")
devInitStarknetChain = os.Getenv("SUBSTREAMS_DEV_INIT_STARKNET_CHAIN")
)

var errInitUnsupportedChain = errors.New("unsupported chain")
Expand Down Expand Up @@ -173,6 +174,43 @@ func runSubstreamsInitE(cmd *cobra.Command, args []string) error {
return fmt.Errorf("render Ethereum %s project: %w", chain.DisplayName, err)
}

case codegen.ProtocolStarknet:
chainSelected, err := promptStarknetChain()
if err != nil {
return fmt.Errorf("running chain prompt: %w", err)
}
if chainSelected == codegen.StarknetChainOther {
fmt.Println()
fmt.Println("We haven't added any templates for your selected chain quite yet")
fmt.Println()
fmt.Println("Come join us in discord at https://discord.gg/u8amUbGBgF and suggest templates/chains you want to see!")
fmt.Println()
return errInitUnsupportedChain
}

// Since Starknet contract ABI decoding has not been implemented yet, for any chain selected we
// would simply generate a template that collects block information. Unlike with Ethereum, We
// don't need to prompt users for any additional info here.

chain := templates.StarknetChainsByID[chainSelected.String()]
if chain == nil {
return fmt.Errorf("unknown chain: %s", chainSelected.String())
}

fmt.Println("Writing project files")
project, err := templates.NewStarknetProject(
projectName,
moduleName,
chain,
)
if err != nil {
return fmt.Errorf("new Starknet %s project: %w", chain.DisplayName, err)
}

if err := renderProjectFilesIn(project, absoluteProjectDir); err != nil {
return fmt.Errorf("render Starknet %s project: %w", chain.DisplayName, err)
}

case codegen.ProtocolOther:
fmt.Println()
fmt.Println("We haven't added any templates for your selected protocol quite yet")
Expand Down Expand Up @@ -579,6 +617,44 @@ func promptEthereumChain() (codegen.EthereumChain, error) {
return chain, nil
}

func promptStarknetChain() (codegen.StarknetChain, error) {
if devInitStarknetChain != "" {
// It's ok to panic, we expect the dev to put in a valid Starknet chain
chain, err := codegen.ParseStarknetChain(devInitStarknetChain)
if err != nil {
panic(fmt.Errorf("invalid chain: %w", err))
}

return chain, nil
}

choice := promptui.Select{
Label: "Select Starknet chain",
Items: codegen.StarknetChainNames(),
Templates: &promptui.SelectTemplates{
Selected: `{{ "Starknet chain:" | faint }} {{ . }}`,
},
HideHelp: true,
}

_, selection, err := choice.Run()
if err != nil {
if errors.Is(err, promptui.ErrInterrupt) {
// We received Ctrl-C, users wants to abort, nothing else to do, quit immediately
os.Exit(1)
}

return codegen.StarknetChainOther, fmt.Errorf("running chain prompt: %w", err)
}

var chain codegen.StarknetChain
if err := chain.UnmarshalText([]byte(selection)); err != nil {
panic(fmt.Errorf("impossible, selecting hard-coded value from enum itself, something is really wrong here"))
}

return chain, nil
}

type promptOptions struct {
Validate promptui.ValidateFunc
IsConfirm bool
Expand Down
1 change: 1 addition & 0 deletions codegen/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package codegen
// ENUM(
//
// Ethereum
// Starknet
// Other
//
// )
Expand Down
20 changes: 13 additions & 7 deletions codegen/protocol_enum.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions codegen/starknet_chain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package codegen

//go:generate go-enum -f=$GOFILE --marshal --names --nocase

// ENUM(
//
// Mainnet
// Sepolia
// Other
//
// )
type StarknetChain uint
96 changes: 96 additions & 0 deletions codegen/starknet_chain_enum.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions codegen/templates/starknet/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/build/
/target/
buf.gen.yaml
*.spkg
21 changes: 21 additions & 0 deletions codegen/templates/starknet/Cargo.toml.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "{{ .name }}"
version = "0.0.1"
edition = "2021"

[lib]
name = "substreams"
crate-type = ["cdylib"]

[dependencies]
prost = "0.11"
prost-types = "0.11"
substreams = "0.5"
substreams-database-change = "1"
substreams-entity-change = "1"
substreams-starknet = "0.1"

[profile.release]
lto = true
opt-level = 's'
strip = "debuginfo"
26 changes: 26 additions & 0 deletions codegen/templates/starknet/Makefile.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
CARGO_VERSION := $(shell cargo version 2>/dev/null)

.PHONY: build
build:
ifdef CARGO_VERSION
cargo build --target wasm32-unknown-unknown --release
else
@echo "Building substreams target using Docker. To speed up this step, install a Rust development environment."
docker run --rm -ti --init -v ${PWD}:/usr/src --workdir /usr/src/ rust:bullseye cargo build --target wasm32-unknown-unknown --release
endif

.PHONY: run
run: build
substreams run substreams.yaml $(if $(MODULE),$(MODULE),map_blocks) $(if $(START_BLOCK),-s $(START_BLOCK)) $(if $(STOP_BLOCK),-t $(STOP_BLOCK))

.PHONY: gui
gui: build
substreams gui substreams.yaml $(if $(MODULE),$(MODULE),map_blocks) $(if $(START_BLOCK),-s $(START_BLOCK)) $(if $(STOP_BLOCK),-t $(STOP_BLOCK))

.PHONY: protogen
protogen:
substreams protogen ./substreams.yaml --exclude-paths="sf/substreams,google"

.PHONY: pack
pack: build
substreams pack substreams.yaml
14 changes: 14 additions & 0 deletions codegen/templates/starknet/proto/block.proto.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
syntax = "proto3";

import "google/protobuf/timestamp.proto";

package block.v1;

message Block {
uint64 height = 1;
bytes hash = 2;
bytes prev_hash = 3;
uint64 timestamp = 4;
uint64 tx_count = 5;
uint64 event_count = 6;
}
4 changes: 4 additions & 0 deletions codegen/templates/starknet/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[toolchain]
channel = "1.77"
components = ["rustfmt"]
targets = ["wasm32-unknown-unknown"]
8 changes: 8 additions & 0 deletions codegen/templates/starknet/schema.clickhouse.sql.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS block (
"height" INT,
"hash" VARCHAR(64),
"prev_hash" VARCHAR(64),
"timestamp" INT,
"tx_count" INT,
"event_count" INT
) ENGINE = MergeTree PRIMARY KEY ("hash");
8 changes: 8 additions & 0 deletions codegen/templates/starknet/schema.graphql.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
type Block @entity {
id: ID!
height: BigInt!
prev_hash: Bytes!
timestamp: BigInt!
tx_count: BigInt!
event_count: BigInt!
}
9 changes: 9 additions & 0 deletions codegen/templates/starknet/schema.sql.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CREATE TABLE IF NOT EXISTS block (
"height" INT,
"hash" VARCHAR(64),
"prev_hash" VARCHAR(64),
"timestamp" INT,
"tx_count" INT,
"event_count" INT,
PRIMARY KEY(hash)
);
Loading

0 comments on commit f02addd

Please sign in to comment.