Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Add project setup information and docs site #4

Merged
merged 6 commits into from
Dec 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@

This project provides bindings to the [NEAR](https://near.org) SDK in order to enable easy writing of NEAR smart contracts in Grain.

## Generating the Documentation
You can find information on how to use this SDK at https://grain-lang.github.io/near-sdk-gr/.

## Developing

### Generating the Documentation

```bash
$ grain doc src -o docs --current-version=0.0.0
$ grain doc near -o docs/near --current-version=0.0.0
```

# Building the Tests
### Building the Tests

Due to an [NPM Bug](https://github.com/npm/cli/issues/4774), this project requires `[email protected]` to build.

Expand Down
119 changes: 119 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# NEAR Smart Contract SDK for Grain

This project allows you to author smart contracts on the NEAR blockchain using the Grain programming language.

## SDK documentation

View the individual pages for each SDK library:

- [Context](./near/context)
- [Economics](./near/economics)
- [Math](./near/math)
- [Promise](./near/promise)
- [Register](./near/register)
- [Storage](./near/storage)
- [Utils](./near/utils)
- [Validator](./near/validator)

## Prerequsites

You'll need a v0.5.x version of the Grain compiler on your machine and general knowledge of the language. For more information about the language and how to install it, visit [grain-lang.org](https://grain-lang.org).

## Setting up your project

Create a directory for your project. For this example, we'll call it `example-contract`.

```sh
mkdir example-contract && cd example-contract
git init
```

Next, add `near-sdk-gr` to your project.

```sh
git submodule add https://github.com/grain-lang/near-sdk-gr.git
```

## Writing your first contract

We'll create a simple counter. Create a file called `counter.gr` with the following contents:

```grain
import Option from "option"
import Storage from "near/storage"
let key = "counter"
export let setCounter = val => {
// Write the value to memory.
Storage.setInt32(key, val)
}
export let loadCounter = () => {
// Check if key is in storage
if (!(Storage.hasKey(key))) {
// Initialize to zero.
setCounter(0l)
}
Option.expect("key should be set", Storage.getInt32(key))
}
```

`Option` is Grain's standard library for working with the `Option` type and `Storage` is the SDK for working with storage on the blockchain.

`key` is the name we'll use for the key-value pair in storage—in our case, it's called `"counter"`.

The `setCounter` function stores a counter value and `loadCounter` retrieves a counter value.

Next, we'll create the core of our contract in a file called `index.gr`:

```grain
import { add as (+), sub as (-) } from "int32"
import Utils from "near/utils"
import { setCounter, loadCounter } from "./counter"
export let increment = () => {
setCounter(loadCounter() + 1l)
}
export let decrement = () => {
setCounter(loadCounter() - 1l)
}
export let getCounter = () => {
let value = toString(loadCounter())
Utils.valueReturnString(value)
}
```

This is the interface of our contract. Our contract has two methods to change the contract state, `increment` and `decrement`, and one method to view the state of the contract, `getCounter`.
`getCounter` utilizes `Utils.valueReturnString` to return the counter value as a string back to the caller.

## Compiling the contract

There are a number of flags we'll need to pass to the compiler.

- `-I near-sdk-gr` to tell the compiler where the SDK is;
- `--wasi-polyfill near-sdk-gr/wasi.gr` to stub out WASI functionality;
- `--no-bulk-memory` to disable bulk memory operations until NEAR supports them;
- `--use-start-section` to ensure the NEAR blockchain loads all contract setup;
- `--no-gc` to save on gas and storage fees;
- `--elide-type-info` to save a bit more on storage fees;
- `--release` to ensure we have the smallest and most efficient contract to deploy

All together, that's

```sh
grain compile -I near-sdk-gr --wasi-polyfill near-sdk-gr/wasi.gr --no-bulk-memory --use-start-section --no-gc --elide-type-info --release index.gr
```

This can be made into a script to make compiling the contract easier.

## Testing the contract

Contracts can be tested before deploying them using `near-workspaces`. For an example, see [the counter contract tests](https://github.com/grain-lang/near-sdk-gr/blob/4eaeeb90a91e700a7a64fd83cad97946e19d99d3/test-suite/example-contracts/counter/tests/counter.test.js).

## Configuring VSCode

If you use VSCode to develop your contract, you can tell the language server where the NEAR SDK is by setting the `grain.cliFlags` setting for your workspace to include `-I near-sdk-gr`. To prevent recompilation of all of the wasm modules in the tree, configure the full set of flags, `-I near-sdk-gr --wasi-polyfill near-sdk-gr/wasi.gr --no-bulk-memory --use-start-section --no-gc --elide-type-info --release`.
Loading