diff --git a/.gitbook/assets/Untitled Diagram-Page-1.png b/.gitbook/assets/Untitled Diagram-Page-1.png
new file mode 100644
index 0000000..b56f2c9
Binary files /dev/null and b/.gitbook/assets/Untitled Diagram-Page-1.png differ
diff --git a/.gitbook/assets/Untitled Diagram-preaudit.png b/.gitbook/assets/Untitled Diagram-preaudit.png
new file mode 100644
index 0000000..34d6011
Binary files /dev/null and b/.gitbook/assets/Untitled Diagram-preaudit.png differ
diff --git a/.gitbook/assets/image (1).png b/.gitbook/assets/image (1).png
new file mode 100644
index 0000000..38f3f64
Binary files /dev/null and b/.gitbook/assets/image (1).png differ
diff --git a/.gitbook/assets/image.png b/.gitbook/assets/image.png
index 38f3f64..6d72050 100644
Binary files a/.gitbook/assets/image.png and b/.gitbook/assets/image.png differ
diff --git a/SUMMARY.md b/SUMMARY.md
index 50d4da2..2f58692 100644
--- a/SUMMARY.md
+++ b/SUMMARY.md
@@ -17,6 +17,7 @@
* [Strategies](strategies/README.md)
* [What is a strategy?](strategies/what-is-a-strategy.md)
* [Create a new strategy](strategies/create.md)
+ * [How to write a basic strategy](strategies/how-to-write-a-basic-strategy.md)
* [Plugins](plugins/README.md)
* [Create a plugin](plugins/create.md)
* [SafeSnap](plugins/safesnap.md)
@@ -34,4 +35,3 @@
* [Contribute](guides/contribute/README.md)
* [🙋♂️ Support](guides/contribute/support.md)
* [Delegation](guides/delegation.md)
-
diff --git a/graphql-api.md b/graphql-api.md
index ae59329..9ca621b 100644
--- a/graphql-api.md
+++ b/graphql-api.md
@@ -8,31 +8,31 @@ description: >-
## Explorer
-You can run queries on Snapshot data using a GraphQL Explorer.
+You can run queries on Snapshot data using a GraphQL Explorer.
-We have exposed an integrated development environment in the browser that includes docs, syntax highlighting, and validation errors. Click the link below to access the interface.
+We have exposed an integrated development environment in the browser that includes docs, syntax highlighting, and validation errors. Click the link below to access the interface.
{% embed url="https://hub.snapshot.org/graphql" %}
-![](.gitbook/assets/image.png)
+![](<.gitbook/assets/image (1).png>)
## Endpoints
Production hub
-```text
+```
https://hub.snapshot.org/graphql
```
Demo hub
-```text
+```
https://testnet.snapshot.org/graphql
```
## Queries
-### Get a single space
+### Get a single space
#### Arguments
@@ -82,16 +82,16 @@ query {
Try on [GraphiQL](https://hub.snapshot.org/graphql?query=query%20%7B%0A%20%20space%28id%3A%20%22yam.eth%22%29%20%7B%0A%20%20%20%20id%0A%20%20%20%20name%0A%20%20%20%20about%0A%20%20%20%20network%0A%20%20%20%20symbol%0A%20%20%20%20members%0A%20%20%7D%0A%7D)
-### Get multiple spaces
+### Get multiple spaces
#### Arguments
-first `number`
-skip `number`
-where:
- - id`string`
- - id\_in`array`
-orderBy `string`
+first `number`\
+skip `number`\
+where:\
+\- id`string`\
+\- id\_in`array`\
+orderBy `string`\
orderDirection `asc` or `desc`
#### Example
@@ -172,9 +172,9 @@ query {
Try on [GraphiQL](https://hub.snapshot.org/graphql?query=%0Aquery%20Spaces%20%7B%0A%20%20spaces%28%0A%20%20%20%20first%3A%2020%2C%0A%20%20%20%20skip%3A%200%2C%0A%20%20%20%20orderBy%3A%20%22created%22%2C%0A%20%20%20%20orderDirection%3A%20asc%0A%20%20%29%20%7B%0A%20%20%20%20id%0A%20%20%20%20name%0A%20%20%20%20about%0A%20%20%20%20network%0A%20%20%20%20symbol%0A%20%20%20%20strategies%20%7B%0A%20%20%20%20%20%20name%0A%20%20%20%20%20%20params%0A%20%20%20%20%7D%0A%20%20%20%20admins%0A%20%20%20%20members%0A%20%20%20%20filters%20%7B%0A%20%20%20%20%20%20minScore%0A%20%20%20%20%20%20onlyMembers%0A%20%20%20%20%7D%0A%20%20%20%20plugins%0A%20%20%7D%0A%7D)
-### Get a single proposal
+### Get a single proposal
-#### Arguments
+#### Arguments
id `string`
@@ -239,25 +239,25 @@ query {
{% endtab %}
{% endtabs %}
-Try on [GraphiQL](https://hub.snapshot.org/graphql?operationName=Proposal&query=query%20Proposal%20%7B%0A%20%20proposal%28id%3A%22QmWbpCtwdLzxuLKnMW4Vv4MPFd2pdPX71YBKPasfZxqLUS%22%29%20%7B%0A%20%20%20%20id%0A%20%20%20%20title%0A%20%20%20%20body%0A%20%20%20%20choices%0A%20%20%20%20start%0A%20%20%20%20end%0A%20%20%20%20snapshot%0A%20%20%20%20state%0A%20%20%20%20author%0A%20%20%20%20space%20%7B%0A%20%20%20%20%20%20id%0A%20%20%20%20%20%20name%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D)
+Try on [GraphiQL](https://hub.snapshot.org/graphql?operationName=Proposal\&query=query%20Proposal%20%7B%0A%20%20proposal%28id%3A%22QmWbpCtwdLzxuLKnMW4Vv4MPFd2pdPX71YBKPasfZxqLUS%22%29%20%7B%0A%20%20%20%20id%0A%20%20%20%20title%0A%20%20%20%20body%0A%20%20%20%20choices%0A%20%20%20%20start%0A%20%20%20%20end%0A%20%20%20%20snapshot%0A%20%20%20%20state%0A%20%20%20%20author%0A%20%20%20%20space%20%7B%0A%20%20%20%20%20%20id%0A%20%20%20%20%20%20name%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D)
-### Get proposals
+### Get proposals
#### Arguments
-first `number`
-skip `number`
-where:
- - id`string`
- - id\_in`array`
- - space:`string`
- - space\_in:`array`
- - author:`string`
- - author\_in:`array`
- - network: `string`
- - network\_in: `array`
- - state: `array`
-orderBy `string`
+first `number`\
+skip `number`\
+where:\
+\- id`string`\
+\- id\_in`array`\
+\- space:`string`\
+\- space\_in:`array`\
+\- author:`string`\
+\- author\_in:`array`\
+\- network: `string`\
+\- network\_in: `array`\
+\- state: `array`\
+orderBy `string`\
orderDirection `asc` or `desc`
#### Example
@@ -326,11 +326,11 @@ query {
{% endtab %}
{% endtabs %}
-Try on [GraphiQL](https://hub.snapshot.org/graphql?operationName=Proposals&query=query%20Proposals%20%7B%0A%20%20proposals%20%28%0A%20%20%20%20first%3A%2020%2C%0A%20%20%20%20skip%3A%200%2C%0A%20%20%20%20where%3A%20%7B%0A%20%20%20%20%20%20space_in%3A%20%5B%22yam.eth%22%5D%2C%0A%20%20%20%20%20%20state%3A%20%22closed%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20orderBy%3A%20%22created%22%2C%0A%20%20%20%20orderDirection%3A%20desc%0A%20%20%29%20%7B%0A%20%20%20%20id%0A%20%20%20%20title%0A%20%20%20%20body%0A%20%20%20%20choices%0A%20%20%20%20start%0A%20%20%20%20end%0A%20%20%20%20snapshot%0A%20%20%20%20state%0A%20%20%20%20author%0A%20%20%20%20space%20%7B%0A%20%20%20%20%20%20id%0A%20%20%20%20%20%20name%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D)
+Try on [GraphiQL](https://hub.snapshot.org/graphql?operationName=Proposals\&query=query%20Proposals%20%7B%0A%20%20proposals%20%28%0A%20%20%20%20first%3A%2020%2C%0A%20%20%20%20skip%3A%200%2C%0A%20%20%20%20where%3A%20%7B%0A%20%20%20%20%20%20space\_in%3A%20%5B%22yam.eth%22%5D%2C%0A%20%20%20%20%20%20state%3A%20%22closed%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20orderBy%3A%20%22created%22%2C%0A%20%20%20%20orderDirection%3A%20desc%0A%20%20%29%20%7B%0A%20%20%20%20id%0A%20%20%20%20title%0A%20%20%20%20body%0A%20%20%20%20choices%0A%20%20%20%20start%0A%20%20%20%20end%0A%20%20%20%20snapshot%0A%20%20%20%20state%0A%20%20%20%20author%0A%20%20%20%20space%20%7B%0A%20%20%20%20%20%20id%0A%20%20%20%20%20%20name%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D)
-### Get a single vote
+### Get a single vote
-#### Arguments
+#### Arguments
id `string`
@@ -376,24 +376,24 @@ query {
{% endtab %}
{% endtabs %}
-Try on [GraphiQL](https://hub.snapshot.org/graphql?operationName=Vote&query=query%20Vote%20%7B%0A%20%20vote%20%28%0A%20%20%20%20id%3A%20%22QmeU7ct9Y4KLrh6F6mbT1eJNMkeQKMSnSujEfMCfbRLCMp%22%0A%20%20%29%20%7B%0A%20%20%20%20id%0A%20%20%20%20voter%0A%20%20%20%20created%0A%20%20%20%20proposal%0A%20%20%20%20choice%0A%20%20%20%20space%20%7B%0A%20%20%20%20%20%20id%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D)
+Try on [GraphiQL](https://hub.snapshot.org/graphql?operationName=Vote\&query=query%20Vote%20%7B%0A%20%20vote%20%28%0A%20%20%20%20id%3A%20%22QmeU7ct9Y4KLrh6F6mbT1eJNMkeQKMSnSujEfMCfbRLCMp%22%0A%20%20%29%20%7B%0A%20%20%20%20id%0A%20%20%20%20voter%0A%20%20%20%20created%0A%20%20%20%20proposal%0A%20%20%20%20choice%0A%20%20%20%20space%20%7B%0A%20%20%20%20%20%20id%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D)
-### Get votes
+### Get votes
#### Arguments
-first `number`
-skip `number`
-where:
- - id`string`
- - id\_in`array`
- - space:`string`
- - space\_in:`array`
- - voter:`string`
- - voter\_in:`array`
- - proposal: `string`
- - proposal\_in: `array`
-orderBy `string`
+first `number`\
+skip `number`\
+where:\
+\- id`string`\
+\- id\_in`array`\
+\- space:`string`\
+\- space\_in:`array`\
+\- voter:`string`\
+\- voter\_in:`array`\
+\- proposal: `string`\
+\- proposal\_in: `array`\
+orderBy `string`\
orderDirection `asc` or `desc`
#### Example
@@ -457,22 +457,22 @@ query {
{% endtab %}
{% endtabs %}
-Try on [GraphiQL](https://hub.snapshot.org/graphql?operationName=Votes&query=query%20Votes%20%7B%0A%20%20votes%20%28%0A%20%20%20%20first%3A%201000%0A%20%20%20%20skip%3A%200%0A%20%20%20%20where%3A%20%7B%0A%20%20%20%20%20%20proposal%3A%20%22QmPvbwguLfcVryzBRrbY4Pb9bCtxURagdv1XjhtFLf3wHj%22%0A%20%20%20%20%7D%0A%20%20%20%20orderBy%3A%20%22created%22%2C%0A%20%20%20%20orderDirection%3A%20desc%0A%20%20%29%20%7B%0A%20%20%20%20id%0A%20%20%20%20voter%0A%20%20%20%20created%0A%20%20%20%20proposal%0A%20%20%20%20choice%0A%20%20%20%20space%20%7B%0A%20%20%20%20%20%20id%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A)
+Try on [GraphiQL](https://hub.snapshot.org/graphql?operationName=Votes\&query=query%20Votes%20%7B%0A%20%20votes%20%28%0A%20%20%20%20first%3A%201000%0A%20%20%20%20skip%3A%200%0A%20%20%20%20where%3A%20%7B%0A%20%20%20%20%20%20proposal%3A%20%22QmPvbwguLfcVryzBRrbY4Pb9bCtxURagdv1XjhtFLf3wHj%22%0A%20%20%20%20%7D%0A%20%20%20%20orderBy%3A%20%22created%22%2C%0A%20%20%20%20orderDirection%3A%20desc%0A%20%20%29%20%7B%0A%20%20%20%20id%0A%20%20%20%20voter%0A%20%20%20%20created%0A%20%20%20%20proposal%0A%20%20%20%20choice%0A%20%20%20%20space%20%7B%0A%20%20%20%20%20%20id%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A)
-### Get follows
+### Get follows
#### Arguments
-first `number`
-skip `number`
-where:
- - id`string`
- - id\_in`array`
- - space:`string`
- - space\_in:`array`
- - follower:`string`
- - follower\_in:`array`
-orderBy `string`
+first `number`\
+skip `number`\
+where:\
+\- id`string`\
+\- id\_in`array`\
+\- space:`string`\
+\- space\_in:`array`\
+\- follower:`string`\
+\- follower\_in:`array`\
+orderBy `string`\
orderDirection `asc` or `desc`
#### Example
@@ -542,4 +542,3 @@ Try on [GraphiQL](https://hub.snapshot.org/graphql?query=query%20%7B%0A%20%20fol
### Aliases
TBD
-
diff --git a/strategies/create.md b/strategies/create.md
index fb831ac..5aba8bf 100644
--- a/strategies/create.md
+++ b/strategies/create.md
@@ -24,6 +24,8 @@ To add your own strategy on Snapshot you need to fork the **snapshot-strategies*
npm run test --strategy= // replace
```
+See [How to write a basic strategy](how-to-write-a-basic-strategy.md)
+
### 4. Make sure you pass the checklist
Have a look here on the requirements for adding a new strategy and make sure you full fill the points in the checklist: [https://github.com/snapshot-labs/snapshot.js/issues/212](https://github.com/snapshot-labs/snapshot.js/issues/212)
@@ -31,4 +33,3 @@ Have a look here on the requirements for adding a new strategy and make sure you
### 5. Create a pull request
The team will then review your PR and after it's approved and merged it will be available in your space settings.
-
diff --git a/strategies/how-to-write-a-basic-strategy.md b/strategies/how-to-write-a-basic-strategy.md
new file mode 100644
index 0000000..f84c5c4
--- /dev/null
+++ b/strategies/how-to-write-a-basic-strategy.md
@@ -0,0 +1,68 @@
+---
+description: Main components of a basic strategy
+---
+
+# How to write a basic strategy
+
+Every strategy is, at its core, the implementation of the `strategy(space, network, provider, addresses, options, snapshot)` function.
+
+A quick word on the function parameters:
+
+* `space`: the space (if applicable), based on the registered ENS associated with this strategy (see [Spaces](../spaces/))
+* `network`: the network id as an integer (1 for Ethereum)
+* `provider`: the network provider used by the web browser
+* `addresses`: the list of addresses of the voters being processed.
+* `options`: a collection of options that can be passed to strategy(...) - those have no default keys and can be used to pass any useful data
+* `snapshots`: the block height at which the data are queried by strategy(...) - if none is passed, 'latest' is used.
+
+`Strategy(...)` returns a javascript object with every addresses from the addresses array as keys and the corresponding voting power as value (expressed in number of token owned by the address for `erc20-balance-of`, as a number of rocks owned for `has-rock`, etc).
+
+Every strategy comes with a JSON file `examples.json`. This file is mandatory as it will be used for testing and validating the strategy before including it in Snapshot main GitHub branch. Here are the main keys:
+
+* `"name"`: a human-reading name for the strategy ("ERC20 balance" for instance).
+* `"strategy"`: the core parameters of the strategy
+ * `"name"`: the strategy name ("erc20-balance-of")
+ * `"params"`: optional parameters passed in `options` to strategy(...). Any useful "key":"value" can be used here and retrieved inside `strategy(...)` via `options.key`
+ * `"address"`: the address of the token contract (the DAI contract for instance)
+ * `"symbol"`: the token symbol ("DAI")
+ * `"decimals"`: the number of decimals (18)
+ * `"network"`: the network id (1 for ethereum)
+ * `"addresses"`: an array of addresses which will be used for testing (they should therefore have some token)
+ * `"snapshot"`: the block height (by taking a block height in the past where the addresses\[] had a positive balance, the test will be easily repeated)
+
+Finally, all strategies will contain some similar steps, illustrated in [erc20-balance-of](https://github.com/snapshot-labs/snapshot-strategies/blob/f41f98249cff78486914473a3fef29ea960971e5/src/strategies/erc20-balance-of/index.ts):
+
+* Getting the block height ('latest' or a specific one via the `snapshot` argument).
+
+```
+ const blockTag = typeof snapshot === 'number' ? snapshot : 'latest';
+```
+
+* Initializing Multicaller: looping over the addresses\[] array is **not allowed** as the strategy complexity would increase with the array size. Instead, Snapshot provides the Multicaller utility to group blockchain queries for a series of addresses. The abi can be in ethers human-readable form ( `['function balanceOf(address account) external view returns (uint256)']` for instance)
+
+```
+ const multi = new Multicaller(network, provider, abi, { blockTag });
+```
+
+* Feeding data into the multicaller and executing the multicall: every query is queued in the multicaller via `Multicaller.call(...)`. Once they are all stored, an unique call is executed via `Multicall.execute()`.
+
+ `option.address` is the token contract address (`strategy.params.address` in `examples.json`).
+
+```
+ addresses.forEach((address) =>
+ multi.call(address, options.address, 'balanceOf', [address])
+ );
+
+ const result: Record = await multi.execute();
+```
+
+* Creating an object where every address from addresses\[] is paired with its corresponding value (returned from the multicall) and returning it
+
+```
+ return Object.fromEntries(
+ Object.entries(result).map(([address, balance]) => [
+ address,
+ parseFloat(formatUnits(balance, options.decimals))
+ ])
+ );
+```