Skip to content

Commit f64e08b

Browse files
simon-somethinggitbook-bot
authored andcommitted
GitBook: [snapshot-labs#7] WIP: how to write a basic strategy
1 parent 102b6e9 commit f64e08b

File tree

8 files changed

+130
-62
lines changed

8 files changed

+130
-62
lines changed
46.3 KB
Loading
51 KB
Loading

.gitbook/assets/image (1).png

197 KB
Loading

.gitbook/assets/image.png

-147 KB
Loading

SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* [Strategies](strategies/README.md)
1818
* [What is a strategy?](strategies/what-is-a-strategy.md)
1919
* [Create a new strategy](strategies/create.md)
20+
* [How to write a basic strategy](strategies/how-to-write-a-basic-strategy.md)
2021
* [Plugins](plugins/README.md)
2122
* [Create a plugin](plugins/create.md)
2223
* [SafeSnap](plugins/safesnap.md)
@@ -34,4 +35,3 @@
3435
* [Contribute](guides/contribute/README.md)
3536
* [🙋‍♂️ Support](guides/contribute/support.md)
3637
* [Delegation](guides/delegation.md)
37-

graphql-api.md

Lines changed: 59 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,31 @@ description: >-
88

99
## Explorer
1010

11-
You can run queries on Snapshot data using a GraphQL Explorer.
11+
You can run queries on Snapshot data using a GraphQL Explorer.
1212

13-
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.
13+
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.
1414

1515
{% embed url="https://hub.snapshot.org/graphql" %}
1616

17-
![](.gitbook/assets/image.png)
17+
![](<.gitbook/assets/image (1).png>)
1818

1919
## Endpoints
2020

2121
Production hub
2222

23-
```text
23+
```
2424
https://hub.snapshot.org/graphql
2525
```
2626

2727
Demo hub
2828

29-
```text
29+
```
3030
https://testnet.snapshot.org/graphql
3131
```
3232

3333
## Queries
3434

35-
### Get a single space <a id="space"></a>
35+
### Get a single space <a href="#space" id="space"></a>
3636

3737
#### Arguments
3838

@@ -82,16 +82,16 @@ query {
8282

8383
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)
8484

85-
### Get multiple spaces <a id="spaces"></a>
85+
### Get multiple spaces <a href="#spaces" id="spaces"></a>
8686

8787
#### Arguments
8888

89-
first `number`
90-
skip `number`
91-
where:
92-
- id`string`
93-
- id\_in`array`
94-
orderBy `string`
89+
first `number`\
90+
skip `number`\
91+
where:\
92+
\- id`string`\
93+
\- id\_in`array`\
94+
orderBy `string`\
9595
orderDirection `asc` or `desc`
9696

9797
#### Example
@@ -172,9 +172,9 @@ query {
172172

173173
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)
174174

175-
### Get a single proposal <a id="proposal"></a>
175+
### Get a single proposal <a href="#proposal" id="proposal"></a>
176176

177-
#### Arguments <a id="arguments"></a>
177+
#### Arguments <a href="#arguments" id="arguments"></a>
178178

179179
id `string`
180180

@@ -239,25 +239,25 @@ query {
239239
{% endtab %}
240240
{% endtabs %}
241241

242-
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)
242+
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)
243243

244-
### Get proposals <a id="proposals"></a>
244+
### Get proposals <a href="#proposals" id="proposals"></a>
245245

246246
#### Arguments
247247

248-
first `number`
249-
skip `number`
250-
where:
251-
- id`string`
252-
- id\_in`array`
253-
- space:`string`
254-
- space\_in:`array`
255-
- author:`string`
256-
- author\_in:`array`
257-
- network: `string`
258-
- network\_in: `array`
259-
- state: `array`
260-
orderBy `string`
248+
first `number`\
249+
skip `number`\
250+
where:\
251+
\- id`string`\
252+
\- id\_in`array`\
253+
\- space:`string`\
254+
\- space\_in:`array`\
255+
\- author:`string`\
256+
\- author\_in:`array`\
257+
\- network: `string`\
258+
\- network\_in: `array`\
259+
\- state: `array`\
260+
orderBy `string`\
261261
orderDirection `asc` or `desc`
262262

263263
#### Example
@@ -326,11 +326,11 @@ query {
326326
{% endtab %}
327327
{% endtabs %}
328328

329-
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)
329+
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)
330330

331-
### Get a single vote <a id="vote"></a>
331+
### Get a single vote <a href="#vote" id="vote"></a>
332332

333-
#### Arguments <a id="arguments"></a>
333+
#### Arguments <a href="#arguments" id="arguments"></a>
334334

335335
id `string`
336336

@@ -376,24 +376,24 @@ query {
376376
{% endtab %}
377377
{% endtabs %}
378378

379-
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)
379+
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)
380380

381-
### Get votes <a id="votes"></a>
381+
### Get votes <a href="#votes" id="votes"></a>
382382

383383
#### Arguments
384384

