From 6f8508a71795783b79ff9d29aa427c7a2dea9a38 Mon Sep 17 00:00:00 2001 From: johnnymatthews <9611008+johnnymatthews@users.noreply.github.com> Date: Sat, 5 Sep 2026 11:38:31 +0000 Subject: [PATCH] Re-adds missing page. Updates links. --- .../concepts/views-for-builders/index.md | 4 +- content/build/create-a-view/index.md | 474 ------------------ .../tutorials/create-your-first-view/index.md | 414 ++++++++++++++- content/reference/components/lens/index.md | 2 +- content/reference/components/viewkit/index.md | 2 +- .../run/operations/troubleshooting/index.md | 2 +- content/run/run-a-host/install/index.md | 4 +- .../understand/core-concepts/pools/index.md | 2 +- static/_redirects | 12 +- templates/macros/footer.html | 2 +- 10 files changed, 428 insertions(+), 490 deletions(-) delete mode 100644 content/build/create-a-view/index.md diff --git a/content/build/concepts/views-for-builders/index.md b/content/build/concepts/views-for-builders/index.md index 0f6b1eb..f6fedf6 100644 --- a/content/build/concepts/views-for-builders/index.md +++ b/content/build/concepts/views-for-builders/index.md @@ -77,11 +77,11 @@ The `Log` collection is the primary source for event-based Views. There is no `E Viewkit is a local-first CLI: you initialize a view bundle, incrementally add or update its query, SDL, and lenses, test it locally against a throwaway DefraDB instance, then deploy to local or devnet. Strong defaults, explicit versioning, and deterministic behavior mean developers focus on data semantics and transformations; Shinzo handles execution, distribution, and verification. -For the hands-on walkthrough, see [Create a View](/build/create-a-view/). For the full command list, filter operators, and deploy internals, see the [Viewkit reference](/reference/components/viewkit/). +For the hands-on walkthrough, see [Create your first View](/build/tutorials/create-your-first-view/). For the full command list, filter operators, and deploy internals, see the [Viewkit reference](/reference/components/viewkit/). ## Where to go next -- [Create a View](/build/create-a-view/): step-by-step guide to building and deploying your first view. +- [Create your first View](/build/tutorials/create-your-first-view/): step-by-step tutorial for building and deploying your first View. - [Pools](/understand/core-concepts/pools/): how developer demand for a View meets the Hosts that serve it. - [Build an app](/build/build-an-app/): use the app-sdk to subscribe to Views and query data locally. - [Query data](/build/query-data/): GraphQL query patterns for deployed Views. diff --git a/content/build/create-a-view/index.md b/content/build/create-a-view/index.md deleted file mode 100644 index b53fa07..0000000 --- a/content/build/create-a-view/index.md +++ /dev/null @@ -1,474 +0,0 @@ -+++ -title = "Create a View" -aliases = ["/views/quickstart", "/views/install"] -description = "Build and deploy your first Shinzo View with Viewkit โ€” from install to local testing to devnet publishing." -+++ -Viewkit is a CLI tool that helps you initialize, manage, and publish Shinzo views. In this guide we're going to build and install the `viewkit` executable, create a view, and publish it to the testnet. If you'd rather work from a browser UI instead of the CLI, [Shinzo Studio](https://studio.shinzo.network/) covers the same create โ†’ deploy โ†’ query flow for Views. - -## Prerequisites - -- Git -- Make -- Go 1.25 - -## Setup - -1. Make sure you've got all the prerequisites installed properly: - - ```shell - git --version && make --version && go version - ``` - - ```output - git version 2.43.0 - GNU Make 4.3 - [...] - go version go1.25.12 linux/arm64 - ``` - -1. Clone the repository: - - ```shell - git clone https://github.com/shinzonetwork/shinzo-view-creator.git - cd shinzo-view-creator - ``` - -1. Build the Viewkit binary: - - ```shell - make build - ``` - - You should see a `build` directory: - -1. Run Viewkit: - - ```shell - ./build/viewkit --help - ``` - - ```output - Viewkit helps you initialize, manage, and publish Shinzo views through a simple CLI interface. - - Usage: - viewkit [command] - - [...] - ``` - -1. Move the `viewkit` executable somewhere reasonable (optional): - - ```shell - sudo mv ./build/viewkit /usr/local/bin - ``` - - Now you can run `viewkit` from anywhere. - -## Wasmer runtime - -Viewkit can execute WebAssembly lenses locally to validate and preview them. - -Under the hood, it uses `wasmer-go`, which depends on a native dynamic library (`libwasmer.dylib`). If your local system cannot find that library, any command that touches lenses will fail with an error like: - -```plaintext -image not found -library not loaded: libwasmer.dylib -``` - -1. Move back into the shinzo-view-creator repo if you moved out of it: - - ```shell - cd shinzo-view-creator - ``` - -1. Install the Wasmer Go module: - - ```shell - go get github.com/wasmerio/wasmer-go@v1.0.4 - ``` - - ```output - go: downloading github.com/wasmerio/wasmer-go v1.0.4 - go: added github.com/wasmerio/wasmer-go v1.0.4 - ``` - - This makes `wasmer-go` and its packaged native libraries available in your `GOPATH`. - -### Environment variables - -We need to set three new environment variables: - -- `WASMER_ROOT`: points to the directory where `libwasmer.dylib` lives. -- `WASMER_LIB_PATH`: used by `wasmer-go` to find the dynamic library. -- `DYLD_LIBRARY_PATH`: MacOS-specific dynamic loader search path. We prepend `WASMER_ROOT` so the loader can find `libwasmer.dylib` when `viewkit` starts. - -1. Append these lines to your shell's RC file. - - MacOS: - - ```shell - echo 'export WASMER_ROOT="$(go env GOPATH)/pkg/mod/github.com/wasmerio/wasmer-go@v1.0.4/wasmer/packaged/lib/darwin-aarch64"' >> ~/.zshrc - echo 'export WASMER_LIB_PATH="$WASMER_ROOT"' >> ~/.zshrc - echo 'export DYLD_LIBRARY_PATH="$WASMER_ROOT:$DYLD_LIBRARY_PATH"' >> ~/.zshrc - ``` - - Linux: - - ```shell - echo 'export WASMER_ROOT="$(go env GOPATH)/pkg/mod/github.com/wasmerio/wasmer-go@v1.0.4/wasmer/packaged/lib/linux-amd64"' >> ~/.zshrc - echo 'export WASMER_LIB_PATH="$WASMER_ROOT"' >> ~/.zshrc - echo 'export LD_LIBRARY_PATH="$WASMER_ROOT:$LD_LIBRARY_PATH"' >> ~/.zshrc - ``` - -1. Reload your shell configuration: - - ```shell - source ~/.zshrc - ``` - -1. Verify that the variables are set: - - ```shell - echo "$WASMER_ROOT" - ls "$WASMER_ROOT" - ``` - - ```output - /home/user/go/pkg/mod/github.com/wasmerio/wasmer-go@v1.0.4/wasmer/packaged/lib/linux-amd64 - dummy.go libwasmer.so - ``` - -{% admonition(type="warning") %} -If `libwasmer.dylib` is missing, re-run the `go get` step and ensure `go env GOPATH` returns a valid path. -{% end %} - -## Create a view - -Now that everything is set up, we can start creating and deploying views. - -1. Initialize the view bundle: - - ```shell - viewkit view init testdeploy - ``` - - ```output - ๐Ÿ“„ View: testdeploy - ๐Ÿ” Query: - ๐Ÿ“ SDL: - ๐Ÿ”ง Lenses: - - (empty) - - ๐Ÿ—‚ Metadata: - - Version: 0 - - Total: 0 - - Created At: 2026-07-09 09:34:27 +0000 UTC - - Updated At: 2026-07-09 09:34:27 +0000 UTC - ``` - - This: - - - Creates a new view bundle called `testdeploy` on disk. - - Registers internal metadata for queries, SDL, lenses, and versions. - -1. Inspect the bundle: - - ```shell - viewkit view inspect testdeploy - ``` - - ```output - ๐Ÿ“„ View: testdeploy - ๐Ÿ” Query: - ๐Ÿ“ SDL: - ๐Ÿ”ง Lenses: - - (empty) - - ๐Ÿ—‚ Metadata: - - Version: 0 - - Total: 0 - - Created At: 2026-07-09 09:34:27 +0000 UTC - - Updated At: 2026-07-09 09:34:27 +0000 UTC - ``` - -1. Next we're going to add a query (raw ingest shape). First, define the raw data shape to ingest, e.g. raw event logs: - - ```shell - viewkit view add query \ - "Log {address topics data transactionHash blockNumber}" \ - --name testdeploy - ``` - - ```output - ๐Ÿ“„ View: testdeploy - ๐Ÿ” Query: - Log {address topics data transactionHash blockNumber} - - ๐Ÿ“ SDL: - ๐Ÿ”ง Lenses: - - (empty) - - ๐Ÿ—‚ Metadata: - - Version: 1 - - Total: 1 - - Created At: 2026-07-09 09:34:27 +0000 UTC - - Updated At: 2026-07-09 09:36:32 +0000 UTC - ``` - - This tells Viewkit that `testdeploy` will ingest `Log` objects with the specified fields. - -1. Then, check: - - ```shell - viewkit view inspect testdeploy - ``` - - ```output - ๐Ÿ“„ View: testdeploy - ๐Ÿ” Query: - Log {address topics data transactionHash blockNumber} - - ๐Ÿ“ SDL: - ๐Ÿ”ง Lenses: - - (empty) - - ๐Ÿ—‚ Metadata: - - Version: 1 - - Total: 1 - - Created At: 2026-07-09 09:34:27 +0000 UTC - - Updated At: 2026-07-09 09:36:32 +0000 UTC - ``` - -1. Add an SDL to describe how the data is modeled/exposed: - - ```shell - viewkit view add sdl \ - "type FilteredAndDecodedLogs @materialized(if: false) {transactionHash: String}" \ - --name testdeploy - ``` - - ```output - ๐Ÿ“„ View: testdeploy - ๐Ÿ” Query: - Log {address topics data transactionHash blockNumber} - - ๐Ÿ“ SDL: - type FilteredAndDecodedLogs @materialized(if: false) {transactionHash: String} - - ๐Ÿ”ง Lenses: - - (empty) - - ๐Ÿ—‚ Metadata: - - Version: 2 - - Total: 2 - - Created At: 2026-07-09 09:34:27 +0000 UTC - - Updated At: 2026-07-09 09:37:24 +0000 UTC - ``` - - {% admonition(type="note") %} -- `@materialized(if: false)`: treat this as a virtual type, not a persisted table. -- `transactionHash: String`: minimal example field; real views will define more fields. - {% end %} - -1. Inspect the view again: - - ```shell - viewkit view inspect testdeploy - # now shows both query and SDL - ``` - - ```output - ๐Ÿ“„ View: testdeploy - ๐Ÿ” Query: - Log {address topics data transactionHash blockNumber} - - ๐Ÿ“ SDL: - type FilteredAndDecodedLogs @materialized(if: false) {transactionHash: String} - - ๐Ÿ”ง Lenses: - - (empty) - - ๐Ÿ—‚ Metadata: - - Version: 2 - - Total: 2 - - Created At: 2026-07-09 09:34:27 +0000 UTC - - Updated At: 2026-07-09 09:37:24 +0000 UTC - ``` - - It now shows both the query and the SDL. - -1. Attach a WebAssembly lens that decodes event logs using an ABI. These are the flags we're using: - - - `--args`: JSON passed to the lens (here, an ABI definition for the ERC-20 `Transfer` event). - - `--label "decode"`: human-readable label for the lens. - - `--url`: remote URL of the `.wasm` binary. - - `--name testdeploy`: attaches this lens to the `testdeploy` view. - - ```shell - viewkit view add lens \ - --args '{"abi":"[{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"type\":\"address\",\"name\":\"from\",\"indexed\":true},{\"type\":\"address\",\"name\":\"to\",\"indexed\":true},{\"type\":\"uint256\",\"name\":\"value\",\"indexed\":false}]}]"}' \ - --label "decode" \ - --url "https://raw.githubusercontent.com/shinzonetwork/wasm-bucket/main/bucket/decode_log/decode_log.wasm" \ - --name testdeploy - ``` - - ```output - ๐Ÿ“„ View: testdeploy - ๐Ÿ” Query: - Log {address topics data transactionHash blockNumber} - - ๐Ÿ“ SDL: - type FilteredAndDecodedLogs @materialized(if: false) {transactionHash: String} - - ๐Ÿ”ง Lenses: - - decode (assets/decode.wasm) - Arguments: - abi: [{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","indexed":true},{"type":"address","name":"to","indexed":true},{"type":"uint256","name":"value","indexed":false}]}] - - ๐Ÿ—‚ Metadata: - - Version: 3 - - Total: 3 - - Created At: 2026-07-09 09:34:27 +0000 UTC - - Updated At: 2026-07-09 09:39:11 +0000 UTC - ``` -1. Inspect the view again: - - ```shell - viewkit view inspect testdeploy - # you should now see: - # - query - # - SDL - # - lens "decode" - ``` - - You should now see the query, SDL, and the `decode` lens: - - ```output - ๐Ÿ“„ View: testdeploy - ๐Ÿ” Query: - Log {address topics data transactionHash blockNumber} - - ๐Ÿ“ SDL: - type FilteredAndDecodedLogs @materialized(if: false) {transactionHash: String} - - ๐Ÿ”ง Lenses: - - decode (assets/decode.wasm) - Arguments: - abi: [{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","indexed":true},{"type":"address","name":"to","indexed":true},{"type":"uint256","name":"value","indexed":false}]}] - - ๐Ÿ—‚ Metadata: - - Version: 3 - - Total: 3 - - Created At: 2026-07-09 09:34:27 +0000 UTC - - Updated At: 2026-07-09 09:39:11 +0000 UTC - ``` - -{% admonition(type="tip") %} -If you see `libwasmer.dylib` / "image not found" errors, revisit the Wasmer setup. -{% end %} - -1. Before deploying, validate that your view builds and compiles successfully: - - ```shell - viewkit view test testdeploy - ``` - - This spins up a temporary local DefraDB instance, applies your schema, runs the lens, and checks that everything compiles. If it passes, your view is ready to deploy. - -## Create a deployment key - -You need a wallet to sign deployments to `devnet`. - -1. Generate a new one: - - ```shell - viewkit wallet generate - ``` - - ```output - โœ… Wallet generated - Mnemonic: document grass code lawn erosion climb people sunset three blame balcony story script hip soup lesson resemble above quiz acid dust salmon plane - Address: 0x2e4150993E841b38f4780BC158A7dA0d62E22ec9 - ``` - -1. Treat this wallet like any other secret or asset: - - - Do not commit it to Git. - - Do not paste the mnemonic in public places. - - Store it securely. - -## Deploy locally - -The recommended flow is to deploy locally first, verify the view in a Playground, then deploy to a shared network. - -1. Deploy locally: - - ```shell - viewkit view deploy testdeploy --target local - ``` - - ```output - ๐Ÿš€ DefraDB is running on port 9181 - โณ Waiting for DefraDB to boot up... - โœ… DefraDB booted up - โณ Applying Schemas ... - โœ… Schema Applied - โณ Data Inserting... - โœ… Data Inserted Successfully - โœ… Applying View ... - โœ… View Successfully Applied - ๐Ÿงช Visit the DefraDB GraphQL Playground at http://127.0.0.1:9181/ - ๐Ÿ“ฆ Press Ctrl+C to stop... - ``` - - Here's what's happening: - - 1. A local DefraDB instance is started (port shown in the logs). - 1. Schemas for your view are applied. - 1. Any seed data (if configured) is inserted. - 1. The view is applied. - 1. A DefraDB GraphQL Playground URL is printed. - -### Use the DefraDB GraphQL Playground - -This section is optional, but it's a good idea to check the View within the built-in GraphQL Playground. - -1. Open the displayed URL in your browser, usually [127.0.0.1:9181](http://127.0.0.1:9181/). -1. You should see a GraphQL Playground. -1. Within this Playground you can: - - Inspect the schema (e.g. see `FilteredAndDecodedLogs`). - - Run test queries against your local view. - - Verify that your lens is filtering logs as expected. - -For example, you can run a query like: - -```graphql -{ - filteredAndDecodedLogs { - transactionHash - } -} -``` - -While this process is running, `viewkit` will keep the local DefraDB instance alive. Press `CTRL` + `c` to stop the DefraDB instance. - -## Deploy to devnet - -Once your view behaves correctly locally, you can deploy it to a shared network. - -1. Gather an RPC URL. -1. Deploy the view to the network: - - ```shell - viewkit view deploy testdeploy --target devnet --rpc http://testnet.shinzo.network:8545/ - ``` - -## More examples - -For progressively more complex View examples (decoding multiple event types, transaction-based views without lenses, materialized vs on-query views, editing and rolling back views), see the [View examples](/build/create-a-view/examples/) page, which includes both the view definitions and the GraphQL queries you run against them. - -For the conceptual overview, see [Views for builders](/build/concepts/views-for-builders/). For the full command list, filter operators, VWL wire format, and deploy internals, see the [Viewkit reference](/reference/components/viewkit/). For a deeper dive on lenses, available modules, and how to chain them, see the [Lens reference](/reference/components/lens/). For troubleshooting and common errors, see [Operations: Troubleshooting](/run/operations/troubleshooting/). - -## Need help - -{{ need_help(client="Viewkit", repo_name="shinzo-view-creator", repo="https://github.com/shinzonetwork/shinzo-view-creator/issues") }} diff --git a/content/build/tutorials/create-your-first-view/index.md b/content/build/tutorials/create-your-first-view/index.md index be223d0..8adde81 100644 --- a/content/build/tutorials/create-your-first-view/index.md +++ b/content/build/tutorials/create-your-first-view/index.md @@ -1,6 +1,418 @@ +++ title = "Create your first View" +aliases = ["/views/quickstart", "/views/install", "/build/create-a-view/"] description = "Tutorial: build, test, and deploy a Shinzo View with Viewkit, from install to querying it on the public testnet." +++ -This page is coming soon. +Viewkit is a CLI tool that helps you initialize, manage, and publish Shinzo views. In this tutorial you will build the `viewkit` executable, assemble a View from its parts, test it locally, and deploy it to the public testnet. If you would rather work from a browser UI instead of the CLI, [Create and deploy Views in Shinzo Studio](/build/how-to/use-shinzo-studio/) covers the same create, deploy, and query flow for Views. + +A View is a versioned bundle with three parts: a query (the raw data shape you ingest), an SDL (the GraphQL schema that models the result), and lenses (WebAssembly transforms that filter, decode, or reshape the data). The View you build here decodes fungible token transfer events from raw logs into readable fields. + +## Prerequisites + +- Git. +- Make. +- Go 1.25 or later. + +## Setup + +1. Make sure the prerequisites are installed properly: + + ```shell + git --version && make --version && go version + ``` + + ```output + git version 2.43.0 + GNU Make 4.3 + [...] + go version go1.25.12 linux/arm64 + ``` + +1. Clone the repository: + + ```shell + git clone https://github.com/shinzonetwork/shinzo-view-creator.git + cd shinzo-view-creator + ``` + +1. Build the Viewkit binary: + + ```shell + make build + ``` + + You should see a `build` directory. + +1. Run Viewkit: + + ```shell + ./build/viewkit --help + ``` + + ```output + Viewkit helps you initialize, manage, and publish Shinzo views through a simple CLI interface. + + Usage: + viewkit [command] + + [...] + ``` + +1. Move the `viewkit` executable somewhere on your PATH (optional): + + ```shell + sudo mv ./build/viewkit /usr/local/bin + ``` + + Now you can run `viewkit` from anywhere. + +## Wasmer runtime + +Viewkit can execute WebAssembly lenses locally to validate and preview them when you run `view test` or deploy locally. + +Under the hood it uses `wasmer-go`, which depends on a native dynamic library (`libwasmer.dylib` on macOS, `libwasmer.so` on Linux). If your system cannot find that library, any command that touches lenses will fail with an error like "image not found" or "library not loaded". + +1. Move back into the shinzo-view-creator repo if you moved out of it: + + ```shell + cd shinzo-view-creator + ``` + +1. Install the Wasmer Go module: + + ```shell + go get github.com/wasmerio/wasmer-go@v1.0.4 + ``` + + ```output + go: downloading github.com/wasmerio/wasmer-go v1.0.4 + go: added github.com/wasmerio/wasmer-go v1.0.4 + ``` + + This makes `wasmer-go` and its packaged native libraries available in your `GOPATH`. + +### Environment variables + +You need to set three environment variables: + +- `WASMER_ROOT`: points to the directory where the Wasmer dynamic library lives. +- `WASMER_LIB_PATH`: used by `wasmer-go` to find the dynamic library. +- `DYLD_LIBRARY_PATH` (macOS) or `LD_LIBRARY_PATH` (Linux): the dynamic loader search path. Prepend `WASMER_ROOT` so the loader finds the library when `viewkit` starts. + +1. Append these lines to your shell's RC file. + + macOS: + + ```shell + echo 'export WASMER_ROOT="$(go env GOPATH)/pkg/mod/github.com/wasmerio/wasmer-go@v1.0.4/wasmer/packaged/lib/darwin-aarch64"' >> ~/.zshrc + echo 'export WASMER_LIB_PATH="$WASMER_ROOT"' >> ~/.zshrc + echo 'export DYLD_LIBRARY_PATH="$WASMER_ROOT:$DYLD_LIBRARY_PATH"' >> ~/.zshrc + ``` + + Linux: + + ```shell + echo 'export WASMER_ROOT="$(go env GOPATH)/pkg/mod/github.com/wasmerio/wasmer-go@v1.0.4/wasmer/packaged/lib/linux-amd64"' >> ~/.zshrc + echo 'export WASMER_LIB_PATH="$WASMER_ROOT"' >> ~/.zshrc + echo 'export LD_LIBRARY_PATH="$WASMER_ROOT:$LD_LIBRARY_PATH"' >> ~/.zshrc + ``` + +1. Reload your shell configuration: + + ```shell + source ~/.zshrc + ``` + +1. Verify the variables are set: + + ```shell + echo "$WASMER_ROOT" + ls "$WASMER_ROOT" + ``` + + ```output + /home/user/go/pkg/mod/github.com/wasmerio/wasmer-go@v1.0.4/wasmer/packaged/lib/linux-amd64 + dummy.go libwasmer.so + ``` + +{% admonition(type="warning") %} +If `libwasmer.dylib` or `libwasmer.so` is missing, re-run the `go get` step and check that `go env GOPATH` returns a valid path. The local `view test` and `view deploy --target local` commands spawn a DefraDB binary that also needs `LD_LIBRARY_PATH` (Linux) or `DYLD_LIBRARY_PATH` (macOS) to be set, so keep these variables set in any shell where you run Viewkit. +{% end %} + +## Create a View + +1. Initialize the View bundle: + + ```shell + viewkit view init testdeploy + ``` + + This creates a new View bundle called `testdeploy` on disk and registers internal metadata for queries, SDL, lenses, and versions. + +1. Add a query defining the raw data shape to ingest. Here it is raw event logs: + + ```shell + viewkit view add query \ + "Log {address topics data transactionHash blockNumber}" \ + --name testdeploy + ``` + + This tells Viewkit that `testdeploy` will ingest `Log` objects with the specified fields. + +1. Add an SDL describing how the data is modeled and exposed: + + ```shell + viewkit view add sdl \ + "type FilteredAndDecodedLogs @materialized(if: false) {transactionHash: String}" \ + --name testdeploy + ``` + + {% admonition(type="note") %} +- `@materialized(if: false)`: treat this as a virtual type, computed at query time rather than stored. +- `transactionHash: String`: a minimal example field; real Views define more fields. + {% end %} + +1. Attach a WebAssembly lens that decodes event logs using an ABI: + + ```shell + viewkit view add lens \ + --args '{"abi":"[{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"type\":\"address\",\"name\":\"from\",\"indexed\":true},{\"type\":\"address\",\"name\":\"to\",\"indexed\":true},{\"type\":\"uint256\",\"name\":\"value\",\"indexed\":false}]}]"}' \ + --label "decode" \ + --url "https://raw.githubusercontent.com/shinzonetwork/wasm-bucket/main/bucket/decode_log/decode_log.wasm" \ + --name testdeploy + ``` + + These are the flags in play: + + - `--args`: JSON passed to the lens. Here it is an ABI definition for a `Transfer` event with `from`, `to`, and `value` fields. + - `--label "decode"`: a human-readable label for the lens. + - `--url`: remote URL of the `.wasm` binary. + - `--name testdeploy`: attaches this lens to the `testdeploy` View. + +1. Inspect the bundle once everything is attached: + + ```shell + viewkit view inspect testdeploy + ``` + + ```output + ๐Ÿ“„ View: testdeploy + ๐Ÿ” Query: + Log {address topics data transactionHash blockNumber} + + ๐Ÿ“ SDL: + type FilteredAndDecodedLogs @materialized(if: false) {transactionHash: String} + + ๐Ÿ”ง Lenses: + - decode (assets/decode.wasm) + Arguments: + abi: [{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","indexed":true},{"type":"address","name":"to","indexed":true},{"type":"uint256","name":"value","indexed":false}]}] + + ๐Ÿ—‚ Metadata: + - Version: 3 + - Total: 3 + - Created At: 2026-09-03 11:35:10 +0000 UTC + - Updated At: 2026-09-03 11:35:28 +0000 UTC + ``` + + Every `view add` command also prints this same summary, so running `inspect` once after all the parts are attached is enough. + +{% admonition(type="tip") %} +If you see `libwasmer.dylib` or "image not found" errors, revisit the Wasmer setup. +{% end %} + +## Test the View + +1. Before deploying, validate that the View builds and compiles successfully: + + ```shell + viewkit view test testdeploy + ``` + + ```output + ๐Ÿ” Loading view... + โš™๏ธ Ensuring DefraDB binary... + ๐Ÿ“ Creating temporary root directory... + ๐Ÿš€ Starting DefraDB... + โณ Waiting for DefraDB to boot... + โœ… DefraDB booted + ๐Ÿ“ฆ Applying schema... + โœ… Schema applied + ๐Ÿ“จ Inserting test data... + โณ Data Inserting... + โœ… Data Inserted Successfully + โœ… Data inserted + ๐Ÿง  Applying view... + โœ… View applied + ๐Ÿ”Ž Extracting collection name... + โ™ป๏ธ Refreshing view... + โœ… View refreshed + โœ… Test flow completed successfully. Shutting down... + โœ… DefraDB stopped. + ``` + + This spins up a temporary local DefraDB instance, applies the schema, runs the lens, and checks that everything compiles. If it passes, the View is ready to deploy. + +## Create a deployment wallet + +Deploying to the network registers the View on chain, so you need a wallet to sign that transaction. + +1. Generate a wallet: + + ```shell + viewkit wallet generate + ``` + + ```output + โœ… Wallet generated + Mnemonic: document grass code lawn erosion climb people sunset three blame balcony story script hip soup lesson resemble above quiz acid dust salmon plane + Address: 0x2e4150993E841b38f4780BC158A7dA0d62E22ec9 + ``` + +1. Treat this wallet like any other secret: + + - Do not commit it to Git. + - Do not paste the mnemonic in public places. + - Store it securely. + +## Fund the wallet + +Registration is an on-chain transaction, so the wallet needs tokens to pay the transaction fee. + +1. Open the [Shinzo faucet](https://faucet.shinzo.network/) in your browser. +1. Paste the address from `viewkit wallet generate` into the input. +1. Click **Get 0.001 $SHN**. + +The faucet shows the transaction hash once the tokens are sent. You only need to do this once per wallet. + +## Deploy locally + +The recommended flow is to deploy locally first, verify the View in the DefraDB Playground, then deploy to the network. + +1. Deploy locally: + + ```shell + viewkit view deploy testdeploy --target local + ``` + + ```output + ๐Ÿš€ DefraDB is running on port 9181 + โณ Waiting for DefraDB to boot up... + โœ… DefraDB booted up + โณ Applying Schemas ... + โœ… Schema Applied + โณ Data Inserting... + โœ… Data Inserted Successfully + โœ… Applying View ... + โœ… View Successfully Applied + ๐Ÿงช Visit the DefraDB GraphQL Playground at http://127.0.0.1:9181/ + ๐Ÿ“ฆ Press Ctrl+C to stop... + ``` + + Here's what happens: + + 1. A local DefraDB instance starts (the port is in the logs). + 1. The schema for the View is applied. + 1. Test data is inserted. + 1. The View is applied. + 1. A DefraDB GraphQL Playground URL is printed. + +### Use the DefraDB GraphQL Playground + +This step is optional, but it is a good way to check the View before deploying it anywhere. + +1. Open the displayed URL in your browser, usually [127.0.0.1:9181](http://127.0.0.1:9181/). +1. You should see a GraphQL Playground where you can: + - Inspect the schema (for example, the `FilteredAndDecodedLogs` type). + - Run test queries against the local View. + - Confirm the lens decodes logs as expected. + + For example: + + ```graphql + { + FilteredAndDecodedLogs { + transactionHash + } + } + ``` + +While this process is running, `viewkit` keeps the local DefraDB instance alive. Press `CTRL` + `c` to stop the DefraDB instance. + +## Deploy to the public testnet + +Once the View behaves correctly locally, deploy it to the public testnet. + +1. Check that the wallet has a balance, and fund it from the [faucet](https://faucet.shinzo.network/) if needed. + +1. Deploy the View to the network: + + ```shell + viewkit view deploy testdeploy --target devnet --rpc http://testnet.shinzo.network:8545/ + ``` + +{% admonition(type="note") %} +The `--target devnet` flag name is historical. In the current Viewkit it is the right target for the public testnet (`--rpc http://testnet.shinzo.network:8545/`). The CLI's `mainnet` target is not supported yet, so `devnet` is the only network target that works. +{% end %} + +The deploy command rebuilds and re-tests the View, sends a `register(bytes)` transaction to the View Registry precompile, and prints the result: + +```output +๐Ÿ”ง Building and testing view before deployment... +โณ View built and tested successfully. Deploying... +โœ… View deployment successful! +---------------------------------------- +๐Ÿ”‘ View ID: FilteredAndDecodedLogs_0x016c19db7f2cf5aa86d34b5779f58de913f92d12ec9ee3642587124ce712c123 +๐Ÿ”‘ View Key: 0x016c19db7f2cf5aa86d34b5779f58de913f92d12ec9ee3642587124ce712c123 +๐Ÿ“ฆ Transaction Hash: 0x7be8a3e99299ed017896ae76fb2811208380a459e36d49a0b4a7ac047747a2df +Wire bytes (tx data):96660 +---------------------------------------- +``` + +Registration completes asynchronously, so give it around 20 seconds before the View shows up on chain. + +## Query your View + +After registration, the View is on chain and any Host that picks it up can serve it. + +1. Confirm your View is registered: + + ```shell + curl "http://testnet.shinzo.network:1317/shinzonetwork/view/v1/views?include_data=false" \ + | jq -r '.views[] | select(.name | contains("FilteredAndDecodedLogs")) | .name, .address' + ``` + + ```output + FilteredAndDecodedLogs + 0xa1226B03c54789e9Bf8876ac956aBbD1bDf5B654 + ``` + +1. Query the View against a public Host: + + ```shell + HOST=$(curl -s "http://testnet.shinzo.network:1317/shinzonetwork/host/v1/hosts" \ + | jq -r '.hosts[0].endpoint_address') + + curl -X POST "$HOST" \ + -H 'Content-Type: application/json' \ + -d '{"query":"{ FilteredAndDecodedLogs(limit: 10) { transactionHash } }"}' + ``` + +Until a Host picks up your View, a query against it returns a schema error: + +```output +{"errors":[{"message":"Cannot query field \"FilteredAndDecodedLogs\" on type \"Query\"."}],"data":null} +``` + +Hosts subscribe to a View and serve it once it has a pool; a brand-new tutorial View usually has none yet. Signed querying is covered in [Query your first View](/build/tutorials/query-your-first-view/), and [Find Views and Hosts](/build/how-to/find-views-and-hosts/) shows how to locate Host endpoints and pools. Browse your View in [Shinzo Studio](https://studio.shinzo.network/) or the [Explorer](https://explorer.shinzo.network/). + +## More examples + +For progressively more complex View examples (decoding multiple event types, transaction-based Views without lenses, materialized versus on-query Views, editing and rolling back Views), see [View recipes](/build/how-to/view-recipes/), which includes both the View definitions and the GraphQL queries you run against them. + +For the conceptual overview, see [Views for builders](/build/explanation/views-for-builders/). For the full command list, filter operators, VWL wire format, and deploy internals, see the [Viewkit reference](/reference/components/viewkit/). For a deeper dive on lenses, available modules, and how to chain them, see the [Lens reference](/reference/components/lens/). For troubleshooting and common errors, see [Operations: Troubleshooting](/run/operations/troubleshooting/). + +## Need help + +{{ need_help(client="Viewkit", repo_name="shinzo-view-creator", repo="https://github.com/shinzonetwork/shinzo-view-creator/issues") }} diff --git a/content/reference/components/lens/index.md b/content/reference/components/lens/index.md index e865b8a..a719d58 100644 --- a/content/reference/components/lens/index.md +++ b/content/reference/components/lens/index.md @@ -204,7 +204,7 @@ This spins up a temporary local DefraDB instance, applies your schema, loads the viewkit view deploy my-view --target local ``` -See the [Quick Start](/build/create-a-view/) for Wasmer runtime setup if you encounter `libwasmer` errors during local testing. +See the [Create your first View](/build/tutorials/create-your-first-view/) tutorial for Wasmer runtime setup if you encounter `libwasmer` errors during local testing. ## Authoring new lenses diff --git a/content/reference/components/viewkit/index.md b/content/reference/components/viewkit/index.md index eeea336..ec90e53 100644 --- a/content/reference/components/viewkit/index.md +++ b/content/reference/components/viewkit/index.md @@ -6,7 +6,7 @@ mermaid = true Viewkit is the local CLI tool for creating, testing, and deploying Shinzo Views. It packages a view into a binary bundle (VWL) and submits a deploy transaction to ShinzoHub. It does not process, store, or serve data. -This page is the technical reference for Viewkit: the full command list, filter operators, the deploy pipeline, the VWL wire format, view ID computation, and the on-disk layout of the source repo. For a hands-on walkthrough of building and deploying your first view, see the [Create a View](/build/create-a-view/) quickstart. For the conceptual overview of what Viewkit is and where it sits in the stack, see [Views for builders](/build/concepts/views-for-builders/). +This page is the technical reference for Viewkit: the full command list, filter operators, the deploy pipeline, the VWL wire format, view ID computation, and the on-disk layout of the source repo. For a hands-on walkthrough of building and deploying your first view, see the [Create your first View](/build/tutorials/create-your-first-view/) tutorial. For the conceptual overview of what Viewkit is and where it sits in the stack, see [Views for builders](/build/concepts/views-for-builders/). ## Command reference diff --git a/content/run/operations/troubleshooting/index.md b/content/run/operations/troubleshooting/index.md index 5acc828..cef3a9f 100644 --- a/content/run/operations/troubleshooting/index.md +++ b/content/run/operations/troubleshooting/index.md @@ -208,7 +208,7 @@ A healthy Host returns `healthy`. A connection refused or timeout means `8080` s Viewkit uses the Wasmer runtime to execute WASM lenses locally. If the native library can't be found, any command that touches lenses will fail. -Fix: set the `WASMER_ROOT`, `WASMER_LIB_PATH`, and `DYLD_LIBRARY_PATH` (macOS) or `LD_LIBRARY_PATH` (Linux) environment variables. See [Create a View](/build/create-a-view/#wasmer-runtime) for full instructions. +Fix: set the `WASMER_ROOT`, `WASMER_LIB_PATH`, and `DYLD_LIBRARY_PATH` (macOS) or `LD_LIBRARY_PATH` (Linux) environment variables. See [Create your first View](/build/tutorials/create-your-first-view/#wasmer-runtime) for full instructions. Quick check: diff --git a/content/run/run-a-host/install/index.md b/content/run/run-a-host/install/index.md index a35684a..2cf438b 100644 --- a/content/run/run-a-host/install/index.md +++ b/content/run/run-a-host/install/index.md @@ -6,7 +6,7 @@ aliases = ["/hosts/install"] A Host client pulls primitive blockchain data from Generator clients, runs Lens WASM transforms, and serves the resulting Views to subscriber nodes over an embedded DefraDB instance. This page is for operators who want to **run** a Host client. {% admonition(type="info") %} -**Only want to query Shinzo data?** You don't need to run your own Host client. Connect to a public Host client instead. See [Querying Views](/build/create-a-view/). Running your own Host client is for serving data to the network, not for reading it. +**Only want to query Shinzo data?** You don't need to run your own Host client. Connect to a public Host client instead. See [Query your first View](/build/tutorials/query-your-first-view/). Running your own Host client is for serving data to the network, not for reading it. {% end %} ## Prerequisites @@ -95,7 +95,7 @@ Pull the image and start it with a single `docker run`. You supply two values: a docker logs shinzo-host | grep -i peer ``` - A healthy connection adds the Generator client's peer and keeps it. You should not see that peer stuck in a loop of `dial backoff` / `all dials failed`. Once it's syncing, query real data from the Playground or the API. A public Generator client to point at is coming; this page will link a known-good endpoint and a ready-to-run query once it's live. See [query examples](/build/create-a-view/). + A healthy connection adds the Generator client's peer and keeps it. You should not see that peer stuck in a loop of `dial backoff` / `all dials failed`. Once it's syncing, query real data from the Playground or the API. A public Generator client to point at is coming; this page will link a known-good endpoint and a ready-to-run query once it's live. See [query examples](/build/how-to/query-data/). 1. To serve data to the network, register your Host client with ShinzoHub. See [Register a Host](/run/run-a-host/register/). diff --git a/content/understand/core-concepts/pools/index.md b/content/understand/core-concepts/pools/index.md index d80d7b3..3f71673 100644 --- a/content/understand/core-concepts/pools/index.md +++ b/content/understand/core-concepts/pools/index.md @@ -33,7 +33,7 @@ A pool closes that gap. Registering demand for a View, and backing it with a bon A pool is created the first time someone registers demand for a View through the Pool Registry on ShinzoHub. The demand carries a bond in ushinzo (SHNZ's base unit), which has to be more than zero and is escrowed as a sign of real intent. If no pool exists yet for that View, one is created; later demand for the same View joins the existing pool rather than making a new one. -A pool is identified by two things: the View it serves, and a small config. Today that config is a single field, the pool's `windowSize`. Changing it produces a different pool, so one View can have several pools under different configs. The View has to be registered first; you can't register demand against a View that doesn't exist yet. See [Create a View](/build/create-a-view/) for how to get that far. +A pool is identified by two things: the View it serves, and a small config. Today that config is a single field, the pool's `windowSize`. Changing it produces a different pool, so one View can have several pools under different configs. The View has to be registered first; you can't register demand against a View that doesn't exist yet. See [Create your first View](/build/tutorials/create-your-first-view/) for how to get that far. ## Two faces of a pool diff --git a/static/_redirects b/static/_redirects index aee9ed1..6608272 100644 --- a/static/_redirects +++ b/static/_redirects @@ -1,6 +1,6 @@ # Legacy path redirects to the current information architecture. Paths handled by Zola aliases on content pages (/, /introduction, /understand) are not duplicated here. -/guides /build/create-a-view/ +/guides /build/tutorials/create-your-first-view/ /host /run/run-a-host/ /host/* /run/run-a-host/:splat /hosts /run/run-a-host/ @@ -11,9 +11,9 @@ /indexer/* /run/run-a-generator/:splat /indexers /run/run-a-generator/ /indexers/* /run/run-a-generator/:splat -/views /build/create-a-view/ -/view-creator /build/create-a-view/ -/view-creator/* /build/create-a-view/:splat +/views /build/tutorials/create-your-first-view/ +/view-creator /build/tutorials/create-your-first-view/ +/view-creator/* /build/tutorials/create-your-first-view/ /reference /reference/architecture/ /reference/components /reference/components/ @@ -42,5 +42,5 @@ /docs/indexer/quickstart/* /run/get-started/ 301 /docs/view-creator/overview /build/concepts/views-for-builders/ 301 /docs/view-creator/overview/* /build/concepts/views-for-builders/ 301 -/docs/view-creator/quickstart /build/create-a-view/ 301 -/docs/view-creator/quickstart/* /build/create-a-view/ 301 +/docs/view-creator/quickstart /build/tutorials/create-your-first-view/ 301 +/docs/view-creator/quickstart/* /build/tutorials/create-your-first-view/ 301 diff --git a/templates/macros/footer.html b/templates/macros/footer.html index f5caadf..6736443 100644 --- a/templates/macros/footer.html +++ b/templates/macros/footer.html @@ -16,7 +16,7 @@