385-
first `number`
386-
skip `number`
387-
where:
388-
- id`string`
389-
- id\_in`array`
390-
- space:`string`
391-
- space\_in:`array`
392-
- voter:`string`
393-
- voter\_in:`array`
394-
- proposal: `string`
395-
- proposal\_in: `array`
396-
orderBy `string`
385+
first `number`\
386+
skip `number`\
387+
where:\
388+
\- id`string`\
389+
\- id\_in`array`\
390+
\- space:`string`\
391+
\- space\_in:`array`\
392+
\- voter:`string`\
393+
\- voter\_in:`array`\
394+
\- proposal: `string`\
395+
\- proposal\_in: `array`\
396+
orderBy `string`\
397397
orderDirection `asc` or `desc`
398398

399399
#### Example
@@ -457,22 +457,22 @@ query {
457457
{% endtab %}
458458
{% endtabs %}
459459

460-
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)
460+
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)
461461

462-
### Get follows <a id="follows"></a>
462+
### Get follows <a href="#follows" id="follows"></a>
463463

464464
#### Arguments
465465

466-
first `number`
467-
skip `number`
468-
where:
469-
- id`string`
470-
- id\_in`array`
471-
- space:`string`
472-
- space\_in:`array`
473-
- follower:`string`
474-
- follower\_in:`array`
475-
orderBy `string`
466+
first `number`\
467+
skip `number`\
468+
where:\
469+
\- id`string`\
470+
\- id\_in`array`\
471+
\- space:`string`\
472+
\- space\_in:`array`\
473+
\- follower:`string`\
474+
\- follower\_in:`array`\
475+
orderBy `string`\
476476
orderDirection `asc` or `desc`
477477

478478
#### Example
@@ -542,4 +542,3 @@ Try on [GraphiQL](https://hub.snapshot.org/graphql?query=query%20%7B%0A%20%20fol
542542
### Aliases
543543

544544
TBD
545-

strategies/create.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@ To add your own strategy on Snapshot you need to fork the **snapshot-strategies*
2424
npm run test --strategy=<STRATEGY NAME> // replace <STRATEGY NAME>
2525
```
2626

27+
See [How to write a basic strategy](how-to-write-a-basic-strategy.md)
28+
2729
### 4. Make sure you pass the checklist
2830

2931
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)
3032

3133
### 5. Create a pull request
3234

3335
The team will then review your PR and after it's approved and merged it will be available in your space settings.
34-
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
description: Main components of a basic strategy
3+
---
4+
5+
# How to write a basic strategy
6+
7+
Every strategy is, at its core, the implementation of the `strategy(space, network, provider, addresses, options, snapshot)` function.
8+
9+
A quick word on the function parameters:
10+
11+
* `space`: the space (if applicable), based on the registered ENS associated with this strategy (see [Spaces](../spaces/))
12+
* `network`: the network id as an integer (1 for Ethereum)
13+
* `provider`: the network provider used by the web browser
14+
* `addresses`: the list of addresses of the voters being processed.
15+
* `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
16+
* `snapshots`: the block height at which the data are queried by strategy(...) - if none is passed, 'latest' is used.&#x20;
17+
18+
`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).
19+
20+
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:
21+
22+
* `"name"`: a human-reading name for the strategy ("ERC20 balance" for instance).
23+
* `"strategy"`: the core parameters of the strategy
24+
* `"name"`: the strategy name ("erc20-balance-of")
25+
* `"params"`: optional parameters passed in `options` to strategy(...). Any useful "key":"value" can be used here and retrieved inside `strategy(...)` via `options.key`
26+
* `"address"`: the address of the token contract (the DAI contract for instance)
27+
* `"symbol"`: the token symbol ("DAI")
28+
* `"decimals"`: the number of decimals (18)
29+
* `"network"`: the network id (1 for ethereum)
30+
* `"addresses"`: an array of addresses which will be used for testing (they should therefore have some token)
31+
* `"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)
32+
33+
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):
34+
35+
* Getting the block height ('latest' or a specific one via the `snapshot` argument).
36+
37+
```
38+
const blockTag = typeof snapshot === 'number' ? snapshot : 'latest';
39+
```
40+
41+
* 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)
42+
43+
```
44+
const multi = new Multicaller(network, provider, abi, { blockTag });
45+
```
46+
47+
* 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()`.&#x20;
48+
49+
`option.address` is the token contract address (`strategy.params.address` in `examples.json`).
50+
51+
```
52+
addresses.forEach((address) =>
53+
multi.call(address, options.address, 'balanceOf', [address])
54+
);
55+
56+
const result: Record<string, BigNumberish> = await multi.execute();
57+
```
58+
59+
* Creating an object where every address from addresses\[] is paired with its corresponding value (returned from the multicall) and returning it
60+
61+
```
62+
return Object.fromEntries(
63+
Object.entries(result).map(([address, balance]) => [
64+
address,
65+
parseFloat(formatUnits(balance, options.decimals))
66+
])
67+
);
68+
```

0 commit comments

Comments
 (0)