Compare commits
198 Commits
Author | SHA1 | Date |
---|---|---|
dependabot[bot] | 2f322ee016 | |
dependabot[bot] | ecc9092f5b | |
dependabot[bot] | ae1a33755f | |
dependabot[bot] | 63bc3f8409 | |
dependabot[bot] | b9bfe07a92 | |
Alex Coseru | d80ba60637 | |
dependabot[bot] | 4e939c70c0 | |
Alex Coseru | ba5e514ddf | |
alexcos20 | 8930eef827 | |
Alex Coseru | 36ae877984 | |
alexcos20 | cf58c9aae4 | |
Alex Coseru | 8bc4dab920 | |
dependabot[bot] | fc07962311 | |
dependabot[bot] | 0077cfa69f | |
dependabot[bot] | 90ad128bc2 | |
dependabot[bot] | 0880f714b0 | |
dependabot[bot] | 7ee41bc29b | |
dependabot[bot] | 957db42e59 | |
dependabot[bot] | db6c3eeeea | |
alexcos20 | 329ea980b6 | |
Alex Coseru | c6004336ae | |
Alex Coseru | 87e42fd6ce | |
alexcos20 | f5b5400261 | |
Alex Coseru | aeef30129a | |
Alex Coseru | 299d196162 | |
Alex Coseru | fa58272978 | |
Alex Coseru | bc56752f3c | |
dependabot[bot] | ab62f18c3e | |
alexcos20 | a62a4c189d | |
Alex Coseru | 39a1210c82 | |
dependabot[bot] | ae9c371e8f | |
dependabot[bot] | 86cc7f0608 | |
dependabot[bot] | b412d2b0b6 | |
alexcos20 | 207a4ac806 | |
dependabot[bot] | 60b8728225 | |
dependabot[bot] | dcaf83775d | |
trizin | 2ca1280328 | |
Maria Carmina | e1df119197 | |
dependabot[bot] | c42cd1c283 | |
dependabot[bot] | e30047c430 | |
dependabot[bot] | 093b452441 | |
alexcos20 | 8691538078 | |
Alex Coseru | 5b2ccbc276 | |
alexcos20 | 9fd0553337 | |
Alex Coseru | c33868d841 | |
alexcos20 | 68944f02a5 | |
Alex Coseru | a77ea45d5f | |
dependabot[bot] | fa071a9cd2 | |
dependabot[bot] | 9164897f2c | |
trizin | 4794dec64e | |
alexcos20 | c8541a071e | |
Alex Coseru | b376cb3942 | |
dependabot[bot] | 81b43ecc20 | |
dependabot[bot] | c02b32b47e | |
dependabot[bot] | a6ded85a37 | |
dependabot[bot] | 4607c673b4 | |
alexcos20 | d888d7d256 | |
Jamie Hewitt | 420a229a61 | |
Jamie Hewitt | 0cf40d40ce | |
dependabot[bot] | b803f1eb6b | |
dependabot[bot] | 1a44345d05 | |
mihaisc | de5f1aab4b | |
Jamie Hewitt | 0a3d513262 | |
dependabot[bot] | 81eb7ea738 | |
dependabot[bot] | 40f09aa6fe | |
dependabot[bot] | 1a5b1a500c | |
dependabot[bot] | dd0512e793 | |
dependabot[bot] | 140bcc6341 | |
Maria Carmina | 6a9b342c52 | |
dependabot[bot] | ec9d7e733f | |
dependabot[bot] | 4c3fd95abc | |
dependabot[bot] | 46f88599b4 | |
dependabot[bot] | 86c6551f31 | |
dependabot[bot] | 1191594196 | |
md00ux | 88a2eecb9b | |
Maria Carmina | 15af2cd609 | |
dependabot[bot] | 1a5906b2b3 | |
dependabot[bot] | 6925cfdde3 | |
dependabot[bot] | 21618b89cf | |
dependabot[bot] | 8ad4f4852b | |
dependabot[bot] | 4cacee3f45 | |
alexcos20 | 3de53c5197 | |
alexcos20 | 7c35711f72 | |
Alex Coseru | 26a53431ea | |
dependabot[bot] | 25021ac9ea | |
dependabot[bot] | 38a7166041 | |
Jamie Hewitt | 9c56b00faa | |
dependabot[bot] | 957488077b | |
dependabot[bot] | 688166e2a0 | |
dependabot[bot] | 1e5e461286 | |
dependabot[bot] | e15d69ebf9 | |
dependabot[bot] | a48b376fa5 | |
dependabot[bot] | 1bb6c9da78 | |
dependabot[bot] | a923bd943f | |
dependabot[bot] | 574b20795b | |
dependabot[bot] | 65515d9d91 | |
dependabot[bot] | cb16d01926 | |
dependabot[bot] | 1293e6ebd7 | |
dependabot[bot] | 004930fd69 | |
dependabot[bot] | 2c7ccabe02 | |
dependabot[bot] | a36c2aecce | |
dependabot[bot] | f34e863623 | |
dependabot[bot] | 8ef553769a | |
dependabot[bot] | c8a4978bc8 | |
dependabot[bot] | c636ad2680 | |
dependabot[bot] | 941dfa28ed | |
dependabot[bot] | d9c5e71d9f | |
Jamie Hewitt | 20c27cd521 | |
mihaisc | 6c4fc1c346 | |
dependabot[bot] | 8eb80507c9 | |
dependabot[bot] | 5ef15e8845 | |
dependabot[bot] | 39ef388831 | |
dependabot[bot] | e6975c60cb | |
dependabot[bot] | 5be8f397af | |
dependabot[bot] | bb90457b91 | |
dependabot[bot] | 89db52ff41 | |
dependabot[bot] | 3a629c7d3e | |
dependabot[bot] | d7e0643c1d | |
dependabot[bot] | a0d3c365bb | |
dependabot[bot] | 52ab055c1a | |
dependabot[bot] | 0cf93fbc52 | |
dependabot[bot] | 5b787d72b5 | |
dependabot[bot] | e9fdbb96d8 | |
dependabot[bot] | c7668c4f1d | |
dependabot[bot] | 45ac3c3d96 | |
dependabot[bot] | 619571b0c2 | |
dependabot[bot] | 29b5efe472 | |
dependabot[bot] | 1e2a3b1814 | |
mihaisc | ae78cae608 | |
mihaisc | 95fcfe9ba7 | |
dependabot[bot] | 7be20246c0 | |
alexcos20 | 92094086f9 | |
Alex Coseru | 868f991f17 | |
dependabot[bot] | 93a05eb767 | |
dependabot[bot] | 12ac5cb523 | |
alexcos20 | 253dc63fa8 | |
Alex Coseru | 24df9f332e | |
alexcos20 | 6c4b270564 | |
Alex Coseru | fe68442fe2 | |
alexcos20 | 91122175dc | |
Alex Coseru | 8cb1d83a26 | |
Berkay Saglam | f61cce9722 | |
Alex Coseru | d2ddf2d156 | |
dependabot[bot] | f3815cdf4b | |
alexcos20 | 181a4f45d0 | |
Alex Coseru | 39b58ba8fe | |
Alex Coseru | 73089dacc3 | |
alexcos20 | a74e3edb3a | |
Alex Coseru | b1a58b7f13 | |
Alex Coseru | c5d86d10df | |
dependabot[bot] | c74d938c24 | |
alexcos20 | 7a627a3bfd | |
Alex Coseru | 0900c1fe88 | |
dependabot[bot] | 2c5459402e | |
dependabot[bot] | 947fe5b341 | |
Idiom | a10c6244b5 | |
Jamie Hewitt | dbb296063b | |
dependabot[bot] | 6af741e5e6 | |
dependabot[bot] | 8b1c3a6060 | |
dependabot[bot] | 3fbc29c145 | |
dependabot[bot] | 9fb268cde9 | |
dependabot[bot] | b340850015 | |
dependabot[bot] | c066d9e59b | |
Jamie Hewitt | 02e980fce2 | |
Jamie Hewitt | 82ce88c026 | |
dependabot[bot] | 6199c34c69 | |
dependabot[bot] | c84c299dbc | |
mihaisc | 06bbaa54c2 | |
mihaisc | 8416d773cc | |
Jamie Hewitt | fd40e490cc | |
Jamie Hewitt | bd03b28197 | |
dependabot[bot] | d9f83dc933 | |
Jamie Hewitt | cedd082749 | |
Jamie Hewitt | 1289a085bb | |
dependabot[bot] | 61cfdbaf23 | |
mihaisc | 4353b15391 | |
mihaisc | a8396aec19 | |
mihaisc | 6572762639 | |
mihaisc | 3ced2e4179 | |
Alex Coseru | e7cb995797 | |
dependabot[bot] | 13d7fb78c1 | |
dependabot[bot] | 5e581e8418 | |
dependabot[bot] | 838de4ba92 | |
dependabot[bot] | cee74ac14a | |
Jamie Hewitt | a733b27fa1 | |
Jamie Hewitt | 493a6d2546 | |
Jamie Hewitt | 07ce9398a6 | |
Jamie Hewitt | 0b8f6e1af5 | |
dependabot[bot] | 6f96246c04 | |
dependabot[bot] | c18d20141d | |
Jamie Hewitt | 3ebc29a74d | |
dependabot[bot] | db8cf22d16 | |
dependabot[bot] | 5da91c2282 | |
dependabot[bot] | f85bfef788 | |
dependabot[bot] | 7aa2be4a34 | |
Jamie Hewitt | cb9890122c | |
Jamie Hewitt | 011e256f5a | |
mihaisc | d864a5ade7 |
|
@ -37,8 +37,6 @@ jobs:
|
|||
with:
|
||||
repository: 'oceanprotocol/barge'
|
||||
path: 'barge'
|
||||
ref: main
|
||||
|
||||
- name: Login to Docker Hub
|
||||
if: ${{ env.DOCKERHUB_PASSWORD && env.DOCKERHUB_USERNAME }}
|
||||
run: |
|
||||
|
@ -51,8 +49,6 @@ jobs:
|
|||
working-directory: ${{ github.workspace }}/barge
|
||||
run: |
|
||||
bash -x start_ocean.sh --with-thegraph --skip-subgraph-deploy --no-dashboard 2>&1 > start_ocean.log &
|
||||
env:
|
||||
CONTRACTS_VERSION: v1.0.0-alpha.28
|
||||
|
||||
- run: npm ci
|
||||
|
||||
|
@ -69,6 +65,11 @@ jobs:
|
|||
sleep 20
|
||||
env:
|
||||
ADDRESS_FILE: /home/runner/.ocean/ocean-contracts/artifacts/address.json
|
||||
BARGE_FOLDER: /home/runner/.ocean/
|
||||
- run: npm run test-integration
|
||||
env:
|
||||
ADDRESS_FILE: /home/runner/.ocean/ocean-contracts/artifacts/address.json
|
||||
BARGE_FOLDER: /home/runner/.ocean/
|
||||
- name: docker logs
|
||||
run: docker logs ocean_graph-node_1
|
||||
if: ${{ failure() }}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"wix.vscode-import-cost"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
},
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"typescript",
|
||||
"typescriptreact"
|
||||
],
|
||||
"search.exclude": {
|
||||
"**/.next": true,
|
||||
"**/out": true
|
||||
}
|
||||
}
|
347
CHANGELOG.md
347
CHANGELOG.md
|
@ -4,8 +4,355 @@ All notable changes to this project will be documented in this file. Dates are d
|
|||
|
||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [v4.0.2](https://github.com/oceanprotocol/ocean-subgraph/compare/v4.0.1...v4.0.2)
|
||||
|
||||
- fix deps [`#744`](https://github.com/oceanprotocol/ocean-subgraph/pull/744)
|
||||
|
||||
#### [v4.0.1](https://github.com/oceanprotocol/ocean-subgraph/compare/v4.0.0...v4.0.1)
|
||||
|
||||
> 22 November 2023
|
||||
|
||||
- Feature/add_optimism & use graph-node 0.33.0 [`#742`](https://github.com/oceanprotocol/ocean-subgraph/pull/742)
|
||||
- Bump chai and @types/chai [`#729`](https://github.com/oceanprotocol/ocean-subgraph/pull/729)
|
||||
- Bump @graphprotocol/graph-cli from 0.56.0 to 0.61.0 [`#738`](https://github.com/oceanprotocol/ocean-subgraph/pull/738)
|
||||
- Bump crypto-js from 4.1.1 to 4.2.0 [`#733`](https://github.com/oceanprotocol/ocean-subgraph/pull/733)
|
||||
- Bump release-it from 15.11.0 to 17.0.0 [`#737`](https://github.com/oceanprotocol/ocean-subgraph/pull/737)
|
||||
- Bump minimist from 1.2.5 to 1.2.6 [`#740`](https://github.com/oceanprotocol/ocean-subgraph/pull/740)
|
||||
- Bump tar from 4.4.13 to 4.4.19 [`#741`](https://github.com/oceanprotocol/ocean-subgraph/pull/741)
|
||||
- Bump @graphprotocol/graph-ts from 0.30.0 to 0.31.0 [`#730`](https://github.com/oceanprotocol/ocean-subgraph/pull/730)
|
||||
- Release 4.0.1 [`cf58c9a`](https://github.com/oceanprotocol/ocean-subgraph/commit/cf58c9aae4aa16f7a30b4c93de72786b1d4b3b3f)
|
||||
|
||||
### [v4.0.0](https://github.com/oceanprotocol/ocean-subgraph/compare/v3.0.10...v4.0.0)
|
||||
|
||||
> 21 November 2023
|
||||
|
||||
- Predictoor support [`#678`](https://github.com/oceanprotocol/ocean-subgraph/pull/678)
|
||||
- bump deps [`#725`](https://github.com/oceanprotocol/ocean-subgraph/pull/725)
|
||||
- Release 4.0.0 [`329ea98`](https://github.com/oceanprotocol/ocean-subgraph/commit/329ea980b628417652de8a444808ba7f470515c8)
|
||||
|
||||
#### [v3.0.10](https://github.com/oceanprotocol/ocean-subgraph/compare/v3.0.9...v3.0.10)
|
||||
|
||||
> 15 August 2023
|
||||
|
||||
- Bump to graphnode 0.28.2 [`#702`](https://github.com/oceanprotocol/ocean-subgraph/pull/702)
|
||||
- Template id detection [`#705`](https://github.com/oceanprotocol/ocean-subgraph/pull/705)
|
||||
- reduce docker siz [`#709`](https://github.com/oceanprotocol/ocean-subgraph/pull/709)
|
||||
- Create README.md [`#698`](https://github.com/oceanprotocol/ocean-subgraph/pull/698)
|
||||
- Bump word-wrap from 1.2.3 to 1.2.4 [`#701`](https://github.com/oceanprotocol/ocean-subgraph/pull/701)
|
||||
- Release 3.0.10 [`f5b5400`](https://github.com/oceanprotocol/ocean-subgraph/commit/f5b540026106cdaddfdfb1ba1edce0cc1eb333fc)
|
||||
|
||||
#### [v3.0.9](https://github.com/oceanprotocol/ocean-subgraph/compare/v3.0.8...v3.0.9)
|
||||
|
||||
> 4 July 2023
|
||||
|
||||
- bump to latest contracts [`#695`](https://github.com/oceanprotocol/ocean-subgraph/pull/695)
|
||||
- Bump release-it from 15.10.3 to 15.11.0 [`#688`](https://github.com/oceanprotocol/ocean-subgraph/pull/688)
|
||||
- Bump mock-local-storage from 1.1.23 to 1.1.24 [`#683`](https://github.com/oceanprotocol/ocean-subgraph/pull/683)
|
||||
- Bump vm2 from 3.9.17 to 3.9.18 [`#681`](https://github.com/oceanprotocol/ocean-subgraph/pull/681)
|
||||
- Release 3.0.9 [`a62a4c1`](https://github.com/oceanprotocol/ocean-subgraph/commit/a62a4c189ddd5f712acb62a683dec1c9c8e067b9)
|
||||
|
||||
#### [v3.0.8](https://github.com/oceanprotocol/ocean-subgraph/compare/v3.0.7...v3.0.8)
|
||||
|
||||
> 16 May 2023
|
||||
|
||||
- Bump @graphprotocol/graph-ts from 0.29.3 to 0.30.0 [`#680`](https://github.com/oceanprotocol/ocean-subgraph/pull/680)
|
||||
- Bump cross-fetch from 3.1.5 to 3.1.6 [`#679`](https://github.com/oceanprotocol/ocean-subgraph/pull/679)
|
||||
- Add lockedAmount to veDelegation [`#672`](https://github.com/oceanprotocol/ocean-subgraph/pull/672)
|
||||
- Fix #628 & #629 & #621: Store event log index for all records [`#630`](https://github.com/oceanprotocol/ocean-subgraph/pull/630)
|
||||
- Bump release-it from 15.10.2 to 15.10.3 [`#673`](https://github.com/oceanprotocol/ocean-subgraph/pull/673)
|
||||
- Bump @types/chai from 4.3.4 to 4.3.5 [`#669`](https://github.com/oceanprotocol/ocean-subgraph/pull/669)
|
||||
- Bump release-it from 15.10.1 to 15.10.2 [`#668`](https://github.com/oceanprotocol/ocean-subgraph/pull/668)
|
||||
- Fix #628 & #629 & #621: Store event log index for all records (#630) [`#628`](https://github.com/oceanprotocol/ocean-subgraph/issues/628)
|
||||
- Release 3.0.8 [`207a4ac`](https://github.com/oceanprotocol/ocean-subgraph/commit/207a4ac806d0f7817ac7f2f4ace5d3c2160ad64c)
|
||||
|
||||
#### [v3.0.7](https://github.com/oceanprotocol/ocean-subgraph/compare/v3.0.6...v3.0.7)
|
||||
|
||||
> 28 April 2023
|
||||
|
||||
- switch amount from wei to numeric [`#666`](https://github.com/oceanprotocol/ocean-subgraph/pull/666)
|
||||
- Release 3.0.7 [`8691538`](https://github.com/oceanprotocol/ocean-subgraph/commit/8691538078f0d8aa81a0543de403a4e540adbfbd)
|
||||
|
||||
#### [v3.0.6](https://github.com/oceanprotocol/ocean-subgraph/compare/v3.0.5...v3.0.6)
|
||||
|
||||
> 28 April 2023
|
||||
|
||||
- proper veDelegation [`#663`](https://github.com/oceanprotocol/ocean-subgraph/pull/663)
|
||||
- Release 3.0.6 [`9fd0553`](https://github.com/oceanprotocol/ocean-subgraph/commit/9fd055333705185b5f507fddcdf0f5502add1f1c)
|
||||
|
||||
#### [v3.0.5](https://github.com/oceanprotocol/ocean-subgraph/compare/v3.0.4...v3.0.5)
|
||||
|
||||
> 26 April 2023
|
||||
|
||||
- add events handlers [`#662`](https://github.com/oceanprotocol/ocean-subgraph/pull/662)
|
||||
- Bump prettier from 2.8.7 to 2.8.8 [`#660`](https://github.com/oceanprotocol/ocean-subgraph/pull/660)
|
||||
- Bump vm2 from 3.9.16 to 3.9.17 [`#659`](https://github.com/oceanprotocol/ocean-subgraph/pull/659)
|
||||
- Add missing veDelegation.save() [`#658`](https://github.com/oceanprotocol/ocean-subgraph/pull/658)
|
||||
- Release 3.0.5 [`68944f0`](https://github.com/oceanprotocol/ocean-subgraph/commit/68944f02a545ea9c06881dcd8883f7dcecd72063)
|
||||
|
||||
#### [v3.0.4](https://github.com/oceanprotocol/ocean-subgraph/compare/v3.0.3...v3.0.4)
|
||||
|
||||
> 14 April 2023
|
||||
|
||||
- add more veOcean stats [`#655`](https://github.com/oceanprotocol/ocean-subgraph/pull/655)
|
||||
- Bump vm2 from 3.9.15 to 3.9.16 [`#653`](https://github.com/oceanprotocol/ocean-subgraph/pull/653)
|
||||
- Bump typescript from 5.0.3 to 5.0.4 [`#652`](https://github.com/oceanprotocol/ocean-subgraph/pull/652)
|
||||
- Bump vm2 from 3.9.11 to 3.9.15 [`#649`](https://github.com/oceanprotocol/ocean-subgraph/pull/649)
|
||||
- Bump release-it from 15.10.0 to 15.10.1 [`#651`](https://github.com/oceanprotocol/ocean-subgraph/pull/651)
|
||||
- Release 3.0.4 [`c8541a0`](https://github.com/oceanprotocol/ocean-subgraph/commit/c8541a071ef13d51e2e62822a194710bef660729)
|
||||
|
||||
#### [v3.0.3](https://github.com/oceanprotocol/ocean-subgraph/compare/v3.0.2...v3.0.3)
|
||||
|
||||
> 6 April 2023
|
||||
|
||||
- Removing amountFraction and adding timestamp [`#647`](https://github.com/oceanprotocol/ocean-subgraph/pull/647)
|
||||
- Fixing decimals issue [`#644`](https://github.com/oceanprotocol/ocean-subgraph/pull/644)
|
||||
- Bump typescript from 5.0.2 to 5.0.3 [`#641`](https://github.com/oceanprotocol/ocean-subgraph/pull/641)
|
||||
- Bump release-it from 15.9.3 to 15.10.0 [`#640`](https://github.com/oceanprotocol/ocean-subgraph/pull/640)
|
||||
- Release 3.0.3 [`d888d7d`](https://github.com/oceanprotocol/ocean-subgraph/commit/d888d7d2566c5fa0fe21903bd16d0b5329815526)
|
||||
|
||||
#### [v3.0.2](https://github.com/oceanprotocol/ocean-subgraph/compare/v3.0.1...v3.0.2)
|
||||
|
||||
> 31 March 2023
|
||||
|
||||
- Storing the fraction of veOcean [`#623`](https://github.com/oceanprotocol/ocean-subgraph/pull/623)
|
||||
- Bump eslint-config-prettier from 8.7.0 to 8.8.0 [`#637`](https://github.com/oceanprotocol/ocean-subgraph/pull/637)
|
||||
- Bump prettier from 2.8.4 to 2.8.7 [`#636`](https://github.com/oceanprotocol/ocean-subgraph/pull/636)
|
||||
- Bump release-it from 15.9.1 to 15.9.3 [`#638`](https://github.com/oceanprotocol/ocean-subgraph/pull/638)
|
||||
- Bump typescript from 4.9.5 to 5.0.2 [`#632`](https://github.com/oceanprotocol/ocean-subgraph/pull/632)
|
||||
- Bump release-it from 15.8.0 to 15.9.1 [`#634`](https://github.com/oceanprotocol/ocean-subgraph/pull/634)
|
||||
- Update ocean-lib with 2.7.0 version. [`#633`](https://github.com/oceanprotocol/ocean-subgraph/pull/633)
|
||||
- Bump eslint-config-prettier from 8.6.0 to 8.7.0 [`#625`](https://github.com/oceanprotocol/ocean-subgraph/pull/625)
|
||||
- Bump @oceanprotocol/lib from 2.6.1 to 2.6.3 [`#614`](https://github.com/oceanprotocol/ocean-subgraph/pull/614)
|
||||
- Bump release-it from 15.7.0 to 15.8.0 [`#624`](https://github.com/oceanprotocol/ocean-subgraph/pull/624)
|
||||
- Bump @oceanprotocol/contracts from 1.1.8 to 1.1.12 [`#627`](https://github.com/oceanprotocol/ocean-subgraph/pull/627)
|
||||
- Bump release-it from 15.6.0 to 15.7.0 [`#618`](https://github.com/oceanprotocol/ocean-subgraph/pull/618)
|
||||
- Update README.md [`#617`](https://github.com/oceanprotocol/ocean-subgraph/pull/617)
|
||||
- Update copyright year. [`#615`](https://github.com/oceanprotocol/ocean-subgraph/pull/615)
|
||||
- Bump prettier from 2.8.3 to 2.8.4 [`#612`](https://github.com/oceanprotocol/ocean-subgraph/pull/612)
|
||||
- Bump http-cache-semantics from 4.1.0 to 4.1.1 [`#608`](https://github.com/oceanprotocol/ocean-subgraph/pull/608)
|
||||
- Bump @graphprotocol/graph-ts from 0.29.1 to 0.29.3 [`#611`](https://github.com/oceanprotocol/ocean-subgraph/pull/611)
|
||||
- Bump typescript from 4.9.4 to 4.9.5 [`#610`](https://github.com/oceanprotocol/ocean-subgraph/pull/610)
|
||||
- Bump @graphprotocol/graph-cli from 0.37.7 to 0.38.0 [`#609`](https://github.com/oceanprotocol/ocean-subgraph/pull/609)
|
||||
- Release 3.0.2 [`de5f1aa`](https://github.com/oceanprotocol/ocean-subgraph/commit/de5f1aab4bc70d6ec831fa0f24099666ef3c46a1)
|
||||
|
||||
#### [v3.0.1](https://github.com/oceanprotocol/ocean-subgraph/compare/v3.0.0...v3.0.1)
|
||||
|
||||
> 27 January 2023
|
||||
|
||||
- fix veDeposit id generation [`#606`](https://github.com/oceanprotocol/ocean-subgraph/pull/606)
|
||||
- Bump @graphprotocol/graph-cli from 0.37.2 to 0.37.7 [`#603`](https://github.com/oceanprotocol/ocean-subgraph/pull/603)
|
||||
- Bump eslint-plugin-import from 2.27.4 to 2.27.5 [`#602`](https://github.com/oceanprotocol/ocean-subgraph/pull/602)
|
||||
- Tracking OPC fees [`#593`](https://github.com/oceanprotocol/ocean-subgraph/pull/593)
|
||||
- Bump prettier from 2.8.2 to 2.8.3 [`#600`](https://github.com/oceanprotocol/ocean-subgraph/pull/600)
|
||||
- Bump @graphprotocol/graph-cli from 0.37.1 to 0.37.2 [`#599`](https://github.com/oceanprotocol/ocean-subgraph/pull/599)
|
||||
- Bump eslint-plugin-import from 2.26.0 to 2.27.4 [`#601`](https://github.com/oceanprotocol/ocean-subgraph/pull/601)
|
||||
- Bump eslint-config-prettier from 8.5.0 to 8.6.0 [`#596`](https://github.com/oceanprotocol/ocean-subgraph/pull/596)
|
||||
- Bump prettier from 2.8.1 to 2.8.2 [`#597`](https://github.com/oceanprotocol/ocean-subgraph/pull/597)
|
||||
- Bump @oceanprotocol/lib from 2.6.0 to 2.6.1 [`#598`](https://github.com/oceanprotocol/ocean-subgraph/pull/598)
|
||||
- Bump json5 from 1.0.1 to 1.0.2 [`#594`](https://github.com/oceanprotocol/ocean-subgraph/pull/594)
|
||||
- Bump @graphprotocol/graph-ts from 0.29.0 to 0.29.1 [`#590`](https://github.com/oceanprotocol/ocean-subgraph/pull/590)
|
||||
- Bump @oceanprotocol/lib from 2.5.2 to 2.6.0 [`#591`](https://github.com/oceanprotocol/ocean-subgraph/pull/591)
|
||||
- Bump release-it from 15.5.1 to 15.6.0 [`#592`](https://github.com/oceanprotocol/ocean-subgraph/pull/592)
|
||||
- Bump typescript from 4.9.3 to 4.9.4 [`#586`](https://github.com/oceanprotocol/ocean-subgraph/pull/586)
|
||||
- Bump mocha from 10.1.0 to 10.2.0 [`#583`](https://github.com/oceanprotocol/ocean-subgraph/pull/583)
|
||||
- Bump qs from 6.5.2 to 6.5.3 [`#587`](https://github.com/oceanprotocol/ocean-subgraph/pull/587)
|
||||
- Bump @graphprotocol/graph-cli from 0.37.0 to 0.37.1 [`#585`](https://github.com/oceanprotocol/ocean-subgraph/pull/585)
|
||||
- Bump prettier from 2.8.0 to 2.8.1 [`#584`](https://github.com/oceanprotocol/ocean-subgraph/pull/584)
|
||||
- Bump @graphprotocol/graph-cli from 0.36.1 to 0.37.0 [`#578`](https://github.com/oceanprotocol/ocean-subgraph/pull/578)
|
||||
- Bump decode-uri-component from 0.2.0 to 0.2.2 [`#581`](https://github.com/oceanprotocol/ocean-subgraph/pull/581)
|
||||
- Bump release-it from 15.5.0 to 15.5.1 [`#579`](https://github.com/oceanprotocol/ocean-subgraph/pull/579)
|
||||
- Bump @types/mocha from 10.0.0 to 10.0.1 [`#580`](https://github.com/oceanprotocol/ocean-subgraph/pull/580)
|
||||
- Bump prettier from 2.7.1 to 2.8.0 [`#577`](https://github.com/oceanprotocol/ocean-subgraph/pull/577)
|
||||
- Release 2.1.4 [`7c35711`](https://github.com/oceanprotocol/ocean-subgraph/commit/7c35711f722b7ea487d8b8c9aa3e42d71f2beb56)
|
||||
- Release 3.0.1 [`3de53c5`](https://github.com/oceanprotocol/ocean-subgraph/commit/3de53c519750ca40ec269ed21f7c17773b53b139)
|
||||
|
||||
### [v3.0.0](https://github.com/oceanprotocol/ocean-subgraph/compare/v2.1.4...v3.0.0)
|
||||
|
||||
> 24 November 2022
|
||||
|
||||
#### [v2.1.4](https://github.com/oceanprotocol/ocean-subgraph/compare/v2.1.3...v2.1.4)
|
||||
|
||||
> 27 January 2023
|
||||
|
||||
- fix veDeposit id generation [`#606`](https://github.com/oceanprotocol/ocean-subgraph/pull/606)
|
||||
- Bump @graphprotocol/graph-cli from 0.37.2 to 0.37.7 [`#603`](https://github.com/oceanprotocol/ocean-subgraph/pull/603)
|
||||
- Bump eslint-plugin-import from 2.27.4 to 2.27.5 [`#602`](https://github.com/oceanprotocol/ocean-subgraph/pull/602)
|
||||
- Tracking OPC fees [`#593`](https://github.com/oceanprotocol/ocean-subgraph/pull/593)
|
||||
- Bump prettier from 2.8.2 to 2.8.3 [`#600`](https://github.com/oceanprotocol/ocean-subgraph/pull/600)
|
||||
- Bump @graphprotocol/graph-cli from 0.37.1 to 0.37.2 [`#599`](https://github.com/oceanprotocol/ocean-subgraph/pull/599)
|
||||
- Bump eslint-plugin-import from 2.26.0 to 2.27.4 [`#601`](https://github.com/oceanprotocol/ocean-subgraph/pull/601)
|
||||
- Bump eslint-config-prettier from 8.5.0 to 8.6.0 [`#596`](https://github.com/oceanprotocol/ocean-subgraph/pull/596)
|
||||
- Bump prettier from 2.8.1 to 2.8.2 [`#597`](https://github.com/oceanprotocol/ocean-subgraph/pull/597)
|
||||
- Bump @oceanprotocol/lib from 2.6.0 to 2.6.1 [`#598`](https://github.com/oceanprotocol/ocean-subgraph/pull/598)
|
||||
- Bump json5 from 1.0.1 to 1.0.2 [`#594`](https://github.com/oceanprotocol/ocean-subgraph/pull/594)
|
||||
- Bump @graphprotocol/graph-ts from 0.29.0 to 0.29.1 [`#590`](https://github.com/oceanprotocol/ocean-subgraph/pull/590)
|
||||
- Bump @oceanprotocol/lib from 2.5.2 to 2.6.0 [`#591`](https://github.com/oceanprotocol/ocean-subgraph/pull/591)
|
||||
- Bump release-it from 15.5.1 to 15.6.0 [`#592`](https://github.com/oceanprotocol/ocean-subgraph/pull/592)
|
||||
- Bump typescript from 4.9.3 to 4.9.4 [`#586`](https://github.com/oceanprotocol/ocean-subgraph/pull/586)
|
||||
- Bump mocha from 10.1.0 to 10.2.0 [`#583`](https://github.com/oceanprotocol/ocean-subgraph/pull/583)
|
||||
- Bump qs from 6.5.2 to 6.5.3 [`#587`](https://github.com/oceanprotocol/ocean-subgraph/pull/587)
|
||||
- Bump @graphprotocol/graph-cli from 0.37.0 to 0.37.1 [`#585`](https://github.com/oceanprotocol/ocean-subgraph/pull/585)
|
||||
- Bump prettier from 2.8.0 to 2.8.1 [`#584`](https://github.com/oceanprotocol/ocean-subgraph/pull/584)
|
||||
- Bump @graphprotocol/graph-cli from 0.36.1 to 0.37.0 [`#578`](https://github.com/oceanprotocol/ocean-subgraph/pull/578)
|
||||
- Bump decode-uri-component from 0.2.0 to 0.2.2 [`#581`](https://github.com/oceanprotocol/ocean-subgraph/pull/581)
|
||||
- Bump release-it from 15.5.0 to 15.5.1 [`#579`](https://github.com/oceanprotocol/ocean-subgraph/pull/579)
|
||||
- Bump @types/mocha from 10.0.0 to 10.0.1 [`#580`](https://github.com/oceanprotocol/ocean-subgraph/pull/580)
|
||||
- Bump prettier from 2.7.1 to 2.8.0 [`#577`](https://github.com/oceanprotocol/ocean-subgraph/pull/577)
|
||||
- nft transfer event [`#573`](https://github.com/oceanprotocol/ocean-subgraph/pull/573)
|
||||
- add lastPriceToken [`#567`](https://github.com/oceanprotocol/ocean-subgraph/pull/567)
|
||||
- Bump typescript from 4.8.4 to 4.9.3 [`#576`](https://github.com/oceanprotocol/ocean-subgraph/pull/576)
|
||||
- Bump @graphprotocol/graph-cli from 0.35.0 to 0.36.1 [`#575`](https://github.com/oceanprotocol/ocean-subgraph/pull/575)
|
||||
- Bump @oceanprotocol/lib from 2.5.1 to 2.5.2 [`#574`](https://github.com/oceanprotocol/ocean-subgraph/pull/574)
|
||||
- Bump @graphprotocol/graph-ts from 0.28.1 to 0.29.0 [`#571`](https://github.com/oceanprotocol/ocean-subgraph/pull/571)
|
||||
- Bump chai and @types/chai [`#572`](https://github.com/oceanprotocol/ocean-subgraph/pull/572)
|
||||
- Bump @oceanprotocol/lib from 2.4.0 to 2.5.1 [`#569`](https://github.com/oceanprotocol/ocean-subgraph/pull/569)
|
||||
- Bump @oceanprotocol/lib from 2.3.0 to 2.4.0 [`#568`](https://github.com/oceanprotocol/ocean-subgraph/pull/568)
|
||||
- Bump @oceanprotocol/contracts from 1.1.7 to 1.1.8 [`#566`](https://github.com/oceanprotocol/ocean-subgraph/pull/566)
|
||||
- Bump @oceanprotocol/lib from 2.2.2 to 2.3.0 [`#565`](https://github.com/oceanprotocol/ocean-subgraph/pull/565)
|
||||
- Bump @graphprotocol/graph-ts from 0.28.0 to 0.28.1 [`#559`](https://github.com/oceanprotocol/ocean-subgraph/pull/559)
|
||||
- Bump @graphprotocol/graph-cli from 0.34.0 to 0.35.0 [`#560`](https://github.com/oceanprotocol/ocean-subgraph/pull/560)
|
||||
- Bump mocha from 10.0.0 to 10.1.0 [`#561`](https://github.com/oceanprotocol/ocean-subgraph/pull/561)
|
||||
- Bump @oceanprotocol/lib from 2.2.1 to 2.2.2 [`#562`](https://github.com/oceanprotocol/ocean-subgraph/pull/562)
|
||||
- Bump @oceanprotocol/lib from 2.1.1 to 2.2.1 [`#557`](https://github.com/oceanprotocol/ocean-subgraph/pull/557)
|
||||
- Bump release-it from 15.4.2 to 15.5.0 [`#558`](https://github.com/oceanprotocol/ocean-subgraph/pull/558)
|
||||
- Bump @types/mocha from 9.1.1 to 10.0.0 [`#556`](https://github.com/oceanprotocol/ocean-subgraph/pull/556)
|
||||
- Bump @graphprotocol/graph-cli from 0.33.1 to 0.34.0 [`#555`](https://github.com/oceanprotocol/ocean-subgraph/pull/555)
|
||||
- Bump typescript from 4.8.3 to 4.8.4 [`#554`](https://github.com/oceanprotocol/ocean-subgraph/pull/554)
|
||||
- Bump @graphprotocol/graph-ts from 0.27.0 to 0.28.0 [`#553`](https://github.com/oceanprotocol/ocean-subgraph/pull/553)
|
||||
- Release 2.1.4 [`7c35711`](https://github.com/oceanprotocol/ocean-subgraph/commit/7c35711f722b7ea487d8b8c9aa3e42d71f2beb56)
|
||||
|
||||
#### [v2.1.3](https://github.com/oceanprotocol/ocean-subgraph/compare/v2.1.2...v2.1.3)
|
||||
|
||||
> 30 September 2022
|
||||
|
||||
- add chainId and nftAddress [`#552`](https://github.com/oceanprotocol/ocean-subgraph/pull/552)
|
||||
- Bump vm2 from 3.9.9 to 3.9.11 [`#550`](https://github.com/oceanprotocol/ocean-subgraph/pull/550)
|
||||
- Release 2.1.3 [`ae78cae`](https://github.com/oceanprotocol/ocean-subgraph/commit/ae78cae6083514592756f2549f21a307361d96d8)
|
||||
|
||||
#### [v2.1.2](https://github.com/oceanprotocol/ocean-subgraph/compare/v2.1.1...v2.1.2)
|
||||
|
||||
> 28 September 2022
|
||||
|
||||
- fix tokenRemoved [`#549`](https://github.com/oceanprotocol/ocean-subgraph/pull/549)
|
||||
- Bump @oceanprotocol/lib from 2.0.2 to 2.1.1 [`#545`](https://github.com/oceanprotocol/ocean-subgraph/pull/545)
|
||||
- Bump eslint-config-oceanprotocol from 2.0.3 to 2.0.4 [`#546`](https://github.com/oceanprotocol/ocean-subgraph/pull/546)
|
||||
- Release 2.1.2 [`9209408`](https://github.com/oceanprotocol/ocean-subgraph/commit/92094086f98ebe7470f1fcbeeb297fbb695a431e)
|
||||
|
||||
#### [v2.1.1](https://github.com/oceanprotocol/ocean-subgraph/compare/v2.1.0...v2.1.1)
|
||||
|
||||
> 26 September 2022
|
||||
|
||||
- fix allocation [`#544`](https://github.com/oceanprotocol/ocean-subgraph/pull/544)
|
||||
- Release 2.1.1 [`253dc63`](https://github.com/oceanprotocol/ocean-subgraph/commit/253dc63fa853011ed95f3501cc4cf0eed6d22f73)
|
||||
|
||||
#### [v2.1.0](https://github.com/oceanprotocol/ocean-subgraph/compare/v2.0.7...v2.1.0)
|
||||
|
||||
> 23 September 2022
|
||||
|
||||
- Feature/more ve [`#543`](https://github.com/oceanprotocol/ocean-subgraph/pull/543)
|
||||
- Release 2.1.0 [`6c4b270`](https://github.com/oceanprotocol/ocean-subgraph/commit/6c4b2705645632b23dc90809868f25550238f2e1)
|
||||
|
||||
#### [v2.0.7](https://github.com/oceanprotocol/ocean-subgraph/compare/v2.0.6...v2.0.7)
|
||||
|
||||
> 21 September 2022
|
||||
|
||||
- Feature/graphnode 27 [`#541`](https://github.com/oceanprotocol/ocean-subgraph/pull/541)
|
||||
- Add gasUsed and gasPrice to order [`#540`](https://github.com/oceanprotocol/ocean-subgraph/pull/540)
|
||||
- add goerli npm command [`#538`](https://github.com/oceanprotocol/ocean-subgraph/pull/538)
|
||||
- Bump release-it from 15.4.1 to 15.4.2 [`#535`](https://github.com/oceanprotocol/ocean-subgraph/pull/535)
|
||||
- Release 2.0.7 [`9112217`](https://github.com/oceanprotocol/ocean-subgraph/commit/91122175dc17d5f670103e193631e176b710c160)
|
||||
|
||||
#### [v2.0.6](https://github.com/oceanprotocol/ocean-subgraph/compare/v2.0.5...v2.0.6)
|
||||
|
||||
> 14 September 2022
|
||||
|
||||
- fix nftUpdate critical bug [`#534`](https://github.com/oceanprotocol/ocean-subgraph/pull/534)
|
||||
- add erc725 key/value store [`#533`](https://github.com/oceanprotocol/ocean-subgraph/pull/533)
|
||||
- Release 2.0.6 [`181a4f4`](https://github.com/oceanprotocol/ocean-subgraph/commit/181a4f45d0be93140677ba96470bb33a4936d88e)
|
||||
|
||||
#### [v2.0.5](https://github.com/oceanprotocol/ocean-subgraph/compare/v2.0.4...v2.0.5)
|
||||
|
||||
> 13 September 2022
|
||||
|
||||
- Feature/df rewards [`#531`](https://github.com/oceanprotocol/ocean-subgraph/pull/531)
|
||||
- nft updates [`#530`](https://github.com/oceanprotocol/ocean-subgraph/pull/530)
|
||||
- Bump typescript from 4.8.2 to 4.8.3 [`#527`](https://github.com/oceanprotocol/ocean-subgraph/pull/527)
|
||||
- Release 2.0.5 [`a74e3ed`](https://github.com/oceanprotocol/ocean-subgraph/commit/a74e3edb3a12070cbfe3caf56fbabf4f57aa8e7f)
|
||||
|
||||
#### [v2.0.4](https://github.com/oceanprotocol/ocean-subgraph/compare/v2.0.3...v2.0.4)
|
||||
|
||||
> 7 September 2022
|
||||
|
||||
- update tests for new ocean.js 2.0 [`#526`](https://github.com/oceanprotocol/ocean-subgraph/pull/526)
|
||||
- Bump @graphprotocol/graph-cli from 0.33.0 to 0.33.1 [`#525`](https://github.com/oceanprotocol/ocean-subgraph/pull/525)
|
||||
- Bump release-it from 15.4.0 to 15.4.1 [`#524`](https://github.com/oceanprotocol/ocean-subgraph/pull/524)
|
||||
- Implementing first pass of veAllocate schema, handlers, and test cove… [`#490`](https://github.com/oceanprotocol/ocean-subgraph/pull/490)
|
||||
- Testing user fields [`#516`](https://github.com/oceanprotocol/ocean-subgraph/pull/516)
|
||||
- Bump json-schema from 0.2.3 to 0.4.0 [`#523`](https://github.com/oceanprotocol/ocean-subgraph/pull/523)
|
||||
- Bump release-it from 15.3.0 to 15.4.0 [`#522`](https://github.com/oceanprotocol/ocean-subgraph/pull/522)
|
||||
- Bump typescript from 4.7.4 to 4.8.2 [`#521`](https://github.com/oceanprotocol/ocean-subgraph/pull/521)
|
||||
- Bump @oceanprotocol/lib from 1.1.7 to 1.1.8 [`#519`](https://github.com/oceanprotocol/ocean-subgraph/pull/519)
|
||||
- Bump @types/chai from 4.3.2 to 4.3.3 [`#517`](https://github.com/oceanprotocol/ocean-subgraph/pull/517)
|
||||
- Bump release-it from 15.2.0 to 15.3.0 [`#518`](https://github.com/oceanprotocol/ocean-subgraph/pull/518)
|
||||
- Dispenser tests [`#514`](https://github.com/oceanprotocol/ocean-subgraph/pull/514)
|
||||
- Fixed rate exchange tests [`#513`](https://github.com/oceanprotocol/ocean-subgraph/pull/513)
|
||||
- Bump @types/chai from 4.3.1 to 4.3.2 [`#511`](https://github.com/oceanprotocol/ocean-subgraph/pull/511)
|
||||
- Bump @oceanprotocol/lib from 1.1.6 to 1.1.7 [`#512`](https://github.com/oceanprotocol/ocean-subgraph/pull/512)
|
||||
- fixed swapper change issue [`#510`](https://github.com/oceanprotocol/ocean-subgraph/pull/510)
|
||||
- Release 2.0.4 [`7a627a3`](https://github.com/oceanprotocol/ocean-subgraph/commit/7a627a3bfde4d496c26a3c0a18e8b4992210a2b2)
|
||||
|
||||
#### [v2.0.3](https://github.com/oceanprotocol/ocean-subgraph/compare/v2.0.2...v2.0.3)
|
||||
|
||||
> 2 August 2022
|
||||
|
||||
- Tracking templateId [`#508`](https://github.com/oceanprotocol/ocean-subgraph/pull/508)
|
||||
- Additional tests for NFT and Datatokens [`#498`](https://github.com/oceanprotocol/ocean-subgraph/pull/498)
|
||||
- Bump mock-local-storage from 1.1.21 to 1.1.23 [`#507`](https://github.com/oceanprotocol/ocean-subgraph/pull/507)
|
||||
- Removing Pool example queries and adding new examples [`#493`](https://github.com/oceanprotocol/ocean-subgraph/pull/493)
|
||||
- Remove tracking of pools [`#492`](https://github.com/oceanprotocol/ocean-subgraph/pull/492)
|
||||
- Bump release-it from 15.1.4 to 15.2.0 [`#503`](https://github.com/oceanprotocol/ocean-subgraph/pull/503)
|
||||
- minor change [`#501`](https://github.com/oceanprotocol/ocean-subgraph/pull/501)
|
||||
- Revert "roolback deps" [`4353b15`](https://github.com/oceanprotocol/ocean-subgraph/commit/4353b153910717182930735c7bd596301132eb92)
|
||||
- roolback deps [`a8396ae`](https://github.com/oceanprotocol/ocean-subgraph/commit/a8396aec1941769c69fd462d0b318464afdb2193)
|
||||
- Release 2.0.3 [`8416d77`](https://github.com/oceanprotocol/ocean-subgraph/commit/8416d773cc2f7cd9606872c0a61f7bf782c95006)
|
||||
|
||||
#### [v2.0.2](https://github.com/oceanprotocol/ocean-subgraph/compare/v2.0.1...v2.0.2)
|
||||
|
||||
> 26 July 2022
|
||||
|
||||
- add event Index to pool transactions [`#497`](https://github.com/oceanprotocol/ocean-subgraph/pull/497)
|
||||
- Bump release-it from 15.1.3 to 15.1.4 [`#499`](https://github.com/oceanprotocol/ocean-subgraph/pull/499)
|
||||
- Bump @graphprotocol/graph-cli from 0.29.0 to 0.33.0 [`#495`](https://github.com/oceanprotocol/ocean-subgraph/pull/495)
|
||||
- Bump typescript from 4.6.4 to 4.7.4 [`#461`](https://github.com/oceanprotocol/ocean-subgraph/pull/461)
|
||||
- Bump release-it from 15.1.2 to 15.1.3 [`#496`](https://github.com/oceanprotocol/ocean-subgraph/pull/496)
|
||||
- Bump release-it from 15.1.1 to 15.1.2 [`#489`](https://github.com/oceanprotocol/ocean-subgraph/pull/489)
|
||||
- Bump @oceanprotocol/lib from 1.1.5 to 1.1.6 [`#488`](https://github.com/oceanprotocol/ocean-subgraph/pull/488)
|
||||
- Issue 471 provider fees [`#474`](https://github.com/oceanprotocol/ocean-subgraph/pull/474)
|
||||
- Bump parse-url from 6.0.0 to 6.0.2 [`#485`](https://github.com/oceanprotocol/ocean-subgraph/pull/485)
|
||||
- Bump @oceanprotocol/lib from 1.1.3 to 1.1.5 [`#481`](https://github.com/oceanprotocol/ocean-subgraph/pull/481)
|
||||
- Bump release-it from 15.1.0 to 15.1.1 [`#479`](https://github.com/oceanprotocol/ocean-subgraph/pull/479)
|
||||
- Bump eslint-plugin-prettier from 4.0.0 to 4.2.1 [`#478`](https://github.com/oceanprotocol/ocean-subgraph/pull/478)
|
||||
- Revert "Removing pools from schema" [`493a6d2`](https://github.com/oceanprotocol/ocean-subgraph/commit/493a6d25461b163c52b08358b62ba17a77cee41f)
|
||||
- Removing pools from schema [`0b8f6e1`](https://github.com/oceanprotocol/ocean-subgraph/commit/0b8f6e1af510c8164f56bd81687012c8a23665b6)
|
||||
- Revert "Removing pool events from subgraph.template.yaml" [`a733b27`](https://github.com/oceanprotocol/ocean-subgraph/commit/a733b27fa134073073390829d6c3e9ae939bb337)
|
||||
|
||||
#### [v2.0.1](https://github.com/oceanprotocol/ocean-subgraph/compare/v2.0.0...v2.0.1)
|
||||
|
||||
> 30 June 2022
|
||||
|
||||
- changing lastPriceToken from token to string [`#477`](https://github.com/oceanprotocol/ocean-subgraph/pull/477)
|
||||
- Release 2.0.1 [`cb98901`](https://github.com/oceanprotocol/ocean-subgraph/commit/cb9890122c02cb42b4fc374892c010e6f7166b8e)
|
||||
|
||||
### [v2.0.0](https://github.com/oceanprotocol/ocean-subgraph/compare/v1.2.1...v2.0.0)
|
||||
|
||||
> 29 June 2022
|
||||
|
||||
- Release 2.0.0 [`d864a5a`](https://github.com/oceanprotocol/ocean-subgraph/commit/d864a5ade7ebcf1067cd7a930b268d75833aa536)
|
||||
|
||||
#### [v1.2.1](https://github.com/oceanprotocol/ocean-subgraph/compare/v1.2.0...v1.2.1)
|
||||
|
||||
> 29 June 2022
|
||||
|
||||
- changing the type of lastPriceToken from string to Token on Order [`#462`](https://github.com/oceanprotocol/ocean-subgraph/pull/462)
|
||||
- Bump @oceanprotocol/lib from 1.1.2 to 1.1.3 [`#470`](https://github.com/oceanprotocol/ocean-subgraph/pull/470)
|
||||
- Bump release-it from 15.0.0 to 15.1.0 [`#469`](https://github.com/oceanprotocol/ocean-subgraph/pull/469)
|
||||
|
|
21
Dockerfile
21
Dockerfile
|
@ -1,9 +1,24 @@
|
|||
FROM node:16
|
||||
|
||||
FROM ubuntu:20.04 as base
|
||||
RUN apt-get update && apt-get -y install bash curl
|
||||
RUN curl -sL https://deb.nodesource.com/setup_16.x -o /tmp/nodesource_setup.sh
|
||||
RUN bash /tmp/nodesource_setup.sh
|
||||
RUN apt install nodejs
|
||||
|
||||
|
||||
|
||||
FROM base as builder
|
||||
RUN apt-get update && apt-get -y install wget
|
||||
COPY package*.json /usr/src/app/
|
||||
WORKDIR /usr/src/app
|
||||
RUN npm install
|
||||
WORKDIR /usr/src/app/
|
||||
ENV NODE_ENV=production
|
||||
RUN npm ci
|
||||
|
||||
|
||||
FROM base as runner
|
||||
ENV NODE_ENV=production
|
||||
COPY . /usr/src/app
|
||||
WORKDIR /usr/src/app/
|
||||
COPY --from=builder /usr/src/app/node_modules/ /usr/src/app/node_modules/
|
||||
ENV DEPLOY_SUBGRAPH=true
|
||||
ENTRYPOINT ["/usr/src/app/docker-entrypoint.sh"]
|
139
README.md
139
README.md
|
@ -30,58 +30,24 @@
|
|||
|
||||
This subgraph is deployed under `/subgraphs/name/oceanprotocol/ocean-subgraph/` namespace for all networks the Ocean Protocol contracts are deployed to:
|
||||
|
||||
- [v4.subgraph.ropsten.oceanprotocol.com](https://v4.subgraph.ropsten.oceanprotocol.com/subgraphs/name/oceanprotocol/ocean-subgraph/graphql)
|
||||
- [v4.subgraph.rinkeby.oceanprotocol.com](https://v4.subgraph.rinkeby.oceanprotocol.com/subgraphs/name/oceanprotocol/ocean-subgraph/graphql)
|
||||
- [v4.subgraph.mainnet.oceanprotocol.com](https://v4.subgraph.mainnet.oceanprotocol.com/subgraphs/name/oceanprotocol/ocean-subgraph/graphql)
|
||||
- [v4.subgraph.polygon.oceanprotocol.com](https://v4.subgraph.polygon.oceanprotocol.com/subgraphs/name/oceanprotocol/ocean-subgraph/graphql)
|
||||
- [v4.subgraph.bsc.oceanprotocol.com](https://v4.subgraph.bsc.oceanprotocol.com/subgraphs/name/oceanprotocol/ocean-subgraph/graphql)
|
||||
- [v4.subgraph.moonriver.oceanprotocol.com](https://v4.subgraph.moonriver.oceanprotocol.com/subgraphs/name/oceanprotocol/ocean-subgraph/graphql)
|
||||
- [v4.subgraph.energyweb.oceanprotocol.com](https://v4.subgraph.energyweb.oceanprotocol.com/subgraphs/name/oceanprotocol/ocean-subgraph/graphql)
|
||||
- [v4.subgraph.mumbai.oceanprotocol.com](https://v4.subgraph.mumbai.oceanprotocol.com/subgraphs/name/oceanprotocol/ocean-subgraph/graphql)
|
||||
- [v4.subgraph.moonbase.oceanprotocol.com](https://v4.subgraph.moonbase.oceanprotocol.com/subgraphs/name/oceanprotocol/ocean-subgraph/graphql)
|
||||
|
||||
## ⛵ Example Queries
|
||||
|
||||
**All pools**
|
||||
|
||||
```graphql
|
||||
{
|
||||
pools(orderBy: baseTokenLiquidity, orderDirection: desc) {
|
||||
id
|
||||
datatoken {
|
||||
address
|
||||
}
|
||||
baseToken {
|
||||
symbol
|
||||
}
|
||||
baseTokenLiquidity
|
||||
datatokenLiquidity
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Pools with the highest liquidity**
|
||||
|
||||
```graphql
|
||||
{
|
||||
pools(where: {datatokenLiquidity_gte: 1}, orderBy: baseTokenLiquidity, orderDirection: desc, first: 15) {
|
||||
id
|
||||
datatoken {
|
||||
address
|
||||
}
|
||||
baseToken {
|
||||
symbol
|
||||
}
|
||||
baseTokenLiquidity
|
||||
datatokenLiquidity
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**All Data NFTs**
|
||||
|
||||
```graphql
|
||||
{
|
||||
nfts(orderBy: createdTimestamp, orderDirection: desc, first: 1000) {
|
||||
id,
|
||||
symbol,
|
||||
name,
|
||||
creator,
|
||||
id
|
||||
symbol
|
||||
name
|
||||
creator
|
||||
createdTimestamp
|
||||
}
|
||||
}
|
||||
|
@ -89,93 +55,66 @@ This subgraph is deployed under `/subgraphs/name/oceanprotocol/ocean-subgraph/`
|
|||
|
||||
> Note: 1000 is the maximum number of items the subgraph can return.
|
||||
|
||||
**All Datatokens**
|
||||
**Total Orders for Each User**
|
||||
|
||||
```graphql
|
||||
{
|
||||
tokens(where: {isDatatoken: true}, orderBy: createdTimestamp, orderDirection: desc, first: 1000) {
|
||||
users(first: 1000) {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
address
|
||||
holderCount
|
||||
totalOrders
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**All pool transactions for a given user**
|
||||
**Total Orders for All Users**
|
||||
|
||||
```graphql
|
||||
{
|
||||
poolTransactions(
|
||||
orderBy: timestamp
|
||||
orderDirection: desc
|
||||
where: { user: $user }
|
||||
first: 1000
|
||||
) {
|
||||
baseToken {
|
||||
symbol
|
||||
address
|
||||
}
|
||||
baseTokenValue
|
||||
datatoken {
|
||||
symbol
|
||||
address
|
||||
}
|
||||
datatokenValue
|
||||
type
|
||||
tx
|
||||
timestamp
|
||||
pool {
|
||||
datatoken {
|
||||
users(first: 1000) {
|
||||
id
|
||||
totalOrders
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> Note: 1000 is the maximum number of items the subgraph can return.
|
||||
|
||||
**Total Orders for a Specific User**
|
||||
|
||||
```graphql
|
||||
{
|
||||
user(id: $user) {
|
||||
id
|
||||
}
|
||||
totalOrders
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> Note: all ETH addresses like `$user` in above example need to be passed as a lowercase string.
|
||||
|
||||
**All pool transactions for a given user in an individual pool**
|
||||
**All Orders**
|
||||
|
||||
```graphql
|
||||
```
|
||||
{
|
||||
poolTransactions(
|
||||
orderBy: timestamp
|
||||
orderDirection: desc
|
||||
where: { pool: $pool, user: $user }
|
||||
first: 1000
|
||||
) {
|
||||
baseToken {
|
||||
symbol
|
||||
address
|
||||
}
|
||||
baseTokenValue
|
||||
datatoken {
|
||||
symbol
|
||||
address
|
||||
}
|
||||
datatokenValue
|
||||
type
|
||||
tx
|
||||
timestamp
|
||||
pool {
|
||||
orders(orderBy: createdTimestamp, orderDirection: desc, first: 1000){
|
||||
amount
|
||||
datatoken {
|
||||
id
|
||||
}
|
||||
consumer {
|
||||
id
|
||||
}
|
||||
payer {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> Note: all ETH addresses like `$pool` and `$user` in above example need to be passed as a lowercase string.
|
||||
> Note: 1000 is the maximum number of items the subgraph can return.
|
||||
|
||||
## 🏊 Development on Barge
|
||||
|
||||
|
||||
1. Clone [barge](https://github.com/oceanprotocol/barge) and run it in another terminal:
|
||||
|
||||
```bash
|
||||
|
@ -195,11 +134,13 @@ npm i
|
|||
```
|
||||
|
||||
3. Let the components know where to pickup the smart contract addresses.
|
||||
|
||||
```
|
||||
export ADDRESS_FILE="${HOME}/.ocean/ocean-contracts/artifacts/address.json"
|
||||
```
|
||||
|
||||
4. Generate the subgraphs
|
||||
|
||||
```bash
|
||||
node ./scripts/generatenetworkssubgraphs.js barge
|
||||
npm run codegen
|
||||
|
@ -219,10 +160,8 @@ npm run deploy:local
|
|||
|
||||
You now have a local graph-node running on http://127.0.0.1:9000/subgraphs/name/oceanprotocol/ocean-subgraph/graphql
|
||||
|
||||
|
||||
## 🏊 Deploying graphs for live networks
|
||||
|
||||
|
||||
1. Clone the repo and install dependencies:
|
||||
|
||||
```bash
|
||||
|
@ -232,11 +171,11 @@ npm i
|
|||
```
|
||||
|
||||
2. Generate & deploy on rinkeby
|
||||
|
||||
```bash
|
||||
npm run quickstart:rinkeby
|
||||
```
|
||||
|
||||
|
||||
## 🔍 Testing
|
||||
|
||||
- Please note: the `npm run test` command is currently not working due to [this issue](https://github.com/graphprotocol/graph-ts/issues/113).
|
||||
|
@ -321,7 +260,7 @@ You can edit the event handler code and then run `npm run deploy:local`, with so
|
|||
## 🏛 License
|
||||
|
||||
```
|
||||
Copyright ((C)) 2022 Ocean Protocol Foundation
|
||||
Copyright ((C)) 2023 Ocean Protocol Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,422 +0,0 @@
|
|||
{
|
||||
"_format": "hh-sol-artifact-1",
|
||||
"contractName": "ERC721RolesAddress",
|
||||
"sourceName": "contracts/utils/ERC721RolesAddress.sol",
|
||||
"abi": [
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "user",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "signer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "timestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "blockNumber",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "AddedManager",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "user",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "signer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "timestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "blockNumber",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "AddedTo725StoreList",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "user",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "signer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "timestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "blockNumber",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "AddedToCreateERC20List",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "user",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "signer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "timestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "blockNumber",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "AddedToMetadataList",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "signer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "timestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "blockNumber",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "CleanedPermissions",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "user",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "signer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "timestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "blockNumber",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "RemovedFrom725StoreList",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "user",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "signer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "timestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "blockNumber",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "RemovedFromCreateERC20List",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "user",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "signer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "timestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "blockNumber",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "RemovedFromMetadataList",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "user",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "signer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "timestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "blockNumber",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "RemovedManager",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_allowedAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "addTo725StoreList",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_allowedAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "addToCreateERC20List",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_allowedAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "addToMetadataList",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "auth",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "user",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getPermissions",
|
||||
"outputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "manager",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "deployERC20",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "updateMetadata",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "store",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"internalType": "struct ERC721RolesAddress.Roles",
|
||||
"name": "",
|
||||
"type": "tuple"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_allowedAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeFrom725StoreList",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_allowedAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeFromCreateERC20List",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_allowedAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeFromMetadataList",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
],
|
||||
"bytecode": "0x608060405234801561001057600080fd5b5061090f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063431053ac1161005b578063431053ac1461019f5780634a63740a146101b2578063b0c41ead146101c5578063fe1ec880146101f057600080fd5b806310c558bf1461008d578063160a7925146100a257806319c186e514610179578063273e06b31461018c575b600080fd5b6100a061009b366004610859565b610203565b005b6101356100b0366004610859565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b0316600090815260208181526040918290208251608081018452905460ff808216151583526101008204811615159383019390935262010000810483161515938201939093526301000000909204161515606082015290565b604051610170919081511515815260208083015115159082015260408083015115159082015260609182015115159181019190915260800190565b60405180910390f35b6100a0610187366004610859565b6102f0565b6100a061019a366004610859565b6103ca565b6100a06101ad366004610859565b6104fc565b6100a06101c0366004610859565b61062d565b6101d86101d3366004610889565b610703565b6040516001600160a01b039091168152602001610170565b6100a06101fe366004610859565b61072d565b3360009081526020819052604090205460ff1615156001146102405760405162461bcd60e51b8152600401610237906108a2565b60405180910390fd5b6001600160a01b038116600081815260208190526040808220805462ff000019166201000017815560018054808201825593527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf690920180546001600160a01b0319168417905551909133917fc2a42571a74ce1442c8c44d375ba9442e7d55d94b37afeace261c83c62128fa4906102e49042904390918252602082015260400190565b60405180910390a35050565b3360009081526020819052604090205460ff1615156001146103245760405162461bcd60e51b8152600401610237906108a2565b6001600160a01b038116600081815260208190526040808220805463ff0000001916630100000017815560018054808201825593527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf690920180546001600160a01b0319168417905551909133917feb09276310ed110a7e565d64966d0ff68a47112d2dd5eeb6cbd7451836ce35ee906102e49042904390918252602082015260400190565b3360009081526020819052604090205460ff1615156001148061041b5750336001600160a01b03821614801561041b5750336000908152602081905260409020546301000000900460ff1615156001145b1561047f576001600160a01b03811660008181526020818152604091829020805463ff000000191681558251428152439281019290925292339290917fc929b18b08ffea86a1f95e29384dbe8968f2fcbd70cfd735df3aba1cc548cbf391016102e4565b60405162461bcd60e51b815260206004820152604660248201527f455243373231526f6c6573416464726573733a204e6f7420656e6f756768207060448201527f65726d697373696f6e7320746f2072656d6f76652066726f6d2037323553746f6064820152651c99531a5cdd60d21b608482015260a401610237565b3360009081526020819052604090205460ff1615156001148061054c5750336001600160a01b03821614801561054c57503360009081526020819052604090205462010000900460ff1615156001145b156105af576001600160a01b03811660008181526020818152604091829020805462ff0000191681558251428152439281019290925292339290917f9b41e1311fa819e825bc77fa2568492112e15ea92d173f3f8ee1c8ec3c1c562b91016102e4565b60405162461bcd60e51b815260206004820152604760248201527f455243373231526f6c6573416464726573733a204e6f7420656e6f756768207060448201527f65726d697373696f6e7320746f2072656d6f76652066726f6d206d65746164616064820152661d18481b1a5cdd60ca1b608482015260a401610237565b3360009081526020819052604090205460ff1615156001146106615760405162461bcd60e51b8152600401610237906108a2565b6001600160a01b038116600081815260208190526040808220805461ff00191661010017815560018054808201825593527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf690920180546001600160a01b0319168417905551909133917f0572d56343be407a66810f01449212e8545e14ff5049c479d34be944cdfd0d4f906102e49042904390918252602082015260400190565b6001818154811061071357600080fd5b6000918252602090912001546001600160a01b0316905081565b3360009081526020819052604090205460ff1615156001148061077d5750336001600160a01b03821614801561077d57503360009081526020819052604090205460ff6101009091041615156001145b156107df576001600160a01b03811660008181526020818152604091829020805461ff00191681558251428152439281019290925292339290917f59bd33f4c27cc16a2d74450e1fa43d7896020be9aecea4bee009db9294de899791016102e4565b60405162461bcd60e51b815260206004820152604360248201527f455243373231526f6c6573416464726573733a204e6f7420656e6f756768207060448201527f65726d697373696f6e7320746f2072656d6f76652066726f6d2045524332304c6064820152621a5cdd60ea1b608482015260a401610237565b60006020828403121561086b57600080fd5b81356001600160a01b038116811461088257600080fd5b9392505050565b60006020828403121561089b57600080fd5b5035919050565b6020808252601f908201527f455243373231526f6c6573416464726573733a204e4f54204d414e414745520060408201526060019056fea2646970667358221220cabd9a0cec3e45ffba59a95bb3ddc1d19aa1c82a0724b54aabff16b67c302d2c64736f6c634300080a0033",
|
||||
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063431053ac1161005b578063431053ac1461019f5780634a63740a146101b2578063b0c41ead146101c5578063fe1ec880146101f057600080fd5b806310c558bf1461008d578063160a7925146100a257806319c186e514610179578063273e06b31461018c575b600080fd5b6100a061009b366004610859565b610203565b005b6101356100b0366004610859565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b0316600090815260208181526040918290208251608081018452905460ff808216151583526101008204811615159383019390935262010000810483161515938201939093526301000000909204161515606082015290565b604051610170919081511515815260208083015115159082015260408083015115159082015260609182015115159181019190915260800190565b60405180910390f35b6100a0610187366004610859565b6102f0565b6100a061019a366004610859565b6103ca565b6100a06101ad366004610859565b6104fc565b6100a06101c0366004610859565b61062d565b6101d86101d3366004610889565b610703565b6040516001600160a01b039091168152602001610170565b6100a06101fe366004610859565b61072d565b3360009081526020819052604090205460ff1615156001146102405760405162461bcd60e51b8152600401610237906108a2565b60405180910390fd5b6001600160a01b038116600081815260208190526040808220805462ff000019166201000017815560018054808201825593527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf690920180546001600160a01b0319168417905551909133917fc2a42571a74ce1442c8c44d375ba9442e7d55d94b37afeace261c83c62128fa4906102e49042904390918252602082015260400190565b60405180910390a35050565b3360009081526020819052604090205460ff1615156001146103245760405162461bcd60e51b8152600401610237906108a2565b6001600160a01b038116600081815260208190526040808220805463ff0000001916630100000017815560018054808201825593527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf690920180546001600160a01b0319168417905551909133917feb09276310ed110a7e565d64966d0ff68a47112d2dd5eeb6cbd7451836ce35ee906102e49042904390918252602082015260400190565b3360009081526020819052604090205460ff1615156001148061041b5750336001600160a01b03821614801561041b5750336000908152602081905260409020546301000000900460ff1615156001145b1561047f576001600160a01b03811660008181526020818152604091829020805463ff000000191681558251428152439281019290925292339290917fc929b18b08ffea86a1f95e29384dbe8968f2fcbd70cfd735df3aba1cc548cbf391016102e4565b60405162461bcd60e51b815260206004820152604660248201527f455243373231526f6c6573416464726573733a204e6f7420656e6f756768207060448201527f65726d697373696f6e7320746f2072656d6f76652066726f6d2037323553746f6064820152651c99531a5cdd60d21b608482015260a401610237565b3360009081526020819052604090205460ff1615156001148061054c5750336001600160a01b03821614801561054c57503360009081526020819052604090205462010000900460ff1615156001145b156105af576001600160a01b03811660008181526020818152604091829020805462ff0000191681558251428152439281019290925292339290917f9b41e1311fa819e825bc77fa2568492112e15ea92d173f3f8ee1c8ec3c1c562b91016102e4565b60405162461bcd60e51b815260206004820152604760248201527f455243373231526f6c6573416464726573733a204e6f7420656e6f756768207060448201527f65726d697373696f6e7320746f2072656d6f76652066726f6d206d65746164616064820152661d18481b1a5cdd60ca1b608482015260a401610237565b3360009081526020819052604090205460ff1615156001146106615760405162461bcd60e51b8152600401610237906108a2565b6001600160a01b038116600081815260208190526040808220805461ff00191661010017815560018054808201825593527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf690920180546001600160a01b0319168417905551909133917f0572d56343be407a66810f01449212e8545e14ff5049c479d34be944cdfd0d4f906102e49042904390918252602082015260400190565b6001818154811061071357600080fd5b6000918252602090912001546001600160a01b0316905081565b3360009081526020819052604090205460ff1615156001148061077d5750336001600160a01b03821614801561077d57503360009081526020819052604090205460ff6101009091041615156001145b156107df576001600160a01b03811660008181526020818152604091829020805461ff00191681558251428152439281019290925292339290917f59bd33f4c27cc16a2d74450e1fa43d7896020be9aecea4bee009db9294de899791016102e4565b60405162461bcd60e51b815260206004820152604360248201527f455243373231526f6c6573416464726573733a204e6f7420656e6f756768207060448201527f65726d697373696f6e7320746f2072656d6f76652066726f6d2045524332304c6064820152621a5cdd60ea1b608482015260a401610237565b60006020828403121561086b57600080fd5b81356001600160a01b038116811461088257600080fd5b9392505050565b60006020828403121561089b57600080fd5b5035919050565b6020808252601f908201527f455243373231526f6c6573416464726573733a204e4f54204d414e414745520060408201526060019056fea2646970667358221220cabd9a0cec3e45ffba59a95bb3ddc1d19aa1c82a0724b54aabff16b67c302d2c64736f6c634300080a0033",
|
||||
"linkReferences": {},
|
||||
"deployedLinkReferences": {}
|
||||
}
|
|
@ -0,0 +1,657 @@
|
|||
<!--
|
||||
Copyright 2023 Ocean Protocol Foundation
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
|
||||
- [Kubernetes deployment](#kubernetes-deployment)
|
||||
- [Postgresql](#postgresql)
|
||||
- [IPFS](#ipfs)
|
||||
- [Graph-node](#graph-node)
|
||||
- [Docker Compose deployment](#docker-compose-deployment)
|
||||
- [Single systemd service (Graph-node+Postgresql+IPFS)](#single-systemd-service-graph-nodepostgresqlipfs)
|
||||
- [Ocean-subgraph deployment](#ocean-subgraph-deployment)
|
||||
|
||||
#### Kubernetes deployment
|
||||
|
||||
[ocean-subgraph](https://github.com/oceanprotocol/ocean-subgraph) must be deployed on top of [graph-node](https://github.com/graphprotocol/graph-node) which has the following dependencies:
|
||||
|
||||
- PostgreSQL
|
||||
|
||||
- IPFS
|
||||
|
||||
Templates (yaml files) provided and could be customized based on the environment's specifics.
|
||||
|
||||
##### Postgresql
|
||||
|
||||
It is recommended to deploy PostgreSQL as helm chart
|
||||
|
||||
References: https://github.com/bitnami/charts/tree/main/bitnami/postgresql/#installing-the-chart
|
||||
|
||||
Once PostgreSQL pods are running, a database must be created: eg. `mumbai`
|
||||
|
||||
##### IPFS
|
||||
|
||||
The following template can be customized to deploy IPFS statefulset and service:
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
labels:
|
||||
app: ipfs
|
||||
name: ipfs
|
||||
spec:
|
||||
podManagementPolicy: OrderedReady
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ipfs
|
||||
serviceName: ipfs
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: ipfs
|
||||
spec:
|
||||
containers:
|
||||
- image: ipfs/go-ipfs:v0.4.22
|
||||
imagePullPolicy: IfNotPresent
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /debug/metrics/prometheus
|
||||
port: api
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 3
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
name: s1-ipfs
|
||||
ports:
|
||||
- containerPort: 5001
|
||||
name: api
|
||||
protocol: TCP
|
||||
- containerPort: 8080
|
||||
name: gateway
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /debug/metrics/prometheus
|
||||
port: api
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 3
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
volumeMounts:
|
||||
- mountPath: /data/ipfs
|
||||
name: ipfs-storage
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext:
|
||||
fsGroup: 1000
|
||||
runAsUser: 1000
|
||||
terminationGracePeriodSeconds: 30
|
||||
updateStrategy:
|
||||
rollingUpdate:
|
||||
partition: 0
|
||||
type: RollingUpdate
|
||||
volumeClaimTemplates:
|
||||
- apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: ipfs-storage
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1G
|
||||
volumeMode: Filesystem
|
||||
status:
|
||||
phase: Pending
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: ipfs
|
||||
name: ipfs
|
||||
spec:
|
||||
clusterIP:
|
||||
clusterIPs:
|
||||
ipFamilies:
|
||||
- IPv4
|
||||
ipFamilyPolicy: SingleStack
|
||||
ports:
|
||||
- name: api
|
||||
port: 5001
|
||||
- name: gateway
|
||||
port: 8080
|
||||
selector:
|
||||
app: ipfs
|
||||
```
|
||||
|
||||
##### Graph-node
|
||||
|
||||
The following annotated templated can be customized to deploy graph-node deployment and service:
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
labels:
|
||||
app: mumbai-graph-node
|
||||
name: mumbai-graph-node
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mumbai-graph-node
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: mumbai-graph-node
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: ipfs
|
||||
value: ipfs.<namespace>.svc.cluster.local:5001
|
||||
- name: postgres_host
|
||||
value: postgresql.<namespace>.svc.cluster.local
|
||||
- name: postgres_user
|
||||
value: < postgresql user >
|
||||
- name: postgres_pass
|
||||
value: < postgresql database password >
|
||||
- name: postgres_db
|
||||
value: < postgresql database >
|
||||
- name: ethereum
|
||||
value: mumbai:https://polygon-mumbai.infura.io/v3/< INFURA ID>
|
||||
- name: GRAPH_KILL_IF_UNRESPONSIVE
|
||||
value: 'true'
|
||||
image: graphprotocol/graph-node:v0.28.2
|
||||
imagePullPolicy: IfNotPresent
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /
|
||||
port: 8000
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
name: mumbai-graph-node
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
name: graphql
|
||||
protocol: TCP
|
||||
- containerPort: 8020
|
||||
name: jsonrpc
|
||||
protocol: TCP
|
||||
- containerPort: 8030
|
||||
name: indexnode
|
||||
protocol: TCP
|
||||
- containerPort: 8040
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /
|
||||
port: 8000
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
resources:
|
||||
limits:
|
||||
cpu: '2'
|
||||
memory: 1536Mi
|
||||
requests:
|
||||
cpu: 1500m
|
||||
memory: 1536Mi
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
terminationGracePeriodSeconds: 30
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: mumbai-graph-node
|
||||
name: mumbai-graph-node
|
||||
spec:
|
||||
clusterIP:
|
||||
clusterIPs:
|
||||
internalTrafficPolicy: Cluster
|
||||
ipFamilies:
|
||||
- IPv4
|
||||
ipFamilyPolicy: SingleStack
|
||||
ports:
|
||||
- name: graphql
|
||||
port: 8000
|
||||
- name: jsonrpc
|
||||
port: 8020
|
||||
- name: indexnode
|
||||
port: 8030
|
||||
- name: metrics
|
||||
port: 8040
|
||||
selector:
|
||||
app: mumbai-graph-node
|
||||
```
|
||||
|
||||
#### Docker Compose deployment
|
||||
|
||||
##### Single systemd service (Graph-node+Postgresql+IPFS)
|
||||
|
||||
a) create _/etc/docker/compose/graph-node/docker-compose.yml_ file
|
||||
|
||||
_/etc/docker/compose/graph-node/docker-compose.yml_ (annotated - example for `mumbai` network)
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
services:
|
||||
graph-node:
|
||||
image: graphprotocol/graph-node:v0.28.2
|
||||
container_name: graph-node
|
||||
restart: on-failure
|
||||
ports:
|
||||
- '8000:8000'
|
||||
- '8020:8020'
|
||||
- '8030:8030'
|
||||
- '8040:8040'
|
||||
depends_on:
|
||||
- ipfs
|
||||
- postgres-graph
|
||||
environment:
|
||||
postgres_host: postgres-graph
|
||||
postgres_user: graph-node
|
||||
postgres_pass: < password >
|
||||
postgres_db: mumbai
|
||||
ipfs: 'ipfs:5001'
|
||||
ethereum: 'mumbai:https://polygon-mumbai.infura.io/v3/< INFURA ID >'
|
||||
GRAPH_LOG: info
|
||||
ipfs:
|
||||
image: ipfs/go-ipfs:v0.4.23
|
||||
container_name: ipfs
|
||||
restart: on-failure
|
||||
ports:
|
||||
- '5001:5001'
|
||||
volumes:
|
||||
- ipfs-graph-node:/data/ipfs
|
||||
postgres-graph:
|
||||
image: postgres:15.3
|
||||
container_name: postgres
|
||||
restart: on-failure
|
||||
ports:
|
||||
- '5432:5432'
|
||||
command: ['postgres', '-cshared_preload_libraries=pg_stat_statements']
|
||||
environment:
|
||||
POSTGRES_USER: graph-node
|
||||
POSTGRES_PASSWORD: < password >
|
||||
POSTGRES_DB: mumbai
|
||||
volumes:
|
||||
- pgdata-graph-node:/var/lib/postgresql/data
|
||||
volumes:
|
||||
pgdata-graph-node:
|
||||
driver: local
|
||||
ipfs-graph-node:
|
||||
driver: local
|
||||
```
|
||||
|
||||
b) create _/etc/systemd/system/docker-compose@graph-node.service_ file
|
||||
|
||||
```shell
|
||||
[Unit]
|
||||
Description=%i service with docker compose
|
||||
Requires=docker.service
|
||||
After=docker.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=true
|
||||
Environment="PROJECT=ocean"
|
||||
WorkingDirectory=/etc/docker/compose/%i
|
||||
ExecStartPre=/usr/bin/env docker-compose -p $PROJECT pull
|
||||
ExecStart=/usr/bin/env docker-compose -p $PROJECT up -d
|
||||
ExecStop=/usr/bin/env docker-compose -p $PROJECT stop
|
||||
ExecStopPost=/usr/bin/env docker-compose -p $PROJECT down
|
||||
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
c) run:
|
||||
|
||||
```shell
|
||||
$ sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
optional - enable service to start at boot:
|
||||
|
||||
```shell
|
||||
$ sudo systemctl enable docker-compose@graph-node.service
|
||||
```
|
||||
|
||||
d) start aquarius service:
|
||||
|
||||
```shell
|
||||
$ sudo systemctl start docker-compose@graph-node.service
|
||||
```
|
||||
|
||||
check status:
|
||||
|
||||
```shell
|
||||
$ sudo systemctl status docker-compose@graph-node.service
|
||||
● docker-compose@graph-node.service - graph-node service with docker compose
|
||||
Loaded: loaded (/etc/systemd/system/docker-compose@graph-node.service; disabled; vendor preset: enabled)
|
||||
Active: active (exited) since Sun 2023-06-25 17:05:25 UTC; 6s ago
|
||||
Process: 4878 ExecStartPre=/usr/bin/env docker-compose -p $PROJECT pull (code=exited, status=0/SUCCESS)
|
||||
Process: 4887 ExecStart=/usr/bin/env docker-compose -p $PROJECT up -d (code=exited, status=0/SUCCESS)
|
||||
Main PID: 4887 (code=exited, status=0/SUCCESS)
|
||||
CPU: 123ms
|
||||
|
||||
Jun 25 17:05:24 testvm env[4887]: Container ipfs Created
|
||||
Jun 25 17:05:24 testvm env[4887]: Container graph-node Creating
|
||||
Jun 25 17:05:24 testvm env[4887]: Container graph-node Created
|
||||
Jun 25 17:05:24 testvm env[4887]: Container ipfs Starting
|
||||
Jun 25 17:05:24 testvm env[4887]: Container postgres Starting
|
||||
Jun 25 17:05:24 testvm env[4887]: Container ipfs Started
|
||||
Jun 25 17:05:25 testvm env[4887]: Container postgres Started
|
||||
Jun 25 17:05:25 testvm env[4887]: Container graph-node Starting
|
||||
Jun 25 17:05:25 testvm env[4887]: Container graph-node Started
|
||||
Jun 25 17:05:25 testvm systemd[1]: Finished graph-node service with docker compose.
|
||||
|
||||
```
|
||||
|
||||
- check containers status
|
||||
|
||||
```shell
|
||||
$ docker ps --format "table {{.Image}}\t{{.Ports}}\t{{.Names}}\t{{.Status}}"
|
||||
IMAGE PORTS NAMES STATUS
|
||||
graphprotocol/graph-node:v0.28.2 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:8020->8020/tcp, :::8020->8020/tcp, 0.0.0.0:8030->8030/tcp, :::8030->8030/tcp, 0.0.0.0:8040->8040/tcp, :::8040->8040/tcp, 8001/tcp graph-node Up 55 minutes
|
||||
ipfs/go-ipfs:v0.4.23 4001/tcp, 8080-8081/tcp, 0.0.0.0:5001->5001/tcp, :::5001->5001/tcp ipfs Up 55 minutes
|
||||
postgres:15.3 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp postgres Up 55 minutes
|
||||
```
|
||||
|
||||
- check logs for graph-node container
|
||||
|
||||
```shell
|
||||
$ docker logs graph-node [--follow]
|
||||
```
|
||||
|
||||
#### Ocean-subgraph deployment
|
||||
|
||||
- install Node.js locally
|
||||
|
||||
- download and extract [Ocean-subgraph](https://github.com/oceanprotocol/ocean-subgraph) (check [here](https://github.com/oceanprotocol/ocean-subgraph/releases) the available releases)
|
||||
- run inside the extracted directory:
|
||||
|
||||
```shell
|
||||
$ npm i
|
||||
```
|
||||
|
||||
then
|
||||
|
||||
(Note: in this example we are deploying on graph-node running for `mumbai` testnet )
|
||||
|
||||
Note: for `ocean-subgraph` deployment in kubernetes environment, both `graph-node` and `ipfs` services must be locally forwarded using `kubectl port-forward` command.
|
||||
|
||||
```shell
|
||||
$ npm run quickstart:mumbai
|
||||
|
||||
> ocean-subgraph@3.0.8 quickstart:mumbai
|
||||
> node ./scripts/generatenetworkssubgraphs.js mumbai && npm run codegen && npm run create:local && npm run deploy:local
|
||||
|
||||
Creating subgraph.yaml for mumbai
|
||||
Adding veOCEAN
|
||||
Skipping polygon
|
||||
Skipping bsc
|
||||
Skipping energyweb
|
||||
Skipping moonriver
|
||||
Skipping mainnet
|
||||
Skipping polygonedge
|
||||
Skipping gaiaxtestnet
|
||||
Skipping alfajores
|
||||
Skipping gen-x-testnet
|
||||
Skipping filecointestnet
|
||||
|
||||
> ocean-subgraph@3.0.8 codegen
|
||||
> graph codegen --output-dir src/@types
|
||||
|
||||
Skip migration: Bump mapping apiVersion from 0.0.1 to 0.0.2
|
||||
Skip migration: Bump mapping apiVersion from 0.0.2 to 0.0.3
|
||||
Skip migration: Bump mapping apiVersion from 0.0.3 to 0.0.4
|
||||
Skip migration: Bump mapping apiVersion from 0.0.4 to 0.0.5
|
||||
Skip migration: Bump mapping apiVersion from 0.0.5 to 0.0.6
|
||||
Skip migration: Bump manifest specVersion from 0.0.1 to 0.0.2
|
||||
Apply migration: Bump manifest specVersion from 0.0.2 to 0.0.4
|
||||
✔ Apply migrations
|
||||
✔ Load subgraph from subgraph.yaml
|
||||
Load contract ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json
|
||||
Load contract ABI from abis/ERC20.json
|
||||
Load contract ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json
|
||||
Load contract ABI from abis/ERC20.json
|
||||
Load contract ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veAllocate.sol/veAllocate.json
|
||||
Load contract ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veOCEAN.vy/veOCEAN.json
|
||||
Load contract ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veDelegation.vy/veDelegation.json
|
||||
Load contract ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veFeeDistributor.vy/veFeeDistributor.json
|
||||
Load contract ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/df/DFRewards.sol/DFRewards.json
|
||||
✔ Load contract ABIs
|
||||
Generate types for contract ABI: ERC721Factory (node_modules/@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json)
|
||||
Write types to src/@types/ERC721Factory/ERC721Factory.ts
|
||||
Generate types for contract ABI: ERC20 (abis/ERC20.json)
|
||||
Write types to src/@types/ERC721Factory/ERC20.ts
|
||||
Generate types for contract ABI: FactoryRouter (node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json)
|
||||
Write types to src/@types/FactoryRouter/FactoryRouter.ts
|
||||
Generate types for contract ABI: ERC20 (abis/ERC20.json)
|
||||
Write types to src/@types/FactoryRouter/ERC20.ts
|
||||
Generate types for contract ABI: veAllocate (node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veAllocate.sol/veAllocate.json)
|
||||
Write types to src/@types/veAllocate/veAllocate.ts
|
||||
Generate types for contract ABI: veOCEAN (node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veOCEAN.vy/veOCEAN.json)
|
||||
Write types to src/@types/veOCEAN/veOCEAN.ts
|
||||
Generate types for contract ABI: veDelegation (node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veDelegation.vy/veDelegation.json)
|
||||
Write types to src/@types/veDelegation/veDelegation.ts
|
||||
Generate types for contract ABI: veFeeDistributor (node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veFeeDistributor.vy/veFeeDistributor.json)
|
||||
Write types to src/@types/veFeeDistributor/veFeeDistributor.ts
|
||||
Generate types for contract ABI: DFRewards (node_modules/@oceanprotocol/contracts/artifacts/contracts/df/DFRewards.sol/DFRewards.json)
|
||||
Write types to src/@types/DFRewards/DFRewards.ts
|
||||
✔ Generate types for contract ABIs
|
||||
Generate types for data source template ERC20Template
|
||||
Generate types for data source template ERC721Template
|
||||
Generate types for data source template Dispenser
|
||||
Generate types for data source template FixedRateExchange
|
||||
Write types for templates to src/@types/templates.ts
|
||||
✔ Generate types for data source templates
|
||||
Load data source template ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json
|
||||
Load data source template ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json
|
||||
Load data source template ABI from abis/ERC20.json
|
||||
Load data source template ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/utils/ERC20Roles.sol/ERC20Roles.json
|
||||
Load data source template ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json
|
||||
Load data source template ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/utils/ERC721RolesAddress.sol/ERC721RolesAddress.json
|
||||
Load data source template ABI from abis/ERC20.json
|
||||
Load data source template ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json
|
||||
Load data source template ABI from abis/ERC20.json
|
||||
Load data source template ABI from node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json
|
||||
Load data source template ABI from abis/ERC20.json
|
||||
✔ Load data source template ABIs
|
||||
Generate types for data source template ABI: ERC20Template > ERC20Template (node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json)
|
||||
Write types to src/@types/templates/ERC20Template/ERC20Template.ts
|
||||
Generate types for data source template ABI: ERC20Template > ERC20TemplateEnterprise (node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json)
|
||||
Write types to src/@types/templates/ERC20Template/ERC20TemplateEnterprise.ts
|
||||
Generate types for data source template ABI: ERC20Template > ERC20 (abis/ERC20.json)
|
||||
Write types to src/@types/templates/ERC20Template/ERC20.ts
|
||||
Generate types for data source template ABI: ERC20Template > ERC20Roles (node_modules/@oceanprotocol/contracts/artifacts/contracts/utils/ERC20Roles.sol/ERC20Roles.json)
|
||||
Write types to src/@types/templates/ERC20Template/ERC20Roles.ts
|
||||
Generate types for data source template ABI: ERC721Template > ERC721Template (node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json)
|
||||
Write types to src/@types/templates/ERC721Template/ERC721Template.ts
|
||||
Generate types for data source template ABI: ERC721Template > ERC721RolesAddress (node_modules/@oceanprotocol/contracts/artifacts/contracts/utils/ERC721RolesAddress.sol/ERC721RolesAddress.json)
|
||||
Write types to src/@types/templates/ERC721Template/ERC721RolesAddress.ts
|
||||
Generate types for data source template ABI: ERC721Template > ERC20 (abis/ERC20.json)
|
||||
Write types to src/@types/templates/ERC721Template/ERC20.ts
|
||||
Generate types for data source template ABI: Dispenser > Dispenser (node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json)
|
||||
Write types to src/@types/templates/Dispenser/Dispenser.ts
|
||||
Generate types for data source template ABI: Dispenser > ERC20 (abis/ERC20.json)
|
||||
Write types to src/@types/templates/Dispenser/ERC20.ts
|
||||
Generate types for data source template ABI: FixedRateExchange > FixedRateExchange (node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json)
|
||||
Write types to src/@types/templates/FixedRateExchange/FixedRateExchange.ts
|
||||
Generate types for data source template ABI: FixedRateExchange > ERC20 (abis/ERC20.json)
|
||||
Write types to src/@types/templates/FixedRateExchange/ERC20.ts
|
||||
✔ Generate types for data source template ABIs
|
||||
✔ Load GraphQL schema from schema.graphql
|
||||
Write types to src/@types/schema.ts
|
||||
✔ Generate types for GraphQL schema
|
||||
|
||||
Types generated successfully
|
||||
|
||||
|
||||
> ocean-subgraph@3.0.8 create:local
|
||||
> graph create oceanprotocol/ocean-subgraph --node http://127.0.0.1:8020
|
||||
|
||||
Created subgraph: oceanprotocol/ocean-subgraph
|
||||
|
||||
> ocean-subgraph@3.0.8 deploy:local
|
||||
> graph deploy oceanprotocol/ocean-subgraph subgraph.yaml -l $npm_package_version --debug --ipfs http://127.0.0.1:5001 --node http://127.0.0.1:8020
|
||||
|
||||
Skip migration: Bump mapping apiVersion from 0.0.1 to 0.0.2
|
||||
Skip migration: Bump mapping apiVersion from 0.0.2 to 0.0.3
|
||||
Skip migration: Bump mapping apiVersion from 0.0.3 to 0.0.4
|
||||
Skip migration: Bump mapping apiVersion from 0.0.4 to 0.0.5
|
||||
Skip migration: Bump mapping apiVersion from 0.0.5 to 0.0.6
|
||||
Skip migration: Bump manifest specVersion from 0.0.1 to 0.0.2
|
||||
Skip migration: Bump manifest specVersion from 0.0.2 to 0.0.4
|
||||
✔ Apply migrations
|
||||
✔ Load subgraph from subgraph.yaml
|
||||
Compile data source: ERC721Factory => build/ERC721Factory/ERC721Factory.wasm
|
||||
Compile data source: FactoryRouter => build/FactoryRouter/FactoryRouter.wasm
|
||||
Compile data source: veAllocate => build/veAllocate/veAllocate.wasm
|
||||
Compile data source: veOCEAN => build/veOCEAN/veOCEAN.wasm
|
||||
Compile data source: veDelegation => build/veDelegation/veDelegation.wasm
|
||||
Compile data source: veFeeDistributor => build/veFeeDistributor/veFeeDistributor.wasm
|
||||
Compile data source: DFRewards => build/DFRewards/DFRewards.wasm
|
||||
Compile data source template: ERC20Template => build/templates/ERC20Template/ERC20Template.wasm
|
||||
Compile data source template: ERC721Template => build/templates/ERC721Template/ERC721Template.wasm
|
||||
Compile data source template: Dispenser => build/templates/Dispenser/Dispenser.wasm
|
||||
Compile data source template: FixedRateExchange => build/templates/FixedRateExchange/FixedRateExchange.wasm
|
||||
✔ Compile subgraph
|
||||
Copy schema file build/schema.graphql
|
||||
Write subgraph file build/ERC721Factory/node_modules/@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json
|
||||
Write subgraph file build/ERC721Factory/abis/ERC20.json
|
||||
Write subgraph file build/FactoryRouter/node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json
|
||||
Write subgraph file build/FactoryRouter/abis/ERC20.json
|
||||
Write subgraph file build/veAllocate/node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veAllocate.sol/veAllocate.json
|
||||
Write subgraph file build/veOCEAN/node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veOCEAN.vy/veOCEAN.json
|
||||
Write subgraph file build/veDelegation/node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veDelegation.vy/veDelegation.json
|
||||
Write subgraph file build/veFeeDistributor/node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veFeeDistributor.vy/veFeeDistributor.json
|
||||
Write subgraph file build/DFRewards/node_modules/@oceanprotocol/contracts/artifacts/contracts/df/DFRewards.sol/DFRewards.json
|
||||
Write subgraph file build/ERC20Template/node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json
|
||||
Write subgraph file build/ERC20Template/node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json
|
||||
Write subgraph file build/ERC20Template/abis/ERC20.json
|
||||
Write subgraph file build/ERC20Template/node_modules/@oceanprotocol/contracts/artifacts/contracts/utils/ERC20Roles.sol/ERC20Roles.json
|
||||
Write subgraph file build/ERC721Template/node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json
|
||||
Write subgraph file build/ERC721Template/node_modules/@oceanprotocol/contracts/artifacts/contracts/utils/ERC721RolesAddress.sol/ERC721RolesAddress.json
|
||||
Write subgraph file build/ERC721Template/abis/ERC20.json
|
||||
Write subgraph file build/Dispenser/node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json
|
||||
Write subgraph file build/Dispenser/abis/ERC20.json
|
||||
Write subgraph file build/FixedRateExchange/node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json
|
||||
Write subgraph file build/FixedRateExchange/abis/ERC20.json
|
||||
Write subgraph manifest build/subgraph.yaml
|
||||
✔ Write compiled subgraph to build/
|
||||
Add file to IPFS build/schema.graphql
|
||||
.. QmQa3a9ypCLC84prHGQdhbcGG4DHJceqADGxmZMmAAXuTz
|
||||
Add file to IPFS build/ERC721Factory/node_modules/@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json
|
||||
.. QmSoG3r5vyWXqjEfKAQYjwtQcQkZCsZEcJXVFWVq1tT1dD
|
||||
Add file to IPFS build/ERC721Factory/abis/ERC20.json
|
||||
.. QmXuTbDkNrN27VydxbS2huvKRk62PMgUTdPDWkxcr2w7j2
|
||||
Add file to IPFS build/FactoryRouter/node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json
|
||||
.. QmcBVA1R3yi2167UZMvV4LvG4cMHjL8ZZXmPMriCjn8DEe
|
||||
Add file to IPFS build/FactoryRouter/abis/ERC20.json
|
||||
.. QmXuTbDkNrN27VydxbS2huvKRk62PMgUTdPDWkxcr2w7j2 (already uploaded)
|
||||
Add file to IPFS build/veAllocate/node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veAllocate.sol/veAllocate.json
|
||||
.. Qmc3iwQkQAhqe1PjzTt6KZLh9rsWQvyxkFt7doj2iXv8C3
|
||||
Add file to IPFS build/veOCEAN/node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veOCEAN.vy/veOCEAN.json
|
||||
.. QmahFjirJqiwKpytFZ9CdE92LdPGBUDZs6AWpsrH2wn1VP
|
||||
Add file to IPFS build/veDelegation/node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veDelegation.vy/veDelegation.json
|
||||
.. QmfU6kZ5sksLdj3q88n7SUP63C1cnhQjU8vuMmRYwf2v5r
|
||||
Add file to IPFS build/veFeeDistributor/node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veFeeDistributor.vy/veFeeDistributor.json
|
||||
.. QmVU51oBr62D4UFXTwnMcbzuBBAAeQssqmqM9jic7A6L3v
|
||||
Add file to IPFS build/DFRewards/node_modules/@oceanprotocol/contracts/artifacts/contracts/df/DFRewards.sol/DFRewards.json
|
||||
.. QmcckRMahzpL7foEFGpWfkDBsyoWbNRfLC32uFq8ceUV3a
|
||||
Add file to IPFS build/ERC721Factory/ERC721Factory.wasm
|
||||
.. QmVfDAgZdKWxMuNfT7kso1LbFre2xhYbEeHBGm3gH3R9oE
|
||||
Add file to IPFS build/FactoryRouter/FactoryRouter.wasm
|
||||
.. QmYCC9AcaYw3nGSqNXNFHVsuB67FQEyZ8twRjRXrprcgyp
|
||||
Add file to IPFS build/veAllocate/veAllocate.wasm
|
||||
.. QmUFaYDxChi5nKEJLvHQZP1cRoqqP5k3fYSwk2JjuSceiJ
|
||||
Add file to IPFS build/veOCEAN/veOCEAN.wasm
|
||||
.. QmRYCyYKwHdSeM55vuvL1mdCooDkFQm6d2TQ7iK2N1qgur
|
||||
Add file to IPFS build/veDelegation/veDelegation.wasm
|
||||
.. QmaTjRLirzfidtQTYgzxqVVD9AX9e69TN1Y8fEsNQ9AEZq
|
||||
Add file to IPFS build/veFeeDistributor/veFeeDistributor.wasm
|
||||
.. QmZCEp4yxiDyuksEjSaceogJwLMto2UGfV1KxVuJTJLTqg
|
||||
Add file to IPFS build/DFRewards/DFRewards.wasm
|
||||
.. QmRSxe52B836bdfoJbuDY4tUCawzqgkHRNxe9ucU1JdYm5
|
||||
Add file to IPFS build/ERC20Template/node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json
|
||||
.. QmPkhFvnBbqA3You7NsK5Zsyh8kkizXUHF9pcC5V6qDJQu
|
||||
Add file to IPFS build/ERC20Template/node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json
|
||||
.. QmZnogwnfr4TeBPykvmCL2oaX63AKQP1F1uBAbbfnyPAzB
|
||||
Add file to IPFS build/ERC20Template/abis/ERC20.json
|
||||
.. QmXuTbDkNrN27VydxbS2huvKRk62PMgUTdPDWkxcr2w7j2 (already uploaded)
|
||||
Add file to IPFS build/ERC20Template/node_modules/@oceanprotocol/contracts/artifacts/contracts/utils/ERC20Roles.sol/ERC20Roles.json
|
||||
.. QmTWTzg4jTx4GxGApVyxirNRTxB7QovS4bHGuWnnW8Ciz2
|
||||
Add file to IPFS build/templates/ERC20Template/ERC20Template.wasm
|
||||
.. QmUcxes5La7n9481Vf9AoQ2Mjt1CrbS7T6tDhpnfF77Uh5
|
||||
Add file to IPFS build/ERC721Template/node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json
|
||||
.. QmPE82CiACicgu1WxEjeFrLmskiJADroQRnxH7owpK6jaP
|
||||
Add file to IPFS build/ERC721Template/node_modules/@oceanprotocol/contracts/artifacts/contracts/utils/ERC721RolesAddress.sol/ERC721RolesAddress.json
|
||||
.. Qmdhi7UK6Ww8vXH9YC3JxVUEFjTyx3XycF53rRZapVK5c3
|
||||
Add file to IPFS build/ERC721Template/abis/ERC20.json
|
||||
.. QmXuTbDkNrN27VydxbS2huvKRk62PMgUTdPDWkxcr2w7j2 (already uploaded)
|
||||
Add file to IPFS build/templates/ERC721Template/ERC721Template.wasm
|
||||
.. QmNhLws24szwpz8LM2sL6HHKc6KK4vtJwzfeZWkghuqn7Q
|
||||
Add file to IPFS build/Dispenser/node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json
|
||||
.. QmdiN7Fhw9sjoVVJgHtTtzxv5fwtFMHLNH1x1yqbswsThW
|
||||
Add file to IPFS build/Dispenser/abis/ERC20.json
|
||||
.. QmXuTbDkNrN27VydxbS2huvKRk62PMgUTdPDWkxcr2w7j2 (already uploaded)
|
||||
Add file to IPFS build/templates/Dispenser/Dispenser.wasm
|
||||
.. QmTpn9wagpmH6byjjdCBZdgypFgcw2mva3bC52nC4z3eLW
|
||||
Add file to IPFS build/FixedRateExchange/node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json
|
||||
.. Qmd2ToAptK74j8pGxe8mZXfAvY3AxstgmYH8JDMAfLtAGd
|
||||
Add file to IPFS build/FixedRateExchange/abis/ERC20.json
|
||||
.. QmXuTbDkNrN27VydxbS2huvKRk62PMgUTdPDWkxcr2w7j2 (already uploaded)
|
||||
Add file to IPFS build/templates/FixedRateExchange/FixedRateExchange.wasm
|
||||
.. QmRrwwoFF33LvPhnGCGgLBLyuLizrFgD44kW9io81tPZzX
|
||||
✔ Upload subgraph to IPFS
|
||||
|
||||
Build completed: QmVUKpgwuyDh9KgUxTzZvVNFJbdevc56YrZpZjQvu8Yp7q
|
||||
|
||||
Deployed to http://127.0.0.1:8000/subgraphs/name/oceanprotocol/ocean-subgraph/graphql
|
||||
|
||||
Subgraph endpoints:
|
||||
Queries (HTTP): http://127.0.0.1:8000/subgraphs/name/oceanprotocol/ocean-subgraph
|
||||
```
|
||||
|
||||
- This subgraph is deployed under `/subgraphs/name/oceanprotocol/ocean-subgraph/`
|
||||
|
||||
http://127.0.0.1:8000/subgraphs/name/oceanprotocol/ocean-subgraph/graphql
|
|
@ -6,6 +6,7 @@ echo "deploy subgraph is ${DEPLOY_SUBGRAPH}"
|
|||
|
||||
if [ "${DEPLOY_SUBGRAPH}" = "true" ]
|
||||
then
|
||||
rm -f /ocean-subgraph/ready
|
||||
echo "Waiting for contracts to be deployed"
|
||||
while [ ! -f "/ocean-contracts/artifacts/ready" ]; do
|
||||
sleep 2
|
||||
|
@ -13,5 +14,7 @@ then
|
|||
export ADDRESS_FILE="/ocean-contracts/artifacts/address.json"
|
||||
cd /usr/src/app/
|
||||
npm run quickstart:barge
|
||||
sleep 3
|
||||
touch /ocean-subgraph/ready
|
||||
fi
|
||||
tail -f /dev/null
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
version: '3'
|
||||
services:
|
||||
graph-node:
|
||||
image: graphprotocol/graph-node:v0.26.0
|
||||
image: graphprotocol/graph-node:v0.28.2
|
||||
ports:
|
||||
- '9000:8000'
|
||||
- '8001:8001'
|
||||
|
@ -17,8 +17,9 @@ services:
|
|||
postgres_pass: let-me-in
|
||||
postgres_db: graph-node
|
||||
ipfs: 'ipfs:5001'
|
||||
ethereum: 'rinkeby:https://rinkeby.infura.io/v3/${INFURA_PROJECT_ID}'
|
||||
RUST_LOG: info
|
||||
ethereum: 'oasis_saphire_testnet:http://192.168.136.129:8080'
|
||||
RUST_LOG: warning
|
||||
GRAPH_ETHEREUM_MAX_BLOCK_RANGE_SIZE: 100
|
||||
ipfs:
|
||||
image: ipfs/go-ipfs:v0.4.23
|
||||
ports:
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
# Add contract as dataSource and use local Subgraph + Ganache + Brownie
|
||||
To develop new features on top of `ocean-subgraph`, it pays to deploy a local Subgraph that consumes from Ganache, so you can deploy your Contracts, execute their functionality, and query the Subgraph to verify Events are being Handled correctly, w/ the right Schema being yielded.
|
||||
|
||||
The following doc takes you through:
|
||||
1. Configuring `docker-compose.yml` to run an internal Subgraph that consumes from a local Ganache.
|
||||
2. Configuring `df-py` + Brownie to connect to the `ocean-subgraph` Ganache so we can deploy our local contracts.
|
||||
3. Adding our smart contract as a dataSource for our internal Subgraph. We can then handle contract events, and transform that data into queryable entities using GQL.
|
||||
4. Finally, we can hook our contracts into Testing & verifying that your subgraph is working as intended.
|
||||
|
||||
Note 1: For this tutorial, you should be using multiple terminal windows. These will be referred to at the top of each section.
|
||||
|
||||
Note 2: For this example, we're going to use the `df-py` repository and integrate `veAllocate` contract into `ocean-subgraph`
|
||||
|
||||
Note 3: For the sake of versatility, the example below is being executed using `df-py` while verification is being done by hand by viewing & querying GQL on the browser.
|
||||
|
||||
### 1. ocean-subgraph - Add & Connect Ganache
|
||||
Section 1 takes place inside `ocean-subgraph` terminal window.
|
||||
|
||||
You should have this repository configured and working on your machine.
|
||||
|
||||
We now need to update `./docker/docker-compose.yml` to implement a local instance of Ganache. Our `graph-node` needs to listen to Ganache for events, so we update the ethereum url.
|
||||
```
|
||||
services:
|
||||
ganache:
|
||||
image: trufflesuite/ganache-cli:latest
|
||||
ports:
|
||||
- 8545:8545
|
||||
entrypoint: ["node", "/app/ganache-core.docker.cli.js", "--db", "./ganache_cache","--chainId","0x2324","--networkId","0x2324","--gasLimit","10000000000","--gasPrice","1","---hardfork","istanbul","--mnemonic","${GANACHE_MNEMONIC}", "-e", "100", "-a", "20"]
|
||||
graph-node:
|
||||
environment:
|
||||
ethereum: 'development:http://ganache:8545'
|
||||
```
|
||||
|
||||
Great, our docker environment is now setup. We can finally deploy it by typing `docker-compose up` inside of `./docker/`.
|
||||
|
||||
### 2a. df-py - Configure to connect to Subgraph
|
||||
Section 2 takes place inside `df-py` terminal window.
|
||||
|
||||
You should have this repository configured and working on your machine.
|
||||
|
||||
First, we make sure that we're inside our venv by typing `source venv/bin/activate/`. Again, we're assuming your requirements.txt, and other dependencies have been properly initialized.
|
||||
|
||||
We now `df-py` connect to Ganache via Brownie. To do this, we're going to add a network so Brownie can listen to our Ganache service.
|
||||
```
|
||||
brownie networks add Ethereum subgraph-ganache host=http://127.0.0.1:8545, chainid=8996
|
||||
```
|
||||
|
||||
We then update our `brownie-config.yaml` so that it uses the network above by default.
|
||||
```
|
||||
networks:
|
||||
default: subgraph-ganache
|
||||
```
|
||||
|
||||
You should now be able to verify that the accounts from `subgraph-ganache` are working from inside `df-py` brownie.
|
||||
```
|
||||
brownie console --network subgraph-ganache
|
||||
>>> accounts[0].balance()
|
||||
100000000000000000000
|
||||
```
|
||||
|
||||
### 2b. df-py - Configure dftools and deploy contracts
|
||||
This section continues from Section 2.
|
||||
|
||||
We can now, also configure dftools to use accounts from Ganache, and deploy contracts into `ocean-subgraph`.
|
||||
|
||||
Look inside the `ocean-subgraph` terminal for the private accounts that were generated for you inside of Ganache. Copy one of their private keys, and do the following inside of `df-py/(venv)/`
|
||||
```
|
||||
export DFTOOL_KEY=0xYourUserPrivateKeyFromGanache
|
||||
export WEB3_INFURA_PROJECT_ID=YourInfuraKey
|
||||
```
|
||||
|
||||
You should now be able to deploy a newToken + veOCEAN + veAllocate contracts.
|
||||
```
|
||||
// deploy a new token
|
||||
dftool newToken 8996
|
||||
|
||||
// use the token address from above to deploy veOcean
|
||||
dftool newVeOcean 8996 token_address
|
||||
|
||||
// deploy veAllocate
|
||||
dftool newVeAllocate 8996
|
||||
```
|
||||
|
||||
You will need the address from the new `veAllocate` contract you just deployed for the next section. This contract will be used in the future so our subgraph can listen for events.
|
||||
|
||||
### 3a. ocean-subgraph - Initialize the project
|
||||
Section 3 takes place inside `ocean-subgraph` terminal.
|
||||
|
||||
We're going to now generate `subgraph.yaml` so we can start connecting the veOCEAN contract into the logic of `ocean-subpgrah`.
|
||||
|
||||
We begin by running the following node script from the root folder.
|
||||
```
|
||||
node ./scripts/generatenetworkssubgraphs.js
|
||||
```
|
||||
|
||||
Here, we're going to configure our local `subgraph.yaml` file so we can serve our local ganache, contracts, and everything that `df-py` depends on.
|
||||
|
||||
Use this file for all of your development until you have things sorted out. If you make any mistakes, you can just recreate the file. You should make your final changes inside of `subgraph.template.yaml` before submitting a PR.
|
||||
|
||||
### 3b. ocean-subgraph - Configure dataSources
|
||||
|
||||
We now configure our `subgraph.yaml` to talk to ganache and add our veAllocate Contract as a dataSource.
|
||||
|
||||
Our first step is to reset our `subgraph.yaml` so that it can consume all the events. Do a search for `startBlock` and make sure all params are initialized to 0.
|
||||
```
|
||||
- kind: ethereum/contract
|
||||
source:
|
||||
startBlock: 0
|
||||
```
|
||||
|
||||
We then add our contract as a dataSource. We get our address from Section 2b `dftool newVeAllocate 8996` and enter it in the `dataSources` section of the `subgraph.yaml` file.
|
||||
```
|
||||
dataSources:
|
||||
- kind: ethereum/contract
|
||||
name: veAllocate
|
||||
network: development
|
||||
source:
|
||||
address: 0x0000000000000000000000000000000
|
||||
abi: veAllocate
|
||||
startBlock: 0
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.6
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/veAllocate.ts
|
||||
entities:
|
||||
- veAllocate
|
||||
abis:
|
||||
- name: veAllocate
|
||||
file: ./abis/veAllocate.json
|
||||
eventHandlers:
|
||||
- event: AllocationSet(indexed address,indexed address,indexed uint256,uint256)
|
||||
handler: handleAllocationSet
|
||||
```
|
||||
|
||||
As you can see, we have also imported our `veAllocate.json ABI` file into the project, added the contract events we want to handle, and created a mapping script `./src/mappings/veAllocate.ts` so we can handle all the vents for the Subgraph.
|
||||
|
||||
Note: This tutorial will not go into details of how to do this work. Someone can create a separate guide on how to handle internal logic, define GraphQL entities, and save records into GraphQL.
|
||||
|
||||
_Please review the PR associated with this README for more intuition on this_
|
||||
|
||||
### 4a. ocean-subgraph - run: `npm run codegen`
|
||||
From the root folder run this command.
|
||||
|
||||
You'll have to do this again every time you change `schema.graphql`
|
||||
|
||||
### 4b. ocean-subgraph - run: `npm run create:local`
|
||||
From the root folder run this command.
|
||||
|
||||
You'll have to do this again every time you run step 5a.
|
||||
|
||||
### 4c. ocean-subgraph - run: `npm run deploy:local`
|
||||
From the root folder run this command.
|
||||
|
||||
You'll have to do this again when you write any new subgraph code (mappings, utils, etc...).
|
||||
|
||||
### 5. ocean-subgraph - restart docker
|
||||
Restart docker containers via `docker-compose up`
|
||||
|
||||
### 6. df-py - Execute onchain events + query subgraph
|
||||
You can now start performing your onchain + contract tests and see records inside of your local subgraph.
|
||||
|
||||
As an example, you may use the following command inside `dftools` to generate many onchain events for Ganache.
|
||||
```
|
||||
dftool manyrandom 8996
|
||||
```
|
File diff suppressed because it is too large
Load Diff
63
package.json
63
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "ocean-subgraph",
|
||||
"version": "1.2.1",
|
||||
"version": "4.0.2",
|
||||
"scripts": {
|
||||
"start": "",
|
||||
"quickstart:development": "node ./scripts/generatenetworkssubgraphs.js development && npm run codegen && npm run create:local && npm run deploy:local",
|
||||
|
@ -13,17 +13,33 @@
|
|||
"quickstart:mainnet": "node ./scripts/generatenetworkssubgraphs.js mainnet && npm run codegen && npm run create:local && npm run deploy:local",
|
||||
"quickstart:moonriver": "node ./scripts/generatenetworkssubgraphs.js moonriver && npm run codegen && npm run create:local && npm run deploy:local",
|
||||
"quickstart:energyweb": "node ./scripts/generatenetworkssubgraphs.js energyweb && npm run codegen && npm run create:local && npm run deploy:local",
|
||||
"quickstart:sepolia": "node ./scripts/generatenetworkssubgraphs.js sepolia && npm run codegen && npm run create:local && npm run deploy:local",
|
||||
"quickstart:gen-x-testnet": "node ./scripts/generatenetworkssubgraphs.js gen-x-testnet && npm run codegen && npm run create:local && npm run deploy:local",
|
||||
"quickstart:bsc": "node ./scripts/generatenetworkssubgraphs.js bsc && npm run codegen && npm run create:local && npm run deploy:local",
|
||||
"quickstart:oasis_saphire_testnet": "node ./scripts/generatenetworkssubgraphs.js oasis_saphire_testnet && npm run codegen && npm run create:local && npm run deploy:local",
|
||||
"quickstart:oasis_saphire": "node ./scripts/generatenetworkssubgraphs.js oasis_saphire && npm run codegen && npm run create:local && npm run deploy:local",
|
||||
"quickstart:optimism": "node ./scripts/generatenetworkssubgraphs.js optimism && npm run codegen && npm run create:local && npm run deploy:local",
|
||||
"quickstart:optimism_sepolia": "node ./scripts/generatenetworkssubgraphs.js optimism_sepolia && npm run codegen && npm run create:local && npm run deploy:local",
|
||||
"create:thegraph": "graph create oceanprotocol/ocean-subgraph --node https://api.thegraph.com/deploy/",
|
||||
"create:local": "graph create oceanprotocol/ocean-subgraph --node http://127.0.0.1:8020",
|
||||
"create:local-barge": "graph create oceanprotocol/ocean-subgraph --node http://172.15.0.15:8020",
|
||||
"codegen": "graph codegen --output-dir src/@types",
|
||||
"build": "graph build",
|
||||
"deploy:thegraph": "graph deploy oceanprotocol/ocean-subgraph -l $npm_package_version --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
|
||||
"deploy:local": "graph deploy oceanprotocol/ocean-subgraph subgraph.yaml -l $npm_package_version --debug --ipfs http://127.0.0.1:5001 --node http://127.0.0.1:8020",
|
||||
"deploy:local-barge": "graph deploy oceanprotocol/ocean-subgraph subgraph.yaml -l $npm_package_version --debug --ipfs http://172.15.0.16:5001 --node http://172.15.0.15:8020",
|
||||
"deploy:local": "graph deploy oceanprotocol/ocean-subgraph subgraph.yaml -l $npm_package_version --ipfs http://127.0.0.1:5001 --node http://127.0.0.1:8020",
|
||||
"deploy:local-barge": "graph deploy oceanprotocol/ocean-subgraph subgraph.yaml -l $npm_package_version --ipfs http://172.15.0.16:5001 --node http://172.15.0.15:8020",
|
||||
"test": "npm run codegen && npm run lint && npm run type-check",
|
||||
"test-integration": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/**/*.test.ts'",
|
||||
"test-dispenser": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/Dispenser.test.ts'",
|
||||
"test-simple": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/SimpleSubgraph.test.ts'",
|
||||
"test-fixed": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/FixedRateExchange.test.ts'",
|
||||
"test-users": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/users.test.ts'",
|
||||
"test-ve": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/VeOcean.test.ts'",
|
||||
"test-df": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/DFRewards.test.ts'",
|
||||
"test-dt": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/Datatoken.test.ts'",
|
||||
"test-zend": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/ZEnding.test.ts'",
|
||||
"test-publish-consume": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/SimplePublishConsume.test.ts'",
|
||||
"test-nft": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/Nft.test.ts'",
|
||||
"lint": "eslint --ignore-path .gitignore --ext .js --ext .ts --ext .tsx .",
|
||||
"lint:fix": "eslint --ignore-path .gitignore --ext .js,.ts,.tsx . --fix",
|
||||
"format": "prettier --ignore-path .gitignore './**/*.{css,yml,js,ts,tsx,json,yaml}' --write",
|
||||
|
@ -33,34 +49,39 @@
|
|||
"changelog": "auto-changelog -p"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@graphprotocol/graph-cli": "^0.29.0",
|
||||
"@graphprotocol/graph-ts": "^0.27.0",
|
||||
"@types/chai": "^4.3.1",
|
||||
"@types/chai": "^4.3.11",
|
||||
"@types/chai-spies": "^1.0.3",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||
"@typescript-eslint/parser": "^4.33.0",
|
||||
"@types/mocha": "^10.0.2",
|
||||
"@types/node": "^20.8.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.4",
|
||||
"@typescript-eslint/parser": "^6.19.0",
|
||||
"auto-changelog": "^2.4.0",
|
||||
"chai": "^4.3.6",
|
||||
"chai": "^4.3.10",
|
||||
"chai-spies": "^1.0.0",
|
||||
"cross-fetch": "^3.1.6",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-oceanprotocol": "^2.0.3",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-config-oceanprotocol": "^2.0.4",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-standard": "^5.0.0",
|
||||
"mocha": "^10.0.0",
|
||||
"mock-local-storage": "^1.1.21",
|
||||
"prettier": "^2.7.1",
|
||||
"release-it": "^15.1.0",
|
||||
"ethereumjs-util": "^7.1.5",
|
||||
"mocha": "^10.2.0",
|
||||
"mock-local-storage": "^1.1.24",
|
||||
"prettier": "^2.8.8",
|
||||
"release-it": "^17.0.0",
|
||||
"source-map-support": "^0.5.21",
|
||||
"ts-node": "^10.9.1",
|
||||
"ts-node-dev": "^2.0.0",
|
||||
"ts-node-register": "^1.0.0",
|
||||
"typescript": "^4.6.4"
|
||||
"typescript": "^5.4.5",
|
||||
"@oceanprotocol/lib": "^2.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@oceanprotocol/lib": "^1.1.3",
|
||||
"cross-fetch": "^3.1.4"
|
||||
"@oceanprotocol/contracts": "^2.0.3",
|
||||
"@graphprotocol/graph-cli": "^0.71.0",
|
||||
"@graphprotocol/graph-ts": "^0.31.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
616
schema.graphql
616
schema.graphql
|
@ -30,7 +30,7 @@ type Token @entity {
|
|||
publishMarketFeeAmount: BigDecimal
|
||||
|
||||
"template ID of the datatoken"
|
||||
templateId: Int
|
||||
templateId: BigInt!
|
||||
|
||||
"number of addresses holding a balance of datatoken , TODO: can we actually calculate this? what happens when users trade the dts"
|
||||
holderCount: BigInt!
|
||||
|
@ -47,19 +47,16 @@ type Token @entity {
|
|||
"dispensers using this token"
|
||||
dispensers: [Dispenser!] @derivedFrom(field:"token")
|
||||
|
||||
"pools, only available for datatokens"
|
||||
pools: [Pool!] @derivedFrom(field:"datatoken")
|
||||
|
||||
"block time datatoken was created"
|
||||
createdTimestamp: Int!
|
||||
|
||||
"datatoken creation transaction id"
|
||||
tx: String!
|
||||
|
||||
eventIndex: Int!
|
||||
"block number when it was created"
|
||||
block: Int!
|
||||
|
||||
lastPriceToken: String!
|
||||
lastPriceToken: Token
|
||||
lastPriceValue: BigDecimal!
|
||||
}
|
||||
|
||||
|
@ -76,12 +73,12 @@ type Nft @entity{
|
|||
id: ID!
|
||||
symbol: String!
|
||||
name: String!
|
||||
tokenUri: String!
|
||||
tokenUri: String
|
||||
|
||||
"address of the owner of the nft"
|
||||
owner: String!
|
||||
owner: User!
|
||||
"address of the creator of the nft"
|
||||
creator: String!
|
||||
creator: User!
|
||||
|
||||
"same as id, it's just for easy discoverability"
|
||||
address: String!
|
||||
|
@ -101,6 +98,9 @@ type Nft @entity{
|
|||
"template address"
|
||||
template: String!
|
||||
|
||||
"template ID of the datatoken"
|
||||
templateId: Int
|
||||
|
||||
"set if NFT is transferable"
|
||||
transferable: Boolean!
|
||||
|
||||
|
@ -108,150 +108,45 @@ type Nft @entity{
|
|||
createdTimestamp: Int!
|
||||
"nft creation transaction id"
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
"block number when it was created"
|
||||
block: Int
|
||||
|
||||
"number of orders executed for all underlying datatokens"
|
||||
orderCount: BigInt!
|
||||
|
||||
"has metadata"
|
||||
hasMetadata: Boolean!
|
||||
|
||||
nftData: [NftData!] @derivedFrom(field: "nft")
|
||||
transferHistory: [NftTransferHistory!] @derivedFrom(field: "nft")
|
||||
}
|
||||
|
||||
type Pool @entity {
|
||||
"pool address"
|
||||
type NftData @entity{
|
||||
"nft address+key"
|
||||
id: ID!
|
||||
|
||||
"owner address, pool controller"
|
||||
controller: String!
|
||||
|
||||
"only finalized pools are relevant to us"
|
||||
isFinalized: Boolean!
|
||||
|
||||
"pool token symbol"
|
||||
symbol: String
|
||||
|
||||
"pool token name"
|
||||
name: String
|
||||
|
||||
"maximum supply if any, converted from wei"
|
||||
cap: BigDecimal
|
||||
|
||||
baseToken: Token!
|
||||
baseTokenLiquidity: BigDecimal!
|
||||
baseTokenWeight: BigDecimal!
|
||||
|
||||
datatoken: Token!
|
||||
datatokenLiquidity: BigDecimal!
|
||||
datatokenWeight: BigDecimal!
|
||||
|
||||
"publisher market fee value"
|
||||
publishMarketSwapFee: BigDecimal!
|
||||
"publisher market fee total amount"
|
||||
publishMarketSwapFeeAmount: BigDecimal
|
||||
|
||||
"Liquidty provider fee value"
|
||||
liquidityProviderSwapFee: BigDecimal
|
||||
"liquidity provider fee total amount"
|
||||
liquidityProviderSwapFeeAmount: BigDecimal!
|
||||
|
||||
"total pool token shares"
|
||||
totalShares: BigDecimal!
|
||||
|
||||
"total tokens that were swaped"
|
||||
totalSwapVolume: [TokenValuePair!]!
|
||||
|
||||
spotPrice: BigDecimal!
|
||||
|
||||
"count for when liquidity has been added"
|
||||
joinCount: BigInt!
|
||||
|
||||
"count for when liquidity has been removed"
|
||||
exitCount: BigInt!
|
||||
|
||||
"count for when tokens were swapped"
|
||||
swapCount: BigInt!
|
||||
|
||||
"number of transactions in this pool involving liquidity changes"
|
||||
transactionCount: BigInt!
|
||||
|
||||
"block time when pool was created"
|
||||
createdTimestamp: Int!
|
||||
"pool creation transaction id"
|
||||
tx: String!
|
||||
"block number when it was created"
|
||||
block: Int
|
||||
|
||||
shares: [PoolShare!] @derivedFrom(field: "pool")
|
||||
transactions: [PoolTransaction!] @derivedFrom(field: "pool")
|
||||
|
||||
"address of the market where the datatoken was created. This address collects market fees."
|
||||
publishMarketFeeAddress: String
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
# we will need to track pool share tx between users - bpool transfer tx event
|
||||
type PoolShare @entity {
|
||||
"poolAddress + userAddress"
|
||||
id: ID!
|
||||
user: User!
|
||||
pool: Pool!
|
||||
shares: BigDecimal!
|
||||
}
|
||||
|
||||
enum PoolTransactionType {
|
||||
JOIN,
|
||||
EXIT,
|
||||
SWAP,
|
||||
SETUP
|
||||
}
|
||||
|
||||
type PoolTransaction @entity {
|
||||
"tx address + caller address"
|
||||
id: ID!
|
||||
"pool related to this tx"
|
||||
pool: Pool!
|
||||
"user that initiates the tx"
|
||||
user: User!
|
||||
type: PoolTransactionType!
|
||||
|
||||
"number of shares transfered"
|
||||
sharesTransferAmount: BigDecimal!
|
||||
|
||||
"block time when pool was created"
|
||||
timestamp: Int!
|
||||
"pool creation transaction id"
|
||||
tx: String!
|
||||
"block number when it was created"
|
||||
block: Int
|
||||
|
||||
gasLimit: BigDecimal!
|
||||
"price expressed in eth"
|
||||
gasPrice: BigDecimal!
|
||||
|
||||
"base tokens transfered"
|
||||
baseToken: Token
|
||||
|
||||
"number of base tokens transfered, for type SWAP if value is negative it means it was removed"
|
||||
baseTokenValue: BigDecimal
|
||||
|
||||
"datatokens transfered"
|
||||
datatoken: Token
|
||||
|
||||
"number of datatokens transfered, for type SWAP if value is negative it means it was removed"
|
||||
datatokenValue: BigDecimal
|
||||
nft: Nft!
|
||||
key: Bytes
|
||||
value: Bytes
|
||||
}
|
||||
|
||||
type OrderReuse @entity {
|
||||
id: ID!
|
||||
order: Order!
|
||||
caller: String!
|
||||
createdTimestamp: BigInt!
|
||||
createdTimestamp: Int!
|
||||
tx: String!
|
||||
block: BigInt!
|
||||
eventIndex: Int!
|
||||
block: Int!
|
||||
providerFee: String
|
||||
providerFeeValidUntil: BigInt
|
||||
"gas price in Wei"
|
||||
gasPrice: BigInt
|
||||
gasUsed: BigDecimal
|
||||
}
|
||||
|
||||
type Order @entity {
|
||||
"transaction hash - token address - from address"
|
||||
"transaction hash - token address - from address - eventIndex"
|
||||
id: ID!
|
||||
datatoken: Token!
|
||||
|
||||
|
@ -259,12 +154,15 @@ type Order @entity {
|
|||
payer: User!
|
||||
amount: BigDecimal!
|
||||
serviceIndex: Int!
|
||||
nftOwner: User!
|
||||
|
||||
|
||||
# the fees will be updated from an event that will be created after (todo)
|
||||
publishingMarket: User
|
||||
publishingMarketToken: Token #
|
||||
publishingMarketAmmount: BigDecimal #call contract to get fee amount
|
||||
providerFee: String
|
||||
providerFeeValidUntil: BigInt
|
||||
|
||||
consumerMarket: User
|
||||
consumerMarketToken: Token #
|
||||
|
@ -274,32 +172,20 @@ type Order @entity {
|
|||
|
||||
createdTimestamp: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
block: Int!
|
||||
|
||||
lastPriceToken: Token!
|
||||
lastPriceToken: Token
|
||||
lastPriceValue: BigDecimal!
|
||||
estimatedUSDValue: BigDecimal!
|
||||
}
|
||||
|
||||
# to be removed, mabye for pool shares only
|
||||
type TokenTransaction @entity {
|
||||
id: ID! # Log ID
|
||||
event: String
|
||||
token: Token
|
||||
user: User
|
||||
|
||||
block: Int!
|
||||
gasUsed: BigDecimal!
|
||||
gasPrice: BigDecimal!
|
||||
createdTimestamp: Int!
|
||||
tx: String!
|
||||
gasUsed: BigDecimal
|
||||
"gas price in Wei"
|
||||
gasPrice: BigInt
|
||||
}
|
||||
|
||||
type User @entity {
|
||||
id: ID!
|
||||
sharesOwned: [PoolShare!] @derivedFrom(field: "user")
|
||||
tokenBalancesOwned: [TokenValuePair!]
|
||||
poolTransactions: [PoolTransaction!] @derivedFrom(field: "user")
|
||||
orders: [Order!] @derivedFrom(field: "payer")
|
||||
freSwaps: [FixedRateExchangeSwap!] @derivedFrom(field: "by")
|
||||
|
||||
|
@ -340,6 +226,7 @@ type FixedRateExchange @entity {
|
|||
|
||||
createdTimestamp: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
block: Int!
|
||||
|
||||
"address of the market where the datatoken was created. This address collects market fees."
|
||||
|
@ -366,6 +253,7 @@ type FixedRateExchangeUpdate @entity {
|
|||
block: Int!
|
||||
createdTimestamp: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
}
|
||||
|
||||
type FixedRateExchangeSwap @entity {
|
||||
|
@ -377,6 +265,10 @@ type FixedRateExchangeSwap @entity {
|
|||
block: Int!
|
||||
createdTimestamp: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
oceanFeeAmount: BigDecimal!
|
||||
marketFeeAmount: BigDecimal!
|
||||
consumeMarketFeeAmount: BigDecimal!
|
||||
}
|
||||
|
||||
|
||||
|
@ -402,6 +294,7 @@ type Dispenser @entity {
|
|||
block: Int!
|
||||
createdTimestamp: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
|
||||
dispenses: [DispenserTransaction!] @derivedFrom(field: "dispenser")
|
||||
}
|
||||
|
@ -415,28 +308,7 @@ type DispenserTransaction @entity {
|
|||
block: Int!
|
||||
createdTimestamp: Int!
|
||||
tx: String!
|
||||
}
|
||||
|
||||
type PoolSnapshot @entity {
|
||||
id: ID!
|
||||
pool: Pool!
|
||||
"total pool shares at the end of the 24h interval"
|
||||
totalShares: BigDecimal!
|
||||
"swap value 24h"
|
||||
swapVolume: BigDecimal!
|
||||
"swap fee value 24h"
|
||||
swapFees: BigDecimal!
|
||||
"date without time"
|
||||
date: Int!
|
||||
"last spot price in the 24h interval"
|
||||
spotPrice: BigDecimal!
|
||||
|
||||
baseToken: Token!
|
||||
baseTokenLiquidity: BigDecimal!
|
||||
|
||||
datatoken: Token!
|
||||
datatokenLiquidity: BigDecimal!
|
||||
|
||||
eventIndex: Int!
|
||||
}
|
||||
|
||||
"utility type"
|
||||
|
@ -448,15 +320,6 @@ type GlobalTotalLiquidityPair @entity {
|
|||
value : BigDecimal!
|
||||
}
|
||||
|
||||
"utility type"
|
||||
type GlobalTotalPoolSwapPair @entity {
|
||||
"address of the token"
|
||||
id : ID!
|
||||
globalStatistic: GlobalStatistic!
|
||||
token : Token!
|
||||
value : BigDecimal!
|
||||
count: BigInt!
|
||||
}
|
||||
"utility type"
|
||||
type GlobalTotalFixedSwapPair @entity {
|
||||
"address of the token"
|
||||
|
@ -469,23 +332,16 @@ type GlobalTotalFixedSwapPair @entity {
|
|||
type GlobalStatistic @entity {
|
||||
id: ID!
|
||||
|
||||
"total liquidity for each base token in pools"
|
||||
totalLiquidity: [GlobalTotalLiquidityPair!]! @derivedFrom(field: "globalStatistic")
|
||||
"total swap volume for each base token in pools"
|
||||
totalPoolSwapVolume: [GlobalTotalPoolSwapPair!]! @derivedFrom(field: "globalStatistic")
|
||||
|
||||
"total swap volume for each base token in fixed rate exchanges"
|
||||
totalFixedSwapVolume: [GlobalTotalFixedSwapPair!] @derivedFrom(field: "globalStatistic")
|
||||
|
||||
"number of total orders. pool orders + fixed rate exchange orders + dispenser orders"
|
||||
"number of total orders. fixed rate exchange orders + dispenser orders"
|
||||
orderCount: Int!
|
||||
|
||||
"total nfts(erc721) created"
|
||||
nftCount: Int!
|
||||
"total datatokens (tokens with isDatatoken = true) created"
|
||||
datatokenCount:Int!
|
||||
"number of pools"
|
||||
poolCount: Int!
|
||||
|
||||
"number of fixed rate exchanges"
|
||||
fixedCount: Int!
|
||||
|
@ -493,6 +349,9 @@ type GlobalStatistic @entity {
|
|||
"number of dispensers created"
|
||||
dispenserCount: Int!
|
||||
|
||||
"total ocean locked in veOcean"
|
||||
totalOceanLocked:BigDecimal!
|
||||
|
||||
"current version"
|
||||
version: String
|
||||
}
|
||||
|
@ -519,7 +378,7 @@ type OPC @entity {
|
|||
|
||||
type NftUpdate @entity {
|
||||
id: ID! # update tx + nft address
|
||||
tokenUri: String!
|
||||
tokenUri: String
|
||||
nft: Nft!
|
||||
|
||||
"provider url that can decrypt the ddo"
|
||||
|
@ -537,14 +396,381 @@ type NftUpdate @entity {
|
|||
block: Int!
|
||||
timestamp: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
}
|
||||
|
||||
|
||||
type Template @entity{
|
||||
id: ID!
|
||||
fixedRateTemplates: [String!]
|
||||
dispenserTemplates: [String!]
|
||||
ssTemplates: [String!]
|
||||
}
|
||||
|
||||
# Not tracking allocationToId or idToAllocation
|
||||
type VeAllocateUser @entity{
|
||||
"id = {user}"
|
||||
id: ID!
|
||||
|
||||
veAllocation: [VeAllocation!] @derivedFrom(field: "allocationUser")
|
||||
allocatedTotal: BigDecimal!
|
||||
|
||||
block: Int!
|
||||
firstContact: Int!
|
||||
lastContact: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
veOcean: VeOCEAN!
|
||||
}
|
||||
|
||||
type VeAllocateId @entity{
|
||||
"id = {DataNFT Address}-{chain id}"
|
||||
id: ID!
|
||||
nftAddress: String!
|
||||
chainId: BigInt!
|
||||
|
||||
veAllocation: [VeAllocation!] @derivedFrom(field: "allocationId")
|
||||
allocatedTotal: BigDecimal!
|
||||
|
||||
block: Int!
|
||||
firstContact: Int!
|
||||
lastContact: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
}
|
||||
|
||||
# we need to track allocation of user to id
|
||||
type VeAllocation @entity {
|
||||
"id = {user}-{DataNFT Address}-{chain id}"
|
||||
id: ID!
|
||||
|
||||
allocationUser: VeAllocateUser!
|
||||
allocationId: VeAllocateId!
|
||||
|
||||
updates: [VeAllocationUpdate!] @derivedFrom(field: "veAllocation")
|
||||
allocated: BigDecimal!
|
||||
chainId: BigInt!
|
||||
nftAddress: String!
|
||||
|
||||
block: Int!
|
||||
firstContact: Int!
|
||||
lastContact: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
}
|
||||
|
||||
enum veAllocationUpdateType {
|
||||
SET,
|
||||
REMOVED
|
||||
}
|
||||
|
||||
type VeAllocationUpdate @entity {
|
||||
"{tx}-{VeAllocation id}-{eventIndex}"
|
||||
id: ID!
|
||||
|
||||
veAllocation: VeAllocation!
|
||||
type: veAllocationUpdateType!
|
||||
allocatedTotal: BigDecimal!
|
||||
|
||||
block: Int!
|
||||
timestamp: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
}
|
||||
|
||||
type VeDelegation @entity {
|
||||
"id = VeDelegation contract + tokenId"
|
||||
id: ID!
|
||||
delegator: VeOCEAN!
|
||||
receiver: VeOCEAN!
|
||||
tokenId: BigInt!
|
||||
amount: BigDecimal!
|
||||
lockedAmount: BigDecimal!
|
||||
timeLeftUnlock: Int!
|
||||
cancelTime: BigInt!
|
||||
expireTime: BigInt!
|
||||
updates: [VeDelegationUpdate!] @derivedFrom(field: "veDelegation")
|
||||
|
||||
}
|
||||
|
||||
type VeDelegationUpdate @entity {
|
||||
"id = {tx}-{eventIndex}"
|
||||
id: ID!
|
||||
block: Int!
|
||||
timestamp: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
sender: String!
|
||||
amount: BigDecimal!
|
||||
cancelTime: BigInt!
|
||||
expireTime: BigInt!
|
||||
"type: CREATE_BOOST = 0, EXTEND_BOOST = 1, BURN_BOOST = 2"
|
||||
type:Int!
|
||||
veDelegation:VeDelegation!
|
||||
}
|
||||
|
||||
|
||||
type VeOCEAN @entity {
|
||||
"id = {user address}"
|
||||
id: ID!
|
||||
"total amount of locked tokens"
|
||||
lockedAmount: BigDecimal!
|
||||
"unlock timestamp"
|
||||
unlockTime: BigInt!
|
||||
delegation: [VeDelegation!] @derivedFrom(field: "delegator")
|
||||
delegates: [VeDelegation!] @derivedFrom(field: "receiver")
|
||||
deposits: [VeDeposit!] @derivedFrom(field: "veOcean")
|
||||
claims: [VeClaim!] @derivedFrom(field: "veOcean")
|
||||
allocation: VeAllocateUser @derivedFrom(field: "veOcean")
|
||||
block: Int!
|
||||
}
|
||||
|
||||
type VeDeposit @entity {
|
||||
"id = {user address}-{tx}-{eventIndex}"
|
||||
id: ID!
|
||||
"veOcean holder"
|
||||
provider:String!
|
||||
"who initiated the tx"
|
||||
sender: String!
|
||||
"amount of tokens locked"
|
||||
value: BigDecimal!
|
||||
"unlock timestamp"
|
||||
unlockTime: BigInt!
|
||||
"deposit type: DEPOSIT_FOR = 0, CREATE_LOCK_TYPE = 1,INCREASE_LOCK_AMOUNT = 2,INCREASE_UNLOCK_TIME = 3, WITHDRAW = 4"
|
||||
type:BigInt!
|
||||
timestamp: BigInt!
|
||||
block: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
veOcean: VeOCEAN!
|
||||
totalOceanLocked:BigDecimal!
|
||||
}
|
||||
|
||||
|
||||
type VeFeeDistributor @entity {
|
||||
"id = contract address"
|
||||
id: ID!
|
||||
"token used by FeeDistributor"
|
||||
token: Token!
|
||||
claims: [VeClaim!] @derivedFrom(field: "VeFeeDistributor")
|
||||
checkpoints: [VeFeeDistributorCheckPoint!] @derivedFrom(field: "VeFeeDistributor")
|
||||
}
|
||||
|
||||
type VeFeeDistributorCheckPoint @entity {
|
||||
"id = {tx}-{eventno}"
|
||||
id: ID!
|
||||
"amount of tokens for rewards"
|
||||
tokens: BigDecimal!
|
||||
"who initiated the tx"
|
||||
sender: String!
|
||||
VeFeeDistributor: VeFeeDistributor!
|
||||
timestamp: BigInt!
|
||||
block: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
}
|
||||
|
||||
type VeClaim @entity {
|
||||
"id = {tx}-{eventno}"
|
||||
id: ID!
|
||||
"amount of tokens claimed"
|
||||
amount: BigDecimal!
|
||||
"claim epoch"
|
||||
claim_epoch: BigInt
|
||||
"max_epoch"
|
||||
max_epoch: BigInt
|
||||
timestamp: BigInt!
|
||||
block: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
veOcean: VeOCEAN!
|
||||
VeFeeDistributor: VeFeeDistributor!
|
||||
}
|
||||
|
||||
enum DFHistoryType {
|
||||
Allocated,
|
||||
Claimed
|
||||
}
|
||||
|
||||
type DFAvailableClaim @entity {
|
||||
"id = {userId}-{tokenId}"
|
||||
id: ID!
|
||||
receiver: DFReward!
|
||||
amount: BigDecimal!
|
||||
token: Token!
|
||||
}
|
||||
|
||||
|
||||
type DFHistory @entity {
|
||||
"id = {user-id}-{txId}-{eventId}"
|
||||
id: ID!
|
||||
receiver: DFReward!
|
||||
amount: BigDecimal!
|
||||
token: Token!
|
||||
type: DFHistoryType!
|
||||
timestamp: BigInt!
|
||||
block: Int!
|
||||
tx: String!
|
||||
eventIndex: Int!
|
||||
}
|
||||
|
||||
|
||||
type DFReward @entity {
|
||||
"id = {user address}"
|
||||
id: ID!
|
||||
receiver: User!
|
||||
availableClaims: [DFAvailableClaim!] @derivedFrom(field: "receiver")
|
||||
history: [DFHistory!] @derivedFrom(field: "receiver")
|
||||
}
|
||||
|
||||
type NftTransferHistory @entity {
|
||||
# ID = hash(nftAddress+txId+eventNumber)
|
||||
id: ID!
|
||||
nft: Nft!
|
||||
oldOwner: User!
|
||||
newOwner: User!
|
||||
txId: String
|
||||
eventIndex: Int!
|
||||
timestamp: Int!
|
||||
block: Int!
|
||||
}
|
||||
|
||||
type Erc721Template @entity {
|
||||
#ID = template address
|
||||
id: ID!
|
||||
templateId: BigInt!
|
||||
}
|
||||
|
||||
type Erc20Template @entity {
|
||||
#ID = template address
|
||||
id: ID!
|
||||
templateId: BigInt!
|
||||
}
|
||||
|
||||
|
||||
|
||||
type PredictSubscription @entity{
|
||||
"id = {contract address}-{txid}-{eventIndex}"
|
||||
id: ID!
|
||||
predictContract: PredictContract!
|
||||
user: User!
|
||||
expireTime: BigInt!
|
||||
"txId"
|
||||
txId: String
|
||||
eventIndex:Int!
|
||||
timestamp: Int!
|
||||
block: Int!
|
||||
}
|
||||
|
||||
enum PredictSlotStatus {
|
||||
Pending,
|
||||
Paying,
|
||||
Canceled
|
||||
}
|
||||
|
||||
|
||||
type PredictPayout @entity{
|
||||
"id = {contract address}-{slot}-{user}"
|
||||
id: ID!
|
||||
prediction: PredictPrediction!
|
||||
payout: BigDecimal!
|
||||
predictedValue: Boolean!
|
||||
trueValue: Boolean!
|
||||
aggregatedPredictedValue: BigDecimal!
|
||||
"txId"
|
||||
txId: String
|
||||
eventIndex:Int!
|
||||
timestamp: Int!
|
||||
block: Int!
|
||||
}
|
||||
|
||||
type PredictPrediction @entity{
|
||||
"id = {contract address}-{slot}-{user}"
|
||||
id: ID!
|
||||
slot: PredictSlot!
|
||||
user: User!
|
||||
stake: BigDecimal!
|
||||
payout: PredictPayout
|
||||
"txId"
|
||||
txId: String
|
||||
eventIndex:Int!
|
||||
timestamp: Int!
|
||||
block: Int!
|
||||
}
|
||||
|
||||
|
||||
type PredictTrueVal @entity{
|
||||
"id = {contract address}-{slot}"
|
||||
id: ID!
|
||||
slot: PredictSlot!
|
||||
trueValue: Boolean!
|
||||
"txId"
|
||||
txId: String
|
||||
eventIndex:Int!
|
||||
timestamp: Int!
|
||||
block: Int!
|
||||
}
|
||||
|
||||
type PredictionRevenue @entity{
|
||||
"id = {contract address}-{slot}-{txid}-{eventIndex}"
|
||||
id: ID!
|
||||
slot: PredictSlot!
|
||||
amount: BigDecimal!
|
||||
"txId"
|
||||
txId: String
|
||||
eventIndex:Int!
|
||||
timestamp: Int!
|
||||
block: Int!
|
||||
}
|
||||
|
||||
type PredictSlot @entity{
|
||||
"id = {contract address}-{slot}"
|
||||
id: ID!
|
||||
predictContract: PredictContract!
|
||||
slot: Int!
|
||||
predictions:[PredictPrediction!] @derivedFrom(field: "slot")
|
||||
trueValues: [PredictTrueVal!] @derivedFrom(field: "slot")
|
||||
revenue: BigDecimal!
|
||||
revenues: [PredictionRevenue!] @derivedFrom(field: "slot")
|
||||
status: PredictSlotStatus!
|
||||
roundSumStakesUp: BigDecimal!
|
||||
roundSumStakes: BigDecimal!
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
type PredictSettingUpdate @entity{
|
||||
"id = {contract address}-{txId}-{eventIndex}"
|
||||
id: ID!
|
||||
predictContract: PredictContract!
|
||||
secondsPerEpoch: BigInt!
|
||||
secondsPerSubscription: BigInt!
|
||||
truevalSubmitTimeout: BigInt!
|
||||
stakeToken: Token
|
||||
"txId"
|
||||
txId: String
|
||||
eventIndex:Int!
|
||||
timestamp: Int!
|
||||
block: Int!
|
||||
}
|
||||
type PredictContract @entity{
|
||||
"id = {contract address}"
|
||||
id: ID!
|
||||
token: Token!
|
||||
paused: Boolean!
|
||||
slots: [PredictSlot!] @derivedFrom(field: "predictContract")
|
||||
settingUpdates: [PredictSettingUpdate!] @derivedFrom(field: "predictContract")
|
||||
subscriptions: [PredictSubscription!] @derivedFrom(field: "predictContract")
|
||||
secondsPerEpoch: BigInt!
|
||||
secondsPerSubscription: BigInt!
|
||||
truevalSubmitTimeout: BigInt!
|
||||
stakeToken: Token
|
||||
"creation txId"
|
||||
txId: String
|
||||
"timestamp of creation tx"
|
||||
timestamp: Int!
|
||||
"block of creation tx"
|
||||
block: Int!
|
||||
eventIndex: Int!
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,15 @@ async function replaceContractAddresses() {
|
|||
}
|
||||
console.log('Creating subgraph.yaml for ' + network)
|
||||
let subgraph = fs.readFileSync('./subgraph.template.yaml', 'utf8')
|
||||
const subgraphVe = fs.readFileSync('./subgraph_ve.template.yaml', 'utf8')
|
||||
if (addresses[network].veOCEAN) {
|
||||
console.log('\t Adding veOCEAN')
|
||||
// fix identation , due to vs auto format (subgraph_ve.template is moved to left)
|
||||
const lines = subgraphVe.split('\n')
|
||||
for (let line = 0; line < lines.length; line++) {
|
||||
subgraph += ' ' + lines[line] + '\n'
|
||||
}
|
||||
}
|
||||
|
||||
subgraph = subgraph.replace(/__NETWORK__/g, network)
|
||||
subgraph = subgraph.replace(
|
||||
|
@ -34,6 +43,31 @@ async function replaceContractAddresses() {
|
|||
/__FACTORYROUTERADDRESS__/g,
|
||||
"'" + addresses[network].Router + "'"
|
||||
)
|
||||
|
||||
subgraph = subgraph.replace(
|
||||
/__VEALLOCATEADDRESS__/g,
|
||||
"'" + addresses[network].veAllocate + "'"
|
||||
)
|
||||
|
||||
subgraph = subgraph.replace(
|
||||
/__VEOCEANADDRESS__/g,
|
||||
"'" + addresses[network].veOCEAN + "'"
|
||||
)
|
||||
|
||||
subgraph = subgraph.replace(
|
||||
/__VEDELEGATIONADDRESS__/g,
|
||||
"'" + addresses[network].veDelegation + "'"
|
||||
)
|
||||
|
||||
subgraph = subgraph.replace(
|
||||
/__VEFEEDISTRIBUTORNADDRESS__/g,
|
||||
"'" + addresses[network].veFeeDistributor + "'"
|
||||
)
|
||||
|
||||
subgraph = subgraph.replace(
|
||||
/__DFREWARDSADDRESS__/g,
|
||||
"'" + addresses[network].DFRewards + "'"
|
||||
)
|
||||
fs.writeFileSync('subgraph.yaml', subgraph, 'utf8')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
import { BigInt } from '@graphprotocol/graph-ts'
|
||||
import { Allocated, Claimed } from '../@types/DFRewards/DFRewards'
|
||||
import { DFHistory } from '../@types/schema'
|
||||
import { weiToDecimal } from './utils/generic'
|
||||
import { getToken } from './utils/tokenUtils'
|
||||
import { getDFReward, getDFAvailableClaim } from './utils/dfUtils'
|
||||
|
||||
export function handleAllocated(event: Allocated): void {
|
||||
// loop all allocations
|
||||
const token = getToken(event.params.tokenAddress, false)
|
||||
for (let i = 0; i < event.params.tos.length; i++) {
|
||||
const reward = getDFReward(event.params.tos[i])
|
||||
const history = new DFHistory(
|
||||
event.params.tos[i].toHexString() +
|
||||
'-' +
|
||||
event.transaction.hash.toHex() +
|
||||
'-' +
|
||||
event.logIndex.toString()
|
||||
)
|
||||
history.amount = weiToDecimal(
|
||||
event.params.values[i].toBigDecimal(),
|
||||
BigInt.fromI32(token.decimals).toI32()
|
||||
)
|
||||
history.receiver = reward.id
|
||||
history.token = token.id
|
||||
history.type = 'Allocated'
|
||||
history.timestamp = event.block.timestamp
|
||||
history.tx = event.transaction.hash.toHex()
|
||||
history.eventIndex = event.logIndex.toI32()
|
||||
history.block = event.block.number.toI32()
|
||||
history.save()
|
||||
|
||||
// update available claims
|
||||
const claim = getDFAvailableClaim(
|
||||
event.params.tos[i],
|
||||
event.params.tokenAddress
|
||||
)
|
||||
claim.amount = claim.amount.plus(history.amount)
|
||||
claim.save()
|
||||
}
|
||||
}
|
||||
|
||||
export function handleClaimed(event: Claimed): void {
|
||||
// loop all allocations
|
||||
const token = getToken(event.params.tokenAddress, false)
|
||||
const reward = getDFReward(event.params.to)
|
||||
const history = new DFHistory(
|
||||
event.transaction.hash.toHex() + '-' + event.logIndex.toString()
|
||||
)
|
||||
history.amount = weiToDecimal(
|
||||
event.params.value.toBigDecimal(),
|
||||
BigInt.fromI32(token.decimals).toI32()
|
||||
)
|
||||
history.receiver = reward.id
|
||||
history.token = token.id
|
||||
history.type = 'Claimed'
|
||||
history.timestamp = event.block.timestamp
|
||||
history.tx = event.transaction.hash.toHex()
|
||||
history.eventIndex = event.logIndex.toI32()
|
||||
history.block = event.block.number.toI32()
|
||||
history.save()
|
||||
|
||||
// update available claims
|
||||
const claim = getDFAvailableClaim(event.params.to, event.params.tokenAddress)
|
||||
claim.amount = claim.amount.minus(history.amount)
|
||||
claim.save()
|
||||
}
|
|
@ -17,6 +17,7 @@ import { weiToDecimal } from './utils/generic'
|
|||
import { addDispenser } from './utils/globalUtils'
|
||||
import { getToken } from './utils/tokenUtils'
|
||||
import { getUser } from './utils/userUtils'
|
||||
import { BigDecimal } from '@graphprotocol/graph-ts'
|
||||
|
||||
export function handleNewDispenser(event: DispenserCreated): void {
|
||||
const dispenserID = getDispenserGraphID(
|
||||
|
@ -38,10 +39,11 @@ export function handleNewDispenser(event: DispenserCreated): void {
|
|||
token.decimals
|
||||
)
|
||||
dispenser.active = true
|
||||
|
||||
dispenser.balance = BigDecimal.zero()
|
||||
dispenser.allowedSwapper = event.params.allowedSwapper.toHex()
|
||||
dispenser.createdTimestamp = event.block.timestamp.toI32()
|
||||
dispenser.tx = event.transaction.hash.toHex()
|
||||
dispenser.eventIndex = event.logIndex.toI32()
|
||||
dispenser.block = event.block.number.toI32()
|
||||
dispenser.save()
|
||||
|
||||
|
@ -56,6 +58,7 @@ export function handleActivate(event: DispenserActivated): void {
|
|||
)
|
||||
const dispenser = getDispenser(dispenserID)
|
||||
dispenser.active = true
|
||||
dispenser.eventIndex = event.logIndex.toI32()
|
||||
dispenser.save()
|
||||
}
|
||||
|
||||
|
@ -65,7 +68,8 @@ export function handleDeactivate(event: DispenserDeactivated): void {
|
|||
event.params.datatokenAddress
|
||||
)
|
||||
const dispenser = getDispenser(dispenserID)
|
||||
dispenser.active = true
|
||||
dispenser.active = false
|
||||
dispenser.eventIndex = event.logIndex.toI32()
|
||||
dispenser.save()
|
||||
}
|
||||
|
||||
|
@ -75,6 +79,7 @@ export function handleAllowedSwapperChanged(
|
|||
const dispenserID = getDispenserGraphID(event.address, event.params.datatoken)
|
||||
const dispenser = getDispenser(dispenserID)
|
||||
dispenser.allowedSwapper = event.params.newAllowedSwapper.toHex()
|
||||
dispenser.eventIndex = event.logIndex.toI32()
|
||||
dispenser.save()
|
||||
}
|
||||
|
||||
|
@ -83,10 +88,8 @@ export function handleTokensDispensed(event: TokensDispensed): void {
|
|||
event.address,
|
||||
event.params.datatokenAddress
|
||||
)
|
||||
const id = event.transaction.hash
|
||||
.toHexString()
|
||||
.concat('-')
|
||||
.concat(dispenserID)
|
||||
const eventIndex: number = event.logIndex.toI32()
|
||||
const id = `${event.transaction.hash.toHexString()}-${dispenserID}-${eventIndex}`
|
||||
|
||||
const dispenserTransaction = new DispenserTransaction(id)
|
||||
const dispenser = getDispenser(dispenserID)
|
||||
|
@ -97,6 +100,7 @@ export function handleTokensDispensed(event: TokensDispensed): void {
|
|||
|
||||
dispenserTransaction.createdTimestamp = event.block.timestamp.toI32()
|
||||
dispenserTransaction.tx = event.transaction.hash.toHex()
|
||||
dispenserTransaction.eventIndex = event.logIndex.toI32()
|
||||
dispenserTransaction.block = event.block.number.toI32()
|
||||
const token = getToken(event.params.datatokenAddress, true)
|
||||
dispenserTransaction.amount = weiToDecimal(
|
||||
|
@ -110,5 +114,6 @@ export function handleOwnerWinthdraw(event: OwnerWithdrawed): void {
|
|||
const dispenserID = getDispenserGraphID(event.address, event.params.datatoken)
|
||||
const dispenser = getDispenser(dispenserID)
|
||||
dispenser.balance = decimal.ZERO
|
||||
dispenser.eventIndex = event.logIndex.toI32()
|
||||
dispenser.save()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,284 @@
|
|||
import {
|
||||
PredictSubscription,
|
||||
PredictPayout,
|
||||
PredictPrediction,
|
||||
PredictTrueVal,
|
||||
PredictSlot,
|
||||
PredictSettingUpdate,
|
||||
PredictionRevenue
|
||||
} from '../@types/schema'
|
||||
import { BigInt, BigDecimal, Address } from '@graphprotocol/graph-ts'
|
||||
|
||||
import {
|
||||
PredictionSubmitted,
|
||||
PredictionPayout,
|
||||
NewSubscription,
|
||||
TruevalSubmitted,
|
||||
SettingChanged,
|
||||
RevenueAdded,
|
||||
Paused
|
||||
} from '../@types/templates/ERC20Template3/ERC20Template3'
|
||||
|
||||
import { weiToDecimal } from './utils/generic'
|
||||
import { getPredictContract, getToken } from './utils/tokenUtils'
|
||||
import { getUser } from './utils/userUtils'
|
||||
|
||||
function getPredictSlot(
|
||||
predictContractAddress: string,
|
||||
slot: i32
|
||||
): PredictSlot {
|
||||
const id = predictContractAddress + '-' + slot.toString()
|
||||
let newPredictSlot = PredictSlot.load(id)
|
||||
if (newPredictSlot === null) {
|
||||
newPredictSlot = new PredictSlot(id)
|
||||
newPredictSlot.predictContract = predictContractAddress
|
||||
newPredictSlot.slot = slot
|
||||
newPredictSlot.revenue = BigDecimal.zero()
|
||||
newPredictSlot.roundSumStakesUp = BigDecimal.zero()
|
||||
newPredictSlot.roundSumStakes = BigDecimal.zero()
|
||||
newPredictSlot.status = 'Pending'
|
||||
newPredictSlot.save()
|
||||
}
|
||||
return newPredictSlot
|
||||
}
|
||||
|
||||
export function handlePredictionSubmitted(event: PredictionSubmitted): void {
|
||||
const predictSlot = getPredictSlot(
|
||||
event.address.toHexString(),
|
||||
event.params.slot.toI32()
|
||||
)
|
||||
const user = getUser(event.params.predictoor.toHex())
|
||||
const id =
|
||||
event.address.toHexString() +
|
||||
'-' +
|
||||
event.params.slot.toString() +
|
||||
'-' +
|
||||
user.id
|
||||
const predictPrediction = new PredictPrediction(id)
|
||||
predictPrediction.slot = predictSlot.id
|
||||
predictPrediction.user = user.id
|
||||
const predictContract = getPredictContract(event.address)
|
||||
let decimals = 18
|
||||
if (predictContract.stakeToken) {
|
||||
const stakeToken = getToken(
|
||||
Address.fromString(predictContract.stakeToken!),
|
||||
false
|
||||
)
|
||||
decimals = stakeToken.decimals
|
||||
}
|
||||
predictPrediction.stake = weiToDecimal(
|
||||
event.params.stake.toBigDecimal(),
|
||||
BigInt.fromI32(decimals).toI32()
|
||||
)
|
||||
predictPrediction.payout = null
|
||||
predictPrediction.block = event.block.number.toI32()
|
||||
predictPrediction.txId = event.transaction.hash.toHexString()
|
||||
predictPrediction.eventIndex = event.logIndex.toI32()
|
||||
predictPrediction.timestamp = event.block.timestamp.toI32()
|
||||
predictPrediction.save()
|
||||
}
|
||||
|
||||
export function handlePredictionPayout(event: PredictionPayout): void {
|
||||
const user = getUser(event.params.predictoor.toHex())
|
||||
const predictionId =
|
||||
event.address.toHexString() +
|
||||
'-' +
|
||||
event.params.slot.toString() +
|
||||
'-' +
|
||||
user.id
|
||||
const predictPrediction = PredictPrediction.load(predictionId)
|
||||
if (!predictPrediction) return
|
||||
const predictionPayout = new PredictPayout(predictionId)
|
||||
predictionPayout.prediction = predictPrediction.id
|
||||
|
||||
let decimals = 18
|
||||
const predictContract = getPredictContract(event.address)
|
||||
if (predictContract.stakeToken) {
|
||||
const stakeToken = getToken(
|
||||
Address.fromString(predictContract.stakeToken!),
|
||||
false
|
||||
)
|
||||
decimals = stakeToken.decimals
|
||||
}
|
||||
predictionPayout.payout = weiToDecimal(
|
||||
event.params.payout.toBigDecimal(),
|
||||
BigInt.fromI32(decimals).toI32()
|
||||
)
|
||||
predictionPayout.predictedValue = event.params.predictedValue
|
||||
predictionPayout.trueValue = event.params.trueValue
|
||||
predictionPayout.aggregatedPredictedValue = weiToDecimal(
|
||||
event.params.aggregatedPredictedValue.toBigDecimal(),
|
||||
18
|
||||
)
|
||||
predictionPayout.block = event.block.number.toI32()
|
||||
predictionPayout.txId = event.transaction.hash.toHexString()
|
||||
predictionPayout.eventIndex = event.logIndex.toI32()
|
||||
predictionPayout.timestamp = event.block.timestamp.toI32()
|
||||
predictionPayout.save()
|
||||
|
||||
predictPrediction.payout = predictionPayout.id
|
||||
predictPrediction.save()
|
||||
|
||||
let shouldUpdateSlot = false
|
||||
const predictSlot = getPredictSlot(
|
||||
event.address.toHexString(),
|
||||
event.params.slot.toI32()
|
||||
)
|
||||
if (event.params.status == 1 && predictSlot.status !== 'Paying') {
|
||||
predictSlot.status = 'Paying'
|
||||
shouldUpdateSlot = true
|
||||
}
|
||||
if (event.params.status == 2 && predictSlot.status !== 'Canceled') {
|
||||
predictSlot.status = 'Canceled'
|
||||
shouldUpdateSlot = true
|
||||
}
|
||||
if (shouldUpdateSlot == true) predictSlot.save()
|
||||
}
|
||||
|
||||
export function handleNewSubscription(event: NewSubscription): void {
|
||||
const id =
|
||||
event.address.toHexString() +
|
||||
'-' +
|
||||
event.transaction.hash.toHexString() +
|
||||
'-' +
|
||||
event.logIndex.toString()
|
||||
const newSubscription = new PredictSubscription(id)
|
||||
const predictContract = getPredictContract(event.address)
|
||||
newSubscription.predictContract = predictContract.id
|
||||
const user = getUser(event.params.user.toHex())
|
||||
newSubscription.user = user.id
|
||||
newSubscription.expireTime = event.params.expires
|
||||
newSubscription.block = event.block.number.toI32()
|
||||
newSubscription.txId = event.transaction.hash.toHexString()
|
||||
newSubscription.eventIndex = event.logIndex.toI32()
|
||||
newSubscription.timestamp = event.block.timestamp.toI32()
|
||||
newSubscription.save()
|
||||
}
|
||||
|
||||
export function handleTruevalSubmitted(event: TruevalSubmitted): void {
|
||||
const predictSlot = getPredictSlot(
|
||||
event.address.toHexString(),
|
||||
event.params.slot.toI32()
|
||||
)
|
||||
const id = event.address.toHexString() + '-' + event.params.slot.toString()
|
||||
const newPredictTrueVals = new PredictTrueVal(id) // they share the same id
|
||||
newPredictTrueVals.slot = predictSlot.id
|
||||
newPredictTrueVals.trueValue = event.params.trueValue
|
||||
newPredictTrueVals.block = event.block.number.toI32()
|
||||
newPredictTrueVals.txId = event.transaction.hash.toHexString()
|
||||
newPredictTrueVals.eventIndex = event.logIndex.toI32()
|
||||
newPredictTrueVals.timestamp = event.block.timestamp.toI32()
|
||||
newPredictTrueVals.save()
|
||||
let decimals = 18
|
||||
const predictContract = getPredictContract(event.address)
|
||||
if (predictContract.stakeToken) {
|
||||
const stakeToken = getToken(
|
||||
Address.fromString(predictContract.stakeToken!),
|
||||
false
|
||||
)
|
||||
decimals = stakeToken.decimals
|
||||
}
|
||||
predictSlot.roundSumStakesUp = weiToDecimal(
|
||||
event.params.roundSumStakesUp.toBigDecimal(),
|
||||
BigInt.fromI32(decimals).toI32()
|
||||
)
|
||||
predictSlot.roundSumStakes = weiToDecimal(
|
||||
event.params.roundSumStakes.toBigDecimal(),
|
||||
BigInt.fromI32(decimals).toI32()
|
||||
)
|
||||
|
||||
if (event.params.status == 1) {
|
||||
predictSlot.status = 'Paying'
|
||||
}
|
||||
if (event.params.status == 2) {
|
||||
predictSlot.status = 'Canceled'
|
||||
}
|
||||
predictSlot.save()
|
||||
}
|
||||
|
||||
export function handleSettingChanged(event: SettingChanged): void {
|
||||
const predictContract = getPredictContract(event.address)
|
||||
predictContract.secondsPerEpoch = event.params.secondsPerEpoch
|
||||
predictContract.secondsPerSubscription = event.params.secondsPerSubscription
|
||||
predictContract.truevalSubmitTimeout = event.params.trueValueSubmitTimeout
|
||||
const stakeToken = getToken(event.params.stakeToken, false)
|
||||
predictContract.stakeToken = stakeToken.id
|
||||
predictContract.save()
|
||||
const predictSettingsUpdate = new PredictSettingUpdate(
|
||||
event.address.toHexString() +
|
||||
'- ' +
|
||||
event.transaction.hash.toHexString() +
|
||||
'-' +
|
||||
event.logIndex.toHexString()
|
||||
)
|
||||
predictSettingsUpdate.block = event.block.number.toI32()
|
||||
predictSettingsUpdate.txId = event.transaction.hash.toHexString()
|
||||
predictSettingsUpdate.eventIndex = event.logIndex.toI32()
|
||||
predictSettingsUpdate.timestamp = event.block.timestamp.toI32()
|
||||
predictSettingsUpdate.predictContract = predictContract.id
|
||||
predictSettingsUpdate.secondsPerEpoch = event.params.secondsPerEpoch
|
||||
predictSettingsUpdate.secondsPerSubscription =
|
||||
event.params.secondsPerSubscription
|
||||
predictSettingsUpdate.truevalSubmitTimeout =
|
||||
event.params.trueValueSubmitTimeout
|
||||
predictSettingsUpdate.stakeToken = stakeToken.id
|
||||
predictSettingsUpdate.save()
|
||||
}
|
||||
|
||||
export function handlePaused(event: Paused): void {
|
||||
const predictContract = getPredictContract(event.address)
|
||||
predictContract.paused = event.params.paused
|
||||
predictContract.save()
|
||||
}
|
||||
|
||||
export function handleRevenueAdded(event: RevenueAdded): void {
|
||||
/*
|
||||
for (uint256 i = 0; i < num_epochs; i++) {
|
||||
subscriptionRevenueAtBlock[
|
||||
slot + secondsPerEpoch * (i)
|
||||
] += amt_per_epoch;
|
||||
}
|
||||
emit RevenueAdded(amount,slot,amt_per_epoch,num_epochs,secondsPerEpoch);
|
||||
*/
|
||||
const numEpochs = event.params.numEpochs
|
||||
const secondsPerEpoch = event.params.secondsPerEpoch
|
||||
let decimals = 18
|
||||
const predictContract = getPredictContract(event.address)
|
||||
if (predictContract.stakeToken) {
|
||||
const stakeToken = getToken(
|
||||
Address.fromString(predictContract.stakeToken!),
|
||||
false
|
||||
)
|
||||
decimals = stakeToken.decimals
|
||||
}
|
||||
const amountPerEpoch = weiToDecimal(
|
||||
event.params.amountPerEpoch.toBigDecimal(),
|
||||
BigInt.fromI32(decimals).toI32()
|
||||
)
|
||||
const slot = event.params.slot
|
||||
for (let i = BigInt.zero(); i.lt(numEpochs); i = i.plus(BigInt.fromI32(1))) {
|
||||
const targetSlot = slot.plus(secondsPerEpoch.times(i))
|
||||
const predictSlot = getPredictSlot(
|
||||
event.address.toHexString(),
|
||||
targetSlot.toI32()
|
||||
)
|
||||
predictSlot.revenue = predictSlot.revenue.plus(amountPerEpoch)
|
||||
predictSlot.save()
|
||||
const revenueId =
|
||||
event.address.toHexString() +
|
||||
'-' +
|
||||
targetSlot.toString() +
|
||||
'-' +
|
||||
event.transaction.hash.toHexString() +
|
||||
'-' +
|
||||
event.logIndex.toHexString()
|
||||
const predictRevenue = new PredictionRevenue(revenueId)
|
||||
predictRevenue.slot = predictSlot.id
|
||||
predictRevenue.amount = amountPerEpoch
|
||||
predictRevenue.block = event.block.number.toI32()
|
||||
predictRevenue.txId = event.transaction.hash.toHexString()
|
||||
predictRevenue.eventIndex = event.logIndex.toI32()
|
||||
predictRevenue.timestamp = event.block.timestamp.toI32()
|
||||
predictRevenue.save()
|
||||
}
|
||||
}
|
|
@ -1,16 +1,19 @@
|
|||
import { Order, Nft, OrderReuse } from '../@types/schema'
|
||||
import { BigInt } from '@graphprotocol/graph-ts'
|
||||
import { BigInt, BigDecimal, Address, log } from '@graphprotocol/graph-ts'
|
||||
|
||||
import {
|
||||
NewPaymentCollector,
|
||||
OrderStarted,
|
||||
PublishMarketFee,
|
||||
PublishMarketFeeChanged,
|
||||
ConsumeMarketFee,
|
||||
AddedMinter,
|
||||
AddedPaymentManager,
|
||||
RemovedMinter,
|
||||
RemovedPaymentManager,
|
||||
CleanedPermissions,
|
||||
OrderReused
|
||||
OrderReused,
|
||||
ProviderFee
|
||||
} from '../@types/templates/ERC20Template/ERC20Template'
|
||||
|
||||
import { integer } from './utils/constants'
|
||||
|
@ -18,21 +21,19 @@ import { weiToDecimal } from './utils/generic'
|
|||
import { addOrder } from './utils/globalUtils'
|
||||
import { getToken, getUSDValue } from './utils/tokenUtils'
|
||||
import { getUser } from './utils/userUtils'
|
||||
|
||||
function getOrderId(
|
||||
tx: string,
|
||||
tokenAddress: string,
|
||||
fromAddress: string
|
||||
): string {
|
||||
return `${tx}-${tokenAddress}-${fromAddress}`
|
||||
}
|
||||
import {
|
||||
getOrderId,
|
||||
searchOrderForEvent,
|
||||
searchOrderReusedForEvent
|
||||
} from './utils/orderUtils'
|
||||
|
||||
export function handleOrderStarted(event: OrderStarted): void {
|
||||
const order = new Order(
|
||||
getOrderId(
|
||||
event.transaction.hash.toHex(),
|
||||
event.address.toHex(),
|
||||
event.transaction.from.toHex()
|
||||
event.transaction.from.toHex(),
|
||||
event.logIndex.toI32()
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -43,6 +44,12 @@ export function handleOrderStarted(event: OrderStarted): void {
|
|||
const consumer = getUser(event.params.consumer.toHex())
|
||||
order.consumer = consumer.id
|
||||
|
||||
if (token.nft) {
|
||||
const nft = Nft.load(token.nft as string) as Nft
|
||||
const nftOwner = getUser(nft.owner)
|
||||
order.nftOwner = nftOwner.id
|
||||
}
|
||||
|
||||
const payer = getUser(event.params.payer.toHex())
|
||||
payer.totalOrders = payer.totalOrders.plus(integer.ONE)
|
||||
payer.save()
|
||||
|
@ -58,19 +65,32 @@ export function handleOrderStarted(event: OrderStarted): void {
|
|||
const publishMarket = getUser(event.params.publishMarketAddress.toHex())
|
||||
order.publishingMarket = publishMarket.id
|
||||
|
||||
// const consumeMarket = getUser(event.params..toHex())
|
||||
// order.consumerMarket = consumeMarket.id
|
||||
|
||||
order.createdTimestamp = event.block.timestamp.toI32()
|
||||
order.tx = event.transaction.hash.toHex()
|
||||
order.eventIndex = event.logIndex.toI32()
|
||||
order.block = event.block.number.toI32()
|
||||
order.lastPriceToken = token.lastPriceToken
|
||||
const tokenId = token.lastPriceToken
|
||||
if (tokenId) {
|
||||
const priceToken = getToken(Address.fromString(tokenId), false)
|
||||
order.lastPriceToken = priceToken.id
|
||||
order.lastPriceValue = token.lastPriceValue
|
||||
order.estimatedUSDValue = getUSDValue(
|
||||
order.lastPriceToken,
|
||||
priceToken.id,
|
||||
order.lastPriceValue,
|
||||
order.createdTimestamp
|
||||
)
|
||||
}
|
||||
|
||||
if (event.receipt !== null && event.receipt!.gasUsed) {
|
||||
order.gasUsed = event.receipt!.gasUsed.toBigDecimal()
|
||||
} else {
|
||||
order.gasUsed = BigDecimal.zero()
|
||||
}
|
||||
if (event.transaction.gasPrice) {
|
||||
order.gasPrice = event.transaction.gasPrice
|
||||
} else {
|
||||
order.gasPrice = BigInt.zero()
|
||||
}
|
||||
order.save()
|
||||
token.save()
|
||||
addOrder()
|
||||
|
@ -87,26 +107,56 @@ export function handleOrderStarted(event: OrderStarted): void {
|
|||
}
|
||||
|
||||
export function handlerOrderReused(event: OrderReused): void {
|
||||
const orderId = getOrderId(
|
||||
const order = searchOrderForEvent(
|
||||
event.params.orderTxId.toHexString(),
|
||||
event.address.toHex(),
|
||||
event.params.caller.toHex()
|
||||
event.params.caller.toHex(),
|
||||
event.logIndex.toI32()
|
||||
)
|
||||
const order = Order.load(orderId)
|
||||
|
||||
if (!order) return
|
||||
const eventIndex: number = event.logIndex.toI32()
|
||||
|
||||
const reuseOrder = new OrderReuse(event.transaction.hash.toHex())
|
||||
reuseOrder.order = orderId
|
||||
const reuseOrder = new OrderReuse(
|
||||
`${event.transaction.hash.toHex()}-${eventIndex}`
|
||||
)
|
||||
if (event.transaction.gasPrice)
|
||||
reuseOrder.gasPrice = event.transaction.gasPrice
|
||||
else reuseOrder.gasPrice = BigInt.zero()
|
||||
if (event.receipt !== null && event.receipt!.gasUsed) {
|
||||
reuseOrder.gasUsed = event.receipt!.gasUsed.toBigDecimal()
|
||||
} else reuseOrder.gasUsed = BigDecimal.zero()
|
||||
reuseOrder.order = order.id
|
||||
reuseOrder.caller = event.params.caller.toHexString()
|
||||
reuseOrder.createdTimestamp = event.params.timestamp
|
||||
reuseOrder.createdTimestamp = event.params.timestamp.toI32()
|
||||
reuseOrder.tx = event.transaction.hash.toHex()
|
||||
reuseOrder.block = event.params.number
|
||||
reuseOrder.eventIndex = event.logIndex.toI32()
|
||||
reuseOrder.block = event.params.number.toI32()
|
||||
|
||||
reuseOrder.save()
|
||||
}
|
||||
|
||||
export function handlePublishMarketFee(event: PublishMarketFee): void {}
|
||||
export function handlePublishMarketFee(event: PublishMarketFee): void {
|
||||
const order = searchOrderForEvent(
|
||||
event.transaction.hash.toHex(),
|
||||
event.address.toHex(),
|
||||
event.transaction.from.toHex(),
|
||||
event.logIndex.toI32()
|
||||
)
|
||||
|
||||
if (!order) return
|
||||
const publishMarket = getUser(event.params.PublishMarketFeeAddress.toHex())
|
||||
order.publishingMarket = publishMarket.id
|
||||
|
||||
const publishMarketToken = getToken(event.params.PublishMarketFeeToken, true)
|
||||
order.publishingMarketToken = publishMarketToken.id
|
||||
order.publishingMarketAmmount = weiToDecimal(
|
||||
event.params.PublishMarketFeeAmount.toBigDecimal(),
|
||||
publishMarketToken.decimals
|
||||
)
|
||||
|
||||
order.save()
|
||||
}
|
||||
export function handlePublishMarketFeeChanged(
|
||||
event: PublishMarketFeeChanged
|
||||
): void {
|
||||
|
@ -127,10 +177,33 @@ export function handlePublishMarketFeeChanged(
|
|||
event.params.PublishMarketFeeAmount.toBigDecimal(),
|
||||
decimals
|
||||
)
|
||||
token.eventIndex = event.logIndex.toI32()
|
||||
token.save()
|
||||
// TODO - shold we have a history
|
||||
}
|
||||
|
||||
export function handleConsumeMarketFee(event: ConsumeMarketFee): void {
|
||||
const order = searchOrderForEvent(
|
||||
event.transaction.hash.toHex(),
|
||||
event.address.toHex(),
|
||||
event.transaction.from.toHex(),
|
||||
event.logIndex.toI32()
|
||||
)
|
||||
|
||||
if (!order) return
|
||||
const consumeMarket = getUser(event.params.consumeMarketFeeAddress.toHex())
|
||||
order.consumerMarket = consumeMarket.id
|
||||
|
||||
const consumeMarketToken = getToken(event.params.consumeMarketFeeToken, false)
|
||||
order.consumerMarketToken = consumeMarketToken.id
|
||||
order.consumerMarketAmmount = weiToDecimal(
|
||||
event.params.consumeMarketFeeAmount.toBigDecimal(),
|
||||
consumeMarketToken.decimals
|
||||
)
|
||||
|
||||
order.save()
|
||||
}
|
||||
|
||||
// roles
|
||||
// roles
|
||||
export function handleAddedMinter(event: AddedMinter): void {
|
||||
|
@ -141,6 +214,7 @@ export function handleAddedMinter(event: AddedMinter): void {
|
|||
if (!existingRoles.includes(event.params.user.toHexString()))
|
||||
existingRoles.push(event.params.user.toHexString())
|
||||
token.minter = existingRoles
|
||||
token.eventIndex = event.logIndex.toI32()
|
||||
token.save()
|
||||
}
|
||||
|
||||
|
@ -157,6 +231,7 @@ export function handleRemovedMinter(event: RemovedMinter): void {
|
|||
if (role !== event.params.user.toHexString()) newList.push(role)
|
||||
}
|
||||
token.minter = newList
|
||||
token.eventIndex = event.logIndex.toI32()
|
||||
token.save()
|
||||
}
|
||||
|
||||
|
@ -168,6 +243,7 @@ export function handleAddedPaymentManager(event: AddedPaymentManager): void {
|
|||
if (!existingRoles.includes(event.params.user.toHexString()))
|
||||
existingRoles.push(event.params.user.toHexString())
|
||||
token.paymentManager = existingRoles
|
||||
token.eventIndex = event.logIndex.toI32()
|
||||
token.save()
|
||||
}
|
||||
export function handleRemovedPaymentManager(
|
||||
|
@ -185,6 +261,7 @@ export function handleRemovedPaymentManager(
|
|||
if (role !== event.params.user.toHexString()) newList.push(role)
|
||||
}
|
||||
token.paymentManager = newList
|
||||
token.eventIndex = event.logIndex.toI32()
|
||||
token.save()
|
||||
}
|
||||
export function handleCleanedPermissions(event: CleanedPermissions): void {
|
||||
|
@ -195,35 +272,48 @@ export function handleCleanedPermissions(event: CleanedPermissions): void {
|
|||
const nft = Nft.load(token.nft as string)
|
||||
if (nft) token.paymentCollector = nft.owner
|
||||
else token.paymentCollector = '0x0000000000000000000000000000000000000000'
|
||||
token.eventIndex = event.logIndex.toI32()
|
||||
token.save()
|
||||
}
|
||||
|
||||
export function handleNewPaymentCollector(event: NewPaymentCollector): void {
|
||||
const token = getToken(event.address, true)
|
||||
token.paymentCollector = event.params._newPaymentCollector.toHexString()
|
||||
token.eventIndex = event.logIndex.toI32()
|
||||
token.save()
|
||||
}
|
||||
|
||||
// export function handlePublishMarketFees(event: PublishMarketFees): void {
|
||||
// const order = Order.load(
|
||||
// getOrderId(
|
||||
// event.transaction.hash.toHex(),
|
||||
// event.address.toHex(),
|
||||
// event.transaction.from.toHex()
|
||||
// )
|
||||
// )
|
||||
export function handleProviderFee(event: ProviderFee): void {
|
||||
const providerFee: string = `{"providerFeeAddress": "${event.params.providerFeeAddress.toHex()}", "providerFeeToken": "${event.params.providerFeeToken.toHex()}", "providerFeeAmount": "${
|
||||
event.params.providerFeeAmount
|
||||
}", "providerData": "${event.params.providerData.toHexString()}", "v": "${
|
||||
event.params.v
|
||||
}", "r": "${event.params.r.toHexString()}", "s": "${event.params.s.toHexString()}", "validUntil": "${
|
||||
event.params.validUntil
|
||||
}"}`
|
||||
|
||||
// order.save()
|
||||
// }
|
||||
const order = searchOrderForEvent(
|
||||
event.transaction.hash.toHex(),
|
||||
event.address.toHex(),
|
||||
event.transaction.from.toHex(),
|
||||
event.logIndex.toI32()
|
||||
)
|
||||
|
||||
// export function handleConsumeMarketFees(event: ConsumeMarketFees): void {
|
||||
// const order = Order.load(
|
||||
// getOrderId(
|
||||
// event.transaction.hash.toHex(),
|
||||
// event.address.toHex(),
|
||||
// event.transaction.from.toHex()
|
||||
// )
|
||||
// )
|
||||
|
||||
// order.save()
|
||||
// }
|
||||
if (order) {
|
||||
order.providerFee = providerFee
|
||||
order.providerFeeValidUntil = event.params.validUntil
|
||||
order.save()
|
||||
return
|
||||
}
|
||||
const orderReuse = searchOrderReusedForEvent(
|
||||
event.transaction.hash.toHex(),
|
||||
event.address.toHex(),
|
||||
event.logIndex.toI32()
|
||||
)
|
||||
if (orderReuse) {
|
||||
log.info('order reuse id in provider fee handler: {}', [orderReuse.id])
|
||||
orderReuse.providerFee = providerFee
|
||||
orderReuse.providerFeeValidUntil = event.params.validUntil
|
||||
orderReuse.save()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,23 @@
|
|||
import { NFTCreated, TokenCreated } from '../@types/ERC721Factory/ERC721Factory'
|
||||
import {
|
||||
NFTCreated,
|
||||
TokenCreated,
|
||||
Template721Added,
|
||||
Template20Added
|
||||
} from '../@types/ERC721Factory/ERC721Factory'
|
||||
import { Erc721Template, Erc20Template } from '../@types/schema'
|
||||
import { decimal } from './utils/constants'
|
||||
import { weiToDecimal } from './utils/generic'
|
||||
|
||||
import {
|
||||
ERC20Template as factoryERC20Template,
|
||||
ERC20Template3 as factoryERC20Template3
|
||||
} from '../@types/templates'
|
||||
import { getUser } from './utils/userUtils'
|
||||
import { getToken, getNftToken } from './utils/tokenUtils'
|
||||
import {
|
||||
getToken,
|
||||
getNftToken,
|
||||
getErc20TemplateId,
|
||||
getPredictContract
|
||||
} from './utils/tokenUtils'
|
||||
import { addDatatoken } from './utils/globalUtils'
|
||||
|
||||
export function handleNftCreated(event: NFTCreated): void {
|
||||
|
@ -20,8 +34,9 @@ export function handleNftCreated(event: NFTCreated): void {
|
|||
nft.createdTimestamp = event.block.timestamp.toI32()
|
||||
nft.tx = event.transaction.hash.toHex()
|
||||
nft.block = event.block.number.toI32()
|
||||
nft.eventIndex = event.logIndex.toI32()
|
||||
nft.transferable = event.params.transferable
|
||||
|
||||
nft.template = event.params.templateAddress.toHexString()
|
||||
nft.save()
|
||||
}
|
||||
|
||||
|
@ -34,6 +49,7 @@ export function handleNewToken(event: TokenCreated): void {
|
|||
token.createdTimestamp = event.block.timestamp.toI32()
|
||||
token.tx = event.transaction.hash.toHex()
|
||||
token.block = event.block.number.toI32()
|
||||
token.eventIndex = event.logIndex.toI32()
|
||||
|
||||
token.nft = event.params.creator.toHexString()
|
||||
|
||||
|
@ -42,7 +58,37 @@ export function handleNewToken(event: TokenCreated): void {
|
|||
token.decimals = 18
|
||||
token.supply = decimal.ZERO
|
||||
token.cap = weiToDecimal(event.params.cap.toBigDecimal(), 18)
|
||||
|
||||
token.templateId = getErc20TemplateId(event.params.templateAddress)
|
||||
token.save()
|
||||
addDatatoken()
|
||||
if (token.templateId.toString() == '3') {
|
||||
factoryERC20Template3.create(event.params.newTokenAddress)
|
||||
const predictContract = getPredictContract(event.params.newTokenAddress)
|
||||
predictContract.timestamp = event.block.timestamp.toI32()
|
||||
predictContract.txId = event.transaction.hash.toHex()
|
||||
predictContract.block = event.block.number.toI32()
|
||||
predictContract.eventIndex = event.logIndex.toI32()
|
||||
predictContract.save()
|
||||
}
|
||||
factoryERC20Template.create(event.params.newTokenAddress)
|
||||
}
|
||||
|
||||
export function handleNew721Template(event: Template721Added): void {
|
||||
let template = Erc721Template.load(
|
||||
event.params._templateAddress.toHexString()
|
||||
)
|
||||
if (template === null) {
|
||||
template = new Erc721Template(event.params._templateAddress.toHexString())
|
||||
template.templateId = event.params.nftTemplateCount
|
||||
template.save()
|
||||
}
|
||||
}
|
||||
|
||||
export function handleNew20Template(event: Template20Added): void {
|
||||
let template = Erc20Template.load(event.params._templateAddress.toHexString())
|
||||
if (template === null) {
|
||||
template = new Erc20Template(event.params._templateAddress.toHexString())
|
||||
template.templateId = event.params.nftTemplateCount
|
||||
template.save()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,19 @@
|
|||
import {
|
||||
NewPool,
|
||||
TokenAdded,
|
||||
TokenRemoved,
|
||||
OPCFeeChanged,
|
||||
FactoryRouter,
|
||||
SSContractAdded,
|
||||
SSContractRemoved,
|
||||
FixedRateContractAdded,
|
||||
FixedRateContractRemoved,
|
||||
DispenserContractAdded,
|
||||
DispenserContractRemoved
|
||||
} from '../@types/FactoryRouter/FactoryRouter'
|
||||
import { BigInt } from '@graphprotocol/graph-ts'
|
||||
import { Pool } from '../@types/schema'
|
||||
import { BPool, FixedRateExchange, Dispenser } from '../@types/templates'
|
||||
import { addPool, getOPC, getTemplates } from './utils/globalUtils'
|
||||
import { FixedRateExchange, Dispenser } from '../@types/templates'
|
||||
import { getOPC, getTemplates } from './utils/globalUtils'
|
||||
import { weiToDecimal } from './utils/generic'
|
||||
import { getToken } from './utils/tokenUtils'
|
||||
|
||||
export function handleNewPool(event: NewPool): void {
|
||||
BPool.create(event.params.poolAddress)
|
||||
const pool = new Pool(event.params.poolAddress.toHexString())
|
||||
pool.save()
|
||||
addPool()
|
||||
}
|
||||
|
||||
export function handleOPCFeeChanged(event: OPCFeeChanged): void {
|
||||
const opc = getOPC()
|
||||
const decimals = BigInt.fromI32(18).toI32()
|
||||
|
@ -95,37 +84,11 @@ export function handleTokenRemoved(event: TokenRemoved): void {
|
|||
while (existingTokens.length > 0) {
|
||||
const role = existingTokens.shift().toString()
|
||||
if (!role) break
|
||||
if (role !== event.params.token.toHexString()) newList.push(role)
|
||||
if (role != event.params.token.toHexString()) newList.push(role)
|
||||
}
|
||||
opc.approvedTokens = newList
|
||||
opc.save()
|
||||
}
|
||||
export function handleSSContractAdded(event: SSContractAdded): void {
|
||||
// add token to approvedTokens
|
||||
const templates = getTemplates()
|
||||
let existingContracts: string[]
|
||||
if (!templates.ssTemplates) existingContracts = []
|
||||
else existingContracts = templates.ssTemplates as string[]
|
||||
if (!existingContracts.includes(event.params.contractAddress.toHexString()))
|
||||
existingContracts.push(event.params.contractAddress.toHexString())
|
||||
templates.ssTemplates = existingContracts
|
||||
templates.save()
|
||||
}
|
||||
export function handleSSContractRemoved(event: SSContractRemoved): void {
|
||||
const templates = getTemplates()
|
||||
const newList: string[] = []
|
||||
let existingContracts: string[]
|
||||
if (!templates.ssTemplates) existingContracts = []
|
||||
else existingContracts = templates.ssTemplates as string[]
|
||||
if (!existingContracts || existingContracts.length < 1) return
|
||||
while (existingContracts.length > 0) {
|
||||
const role = existingContracts.shift().toString()
|
||||
if (!role) break
|
||||
if (role !== event.params.contractAddress.toHexString()) newList.push(role)
|
||||
}
|
||||
templates.ssTemplates = newList
|
||||
templates.save()
|
||||
}
|
||||
|
||||
export function handleFixedRateContractAdded(
|
||||
event: FixedRateContractAdded
|
||||
|
@ -153,7 +116,7 @@ export function handleFixedRateContractRemoved(
|
|||
while (existingContracts.length > 0) {
|
||||
const role = existingContracts.shift().toString()
|
||||
if (!role) break
|
||||
if (role !== event.params.contractAddress.toHexString()) newList.push(role)
|
||||
if (role != event.params.contractAddress.toHexString()) newList.push(role)
|
||||
}
|
||||
templates.fixedRateTemplates = newList
|
||||
templates.save()
|
||||
|
@ -184,7 +147,7 @@ export function handleDispenserContractRemoved(
|
|||
while (existingContracts.length > 0) {
|
||||
const role = existingContracts.shift().toString()
|
||||
if (!role) break
|
||||
if (role !== event.params.contractAddress.toHexString()) newList.push(role)
|
||||
if (role != event.params.contractAddress.toHexString()) newList.push(role)
|
||||
}
|
||||
templates.dispenserTemplates = newList
|
||||
templates.save()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { BigInt, Address } from '@graphprotocol/graph-ts'
|
||||
import { BigInt, Address, BigDecimal } from '@graphprotocol/graph-ts'
|
||||
import {
|
||||
ExchangeActivated,
|
||||
ExchangeAllowedSwapperChanged,
|
||||
|
@ -38,7 +38,11 @@ export function handleExchangeCreated(event: ExchangeCreated): void {
|
|||
fixedRateExchange.exchangeId = event.params.exchangeId.toHexString()
|
||||
fixedRateExchange.datatoken = getToken(event.params.datatoken, true).id
|
||||
fixedRateExchange.baseToken = getToken(event.params.baseToken, false).id
|
||||
|
||||
fixedRateExchange.datatokenSupply = BigDecimal.zero()
|
||||
fixedRateExchange.baseTokenSupply = BigDecimal.zero()
|
||||
fixedRateExchange.datatokenBalance = BigDecimal.zero()
|
||||
fixedRateExchange.baseTokenBalance = BigDecimal.zero()
|
||||
fixedRateExchange.totalSwapValue = BigDecimal.zero()
|
||||
fixedRateExchange.active = false
|
||||
fixedRateExchange.price = weiToDecimal(
|
||||
event.params.fixedRate.toBigDecimal(),
|
||||
|
@ -46,6 +50,7 @@ export function handleExchangeCreated(event: ExchangeCreated): void {
|
|||
)
|
||||
fixedRateExchange.createdTimestamp = event.block.timestamp.toI32()
|
||||
fixedRateExchange.tx = event.transaction.hash.toHex()
|
||||
fixedRateExchange.eventIndex = event.logIndex.toI32()
|
||||
fixedRateExchange.block = event.block.number.toI32()
|
||||
fixedRateExchange.save()
|
||||
|
||||
|
@ -58,15 +63,17 @@ export function handleRateChange(event: ExchangeRateChanged): void {
|
|||
event.params.exchangeId.toHexString(),
|
||||
event.address
|
||||
)
|
||||
|
||||
const fixedRateExchange = getFixedRateExchange(fixedRateId)
|
||||
const eventIndex: number = event.logIndex.toI32()
|
||||
const newExchangeUpdate = new FixedRateExchangeUpdate(
|
||||
getUpdateOrSwapId(event.transaction.hash.toHex(), fixedRateId)
|
||||
getUpdateOrSwapId(event.transaction.hash.toHex(), fixedRateId, eventIndex)
|
||||
)
|
||||
newExchangeUpdate.oldPrice = fixedRateExchange.price
|
||||
newExchangeUpdate.createdTimestamp = event.block.timestamp.toI32()
|
||||
newExchangeUpdate.tx = event.transaction.hash.toHex()
|
||||
newExchangeUpdate.eventIndex = event.logIndex.toI32()
|
||||
newExchangeUpdate.block = event.block.number.toI32()
|
||||
newExchangeUpdate.exchangeId = fixedRateId
|
||||
|
||||
fixedRateExchange.price = weiToDecimal(
|
||||
event.params.newRate.toBigDecimal(),
|
||||
|
@ -85,24 +92,26 @@ export function handleMintStateChanged(event: ExchangeMintStateChanged): void {
|
|||
)
|
||||
const fixedRateExchange = getFixedRateExchange(fixedRateId)
|
||||
fixedRateExchange.withMint = event.params.withMint
|
||||
fixedRateExchange.eventIndex = event.logIndex.toI32()
|
||||
fixedRateExchange.save()
|
||||
}
|
||||
|
||||
// TODO: implement fre updates/history for changes
|
||||
|
||||
export function handleActivated(event: ExchangeActivated): void {
|
||||
const fixedRateId = getFixedRateGraphID(
|
||||
event.params.exchangeId.toHexString(),
|
||||
event.address
|
||||
)
|
||||
const fixedRateExchange = getFixedRateExchange(fixedRateId)
|
||||
const eventIndex: number = event.logIndex.toI32()
|
||||
const newExchangeUpdate = new FixedRateExchangeUpdate(
|
||||
getUpdateOrSwapId(event.transaction.hash.toHex(), fixedRateId)
|
||||
getUpdateOrSwapId(event.transaction.hash.toHex(), fixedRateId, eventIndex)
|
||||
)
|
||||
newExchangeUpdate.exchangeId = fixedRateId
|
||||
newExchangeUpdate.oldActive = fixedRateExchange.active
|
||||
newExchangeUpdate.newActive = true
|
||||
newExchangeUpdate.createdTimestamp = event.block.timestamp.toI32()
|
||||
newExchangeUpdate.tx = event.transaction.hash.toHex()
|
||||
newExchangeUpdate.eventIndex = event.logIndex.toI32()
|
||||
newExchangeUpdate.block = event.block.number.toI32()
|
||||
|
||||
fixedRateExchange.active = true
|
||||
|
@ -117,14 +126,17 @@ export function handleDeactivated(event: ExchangeDeactivated): void {
|
|||
event.address
|
||||
)
|
||||
const fixedRateExchange = getFixedRateExchange(fixedRateId)
|
||||
const eventIndex: number = event.logIndex.toI32()
|
||||
const newExchangeUpdate = new FixedRateExchangeUpdate(
|
||||
getUpdateOrSwapId(event.transaction.hash.toHex(), fixedRateId)
|
||||
getUpdateOrSwapId(event.transaction.hash.toHex(), fixedRateId, eventIndex)
|
||||
)
|
||||
newExchangeUpdate.oldActive = fixedRateExchange.active
|
||||
newExchangeUpdate.newActive = false
|
||||
|
||||
newExchangeUpdate.exchangeId = fixedRateId
|
||||
newExchangeUpdate.createdTimestamp = event.block.timestamp.toI32()
|
||||
newExchangeUpdate.tx = event.transaction.hash.toHex()
|
||||
newExchangeUpdate.eventIndex = event.logIndex.toI32()
|
||||
newExchangeUpdate.block = event.block.number.toI32()
|
||||
|
||||
fixedRateExchange.active = false
|
||||
|
@ -140,15 +152,16 @@ export function handleAllowedSwapperChanged(
|
|||
event.address
|
||||
)
|
||||
const fixedRateExchange = getFixedRateExchange(fixedRateId)
|
||||
const eventIndex: number = event.logIndex.toI32()
|
||||
const newExchangeUpdate = new FixedRateExchangeUpdate(
|
||||
getUpdateOrSwapId(event.transaction.hash.toHex(), fixedRateId)
|
||||
getUpdateOrSwapId(event.transaction.hash.toHex(), fixedRateId, eventIndex)
|
||||
)
|
||||
|
||||
newExchangeUpdate.createdTimestamp = event.block.timestamp.toI32()
|
||||
newExchangeUpdate.tx = event.transaction.hash.toHex()
|
||||
newExchangeUpdate.eventIndex = event.logIndex.toI32()
|
||||
newExchangeUpdate.block = event.block.number.toI32()
|
||||
newExchangeUpdate.oldAllowedSwapper = fixedRateExchange.allowedSwapper
|
||||
|
||||
newExchangeUpdate.exchangeId = fixedRateId
|
||||
fixedRateExchange.allowedSwapper = event.params.allowedSwapper.toHex()
|
||||
newExchangeUpdate.newAllowedSwapper = fixedRateExchange.allowedSwapper
|
||||
newExchangeUpdate.save()
|
||||
|
@ -162,12 +175,13 @@ export function handleSwap(event: Swapped): void {
|
|||
event.address
|
||||
)
|
||||
const fixedRateExchange = getFixedRateExchange(fixedRateId)
|
||||
|
||||
const eventIndex: number = event.logIndex.toI32()
|
||||
const swap = new FixedRateExchangeSwap(
|
||||
getUpdateOrSwapId(event.transaction.hash.toHex(), fixedRateId)
|
||||
getUpdateOrSwapId(event.transaction.hash.toHex(), fixedRateId, eventIndex)
|
||||
)
|
||||
swap.createdTimestamp = event.block.timestamp.toI32()
|
||||
swap.tx = event.transaction.hash.toHex()
|
||||
swap.eventIndex = event.logIndex.toI32()
|
||||
swap.block = event.block.number.toI32()
|
||||
|
||||
swap.exchangeId = fixedRateId
|
||||
|
@ -178,6 +192,7 @@ export function handleSwap(event: Swapped): void {
|
|||
Address.fromString(fixedRateExchange.baseToken),
|
||||
false
|
||||
)
|
||||
|
||||
swap.baseTokenAmount = weiToDecimal(
|
||||
event.params.baseTokenSwappedAmount.toBigDecimal(),
|
||||
BigInt.fromI32(baseToken.decimals).toI32()
|
||||
|
@ -187,25 +202,40 @@ export function handleSwap(event: Swapped): void {
|
|||
BigInt.fromI32(18).toI32()
|
||||
)
|
||||
|
||||
// Track fees
|
||||
swap.oceanFeeAmount = weiToDecimal(
|
||||
event.params.oceanFeeAmount.toBigDecimal(),
|
||||
BigInt.fromI32(baseToken.decimals).toI32()
|
||||
)
|
||||
swap.marketFeeAmount = weiToDecimal(
|
||||
event.params.marketFeeAmount.toBigDecimal(),
|
||||
BigInt.fromI32(baseToken.decimals).toI32()
|
||||
)
|
||||
swap.consumeMarketFeeAmount = weiToDecimal(
|
||||
event.params.consumeMarketFeeAmount.toBigDecimal(),
|
||||
BigInt.fromI32(baseToken.decimals).toI32()
|
||||
)
|
||||
|
||||
swap.save()
|
||||
|
||||
updateFixedRateExchangeSupply(event.params.exchangeId, event.address)
|
||||
if (event.params.tokenOutAddress.toHexString() == fixedRateExchange.datatoken)
|
||||
|
||||
if (event.params.tokenOutAddress.toHexString() == fixedRateExchange.baseToken)
|
||||
addFixedSwap(
|
||||
event.params.tokenOutAddress.toHexString(),
|
||||
swap.dataTokenAmount
|
||||
)
|
||||
else
|
||||
addFixedSwap(
|
||||
event.params.tokenOutAddress.toHexString(),
|
||||
swap.baseTokenAmount
|
||||
)
|
||||
|
||||
else addFixedSwap(fixedRateExchange.baseToken, swap.baseTokenAmount)
|
||||
// update datatoken lastPriceToken and lastPriceValue
|
||||
const datatoken = getToken(
|
||||
Address.fromString(fixedRateExchange.datatoken),
|
||||
true
|
||||
)
|
||||
datatoken.lastPriceToken = fixedRateExchange.baseToken
|
||||
const priceToken = getToken(
|
||||
Address.fromString(fixedRateExchange.baseToken),
|
||||
false
|
||||
)
|
||||
datatoken.lastPriceToken = priceToken.id
|
||||
datatoken.lastPriceValue = fixedRateExchange.price
|
||||
datatoken.save()
|
||||
}
|
||||
|
@ -225,6 +255,7 @@ export function handlePublishMarketFeeChanged(
|
|||
event.params.swapFee.toBigDecimal(),
|
||||
BigInt.fromI32(18).toI32()
|
||||
)
|
||||
fixedRateExchange.eventIndex = event.logIndex.toI32()
|
||||
fixedRateExchange.save()
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +273,7 @@ export function handleTokenCollected(event: TokenCollected): void {
|
|||
fixedRateExchange.baseTokenBalance.minus(
|
||||
weiToDecimal(event.params.amount.toBigDecimal(), baseToken.decimals)
|
||||
)
|
||||
|
||||
fixedRateExchange.eventIndex = event.logIndex.toI32()
|
||||
fixedRateExchange.save()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Nft, NftUpdate } from '../@types/schema'
|
||||
import { Nft, NftUpdate, NftData, NftTransferHistory } from '../@types/schema'
|
||||
import {
|
||||
MetadataCreated,
|
||||
MetadataState,
|
||||
|
@ -13,14 +13,15 @@ import {
|
|||
RemovedFromMetadataList,
|
||||
RemovedManager,
|
||||
CleanedPermissions,
|
||||
Transfer
|
||||
Transfer,
|
||||
DataChanged
|
||||
} from '../@types/templates/ERC721Template/ERC721Template'
|
||||
import { NftUpdateType } from './utils/constants'
|
||||
import { getNftToken, getNftTokenWithID } from './utils/tokenUtils'
|
||||
import { getUser } from './utils/userUtils'
|
||||
|
||||
function getId(tx: string, nftAddress: string): string {
|
||||
return `${tx}-${nftAddress}`
|
||||
function getId(tx: string, nftAddress: string, eventIndex: number): string {
|
||||
return `${tx}-${nftAddress}-${eventIndex}`
|
||||
}
|
||||
|
||||
export function handleMetadataCreated(event: MetadataCreated): void {
|
||||
|
@ -30,9 +31,11 @@ export function handleMetadataCreated(event: MetadataCreated): void {
|
|||
|
||||
nft.assetState = event.params.state
|
||||
nft.providerUrl = event.params.decryptorUrl.toString()
|
||||
nft.hasMetadata = true
|
||||
|
||||
const eventIndex: number = event.logIndex.toI32()
|
||||
const nftUpdate = new NftUpdate(
|
||||
getId(event.transaction.hash.toHex(), nftAddress)
|
||||
getId(event.transaction.hash.toHex(), nftAddress, eventIndex)
|
||||
)
|
||||
|
||||
nftUpdate.type = NftUpdateType.METADATA_CREATED
|
||||
|
@ -41,9 +44,11 @@ export function handleMetadataCreated(event: MetadataCreated): void {
|
|||
|
||||
nftUpdate.nft = nft.id
|
||||
nftUpdate.providerUrl = nft.providerUrl
|
||||
nftUpdate.tokenUri = nft.tokenUri
|
||||
|
||||
nftUpdate.timestamp = event.block.timestamp.toI32()
|
||||
nftUpdate.tx = event.transaction.hash.toHex()
|
||||
nftUpdate.eventIndex = event.logIndex.toI32()
|
||||
nftUpdate.block = event.block.number.toI32()
|
||||
|
||||
nftUpdate.save()
|
||||
|
@ -56,9 +61,10 @@ export function handleMetadataUpdated(event: MetadataUpdated): void {
|
|||
if (!nft) return
|
||||
|
||||
nft.assetState = event.params.state
|
||||
|
||||
nft.hasMetadata = true
|
||||
const eventIndex: number = event.logIndex.toI32()
|
||||
const nftUpdate = new NftUpdate(
|
||||
getId(event.transaction.hash.toHex(), nftAddress)
|
||||
getId(event.transaction.hash.toHex(), nftAddress, eventIndex)
|
||||
)
|
||||
|
||||
nftUpdate.nft = nft.id
|
||||
|
@ -68,6 +74,7 @@ export function handleMetadataUpdated(event: MetadataUpdated): void {
|
|||
|
||||
nftUpdate.timestamp = event.block.timestamp.toI32()
|
||||
nftUpdate.tx = event.transaction.hash.toHex()
|
||||
nftUpdate.eventIndex = event.logIndex.toI32()
|
||||
nftUpdate.block = event.block.number.toI32()
|
||||
|
||||
nftUpdate.save()
|
||||
|
@ -80,9 +87,9 @@ export function handleMetadataState(event: MetadataState): void {
|
|||
if (!nft) return
|
||||
|
||||
nft.assetState = event.params.state
|
||||
|
||||
const eventIndex: number = event.logIndex.toI32()
|
||||
const nftUpdate = new NftUpdate(
|
||||
getId(event.transaction.hash.toHex(), nftAddress)
|
||||
getId(event.transaction.hash.toHex(), nftAddress, eventIndex)
|
||||
)
|
||||
|
||||
nftUpdate.nft = nft.id
|
||||
|
@ -92,6 +99,7 @@ export function handleMetadataState(event: MetadataState): void {
|
|||
|
||||
nftUpdate.timestamp = event.block.timestamp.toI32()
|
||||
nftUpdate.tx = event.transaction.hash.toHex()
|
||||
nftUpdate.eventIndex = event.logIndex.toI32()
|
||||
nftUpdate.block = event.block.number.toI32()
|
||||
|
||||
nftUpdate.save()
|
||||
|
@ -105,9 +113,9 @@ export function handleTokenUriUpdate(event: TokenURIUpdate): void {
|
|||
if (!nft) return
|
||||
|
||||
nft.tokenUri = event.params.tokenURI.toString()
|
||||
|
||||
const eventIndex: number = event.logIndex.toI32()
|
||||
const nftUpdate = new NftUpdate(
|
||||
getId(event.transaction.hash.toHex(), nftAddress)
|
||||
getId(event.transaction.hash.toHex(), nftAddress, eventIndex)
|
||||
)
|
||||
nftUpdate.nft = nft.id
|
||||
nftUpdate.type = NftUpdateType.TOKENURI_UPDATED
|
||||
|
@ -115,8 +123,9 @@ export function handleTokenUriUpdate(event: TokenURIUpdate): void {
|
|||
nftUpdate.tokenUri = nft.tokenUri
|
||||
nftUpdate.timestamp = event.block.timestamp.toI32()
|
||||
nftUpdate.tx = event.transaction.hash.toHex()
|
||||
nftUpdate.eventIndex = event.logIndex.toI32()
|
||||
nftUpdate.block = event.block.number.toI32()
|
||||
|
||||
nftUpdate.assetState = nft.assetState
|
||||
nftUpdate.save()
|
||||
nft.save()
|
||||
}
|
||||
|
@ -130,6 +139,7 @@ export function handleAddedManager(event: AddedManager): void {
|
|||
if (!existingRoles.includes(event.params.user.toHexString()))
|
||||
existingRoles.push(event.params.user.toHexString())
|
||||
nft.managerRole = existingRoles
|
||||
nft.eventIndex = event.logIndex.toI32()
|
||||
nft.save()
|
||||
}
|
||||
export function handleRemovedManager(event: RemovedManager): void {
|
||||
|
@ -145,6 +155,7 @@ export function handleRemovedManager(event: RemovedManager): void {
|
|||
if (role !== event.params.user.toHexString()) newList.push(role)
|
||||
}
|
||||
nft.managerRole = newList
|
||||
nft.eventIndex = event.logIndex.toI32()
|
||||
nft.save()
|
||||
}
|
||||
|
||||
|
@ -157,6 +168,7 @@ export function handleAddedTo725StoreList(event: AddedTo725StoreList): void {
|
|||
if (!existingRoles.includes(event.params.user.toHexString()))
|
||||
existingRoles.push(event.params.user.toHexString())
|
||||
nft.storeUpdateRole = existingRoles
|
||||
nft.eventIndex = event.logIndex.toI32()
|
||||
nft.save()
|
||||
}
|
||||
|
||||
|
@ -175,6 +187,7 @@ export function handleRemovedFrom725StoreList(
|
|||
if (role !== event.params.user.toHexString()) newList.push(role)
|
||||
}
|
||||
nft.storeUpdateRole = newList
|
||||
nft.eventIndex = event.logIndex.toI32()
|
||||
nft.save()
|
||||
}
|
||||
|
||||
|
@ -189,6 +202,7 @@ export function handleAddedToCreateERC20List(
|
|||
if (!existingRoles.includes(event.params.user.toHexString()))
|
||||
existingRoles.push(event.params.user.toHexString())
|
||||
nft.erc20DeployerRole = existingRoles
|
||||
nft.eventIndex = event.logIndex.toI32()
|
||||
nft.save()
|
||||
}
|
||||
|
||||
|
@ -207,6 +221,7 @@ export function handleRemovedFromCreateERC20List(
|
|||
if (role !== event.params.user.toHexString()) newList.push(role)
|
||||
}
|
||||
nft.erc20DeployerRole = newList
|
||||
nft.eventIndex = event.logIndex.toI32()
|
||||
nft.save()
|
||||
}
|
||||
|
||||
|
@ -219,6 +234,7 @@ export function handleAddedToMetadataList(event: AddedToMetadataList): void {
|
|||
if (!existingRoles.includes(event.params.user.toHexString()))
|
||||
existingRoles.push(event.params.user.toHexString())
|
||||
nft.metadataRole = existingRoles
|
||||
nft.eventIndex = event.logIndex.toI32()
|
||||
nft.save()
|
||||
}
|
||||
|
||||
|
@ -237,6 +253,7 @@ export function handleRemovedFromMetadataList(
|
|||
if (role !== event.params.user.toHexString()) newList.push(role)
|
||||
}
|
||||
nft.metadataRole = newList
|
||||
nft.eventIndex = event.logIndex.toI32()
|
||||
nft.save()
|
||||
}
|
||||
|
||||
|
@ -247,14 +264,41 @@ export function handleCleanedPermissions(event: CleanedPermissions): void {
|
|||
nft.erc20DeployerRole = newList
|
||||
nft.storeUpdateRole = newList
|
||||
nft.managerRole = newList
|
||||
nft.eventIndex = event.logIndex.toI32()
|
||||
nft.save()
|
||||
}
|
||||
|
||||
export function handleNftTransferred(event: Transfer): void {
|
||||
const id = event.address.toHex()
|
||||
const nft = getNftTokenWithID(id)
|
||||
const oldOwner = nft.owner
|
||||
const newOwner = getUser(event.params.to.toHexString())
|
||||
nft.owner = newOwner.id
|
||||
|
||||
nft.save()
|
||||
const eventIndex: number = event.logIndex.toI32()
|
||||
const transferId = `${
|
||||
nft.address
|
||||
}-${event.transaction.hash.toHex()}-${eventIndex}`
|
||||
const newTransfer = new NftTransferHistory(transferId)
|
||||
newTransfer.oldOwner = oldOwner
|
||||
newTransfer.nft = nft.id
|
||||
newTransfer.newOwner = newOwner.id
|
||||
newTransfer.txId = event.transaction.hash.toHex()
|
||||
newTransfer.eventIndex = event.logIndex.toI32()
|
||||
newTransfer.timestamp = event.block.timestamp.toI32()
|
||||
newTransfer.block = event.block.number.toI32()
|
||||
newTransfer.save()
|
||||
}
|
||||
|
||||
export function handleNftData(event: DataChanged): void {
|
||||
const id = event.address.toHexString() + '-' + event.params.key.toHexString()
|
||||
const nft = getNftToken(event.address)
|
||||
let data = NftData.load(id)
|
||||
if (data == null) {
|
||||
data = new NftData(id)
|
||||
}
|
||||
data.key = event.params.key
|
||||
data.value = event.params.value
|
||||
data.nft = nft.id
|
||||
data.save()
|
||||
}
|
||||
|
|
|
@ -1,342 +0,0 @@
|
|||
import { BigInt, Address } from '@graphprotocol/graph-ts'
|
||||
import {
|
||||
LOG_EXIT,
|
||||
LOG_JOIN,
|
||||
LOG_SETUP,
|
||||
LOG_SWAP,
|
||||
PublishMarketFeeChanged,
|
||||
SwapFeeChanged
|
||||
} from '../@types/templates/BPool/BPool'
|
||||
import { Transfer } from '../@types/templates/BPool/BToken'
|
||||
import {
|
||||
decimal,
|
||||
integer,
|
||||
PoolTransactionType,
|
||||
ZERO_ADDRESS
|
||||
} from './utils/constants'
|
||||
import { weiToDecimal } from './utils/generic'
|
||||
import { addLiquidity, addPoolSwap, removeLiquidity } from './utils/globalUtils'
|
||||
import {
|
||||
calcSpotPrice,
|
||||
getPool,
|
||||
getPoolTransaction,
|
||||
getPoolShare,
|
||||
getPoolSnapshot,
|
||||
getPoolLpSwapFee,
|
||||
getPoolPublisherMarketFee
|
||||
} from './utils/poolUtils'
|
||||
import { getToken } from './utils/tokenUtils'
|
||||
import { getUser } from './utils/userUtils'
|
||||
|
||||
// kinda redundant code in join/swap/exit
|
||||
export function handleJoin(event: LOG_JOIN): void {
|
||||
const pool = getPool(event.address.toHex())
|
||||
const user = getUser(event.params.caller.toHex())
|
||||
const poolTx = getPoolTransaction(event, user.id, PoolTransactionType.JOIN)
|
||||
|
||||
pool.transactionCount = pool.transactionCount.plus(integer.ONE)
|
||||
pool.joinCount = pool.joinCount.plus(integer.ONE)
|
||||
|
||||
// get token, update pool transaction, poolSnapshot
|
||||
|
||||
const token = getToken(event.params.tokenIn, false)
|
||||
const ammount = weiToDecimal(
|
||||
event.params.tokenAmountIn.toBigDecimal(),
|
||||
token.decimals
|
||||
)
|
||||
if (token.isDatatoken) {
|
||||
poolTx.datatoken = token.id
|
||||
poolTx.datatokenValue = ammount
|
||||
|
||||
pool.datatokenLiquidity = pool.datatokenLiquidity.plus(ammount)
|
||||
} else {
|
||||
poolTx.baseToken = token.id
|
||||
poolTx.baseTokenValue = ammount
|
||||
pool.baseTokenLiquidity = pool.baseTokenLiquidity.plus(ammount)
|
||||
|
||||
addLiquidity(token.id, ammount)
|
||||
}
|
||||
|
||||
poolTx.save()
|
||||
pool.save()
|
||||
|
||||
if (pool.isFinalized) {
|
||||
const poolSnapshot = getPoolSnapshot(pool.id, event.block.timestamp.toI32())
|
||||
poolSnapshot.baseTokenLiquidity = pool.baseTokenLiquidity
|
||||
poolSnapshot.datatokenLiquidity = pool.datatokenLiquidity
|
||||
poolSnapshot.totalShares = pool.totalShares
|
||||
poolSnapshot.save()
|
||||
}
|
||||
}
|
||||
|
||||
export function handleExit(event: LOG_EXIT): void {
|
||||
const pool = getPool(event.address.toHex())
|
||||
const user = getUser(event.params.caller.toHex())
|
||||
const poolTx = getPoolTransaction(event, user.id, PoolTransactionType.EXIT)
|
||||
|
||||
pool.transactionCount = pool.transactionCount.plus(integer.ONE)
|
||||
pool.joinCount = pool.joinCount.plus(integer.ONE)
|
||||
|
||||
// get token and update pool transaction, value is negative because this is an exit event.
|
||||
const token = getToken(event.params.tokenOut, false)
|
||||
const poolSnapshot = getPoolSnapshot(pool.id, event.block.timestamp.toI32())
|
||||
const ammount = weiToDecimal(
|
||||
event.params.tokenAmountOut.toBigDecimal(),
|
||||
token.decimals
|
||||
)
|
||||
if (token.isDatatoken) {
|
||||
poolTx.datatoken = token.id
|
||||
poolTx.datatokenValue = ammount
|
||||
|
||||
pool.datatokenLiquidity = pool.datatokenLiquidity.minus(ammount)
|
||||
} else {
|
||||
poolTx.baseToken = token.id
|
||||
poolTx.baseTokenValue = ammount
|
||||
|
||||
pool.baseTokenLiquidity = pool.baseTokenLiquidity.minus(ammount)
|
||||
removeLiquidity(token.id, ammount)
|
||||
}
|
||||
|
||||
poolSnapshot.baseTokenLiquidity = pool.baseTokenLiquidity
|
||||
poolSnapshot.datatokenLiquidity = pool.datatokenLiquidity
|
||||
poolSnapshot.totalShares = pool.totalShares
|
||||
|
||||
poolSnapshot.save()
|
||||
poolTx.save()
|
||||
pool.save()
|
||||
}
|
||||
|
||||
export function handleSwap(event: LOG_SWAP): void {
|
||||
const pool = getPool(event.address.toHex())
|
||||
const user = getUser(event.params.caller.toHex())
|
||||
const poolTx = getPoolTransaction(event, user.id, PoolTransactionType.SWAP)
|
||||
|
||||
pool.transactionCount = pool.transactionCount.plus(integer.ONE)
|
||||
pool.joinCount = pool.joinCount.plus(integer.ONE)
|
||||
|
||||
const poolSnapshot = getPoolSnapshot(pool.id, event.block.timestamp.toI32())
|
||||
const tokenOut = getToken(event.params.tokenOut, false)
|
||||
const tokenIn = getToken(event.params.tokenIn, false)
|
||||
let spotPrice = decimal.ZERO
|
||||
|
||||
const ammountOut = weiToDecimal(
|
||||
event.params.tokenAmountOut.toBigDecimal(),
|
||||
tokenOut.decimals
|
||||
)
|
||||
const tokenOutNewBalance = weiToDecimal(
|
||||
event.params.outBalance.toBigDecimal(),
|
||||
tokenOut.decimals
|
||||
)
|
||||
const tokenInNewBalance = weiToDecimal(
|
||||
event.params.inBalance.toBigDecimal(),
|
||||
tokenIn.decimals
|
||||
)
|
||||
|
||||
if (tokenOut.isDatatoken) {
|
||||
poolTx.datatoken = tokenOut.id
|
||||
poolTx.datatokenValue = ammountOut.neg()
|
||||
|
||||
pool.datatokenLiquidity = tokenOutNewBalance
|
||||
} else {
|
||||
poolTx.baseToken = tokenOut.id
|
||||
poolTx.baseTokenValue = ammountOut.neg()
|
||||
|
||||
spotPrice = decimal.ONE.div(
|
||||
weiToDecimal(event.params.newSpotPrice.toBigDecimal(), tokenOut.decimals)
|
||||
)
|
||||
pool.baseTokenLiquidity = tokenOutNewBalance
|
||||
poolSnapshot.swapVolume = poolSnapshot.swapVolume.plus(ammountOut)
|
||||
|
||||
addPoolSwap(tokenOut.id, ammountOut)
|
||||
removeLiquidity(tokenOut.id, ammountOut)
|
||||
}
|
||||
|
||||
// update pool token in
|
||||
const ammountIn = weiToDecimal(
|
||||
event.params.tokenAmountIn.toBigDecimal(),
|
||||
tokenIn.decimals
|
||||
)
|
||||
if (tokenIn.isDatatoken) {
|
||||
poolTx.datatoken = tokenIn.id
|
||||
poolTx.datatokenValue = ammountIn
|
||||
|
||||
pool.datatokenLiquidity = tokenInNewBalance
|
||||
} else {
|
||||
poolTx.baseToken = tokenIn.id
|
||||
poolTx.baseTokenValue = ammountIn
|
||||
|
||||
spotPrice = weiToDecimal(
|
||||
event.params.newSpotPrice.toBigDecimal(),
|
||||
tokenOut.decimals
|
||||
)
|
||||
pool.baseTokenLiquidity = tokenInNewBalance
|
||||
poolSnapshot.swapVolume = poolSnapshot.swapVolume.plus(ammountIn)
|
||||
addLiquidity(tokenIn.id, ammountIn)
|
||||
addPoolSwap(tokenIn.id, ammountIn)
|
||||
}
|
||||
|
||||
// update spot price
|
||||
pool.spotPrice = spotPrice
|
||||
poolSnapshot.spotPrice = spotPrice
|
||||
poolSnapshot.baseTokenLiquidity = pool.baseTokenLiquidity
|
||||
poolSnapshot.datatokenLiquidity = pool.datatokenLiquidity
|
||||
poolSnapshot.totalShares = pool.totalShares
|
||||
|
||||
poolSnapshot.save()
|
||||
poolTx.save()
|
||||
pool.save()
|
||||
|
||||
// update datatoken lastPriceToken and lastPriceValue
|
||||
const datatoken = getToken(Address.fromString(pool.datatoken), true)
|
||||
datatoken.lastPriceToken = pool.baseToken
|
||||
datatoken.lastPriceValue = spotPrice
|
||||
datatoken.save()
|
||||
}
|
||||
|
||||
// setup is just to set token weight(it will mostly be 50:50) and spotPrice
|
||||
export function handleSetup(event: LOG_SETUP): void {
|
||||
const pool = getPool(event.address.toHex())
|
||||
|
||||
pool.controller = event.params.caller.toHexString()
|
||||
const token = getToken(event.params.baseToken, false)
|
||||
pool.baseToken = token.id
|
||||
pool.baseTokenWeight = weiToDecimal(
|
||||
event.params.baseTokenWeight.toBigDecimal(),
|
||||
18
|
||||
)
|
||||
|
||||
// decimals hardcoded because datatokens have 18 decimals
|
||||
const datatoken = getToken(event.params.datatoken, true)
|
||||
pool.datatoken = datatoken.id
|
||||
pool.datatokenWeight = weiToDecimal(
|
||||
event.params.datatokenWeight.toBigDecimal(),
|
||||
18
|
||||
)
|
||||
|
||||
// calculate spotPrice
|
||||
const spotPrice = calcSpotPrice(
|
||||
pool.id,
|
||||
pool.baseToken,
|
||||
pool.datatoken,
|
||||
token.decimals
|
||||
)
|
||||
pool.spotPrice = spotPrice
|
||||
pool.isFinalized = true
|
||||
// TODO: proper tx , add baseToken, datatoken
|
||||
const fromUser = getUser(event.transaction.from.toHexString())
|
||||
const poolTx = getPoolTransaction(
|
||||
event,
|
||||
fromUser.id,
|
||||
PoolTransactionType.SETUP
|
||||
)
|
||||
poolTx.type = PoolTransactionType.SETUP
|
||||
poolTx.baseToken = token.id
|
||||
poolTx.baseTokenValue = weiToDecimal(
|
||||
event.params.baseTokenAmountIn.toBigDecimal(),
|
||||
token.decimals
|
||||
)
|
||||
pool.save()
|
||||
poolTx.save()
|
||||
|
||||
const lpFee = getPoolLpSwapFee(event.address)
|
||||
pool.liquidityProviderSwapFee = lpFee
|
||||
const publisherMarketFee = getPoolPublisherMarketFee(event.address)
|
||||
pool.publishMarketSwapFee = publisherMarketFee
|
||||
|
||||
pool.save()
|
||||
const poolSnapshot = getPoolSnapshot(pool.id, event.block.timestamp.toI32())
|
||||
poolSnapshot.spotPrice = spotPrice
|
||||
poolSnapshot.baseTokenLiquidity = pool.baseTokenLiquidity
|
||||
poolSnapshot.datatokenLiquidity = pool.datatokenLiquidity
|
||||
poolSnapshot.totalShares = pool.totalShares
|
||||
|
||||
poolSnapshot.save()
|
||||
datatoken.save()
|
||||
}
|
||||
|
||||
export function handlerBptTransfer(event: Transfer): void {
|
||||
const fromAddress = event.params.src.toHexString()
|
||||
const toAddress = event.params.dst.toHexString()
|
||||
const poolAddress = event.address.toHex()
|
||||
const caller = getUser(event.transaction.from.toHex())
|
||||
const poolTx = getPoolTransaction(event, caller.id, PoolTransactionType.SWAP)
|
||||
|
||||
// btoken has 18 decimals
|
||||
const ammount = weiToDecimal(event.params.amt.toBigDecimal(), 18)
|
||||
|
||||
if (fromAddress != ZERO_ADDRESS && toAddress != ZERO_ADDRESS) {
|
||||
poolTx.sharesTransferAmount = poolTx.sharesTransferAmount.plus(ammount)
|
||||
}
|
||||
|
||||
if (fromAddress == ZERO_ADDRESS) {
|
||||
// add total
|
||||
const pool = getPool(poolAddress)
|
||||
pool.totalShares = pool.totalShares.plus(ammount)
|
||||
|
||||
// check tx?
|
||||
if (pool.isFinalized) {
|
||||
const poolSnapshot = getPoolSnapshot(
|
||||
poolAddress,
|
||||
event.block.timestamp.toI32()
|
||||
)
|
||||
poolSnapshot.totalShares = pool.totalShares
|
||||
poolSnapshot.save()
|
||||
}
|
||||
|
||||
pool.save()
|
||||
} else {
|
||||
if (poolAddress != fromAddress) {
|
||||
const fromUser = getPoolShare(poolAddress, fromAddress)
|
||||
fromUser.shares = fromUser.shares.minus(ammount)
|
||||
fromUser.save()
|
||||
}
|
||||
}
|
||||
|
||||
if (toAddress == ZERO_ADDRESS) {
|
||||
// remove
|
||||
const pool = getPool(poolAddress)
|
||||
pool.totalShares = pool.totalShares.minus(ammount)
|
||||
if (pool.isFinalized) {
|
||||
const poolSnapshot = getPoolSnapshot(
|
||||
poolAddress,
|
||||
event.block.timestamp.toI32()
|
||||
)
|
||||
poolSnapshot.totalShares = pool.totalShares
|
||||
poolSnapshot.save()
|
||||
}
|
||||
pool.save()
|
||||
} else {
|
||||
if (poolAddress != toAddress) {
|
||||
const toUser = getPoolShare(poolAddress, toAddress)
|
||||
toUser.shares = toUser.shares.plus(ammount)
|
||||
toUser.save()
|
||||
}
|
||||
}
|
||||
|
||||
poolTx.save()
|
||||
}
|
||||
|
||||
export function handlePublishMarketFeeChanged(
|
||||
event: PublishMarketFeeChanged
|
||||
): void {
|
||||
const pool = getPool(event.address.toHex())
|
||||
if (pool) {
|
||||
pool.publishMarketFeeAddress = event.params.newMarketCollector.toHexString()
|
||||
pool.publishMarketSwapFee = weiToDecimal(
|
||||
event.params.swapFee.toBigDecimal(),
|
||||
BigInt.fromI32(18).toI32()
|
||||
)
|
||||
pool.save()
|
||||
}
|
||||
}
|
||||
|
||||
export function handleSwapFeeChanged(event: SwapFeeChanged): void {
|
||||
const pool = getPool(event.address.toHex())
|
||||
if (pool) {
|
||||
pool.liquidityProviderSwapFee = weiToDecimal(
|
||||
event.params.amount.toBigDecimal(),
|
||||
BigInt.fromI32(18).toI32()
|
||||
)
|
||||
pool.save()
|
||||
}
|
||||
}
|
|
@ -21,12 +21,6 @@ export namespace decimal {
|
|||
}
|
||||
|
||||
// string enums don't work in wasm so this was the alternative, not optimal
|
||||
export namespace PoolTransactionType {
|
||||
export const JOIN = 'JOIN'
|
||||
export const EXIT = 'EXIT'
|
||||
export const SWAP = 'SWAP'
|
||||
export const SETUP = 'SETUP'
|
||||
}
|
||||
|
||||
export namespace NftUpdateType {
|
||||
export const METADATA_CREATED = 'METADATA_CREATED'
|
||||
|
@ -34,3 +28,8 @@ export namespace NftUpdateType {
|
|||
export const STATE_UPDATED = 'STATE_UPDATED'
|
||||
export const TOKENURI_UPDATED = 'TOKENURI_UPDATED'
|
||||
}
|
||||
|
||||
export namespace veAllocationUpdateType {
|
||||
export const SET = 'SET'
|
||||
export const REMOVED = 'REMOVED'
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import { Address, BigDecimal } from '@graphprotocol/graph-ts'
|
||||
import { DFAvailableClaim, DFReward } from '../../@types/schema'
|
||||
import { getUser } from './userUtils'
|
||||
|
||||
export function createDFReward(address: Address): DFReward {
|
||||
const dfRewards = new DFReward(address.toHexString())
|
||||
const user = getUser(address.toHexString())
|
||||
dfRewards.receiver = user.id
|
||||
dfRewards.save()
|
||||
return dfRewards
|
||||
}
|
||||
|
||||
export function getDFReward(address: Address): DFReward {
|
||||
let dfRewards = DFReward.load(address.toHexString())
|
||||
if (dfRewards === null) {
|
||||
dfRewards = createDFReward(address)
|
||||
}
|
||||
return dfRewards
|
||||
}
|
||||
|
||||
export function getDFAvailableClaim(
|
||||
user: Address,
|
||||
token: Address
|
||||
): DFAvailableClaim {
|
||||
const id = user.toHexString() + '-' + token.toHexString()
|
||||
let dfClaim = DFAvailableClaim.load(id)
|
||||
if (dfClaim == null) {
|
||||
dfClaim = new DFAvailableClaim(id)
|
||||
dfClaim.receiver = user.toHexString()
|
||||
dfClaim.amount = BigDecimal.zero()
|
||||
dfClaim.token = token.toHexString()
|
||||
}
|
||||
return dfClaim
|
||||
}
|
|
@ -52,12 +52,18 @@ export function updateFixedRateExchangeSupply(
|
|||
fixedRateDetails.value.value8.toBigDecimal(),
|
||||
baseToken.decimals
|
||||
)
|
||||
// update withMint state
|
||||
fixedRateExchange.withMint = fixedRateDetails.value.value11
|
||||
|
||||
// update active state
|
||||
fixedRateExchange.active = fixedRateDetails.value.value6
|
||||
fixedRateExchange.save()
|
||||
}
|
||||
|
||||
export function getUpdateOrSwapId(
|
||||
txAddress: string,
|
||||
exchangeId: string
|
||||
exchangeId: string,
|
||||
eventIndex: number
|
||||
): string {
|
||||
return `${txAddress}-${exchangeId}`
|
||||
return `${txAddress}-${exchangeId}-${eventIndex}`
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ import {
|
|||
GlobalStatistic,
|
||||
GlobalTotalFixedSwapPair,
|
||||
GlobalTotalLiquidityPair,
|
||||
GlobalTotalPoolSwapPair,
|
||||
OPC,
|
||||
Template
|
||||
} from '../../@types/schema'
|
||||
|
@ -14,7 +13,13 @@ export function getGlobalStats(): GlobalStatistic {
|
|||
let globalStats = GlobalStatistic.load(GLOBAL_ID)
|
||||
if (!globalStats) {
|
||||
globalStats = new GlobalStatistic(GLOBAL_ID)
|
||||
globalStats.version = '1.2.1'
|
||||
globalStats.version = '4.0.2'
|
||||
globalStats.orderCount = 0
|
||||
globalStats.fixedCount = 0
|
||||
globalStats.datatokenCount = 0
|
||||
globalStats.dispenserCount = 0
|
||||
globalStats.nftCount = 0
|
||||
globalStats.totalOceanLocked = BigDecimal.zero()
|
||||
globalStats.save()
|
||||
}
|
||||
return globalStats
|
||||
|
@ -29,6 +34,11 @@ export function getOPC(): OPC {
|
|||
return globalStats
|
||||
}
|
||||
|
||||
export function getTotalOceanLocked(): BigDecimal {
|
||||
const globalStats = getGlobalStats()
|
||||
return globalStats.totalOceanLocked
|
||||
}
|
||||
|
||||
export function getTemplates(): Template {
|
||||
let templates = Template.load(GLOBAL_ID)
|
||||
if (!templates) {
|
||||
|
@ -38,6 +48,12 @@ export function getTemplates(): Template {
|
|||
return templates
|
||||
}
|
||||
|
||||
export function updateTotalOceanLocked(amount: BigDecimal): void {
|
||||
const globalStats = getGlobalStats()
|
||||
globalStats.totalOceanLocked = amount
|
||||
globalStats.save()
|
||||
}
|
||||
|
||||
export function addOrder(): void {
|
||||
const globalStats = getGlobalStats()
|
||||
globalStats.orderCount = globalStats.orderCount + 1
|
||||
|
@ -68,31 +84,14 @@ export function addDispenser(): void {
|
|||
globalStats.save()
|
||||
}
|
||||
|
||||
export function addPool(): void {
|
||||
const globalStats = getGlobalStats()
|
||||
globalStats.poolCount = globalStats.poolCount + 1
|
||||
globalStats.save()
|
||||
}
|
||||
|
||||
export function addPoolSwap(tokenAddress: string, value: BigDecimal): void {
|
||||
let poolSwapPair = GlobalTotalPoolSwapPair.load(tokenAddress)
|
||||
if (!poolSwapPair) {
|
||||
poolSwapPair = new GlobalTotalPoolSwapPair(tokenAddress)
|
||||
poolSwapPair.globalStatistic = GLOBAL_ID
|
||||
poolSwapPair.token = tokenAddress
|
||||
}
|
||||
poolSwapPair.value = poolSwapPair.value.plus(value)
|
||||
poolSwapPair.count = poolSwapPair.count.plus(BigInt.fromI32(1))
|
||||
|
||||
poolSwapPair.save()
|
||||
}
|
||||
|
||||
export function addFixedSwap(tokenAddress: string, value: BigDecimal): void {
|
||||
let fixedSwapPair = GlobalTotalFixedSwapPair.load(tokenAddress)
|
||||
if (!fixedSwapPair) {
|
||||
fixedSwapPair = new GlobalTotalFixedSwapPair(tokenAddress)
|
||||
fixedSwapPair.globalStatistic = GLOBAL_ID
|
||||
fixedSwapPair.token = tokenAddress
|
||||
fixedSwapPair.value = BigDecimal.zero()
|
||||
fixedSwapPair.count = BigInt.zero()
|
||||
}
|
||||
fixedSwapPair.value = fixedSwapPair.value.plus(value)
|
||||
fixedSwapPair.count = fixedSwapPair.count.plus(BigInt.fromI32(1))
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import { Order, OrderReuse } from '../../@types/schema'
|
||||
|
||||
export function getOrderId(
|
||||
tx: string,
|
||||
tokenAddress: string,
|
||||
fromAddress: string,
|
||||
eventIndex: number
|
||||
): string {
|
||||
return `${tx}-${tokenAddress}-${fromAddress}-${eventIndex}`
|
||||
}
|
||||
|
||||
export function createOrder(orderId: string): Order {
|
||||
const order = new Order(orderId)
|
||||
return order
|
||||
}
|
||||
|
||||
export function getOrder(
|
||||
transactionHash: string,
|
||||
address: string,
|
||||
transactionFrom: string,
|
||||
eventIndex: number
|
||||
): Order {
|
||||
const orderId = getOrderId(
|
||||
transactionHash,
|
||||
address,
|
||||
transactionFrom,
|
||||
eventIndex
|
||||
)
|
||||
let newOrder = Order.load(orderId)
|
||||
if (newOrder === null) {
|
||||
newOrder = createOrder(orderId)
|
||||
}
|
||||
return newOrder
|
||||
}
|
||||
|
||||
export function searchOrderForEvent(
|
||||
transactionHash: string,
|
||||
address: string,
|
||||
transactionFrom: string,
|
||||
eventIndex: number
|
||||
): Order | null {
|
||||
for (let i = eventIndex; i >= 0; i--) {
|
||||
const orderId = getOrderId(transactionHash, address, transactionFrom, i)
|
||||
const order = Order.load(orderId)
|
||||
if (order && order.datatoken == address) {
|
||||
return order
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export function searchOrderReusedForEvent(
|
||||
transactionHash: string,
|
||||
eventAddress: string,
|
||||
eventIndex: number
|
||||
): OrderReuse | null {
|
||||
for (let i = eventIndex; i >= 0; i--) {
|
||||
const orderReused = OrderReuse.load(`${transactionHash}-${i}`)
|
||||
if (!orderReused) {
|
||||
continue
|
||||
}
|
||||
const order = Order.load(orderReused.order)
|
||||
|
||||
if (order && order.datatoken == eventAddress) {
|
||||
return orderReused
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
import { Address, BigDecimal, ethereum } from '@graphprotocol/graph-ts'
|
||||
import {
|
||||
Pool,
|
||||
PoolShare,
|
||||
PoolSnapshot,
|
||||
PoolTransaction
|
||||
} from '../../@types/schema'
|
||||
import { BPool } from '../../@types/templates/BPool/BPool'
|
||||
import { DAY, decimal, integer } from './constants'
|
||||
import { gweiToEth, weiToDecimal } from './generic'
|
||||
import { getUser } from './userUtils'
|
||||
|
||||
export function getPoolShareId(
|
||||
poolAddress: string,
|
||||
userAddress: string
|
||||
): string {
|
||||
return `${poolAddress}-${userAddress}`
|
||||
}
|
||||
|
||||
export function getPoolTransactionId(
|
||||
txHash: string,
|
||||
userAddress: string
|
||||
): string {
|
||||
return `${txHash}-${userAddress}`
|
||||
}
|
||||
|
||||
export function getPoolTransaction(
|
||||
event: ethereum.Event,
|
||||
userAddress: string,
|
||||
type: string
|
||||
): PoolTransaction {
|
||||
const txId = getPoolTransactionId(
|
||||
event.transaction.hash.toHexString(),
|
||||
userAddress
|
||||
)
|
||||
let poolTx = PoolTransaction.load(txId)
|
||||
|
||||
// create pool transaction and fill basic fields
|
||||
if (poolTx === null) {
|
||||
poolTx = new PoolTransaction(txId)
|
||||
|
||||
poolTx.user = userAddress
|
||||
poolTx.pool = event.address.toHex()
|
||||
poolTx.type = type
|
||||
|
||||
poolTx.timestamp = event.block.timestamp.toI32()
|
||||
poolTx.tx = event.transaction.hash.toHex()
|
||||
poolTx.block = event.block.number.toI32()
|
||||
|
||||
poolTx.gasPrice = gweiToEth(event.transaction.gasPrice.toBigDecimal())
|
||||
poolTx.gasLimit = event.transaction.gasLimit.toBigDecimal()
|
||||
}
|
||||
|
||||
return poolTx
|
||||
}
|
||||
|
||||
export function getPoolShare(
|
||||
poolAddress: string,
|
||||
userAddress: string
|
||||
): PoolShare {
|
||||
let poolShare = PoolShare.load(getPoolShareId(poolAddress, userAddress))
|
||||
if (poolShare === null) {
|
||||
poolShare = new PoolShare(getPoolShareId(poolAddress, userAddress))
|
||||
poolShare.user = getUser(userAddress).id
|
||||
poolShare.pool = poolAddress
|
||||
poolShare.save()
|
||||
}
|
||||
return poolShare
|
||||
}
|
||||
|
||||
export function getPool(poolAddress: string): Pool {
|
||||
const pool = Pool.load(poolAddress)
|
||||
if (pool === null) {
|
||||
// what now?
|
||||
throw new Error(`Didn't find pool with address ${poolAddress} `)
|
||||
}
|
||||
return pool
|
||||
}
|
||||
|
||||
export function calcSpotPrice(
|
||||
poolAddress: string,
|
||||
baseTokenAddress: string,
|
||||
datatokenAddress: string,
|
||||
baseTokenDecimals: i32
|
||||
): BigDecimal {
|
||||
const poolContract = BPool.bind(Address.fromString(poolAddress))
|
||||
// tokenIn is always the baseToken and tokenOut is the datatoken because we want the spot price to be in baseToken eg: 1 DT = 0.5 OCEAN
|
||||
const weiPrice = poolContract.try_getSpotPrice(
|
||||
Address.fromString(baseTokenAddress),
|
||||
Address.fromString(datatokenAddress),
|
||||
integer.ZERO
|
||||
).value
|
||||
const price = weiToDecimal(weiPrice.toBigDecimal(), baseTokenDecimals)
|
||||
|
||||
return price
|
||||
}
|
||||
|
||||
export function getDateFromTimestamp(timestamp: i32): i32 {
|
||||
// date without time
|
||||
return timestamp - (timestamp % DAY)
|
||||
}
|
||||
export function getPoolSnapshotId(poolAddress: string, timestamp: i32): string {
|
||||
return `${poolAddress}-${getDateFromTimestamp(timestamp)}`
|
||||
}
|
||||
|
||||
export function createPoolSnapshot(
|
||||
poolAddress: string,
|
||||
timestamp: i32
|
||||
): PoolSnapshot {
|
||||
const snapshotId = getPoolSnapshotId(poolAddress, timestamp)
|
||||
|
||||
const pool = getPool(poolAddress)
|
||||
const snapshot = new PoolSnapshot(snapshotId)
|
||||
|
||||
snapshot.pool = poolAddress
|
||||
|
||||
snapshot.totalShares = pool.totalShares
|
||||
snapshot.swapVolume = decimal.ZERO
|
||||
snapshot.swapFees = decimal.ZERO
|
||||
snapshot.baseToken = pool.baseToken
|
||||
snapshot.datatoken = pool.datatoken
|
||||
snapshot.datatokenLiquidity = decimal.ZERO
|
||||
|
||||
snapshot.date = getDateFromTimestamp(timestamp)
|
||||
snapshot.spotPrice = pool.spotPrice
|
||||
|
||||
snapshot.save()
|
||||
return snapshot
|
||||
}
|
||||
|
||||
export function getPoolSnapshot(
|
||||
poolAddress: string,
|
||||
timestamp: i32
|
||||
): PoolSnapshot {
|
||||
let snapshot = PoolSnapshot.load(getPoolSnapshotId(poolAddress, timestamp))
|
||||
if (snapshot === null) {
|
||||
snapshot = createPoolSnapshot(poolAddress, timestamp)
|
||||
}
|
||||
|
||||
return snapshot
|
||||
}
|
||||
|
||||
export function getPoolLpSwapFee(poolAddress: Address): BigDecimal {
|
||||
const contract = BPool.bind(poolAddress)
|
||||
const lpFeeWei = contract.getSwapFee()
|
||||
const lpFee = weiToDecimal(lpFeeWei.toBigDecimal(), 18)
|
||||
return lpFee
|
||||
}
|
||||
export function getPoolPublisherMarketFee(poolAddress: Address): BigDecimal {
|
||||
const contract = BPool.bind(poolAddress)
|
||||
const marketFeeWei = contract.getMarketFee()
|
||||
const marketFee = weiToDecimal(marketFeeWei.toBigDecimal(), 18)
|
||||
return marketFee
|
||||
}
|
||||
|
||||
export function getBalance(
|
||||
poolAddress: Address,
|
||||
tokenAddress: Address,
|
||||
tokenDecimals: i32
|
||||
): BigDecimal {
|
||||
const contract = BPool.bind(poolAddress)
|
||||
const balanceWei = contract.getBalance(tokenAddress)
|
||||
const balance = weiToDecimal(balanceWei.toBigDecimal(), tokenDecimals)
|
||||
return balance
|
||||
}
|
|
@ -1,15 +1,18 @@
|
|||
import { Address, log, BigDecimal } from '@graphprotocol/graph-ts'
|
||||
import { Nft, Token } from '../../@types/schema'
|
||||
import { Address, log, BigDecimal, BigInt } from '@graphprotocol/graph-ts'
|
||||
import {
|
||||
Nft,
|
||||
Token,
|
||||
PredictContract,
|
||||
Erc721Template,
|
||||
Erc20Template
|
||||
} from '../../@types/schema'
|
||||
import { ERC20 } from '../../@types/templates/ERC20Template/ERC20'
|
||||
import { ERC20Template, ERC721Template } from '../../@types/templates'
|
||||
import { ERC721Template } from '../../@types/templates'
|
||||
import { addNft } from './globalUtils'
|
||||
import { ZERO_ADDRESS } from './constants'
|
||||
|
||||
export function createToken(address: Address, isDatatoken: boolean): Token {
|
||||
log.debug('started creating token with address: {}', [address.toHexString()])
|
||||
if (isDatatoken) {
|
||||
ERC20Template.create(address)
|
||||
}
|
||||
const token = new Token(address.toHexString())
|
||||
const contract = ERC20.bind(address)
|
||||
const name = contract.try_name()
|
||||
|
@ -25,6 +28,13 @@ export function createToken(address: Address, isDatatoken: boolean): Token {
|
|||
else token.decimals = decimals.value
|
||||
token.lastPriceToken = ZERO_ADDRESS
|
||||
token.lastPriceValue = BigDecimal.zero()
|
||||
token.orderCount = BigInt.zero()
|
||||
token.holderCount = BigInt.zero()
|
||||
token.createdTimestamp = 0
|
||||
token.block = 0
|
||||
token.tx = ''
|
||||
token.eventIndex = 0
|
||||
token.templateId = BigInt.zero()
|
||||
token.save()
|
||||
return token
|
||||
}
|
||||
|
@ -38,15 +48,24 @@ export function getToken(address: Address, isDatatoken: boolean): Token {
|
|||
}
|
||||
|
||||
export function createNftToken(address: Address): Nft {
|
||||
log.debug('started creating nft token with address: {}', [
|
||||
address.toHexString()
|
||||
])
|
||||
ERC721Template.create(address)
|
||||
const token = new Nft(address.toHexString())
|
||||
// const contract = ERC721Template.bind(address)
|
||||
token.name = ''
|
||||
token.symbol = ''
|
||||
token.address = address.toHexString()
|
||||
token.providerUrl = ''
|
||||
token.tokenUri = ''
|
||||
token.owner = ''
|
||||
token.creator = ''
|
||||
token.assetState = 0
|
||||
token.template = ''
|
||||
token.transferable = true
|
||||
token.createdTimestamp = 0
|
||||
token.block = 0
|
||||
token.tx = ''
|
||||
token.orderCount = BigInt.zero()
|
||||
token.hasMetadata = false
|
||||
token.eventIndex = 0
|
||||
token.save()
|
||||
addNft()
|
||||
return token
|
||||
|
@ -68,6 +87,19 @@ export function getNftTokenWithID(tokenId: string): Nft {
|
|||
nftToken.name = ''
|
||||
nftToken.symbol = ''
|
||||
nftToken.address = tokenId
|
||||
nftToken.providerUrl = ''
|
||||
nftToken.tokenUri = ''
|
||||
nftToken.owner = ''
|
||||
nftToken.creator = ''
|
||||
nftToken.assetState = 0
|
||||
nftToken.template = ''
|
||||
nftToken.transferable = true
|
||||
nftToken.createdTimestamp = 0
|
||||
nftToken.block = 0
|
||||
nftToken.tx = ''
|
||||
nftToken.orderCount = BigInt.zero()
|
||||
nftToken.hasMetadata = false
|
||||
nftToken.eventIndex = 0
|
||||
nftToken.save()
|
||||
addNft()
|
||||
}
|
||||
|
@ -81,3 +113,44 @@ export function getUSDValue(
|
|||
): BigDecimal {
|
||||
return BigDecimal.zero()
|
||||
}
|
||||
|
||||
export function getErc721TemplateId(address: Address): BigInt {
|
||||
const template = Erc721Template.load(address.toHexString())
|
||||
if (template) {
|
||||
return template.templateId
|
||||
}
|
||||
return BigInt.zero()
|
||||
}
|
||||
|
||||
export function getErc20TemplateId(address: Address): BigInt {
|
||||
const template = Erc20Template.load(address.toHexString())
|
||||
if (template) {
|
||||
return template.templateId
|
||||
}
|
||||
return BigInt.zero()
|
||||
}
|
||||
|
||||
export function createPredictContract(address: Address): PredictContract {
|
||||
const predictContract = new PredictContract(address.toHexString())
|
||||
const token = getToken(address, true)
|
||||
predictContract.token = token.id
|
||||
predictContract.secondsPerEpoch = BigInt.zero()
|
||||
predictContract.secondsPerSubscription = BigInt.zero()
|
||||
predictContract.truevalSubmitTimeout = BigInt.zero()
|
||||
predictContract.stakeToken = null
|
||||
predictContract.txId = ''
|
||||
predictContract.timestamp = 0
|
||||
predictContract.block = 0
|
||||
predictContract.eventIndex = 0
|
||||
predictContract.paused = false
|
||||
predictContract.save()
|
||||
return predictContract
|
||||
}
|
||||
|
||||
export function getPredictContract(address: Address): PredictContract {
|
||||
let newPredictContract = PredictContract.load(address.toHexString())
|
||||
if (newPredictContract === null) {
|
||||
newPredictContract = createPredictContract(address)
|
||||
}
|
||||
return newPredictContract
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import { BigInt } from '@graphprotocol/graph-ts'
|
||||
import { User } from '../../@types/schema'
|
||||
|
||||
export function getUser(address: string): User {
|
||||
let user = User.load(address)
|
||||
if (user === null) {
|
||||
user = new User(address)
|
||||
user.totalOrders = BigInt.zero()
|
||||
user.totalSales = BigInt.zero()
|
||||
user.save()
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
import { BigDecimal, ethereum, BigInt, Address } from '@graphprotocol/graph-ts'
|
||||
import {
|
||||
VeAllocateUser,
|
||||
VeAllocateId,
|
||||
VeAllocation,
|
||||
VeAllocationUpdate,
|
||||
VeDelegation,
|
||||
VeOCEAN,
|
||||
VeDeposit,
|
||||
VeFeeDistributor
|
||||
} from '../../@types/schema'
|
||||
import { veFeeDistributor as VeFeeDistributorContract } from '../../@types/veFeeDistributor/veFeeDistributor'
|
||||
import { veAllocationUpdateType } from './constants'
|
||||
import { getToken } from './tokenUtils'
|
||||
|
||||
export function getveOCEAN(id: string): VeOCEAN {
|
||||
let ve = VeOCEAN.load(id)
|
||||
|
||||
if (ve === null) {
|
||||
ve = new VeOCEAN(id)
|
||||
ve.unlockTime = BigInt.zero()
|
||||
ve.lockedAmount = BigDecimal.zero()
|
||||
ve.block = 0
|
||||
ve.save()
|
||||
}
|
||||
|
||||
return ve
|
||||
}
|
||||
|
||||
export function getveAllocateUser(
|
||||
event: ethereum.Event,
|
||||
sender: string
|
||||
): VeAllocateUser {
|
||||
let allocateUser = VeAllocateUser.load(sender)
|
||||
if (allocateUser === null) {
|
||||
allocateUser = new VeAllocateUser(sender)
|
||||
allocateUser.allocatedTotal = BigDecimal.zero()
|
||||
|
||||
allocateUser.firstContact = event.block.timestamp.toI32()
|
||||
allocateUser.tx = event.transaction.hash.toHex()
|
||||
allocateUser.eventIndex = event.logIndex.toI32()
|
||||
allocateUser.block = event.block.number.toI32()
|
||||
allocateUser.lastContact = 0
|
||||
const veOcean = getveOCEAN(sender)
|
||||
allocateUser.veOcean = veOcean.id
|
||||
|
||||
allocateUser.save()
|
||||
}
|
||||
|
||||
return allocateUser
|
||||
}
|
||||
|
||||
export function getveAllocateId(
|
||||
event: ethereum.Event,
|
||||
id: string
|
||||
): VeAllocateId {
|
||||
let allocateId = VeAllocateId.load(id)
|
||||
if (allocateId === null) {
|
||||
allocateId = new VeAllocateId(id)
|
||||
allocateId.allocatedTotal = BigDecimal.zero()
|
||||
|
||||
allocateId.firstContact = event.block.timestamp.toI32()
|
||||
allocateId.tx = event.transaction.hash.toHex()
|
||||
allocateId.eventIndex = event.logIndex.toI32()
|
||||
allocateId.block = event.block.number.toI32()
|
||||
allocateId.lastContact = 0
|
||||
allocateId.chainId = BigInt.zero()
|
||||
allocateId.nftAddress = ''
|
||||
|
||||
allocateId.save()
|
||||
}
|
||||
|
||||
return allocateId
|
||||
}
|
||||
|
||||
export function getveAllocation(
|
||||
event: ethereum.Event,
|
||||
sender: string,
|
||||
id: string
|
||||
): VeAllocation {
|
||||
let veAllocation = VeAllocation.load(sender + '-' + id)
|
||||
if (veAllocation === null) {
|
||||
veAllocation = new VeAllocation(sender + '-' + id)
|
||||
veAllocation.allocationUser = getveAllocateUser(event, sender).id
|
||||
veAllocation.allocationId = getveAllocateId(event, id).id
|
||||
veAllocation.allocated = BigDecimal.zero()
|
||||
veAllocation.chainId = BigInt.zero()
|
||||
veAllocation.nftAddress = ''
|
||||
|
||||
veAllocation.firstContact = event.block.timestamp.toI32()
|
||||
veAllocation.tx = event.transaction.hash.toHex()
|
||||
veAllocation.eventIndex = event.logIndex.toI32()
|
||||
veAllocation.block = event.block.number.toI32()
|
||||
veAllocation.lastContact = 0
|
||||
|
||||
veAllocation.save()
|
||||
}
|
||||
|
||||
return veAllocation
|
||||
}
|
||||
|
||||
// Pass veAllocation being updated
|
||||
export function writeveAllocationUpdate(
|
||||
event: ethereum.Event,
|
||||
veAllocationId: string,
|
||||
allocationType: string,
|
||||
amount: BigDecimal
|
||||
): VeAllocationUpdate {
|
||||
const id = `${event.transaction.hash.toHex()}-${veAllocationId}-${event.logIndex.toString()}`
|
||||
let allocationUpdate = VeAllocationUpdate.load(id)
|
||||
if (allocationUpdate === null) {
|
||||
allocationUpdate = new VeAllocationUpdate(id)
|
||||
allocationUpdate.veAllocation = veAllocationId
|
||||
allocationUpdate.type = allocationType
|
||||
allocationUpdate.allocatedTotal = amount
|
||||
|
||||
allocationUpdate.timestamp = event.block.timestamp.toI32()
|
||||
allocationUpdate.tx = event.transaction.hash.toHex()
|
||||
allocationUpdate.eventIndex = event.logIndex.toI32()
|
||||
allocationUpdate.block = event.block.number.toI32()
|
||||
|
||||
allocationUpdate.save()
|
||||
}
|
||||
|
||||
return allocationUpdate
|
||||
}
|
||||
|
||||
export function getveDelegation(
|
||||
contract: Address,
|
||||
eventid: string
|
||||
): VeDelegation {
|
||||
const id = contract.toHex() + '-' + eventid
|
||||
let veDelegation = VeDelegation.load(id)
|
||||
|
||||
if (veDelegation === null) {
|
||||
veDelegation = new VeDelegation(id)
|
||||
veDelegation.cancelTime = BigInt.zero()
|
||||
veDelegation.expireTime = BigInt.zero()
|
||||
veDelegation.tokenId = BigInt.zero()
|
||||
veDelegation.amount = BigDecimal.zero()
|
||||
veDelegation.receiver = ''
|
||||
veDelegation.delegator = ''
|
||||
veDelegation.lockedAmount = BigDecimal.zero()
|
||||
veDelegation.timeLeftUnlock = 0
|
||||
veDelegation.save()
|
||||
}
|
||||
return veDelegation
|
||||
}
|
||||
export function getDeposit(id: string): VeDeposit {
|
||||
let deposit = VeDeposit.load(id)
|
||||
if (deposit === null) {
|
||||
deposit = new VeDeposit(id)
|
||||
deposit.provider = ''
|
||||
deposit.sender = ''
|
||||
deposit.value = BigDecimal.zero()
|
||||
deposit.unlockTime = BigInt.zero()
|
||||
deposit.type = BigInt.zero()
|
||||
deposit.timestamp = BigInt.zero()
|
||||
deposit.tx = ''
|
||||
deposit.eventIndex = 0
|
||||
deposit.block = 0
|
||||
// do not save it
|
||||
// deposit.save()
|
||||
}
|
||||
return deposit
|
||||
}
|
||||
|
||||
export function handleOneAllocation(
|
||||
eventSender: string,
|
||||
nftAddress: string,
|
||||
chainId: BigInt,
|
||||
allocationAmount: BigDecimal,
|
||||
event: ethereum.Event
|
||||
): void {
|
||||
const eventId = nftAddress + '-' + chainId.toString()
|
||||
|
||||
const allocateUser = getveAllocateUser(event, eventSender)
|
||||
const allocateId = getveAllocateId(event, eventId)
|
||||
const veAllocation = getveAllocation(event, eventSender, eventId)
|
||||
|
||||
// Update user allocation
|
||||
const newUserAllocation = allocateUser.allocatedTotal.minus(
|
||||
veAllocation.allocated
|
||||
)
|
||||
allocateUser.allocatedTotal = newUserAllocation.plus(allocationAmount)
|
||||
|
||||
// Update id allocation
|
||||
const newIdAllocation = allocateId.allocatedTotal.minus(
|
||||
veAllocation.allocated
|
||||
)
|
||||
allocateId.allocatedTotal = newIdAllocation.plus(allocationAmount)
|
||||
|
||||
veAllocation.allocated = allocationAmount
|
||||
veAllocation.chainId = chainId
|
||||
veAllocation.nftAddress = nftAddress
|
||||
|
||||
allocateUser.lastContact = event.block.timestamp.toI32()
|
||||
allocateId.lastContact = event.block.timestamp.toI32()
|
||||
veAllocation.lastContact = event.block.timestamp.toI32()
|
||||
|
||||
// register allocation update event
|
||||
writeveAllocationUpdate(
|
||||
event,
|
||||
veAllocation.id,
|
||||
veAllocationUpdateType.SET,
|
||||
allocationAmount
|
||||
)
|
||||
|
||||
allocateId.chainId = chainId
|
||||
allocateId.nftAddress = nftAddress
|
||||
|
||||
// save entities
|
||||
allocateUser.save()
|
||||
allocateId.save()
|
||||
veAllocation.save()
|
||||
}
|
||||
|
||||
export function getVeFeeDistributor(id: Address): VeFeeDistributor {
|
||||
let distributor = VeFeeDistributor.load(id.toHexString())
|
||||
|
||||
if (distributor === null) {
|
||||
distributor = new VeFeeDistributor(id.toHexString())
|
||||
const contract = VeFeeDistributorContract.bind(id)
|
||||
const tokenAddress = contract.try_token()
|
||||
const token = getToken(tokenAddress.value, false)
|
||||
distributor.token = token.id
|
||||
distributor.save()
|
||||
}
|
||||
return distributor
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
import {
|
||||
AllocationSet,
|
||||
AllocationSetMultiple
|
||||
} from '../@types/veAllocate/veAllocate'
|
||||
|
||||
import { handleOneAllocation } from './utils/veUtils'
|
||||
|
||||
export function handleAllocationSet(event: AllocationSet): void {
|
||||
// get allocation entities
|
||||
const eventSender = event.params.sender.toHexString()
|
||||
const nftAddress = event.params.nft.toHexString()
|
||||
const chainId = event.params.chainId
|
||||
const allocationAmount = event.params.amount.toBigDecimal()
|
||||
|
||||
handleOneAllocation(eventSender, nftAddress, chainId, allocationAmount, event)
|
||||
}
|
||||
|
||||
export function handleAllocationSetMultiple(
|
||||
event: AllocationSetMultiple
|
||||
): void {
|
||||
// loop
|
||||
for (let i = 0; i < event.params.nft.length; i++) {
|
||||
const eventSender = event.params.sender.toHexString()
|
||||
const nftAddress = event.params.nft[i].toHexString()
|
||||
const chainId = event.params.chainId[i]
|
||||
const allocationAmount = event.params.amount[i].toBigDecimal()
|
||||
handleOneAllocation(
|
||||
eventSender,
|
||||
nftAddress,
|
||||
chainId,
|
||||
allocationAmount,
|
||||
event
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
import { BigDecimal, BigInt } from '@graphprotocol/graph-ts'
|
||||
import { VeDelegationUpdate } from '../@types/schema'
|
||||
import {
|
||||
BurnBoost,
|
||||
DelegateBoost,
|
||||
ExtendBoost,
|
||||
TransferBoost
|
||||
} from '../@types/veDelegation/veDelegation'
|
||||
import { weiToDecimal } from './utils/generic'
|
||||
import { getveDelegation, getveOCEAN } from './utils/veUtils'
|
||||
|
||||
export function handleDelegation(event: DelegateBoost): void {
|
||||
const _delegator = event.params._delegator.toHex()
|
||||
const _receiver = event.params._receiver.toHex()
|
||||
const _tokenId = event.params._token_id
|
||||
const _amount = event.params._amount
|
||||
const _cancelTime = event.params._cancel_time
|
||||
const _expireTime = event.params._expire_time
|
||||
// create veOcean if does not exists
|
||||
getveOCEAN(_receiver)
|
||||
const delegator = getveOCEAN(_delegator)
|
||||
const veDelegation = getveDelegation(event.address, _tokenId.toHex())
|
||||
const ts = event.block.timestamp.toI32()
|
||||
|
||||
veDelegation.delegator = _delegator
|
||||
veDelegation.receiver = _receiver
|
||||
veDelegation.tokenId = _tokenId
|
||||
veDelegation.amount = weiToDecimal(
|
||||
_amount.toBigDecimal(),
|
||||
BigInt.fromI32(18).toI32()
|
||||
)
|
||||
veDelegation.lockedAmount = delegator.lockedAmount
|
||||
veDelegation.timeLeftUnlock = delegator.unlockTime.toI32() - ts
|
||||
veDelegation.cancelTime = _cancelTime
|
||||
veDelegation.expireTime = _expireTime
|
||||
veDelegation.save()
|
||||
|
||||
const veDelegationUpdate = new VeDelegationUpdate(
|
||||
event.transaction.hash.toHex() + '-' + event.logIndex.toString()
|
||||
)
|
||||
veDelegationUpdate.type = 0
|
||||
veDelegationUpdate.veDelegation = veDelegation.id
|
||||
veDelegationUpdate.block = event.block.number.toI32()
|
||||
veDelegationUpdate.timestamp = event.block.timestamp.toI32()
|
||||
veDelegationUpdate.tx = event.transaction.hash.toHex()
|
||||
veDelegationUpdate.eventIndex = event.logIndex.toI32()
|
||||
veDelegationUpdate.amount = veDelegation.amount
|
||||
veDelegationUpdate.cancelTime = _cancelTime
|
||||
veDelegationUpdate.expireTime = _expireTime
|
||||
veDelegationUpdate.sender = event.transaction.from.toHex()
|
||||
veDelegationUpdate.save()
|
||||
}
|
||||
|
||||
export function handleExtendBoost(event: ExtendBoost): void {
|
||||
const _delegator = event.params._delegator.toHex()
|
||||
const _receiver = event.params._receiver.toHex()
|
||||
const _tokenId = event.params._token_id
|
||||
const _amount = event.params._amount
|
||||
const _cancelTime = event.params._cancel_time
|
||||
const _expireTime = event.params._expire_time
|
||||
// create veOcean if does not exists
|
||||
getveOCEAN(_receiver)
|
||||
getveOCEAN(_delegator)
|
||||
// it's possible to not have veDelegation object, because we missed handleDelegation
|
||||
// that should not happend, but we create the object anyway
|
||||
const veDelegation = getveDelegation(event.address, _tokenId.toHex())
|
||||
veDelegation.delegator = _delegator
|
||||
veDelegation.receiver = _receiver
|
||||
veDelegation.tokenId = _tokenId
|
||||
veDelegation.amount = weiToDecimal(
|
||||
_amount.toBigDecimal(),
|
||||
BigInt.fromI32(18).toI32()
|
||||
)
|
||||
veDelegation.cancelTime = _cancelTime
|
||||
veDelegation.expireTime = _expireTime
|
||||
veDelegation.save()
|
||||
|
||||
const veDelegationUpdate = new VeDelegationUpdate(
|
||||
event.transaction.hash.toHex() + '-' + event.logIndex.toString()
|
||||
)
|
||||
veDelegationUpdate.veDelegation = veDelegation.id
|
||||
veDelegationUpdate.type = 1
|
||||
veDelegationUpdate.block = event.block.number.toI32()
|
||||
veDelegationUpdate.timestamp = event.block.timestamp.toI32()
|
||||
veDelegationUpdate.tx = event.transaction.hash.toHex()
|
||||
veDelegationUpdate.eventIndex = event.logIndex.toI32()
|
||||
veDelegationUpdate.amount = veDelegation.amount
|
||||
veDelegationUpdate.cancelTime = _cancelTime
|
||||
veDelegationUpdate.expireTime = _expireTime
|
||||
veDelegationUpdate.sender = event.transaction.from.toHex()
|
||||
veDelegationUpdate.save()
|
||||
}
|
||||
|
||||
export function handleTransferBoost(event: TransferBoost): void {
|
||||
// TODO not sure if we need this
|
||||
// --------------------------------
|
||||
// const _from = event.params._from
|
||||
// const _to = event.params._to
|
||||
// const _tokenId = event.params._token_id
|
||||
// const _amount = event.params._amount
|
||||
// const _expireTime = event.params._expire_time
|
||||
}
|
||||
export function handleBurnBoost(event: BurnBoost): void {
|
||||
const _tokenId = event.params._token_id
|
||||
|
||||
// delete
|
||||
const veDelegation = getveDelegation(event.address, _tokenId.toHex())
|
||||
veDelegation.amount = BigDecimal.zero()
|
||||
veDelegation.save()
|
||||
|
||||
const veDelegationUpdate = new VeDelegationUpdate(
|
||||
event.transaction.hash.toHex() + '-' + event.logIndex.toString()
|
||||
)
|
||||
veDelegationUpdate.veDelegation = veDelegation.id
|
||||
veDelegationUpdate.type = 2
|
||||
veDelegationUpdate.block = event.block.number.toI32()
|
||||
veDelegationUpdate.timestamp = event.block.timestamp.toI32()
|
||||
veDelegationUpdate.tx = event.transaction.hash.toHex()
|
||||
veDelegationUpdate.eventIndex = event.logIndex.toI32()
|
||||
veDelegationUpdate.amount = veDelegation.amount
|
||||
veDelegationUpdate.cancelTime = veDelegation.cancelTime
|
||||
veDelegationUpdate.expireTime = veDelegation.expireTime
|
||||
veDelegationUpdate.sender = event.transaction.from.toHex()
|
||||
veDelegationUpdate.save()
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
import { Address } from '@graphprotocol/graph-ts'
|
||||
import {
|
||||
Claimed,
|
||||
CheckpointToken
|
||||
} from '../@types/veFeeDistributor/veFeeDistributor'
|
||||
import { weiToDecimal } from './utils/generic'
|
||||
import { getveOCEAN, getVeFeeDistributor } from './utils/veUtils'
|
||||
import { VeClaim, VeFeeDistributorCheckPoint } from '../@types/schema'
|
||||
import { getToken } from './utils/tokenUtils'
|
||||
|
||||
export function handleClaimed(event: Claimed): void {
|
||||
const distributor = getVeFeeDistributor(event.address)
|
||||
const id =
|
||||
event.transaction.hash.toHexString() + '-' + event.logIndex.toString()
|
||||
const veOcean = getveOCEAN(event.params.recipient.toHexString())
|
||||
const token = getToken(Address.fromString(distributor.token), false)
|
||||
const claim = new VeClaim(id)
|
||||
claim.amount = weiToDecimal(
|
||||
event.params.amount.toBigDecimal(),
|
||||
token.decimals
|
||||
)
|
||||
claim.claim_epoch = event.params.claim_epoch
|
||||
claim.max_epoch = event.params.max_epoch
|
||||
|
||||
claim.veOcean = veOcean.id
|
||||
claim.VeFeeDistributor = distributor.id
|
||||
|
||||
claim.block = event.block.number.toI32()
|
||||
claim.tx = event.transaction.hash.toHex()
|
||||
claim.eventIndex = event.logIndex.toI32()
|
||||
claim.timestamp = event.block.timestamp
|
||||
claim.save()
|
||||
}
|
||||
|
||||
export function handleCheckpoint(event: CheckpointToken): void {
|
||||
const distributor = getVeFeeDistributor(event.address)
|
||||
const id =
|
||||
event.transaction.hash.toHexString() + '-' + event.logIndex.toString()
|
||||
const token = getToken(Address.fromString(distributor.token), false)
|
||||
const checkpoint = new VeFeeDistributorCheckPoint(id)
|
||||
checkpoint.tokens = weiToDecimal(
|
||||
event.params.tokens.toBigDecimal(),
|
||||
token.decimals
|
||||
)
|
||||
checkpoint.sender = event.transaction.from.toHexString()
|
||||
checkpoint.block = event.block.number.toI32()
|
||||
checkpoint.tx = event.transaction.hash.toHex()
|
||||
checkpoint.eventIndex = event.logIndex.toI32()
|
||||
checkpoint.timestamp = event.params.time
|
||||
checkpoint.VeFeeDistributor = distributor.id
|
||||
checkpoint.save()
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
import { BigDecimal, BigInt } from '@graphprotocol/graph-ts'
|
||||
import { Deposit, Supply, Withdraw } from '../@types/veOCEAN/veOCEAN'
|
||||
import { weiToDecimal } from './utils/generic'
|
||||
import { getDeposit, getveOCEAN } from './utils/veUtils'
|
||||
import {
|
||||
getTotalOceanLocked,
|
||||
updateTotalOceanLocked
|
||||
} from './utils/globalUtils'
|
||||
|
||||
export function handleDeposit(event: Deposit): void {
|
||||
const provider = event.params.provider
|
||||
const value = event.params.value
|
||||
const locktime = event.params.locktime
|
||||
const type = event.params.type
|
||||
const ts = event.params.ts
|
||||
const totalOceanLocked = getTotalOceanLocked()
|
||||
const veOCEAN = getveOCEAN(provider.toHex())
|
||||
// Create new Deposit entity
|
||||
const deposit = getDeposit(
|
||||
provider.toHex() +
|
||||
'-' +
|
||||
event.transaction.hash.toHex() +
|
||||
'-' +
|
||||
event.logIndex.toString()
|
||||
)
|
||||
deposit.provider = provider.toHex()
|
||||
deposit.value = weiToDecimal(value.toBigDecimal(), 18)
|
||||
deposit.unlockTime = locktime
|
||||
deposit.type = type
|
||||
deposit.timestamp = ts
|
||||
deposit.block = event.block.number.toI32()
|
||||
deposit.tx = event.transaction.hash.toHex()
|
||||
deposit.sender = event.transaction.from.toHex()
|
||||
deposit.veOcean = veOCEAN.id
|
||||
|
||||
deposit.totalOceanLocked = totalOceanLocked.plus(deposit.value)
|
||||
updateTotalOceanLocked(deposit.totalOceanLocked)
|
||||
|
||||
deposit.save()
|
||||
// --------------------------------------------
|
||||
|
||||
const lockedAmount = weiToDecimal(value.toBigDecimal(), 18)
|
||||
veOCEAN.unlockTime = locktime
|
||||
veOCEAN.lockedAmount = veOCEAN.lockedAmount.plus(lockedAmount)
|
||||
veOCEAN.block = event.block.number.toI32()
|
||||
veOCEAN.save()
|
||||
}
|
||||
export function handleSupply(event: Supply): void {}
|
||||
export function handleWithdraw(event: Withdraw): void {
|
||||
const totalOceanLocked = getTotalOceanLocked()
|
||||
const provider = event.params.provider
|
||||
const value = event.params.value
|
||||
const ts = event.params.ts
|
||||
|
||||
const veOCEAN = getveOCEAN(provider.toHex())
|
||||
// Create new Deposit entity
|
||||
const deposit = getDeposit(
|
||||
provider.toHex() +
|
||||
'-' +
|
||||
event.transaction.hash.toHex() +
|
||||
'-' +
|
||||
event.logIndex.toString()
|
||||
)
|
||||
deposit.provider = provider.toHex()
|
||||
deposit.value = weiToDecimal(value.toBigDecimal(), 18).neg()
|
||||
deposit.unlockTime = BigInt.zero()
|
||||
deposit.type = BigInt.fromI32(4)
|
||||
deposit.timestamp = ts
|
||||
deposit.block = event.block.number.toI32()
|
||||
deposit.tx = event.transaction.hash.toHex()
|
||||
deposit.eventIndex = event.logIndex.toI32()
|
||||
deposit.sender = event.transaction.from.toHex()
|
||||
deposit.veOcean = veOCEAN.id
|
||||
deposit.totalOceanLocked = totalOceanLocked.plus(deposit.value) // it's already negated above
|
||||
updateTotalOceanLocked(deposit.totalOceanLocked)
|
||||
deposit.save()
|
||||
// --------------------------------------------
|
||||
|
||||
veOCEAN.lockedAmount = BigDecimal.zero()
|
||||
veOCEAN.unlockTime = BigInt.zero()
|
||||
veOCEAN.block = event.block.number.toI32()
|
||||
veOCEAN.save()
|
||||
}
|
|
@ -3,73 +3,6 @@ description: Ocean provides data sharing through IDOs
|
|||
repository: https://github.com/oceanprotocol/ocean-subgraph
|
||||
schema:
|
||||
file: ./schema.graphql
|
||||
dataSources:
|
||||
- kind: ethereum/contract
|
||||
name: ERC721Factory
|
||||
network: __NETWORK__
|
||||
source:
|
||||
address: __ERC721FACTORYADDRESS__
|
||||
abi: ERC721Factory
|
||||
startBlock: __STARTBLOCK__
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.6
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/erc721Factory.ts
|
||||
entities:
|
||||
- ERC721Factory
|
||||
abis:
|
||||
- name: ERC721Factory
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json
|
||||
- name: ERC20
|
||||
file: ./abis/ERC20.json
|
||||
eventHandlers:
|
||||
- event: NFTCreated(address,indexed address,string,indexed address,string,string,bool,indexed address)
|
||||
handler: handleNftCreated
|
||||
- event: TokenCreated(indexed address,indexed address,string,string,uint256,address)
|
||||
handler: handleNewToken
|
||||
|
||||
- kind: ethereum/contract
|
||||
name: FactoryRouter
|
||||
network: __NETWORK__
|
||||
source:
|
||||
address: __FACTORYROUTERADDRESS__
|
||||
abi: FactoryRouter
|
||||
startBlock: __STARTBLOCK__
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.6
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/factoryRouter.ts
|
||||
entities:
|
||||
- FactoryRouter
|
||||
abis:
|
||||
- name: FactoryRouter
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json
|
||||
- name: ERC20
|
||||
file: ./abis/ERC20.json
|
||||
eventHandlers:
|
||||
- event: NewPool(indexed address,bool)
|
||||
handler: handleNewPool
|
||||
- event: TokenAdded(indexed address,indexed address)
|
||||
handler: handleTokenAdded
|
||||
- event: TokenRemoved(indexed address,indexed address)
|
||||
handler: handleTokenRemoved
|
||||
- event: OPCFeeChanged(indexed address,uint256,uint256,uint256,uint256)
|
||||
handler: handleOPCFeeChanged
|
||||
- event: SSContractAdded(indexed address,indexed address)
|
||||
handler: handleSSContractAdded
|
||||
- event: SSContractRemoved(indexed address,indexed address)
|
||||
handler: handleSSContractRemoved
|
||||
- event: FixedRateContractAdded(indexed address,indexed address)
|
||||
handler: handleFixedRateContractAdded
|
||||
- event: FixedRateContractRemoved(indexed address,indexed address)
|
||||
handler: handleFixedRateContractRemoved
|
||||
- event: DispenserContractAdded(indexed address,indexed address)
|
||||
handler: handleDispenserContractAdded
|
||||
- event: DispenserContractRemoved(indexed address,indexed address)
|
||||
handler: handleDispenserContractRemoved
|
||||
|
||||
templates:
|
||||
- name: ERC20Template
|
||||
kind: ethereum/contract
|
||||
|
@ -78,7 +11,7 @@ templates:
|
|||
abi: ERC20Template
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.6
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/erc20Templates.ts
|
||||
entities:
|
||||
|
@ -95,14 +28,18 @@ templates:
|
|||
eventHandlers:
|
||||
- event: OrderStarted(indexed address,address,uint256,uint256,uint256,indexed address,uint256)
|
||||
handler: handleOrderStarted
|
||||
receipt: true
|
||||
- event: OrderReused(bytes32,address,uint256,uint256)
|
||||
handler: handlerOrderReused
|
||||
receipt: true
|
||||
- event: NewPaymentCollector(indexed address,indexed address,uint256,uint256)
|
||||
handler: handleNewPaymentCollector
|
||||
- event: PublishMarketFee(indexed address,indexed address,uint256)
|
||||
handler: handlePublishMarketFee
|
||||
- event: PublishMarketFeeChanged(address,address,address,uint256)
|
||||
handler: handlePublishMarketFeeChanged
|
||||
- event: ConsumeMarketFee(indexed address,indexed address,uint256)
|
||||
handler: handleConsumeMarketFee
|
||||
- event: AddedMinter(indexed address,indexed address,uint256,uint256)
|
||||
handler: handleAddedMinter
|
||||
- event: AddedPaymentManager(indexed address,indexed address,uint256,uint256)
|
||||
|
@ -113,43 +50,44 @@ templates:
|
|||
handler: handleRemovedPaymentManager
|
||||
- event: CleanedPermissions(indexed address,uint256,uint256)
|
||||
handler: handleCleanedPermissions
|
||||
- event: ProviderFee(indexed address,indexed address,uint256,bytes,uint8,bytes32,bytes32,uint256)
|
||||
handler: handleProviderFee
|
||||
receipt: true
|
||||
|
||||
- name: BPool
|
||||
- name: ERC20Template3
|
||||
kind: ethereum/contract
|
||||
network: __NETWORK__
|
||||
source:
|
||||
abi: BPool
|
||||
abi: ERC20Template3
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.6
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/pool.ts
|
||||
file: ./src/mappings/erc20Template3.ts
|
||||
entities:
|
||||
- BPool
|
||||
- ERC20Template3
|
||||
abis:
|
||||
- name: BPool
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BPool.sol/BPool.json
|
||||
- name: BToken
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BToken.sol/BToken.json
|
||||
- name: BMath
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/balancer/BMath.sol/BMath.json
|
||||
- name: ERC20Template3
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template3.sol/ERC20Template3.json
|
||||
- name: ERC20
|
||||
file: ./abis/ERC20.json
|
||||
- name: ERC20Roles
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/utils/ERC20Roles.sol/ERC20Roles.json
|
||||
eventHandlers:
|
||||
- event: LOG_SWAP(indexed address,indexed address,indexed address,uint256,uint256,uint256,uint256,uint256,uint256)
|
||||
handler: handleSwap
|
||||
- event: LOG_JOIN(indexed address,indexed address,uint256,uint256)
|
||||
handler: handleJoin
|
||||
- event: LOG_EXIT(indexed address,indexed address,uint256,uint256)
|
||||
handler: handleExit
|
||||
- event: LOG_SETUP(indexed address,indexed address,uint256,uint256,indexed address,uint256,uint256)
|
||||
handler: handleSetup
|
||||
- event: Transfer(indexed address,indexed address,uint256)
|
||||
handler: handlerBptTransfer
|
||||
- event: PublishMarketFeeChanged(address,address,uint256)
|
||||
handler: handlePublishMarketFeeChanged
|
||||
- event: SwapFeeChanged(address,uint256)
|
||||
handler: handleSwapFeeChanged
|
||||
- event: PredictionSubmitted(indexed address,indexed uint256,uint256)
|
||||
handler: handlePredictionSubmitted
|
||||
- event: PredictionPayout(indexed address,indexed uint256,uint256,uint256,bool,bool,uint256,uint8)
|
||||
handler: handlePredictionPayout
|
||||
- event: NewSubscription(indexed address,uint256,uint256)
|
||||
handler: handleNewSubscription
|
||||
- event: TruevalSubmitted(indexed uint256,bool,uint8,uint256,uint256)
|
||||
handler: handleTruevalSubmitted
|
||||
- event: SettingChanged(uint256,uint256,uint256,address)
|
||||
handler: handleSettingChanged
|
||||
- event: RevenueAdded(uint256,uint256,uint256,uint256,uint256)
|
||||
handler: handleRevenueAdded
|
||||
- event: Paused(bool)
|
||||
handler: handlePaused
|
||||
|
||||
- name: ERC721Template
|
||||
kind: ethereum/contract
|
||||
|
@ -158,7 +96,7 @@ templates:
|
|||
abi: ERC721Template
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.6
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/nftUpdate.ts
|
||||
entities:
|
||||
|
@ -199,6 +137,8 @@ templates:
|
|||
handler: handleCleanedPermissions
|
||||
- event: Transfer(indexed address,indexed address,indexed uint256)
|
||||
handler: handleNftTransferred
|
||||
- event: DataChanged(indexed bytes32,bytes)
|
||||
handler: handleNftData
|
||||
|
||||
- name: Dispenser
|
||||
kind: ethereum/contract
|
||||
|
@ -207,7 +147,7 @@ templates:
|
|||
abi: Dispenser
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.6
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/dispenser.ts
|
||||
entities:
|
||||
|
@ -238,7 +178,7 @@ templates:
|
|||
abi: FixedRateExchange
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.6
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/fixedRateExchange.ts
|
||||
entities:
|
||||
|
@ -267,3 +207,72 @@ templates:
|
|||
handler: handlePublishMarketFeeChanged
|
||||
- event: TokenCollected(indexed bytes32,indexed address,indexed address,uint256)
|
||||
handler: handleTokenCollected
|
||||
|
||||
dataSources:
|
||||
- kind: ethereum/contract
|
||||
name: ERC721Factory
|
||||
network: __NETWORK__
|
||||
source:
|
||||
address: __ERC721FACTORYADDRESS__
|
||||
abi: ERC721Factory
|
||||
startBlock: __STARTBLOCK__
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/erc721Factory.ts
|
||||
entities:
|
||||
- ERC721Factory
|
||||
abis:
|
||||
- name: ERC721Template
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json
|
||||
- name: ERC20Template
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json
|
||||
- name: ERC721Factory
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json
|
||||
- name: ERC20
|
||||
file: ./abis/ERC20.json
|
||||
eventHandlers:
|
||||
- event: NFTCreated(address,indexed address,string,indexed address,string,string,bool,indexed address)
|
||||
handler: handleNftCreated
|
||||
- event: TokenCreated(indexed address,indexed address,string,string,uint256,address)
|
||||
handler: handleNewToken
|
||||
- event: Template721Added(indexed address,indexed uint256)
|
||||
handler: handleNew721Template
|
||||
- event: Template20Added(indexed address,indexed uint256)
|
||||
handler: handleNew20Template
|
||||
|
||||
- kind: ethereum/contract
|
||||
name: FactoryRouter
|
||||
network: __NETWORK__
|
||||
source:
|
||||
address: __FACTORYROUTERADDRESS__
|
||||
abi: FactoryRouter
|
||||
startBlock: __STARTBLOCK__
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/factoryRouter.ts
|
||||
entities:
|
||||
- FactoryRouter
|
||||
abis:
|
||||
- name: FactoryRouter
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json
|
||||
- name: ERC20
|
||||
file: ./abis/ERC20.json
|
||||
eventHandlers:
|
||||
- event: TokenAdded(indexed address,indexed address)
|
||||
handler: handleTokenAdded
|
||||
- event: TokenRemoved(indexed address,indexed address)
|
||||
handler: handleTokenRemoved
|
||||
- event: OPCFeeChanged(indexed address,uint256,uint256,uint256,uint256)
|
||||
handler: handleOPCFeeChanged
|
||||
- event: FixedRateContractAdded(indexed address,indexed address)
|
||||
handler: handleFixedRateContractAdded
|
||||
- event: FixedRateContractRemoved(indexed address,indexed address)
|
||||
handler: handleFixedRateContractRemoved
|
||||
- event: DispenserContractAdded(indexed address,indexed address)
|
||||
handler: handleDispenserContractAdded
|
||||
- event: DispenserContractRemoved(indexed address,indexed address)
|
||||
handler: handleDispenserContractRemoved
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
- name: veAllocate
|
||||
kind: ethereum/contract
|
||||
network: __NETWORK__
|
||||
source:
|
||||
abi: veAllocate
|
||||
address: __VEALLOCATEADDRESS__
|
||||
startBlock: __STARTBLOCK__
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/veAllocate.ts
|
||||
entities:
|
||||
- veAllocate
|
||||
abis:
|
||||
- name: veAllocate
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veAllocate.sol/veAllocate.json
|
||||
eventHandlers:
|
||||
- event: AllocationSet(indexed address,indexed address,indexed uint256,uint256)
|
||||
handler: handleAllocationSet
|
||||
- event: AllocationSetMultiple(indexed address,address[],uint256[],uint256[])
|
||||
handler: handleAllocationSetMultiple
|
||||
|
||||
- name: veOCEAN
|
||||
kind: ethereum/contract
|
||||
network: __NETWORK__
|
||||
source:
|
||||
abi: veOCEAN
|
||||
address: __VEOCEANADDRESS__
|
||||
startBlock: __STARTBLOCK__
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/veOCEAN.ts
|
||||
entities:
|
||||
- veOCEAN
|
||||
abis:
|
||||
- name: veOCEAN
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veOCEAN.vy/veOCEAN.json
|
||||
eventHandlers:
|
||||
- event: Deposit(indexed address,uint256,indexed uint256,int128,uint256)
|
||||
handler: handleDeposit
|
||||
- event: Withdraw(indexed address,uint256,uint256)
|
||||
handler: handleWithdraw
|
||||
- event: Supply(uint256,uint256)
|
||||
handler: handleSupply
|
||||
|
||||
- name: veDelegation
|
||||
kind: ethereum/contract
|
||||
network: __NETWORK__
|
||||
source:
|
||||
abi: veDelegation
|
||||
address: __VEDELEGATIONADDRESS__
|
||||
startBlock: __STARTBLOCK__
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/veDelegation.ts
|
||||
entities:
|
||||
- veDelegation
|
||||
abis:
|
||||
- name: veDelegation
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veDelegation.vy/veDelegation.json
|
||||
eventHandlers:
|
||||
- event: DelegateBoost(indexed address,indexed address,indexed uint256,uint256,uint256,uint256)
|
||||
handler: handleDelegation
|
||||
- event: ExtendBoost(indexed address,indexed address,indexed uint256,uint256,uint256,uint256)
|
||||
handler: handleExtendBoost
|
||||
- event: BurnBoost(indexed address,indexed address,indexed uint256)
|
||||
handler: handleBurnBoost
|
||||
|
||||
- name: veFeeDistributor
|
||||
kind: ethereum/contract
|
||||
network: __NETWORK__
|
||||
source:
|
||||
abi: veFeeDistributor
|
||||
address: __VEFEEDISTRIBUTORNADDRESS__
|
||||
startBlock: __STARTBLOCK__
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/veFeeDistributor.ts
|
||||
entities:
|
||||
- veFeeDistributor
|
||||
abis:
|
||||
- name: veFeeDistributor
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/ve/veFeeDistributor.vy/veFeeDistributor.json
|
||||
eventHandlers:
|
||||
- event: Claimed(indexed address,uint256,uint256,uint256)
|
||||
handler: handleClaimed
|
||||
- event: CheckpointToken(uint256,uint256)
|
||||
handler: handleCheckpoint
|
||||
|
||||
- name: DFRewards
|
||||
kind: ethereum/contract
|
||||
network: __NETWORK__
|
||||
source:
|
||||
abi: DFRewards
|
||||
address: __DFREWARDSADDRESS__
|
||||
startBlock: __STARTBLOCK__
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
file: ./src/mappings/dfRewards.ts
|
||||
entities:
|
||||
- DFRewards
|
||||
abis:
|
||||
- name: DFRewards
|
||||
file: ./node_modules/@oceanprotocol/contracts/artifacts/contracts/df/DFRewards.sol/DFRewards.json
|
||||
eventHandlers:
|
||||
- event: Allocated(address[],uint256[],address)
|
||||
handler: handleAllocated
|
||||
- event: Claimed(address,uint256,address)
|
||||
handler: handleClaimed
|
|
@ -0,0 +1,243 @@
|
|||
import { NftFactory, sleep, Datatoken, DfRewards } from '@oceanprotocol/lib'
|
||||
import { assert } from 'chai'
|
||||
import Web3 from 'web3'
|
||||
import { homedir } from 'os'
|
||||
import fs from 'fs'
|
||||
import { fetch } from 'cross-fetch'
|
||||
|
||||
const data = JSON.parse(
|
||||
fs.readFileSync(
|
||||
process.env.ADDRESS_FILE ||
|
||||
`${homedir}/.ocean/ocean-contracts/artifacts/address.json`,
|
||||
'utf8'
|
||||
)
|
||||
)
|
||||
|
||||
const addresses = data.development
|
||||
// const aquarius = new Aquarius('http://127.0.0.1:5000')
|
||||
const web3 = new Web3('http://127.0.0.1:8545')
|
||||
|
||||
const subgraphUrl =
|
||||
'http://127.0.0.1:9000/subgraphs/name/oceanprotocol/ocean-subgraph'
|
||||
|
||||
describe('DFRewards tests', async () => {
|
||||
const nftName = 'testNFT'
|
||||
const nftSymbol = 'TST'
|
||||
const marketPlaceFeeAddress = '0x1230000000000000000000000000000000000000'
|
||||
const feeToken = '0x3210000000000000000000000000000000000000'
|
||||
const publishMarketFeeAmount = '0.1'
|
||||
const cap = '10000'
|
||||
const templateIndex = 1
|
||||
let datatokenAddress1: string
|
||||
let datatokenAddress2: string
|
||||
let dataToken: Datatoken
|
||||
let Factory: NftFactory
|
||||
let factoryAddress: string
|
||||
let accounts: string[]
|
||||
let publisher: string
|
||||
let dfRewards: DfRewards
|
||||
let user1: string
|
||||
let user2: string
|
||||
|
||||
before(async () => {
|
||||
factoryAddress = addresses.ERC721Factory.toLowerCase()
|
||||
Factory = new NftFactory(factoryAddress, web3)
|
||||
accounts = await web3.eth.getAccounts()
|
||||
dataToken = new Datatoken(web3)
|
||||
dfRewards = new DfRewards(addresses.DFRewards, web3)
|
||||
publisher = accounts[0].toLowerCase()
|
||||
user1 = accounts[1].toLowerCase()
|
||||
user2 = accounts[2].toLowerCase()
|
||||
})
|
||||
|
||||
it('should publish two datatokens', async () => {
|
||||
let result = await Factory.createNftWithDatatoken(
|
||||
publisher,
|
||||
{
|
||||
name: nftName,
|
||||
symbol: nftSymbol,
|
||||
templateIndex,
|
||||
tokenURI: '',
|
||||
transferable: true,
|
||||
owner: publisher
|
||||
},
|
||||
{
|
||||
templateIndex,
|
||||
cap,
|
||||
feeAmount: publishMarketFeeAmount,
|
||||
paymentCollector: '0x0000000000000000000000000000000000000000',
|
||||
feeToken,
|
||||
minter: publisher,
|
||||
mpFeeAddress: marketPlaceFeeAddress,
|
||||
name: 'DT1',
|
||||
symbol: 'DT1'
|
||||
}
|
||||
)
|
||||
datatokenAddress1 = result.events.TokenCreated.returnValues[0].toLowerCase()
|
||||
|
||||
result = await Factory.createNftWithDatatoken(
|
||||
publisher,
|
||||
{
|
||||
name: nftName,
|
||||
symbol: nftSymbol,
|
||||
templateIndex,
|
||||
tokenURI: '',
|
||||
transferable: true,
|
||||
owner: publisher
|
||||
},
|
||||
{
|
||||
templateIndex,
|
||||
cap,
|
||||
feeAmount: publishMarketFeeAmount,
|
||||
paymentCollector: '0x0000000000000000000000000000000000000000',
|
||||
feeToken,
|
||||
minter: publisher,
|
||||
mpFeeAddress: marketPlaceFeeAddress,
|
||||
name: 'DT2',
|
||||
symbol: 'DT2'
|
||||
}
|
||||
)
|
||||
datatokenAddress2 = result.events.TokenCreated.returnValues[0].toLowerCase()
|
||||
})
|
||||
|
||||
it('should top-up DF Rewards', async () => {
|
||||
// mint tokens
|
||||
await dataToken.mint(datatokenAddress1, publisher, '1000')
|
||||
await dataToken.mint(datatokenAddress2, publisher, '1000')
|
||||
// approve
|
||||
await dataToken.approve(
|
||||
datatokenAddress1,
|
||||
addresses.DFRewards,
|
||||
'1000',
|
||||
publisher
|
||||
)
|
||||
await dataToken.approve(
|
||||
datatokenAddress2,
|
||||
addresses.DFRewards,
|
||||
'1000',
|
||||
publisher
|
||||
)
|
||||
|
||||
// top-up DF Rewards
|
||||
const tx = await dfRewards.allocateRewards(
|
||||
publisher,
|
||||
[user1, user2],
|
||||
['100', '200'],
|
||||
datatokenAddress1
|
||||
)
|
||||
const user1Balance = await dfRewards.getAvailableRewards(
|
||||
user1,
|
||||
datatokenAddress1
|
||||
)
|
||||
// check subgraph
|
||||
await sleep(2000)
|
||||
const initialQuery = {
|
||||
query: `query {
|
||||
dfrewards(where: {id:"${user1.toLowerCase()}"}){
|
||||
id
|
||||
receiver {
|
||||
id
|
||||
}
|
||||
availableClaims(where: {token:"${datatokenAddress1.toLowerCase()}"}){
|
||||
id
|
||||
receiver {
|
||||
id
|
||||
}
|
||||
amount
|
||||
token {
|
||||
id
|
||||
}
|
||||
}
|
||||
history(orderBy:timestamp,orderDirection:desc){
|
||||
id
|
||||
receiver {
|
||||
id
|
||||
}
|
||||
amount
|
||||
token {
|
||||
id
|
||||
}
|
||||
type
|
||||
tx
|
||||
eventIndex
|
||||
}
|
||||
}
|
||||
}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
const info = (await initialResponse.json()).data.dfrewards
|
||||
assert(info[0].receiver.id === user1.toLowerCase())
|
||||
assert(String(info[0].availableClaims[0].amount) === user1Balance)
|
||||
assert(
|
||||
info[0].availableClaims[0].token.id === datatokenAddress1.toLowerCase()
|
||||
)
|
||||
assert(info[0].history[0].amount === '100')
|
||||
assert(info[0].history[0].tx === tx.transactionHash.toLowerCase())
|
||||
assert(info[0].history[0].eventIndex === tx.events.Allocated.logIndex)
|
||||
assert(info[0].history[0].type === 'Allocated')
|
||||
})
|
||||
|
||||
it('user2 claims some rewards', async () => {
|
||||
const expectedReward = await dfRewards.getAvailableRewards(
|
||||
user2,
|
||||
datatokenAddress1
|
||||
)
|
||||
const tx = await dfRewards.claimRewards(user2, user2, datatokenAddress1)
|
||||
|
||||
const user2Balance = await dfRewards.getAvailableRewards(
|
||||
user2,
|
||||
datatokenAddress1
|
||||
)
|
||||
// check subgraph
|
||||
await sleep(2000)
|
||||
const initialQuery = {
|
||||
query: `query {
|
||||
dfrewards(where: {id:"${user2.toLowerCase()}"}){
|
||||
id
|
||||
receiver {
|
||||
id
|
||||
}
|
||||
availableClaims(where: {token:"${datatokenAddress1.toLowerCase()}"}){
|
||||
id
|
||||
receiver {
|
||||
id
|
||||
}
|
||||
amount
|
||||
token {
|
||||
id
|
||||
}
|
||||
}
|
||||
history(orderBy:timestamp,orderDirection:desc){
|
||||
id
|
||||
receiver {
|
||||
id
|
||||
}
|
||||
amount
|
||||
token {
|
||||
id
|
||||
}
|
||||
type
|
||||
tx
|
||||
eventIndex
|
||||
}
|
||||
}
|
||||
}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
const info = (await initialResponse.json()).data.dfrewards
|
||||
assert(info[0].receiver.id === user2.toLowerCase())
|
||||
assert(String(info[0].availableClaims[0].amount) === user2Balance)
|
||||
assert(
|
||||
info[0].availableClaims[0].token.id === datatokenAddress1.toLowerCase()
|
||||
)
|
||||
assert(info[0].history[0].amount === expectedReward)
|
||||
assert(info[0].history[0].type === 'Claimed')
|
||||
assert(info[0].history[0].eventIndex === tx.events.Claimed.logIndex)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,557 @@
|
|||
import 'mocha'
|
||||
import {
|
||||
DatatokenCreateParams,
|
||||
ProviderInstance,
|
||||
Nft,
|
||||
NftFactory,
|
||||
NftCreateData,
|
||||
getHash,
|
||||
sleep,
|
||||
Datatoken,
|
||||
ProviderFees,
|
||||
ZERO_ADDRESS,
|
||||
signHash
|
||||
} from '@oceanprotocol/lib'
|
||||
import { assert } from 'chai'
|
||||
import Web3 from 'web3'
|
||||
import { SHA256 } from 'crypto-js'
|
||||
import { homedir } from 'os'
|
||||
import fs from 'fs'
|
||||
import { fetch } from 'cross-fetch'
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
|
||||
const data = JSON.parse(
|
||||
fs.readFileSync(
|
||||
process.env.ADDRESS_FILE ||
|
||||
`${homedir}/.ocean/ocean-contracts/artifacts/address.json`,
|
||||
'utf8'
|
||||
)
|
||||
)
|
||||
|
||||
const addresses = data.development
|
||||
// const aquarius = new Aquarius('http://127.0.0.1:5000')
|
||||
const web3 = new Web3('http://127.0.0.1:8545')
|
||||
|
||||
const providerUrl = 'http://172.15.0.4:8030'
|
||||
const subgraphUrl =
|
||||
'http://127.0.0.1:9000/subgraphs/name/oceanprotocol/ocean-subgraph'
|
||||
const assetUrl = [
|
||||
{
|
||||
type: 'url',
|
||||
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
const ddo = {
|
||||
'@context': ['https://w3id.org/did/v1'],
|
||||
id: 'did:op:efba17455c127a885ec7830d687a8f6e64f5ba559f8506f8723c1f10f05c049c',
|
||||
version: '4.0.0',
|
||||
chainId: 4,
|
||||
nftAddress: '0x0',
|
||||
metadata: {
|
||||
created: '2021-12-20T14:35:20Z',
|
||||
updated: '2021-12-20T14:35:20Z',
|
||||
type: 'dataset',
|
||||
name: 'dfgdfgdg',
|
||||
description: 'd dfgd fgd dfg dfgdfgd dfgdf',
|
||||
tags: [''],
|
||||
author: 'dd',
|
||||
license: 'https://market.oceanprotocol.com/terms',
|
||||
additionalInformation: {
|
||||
termsAndConditions: true
|
||||
}
|
||||
},
|
||||
services: [
|
||||
{
|
||||
id: 'notAnId',
|
||||
type: 'access',
|
||||
files: '',
|
||||
datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3',
|
||||
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
|
||||
timeout: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
describe('Datatoken tests', async () => {
|
||||
const nftName = 'testNFT'
|
||||
const nftSymbol = 'TST'
|
||||
const marketPlaceFeeAddress = '0x1230000000000000000000000000000000000000'
|
||||
const feeToken = '0x3210000000000000000000000000000000000000'
|
||||
const publishMarketFeeAmount = '0.1'
|
||||
const cap = '10000'
|
||||
const templateIndex = 1
|
||||
let datatokenAddress: string
|
||||
let nft: Nft
|
||||
let Factory: NftFactory
|
||||
let factoryAddress: string
|
||||
let accounts: string[]
|
||||
let publisher: string
|
||||
let user1: string
|
||||
let user2: string
|
||||
let user3: string
|
||||
let erc721Address: string
|
||||
let time: number
|
||||
let blockNumber: number
|
||||
|
||||
before(async () => {
|
||||
nft = new Nft(web3)
|
||||
factoryAddress = addresses.ERC721Factory.toLowerCase()
|
||||
Factory = new NftFactory(factoryAddress, web3)
|
||||
accounts = await web3.eth.getAccounts()
|
||||
publisher = accounts[0].toLowerCase()
|
||||
user1 = accounts[1].toLowerCase()
|
||||
user2 = accounts[2].toLowerCase()
|
||||
user3 = accounts[3].toLowerCase()
|
||||
})
|
||||
|
||||
it('should publish an NFT & datatoken', async () => {
|
||||
const date = new Date()
|
||||
time = Math.floor(date.getTime() / 1000)
|
||||
blockNumber = await web3.eth.getBlockNumber()
|
||||
|
||||
const nftParams: NftCreateData = {
|
||||
name: nftName,
|
||||
symbol: nftSymbol,
|
||||
templateIndex,
|
||||
tokenURI: '',
|
||||
transferable: true,
|
||||
owner: publisher
|
||||
}
|
||||
const erc20Params: DatatokenCreateParams = {
|
||||
templateIndex,
|
||||
cap,
|
||||
feeAmount: publishMarketFeeAmount,
|
||||
paymentCollector: '0x0000000000000000000000000000000000000000',
|
||||
feeToken,
|
||||
minter: publisher,
|
||||
mpFeeAddress: marketPlaceFeeAddress
|
||||
}
|
||||
const result = await Factory.createNftWithDatatoken(
|
||||
publisher,
|
||||
nftParams,
|
||||
erc20Params
|
||||
)
|
||||
erc721Address = result.events.NFTCreated.returnValues[0].toLowerCase()
|
||||
datatokenAddress = result.events.TokenCreated.returnValues[0].toLowerCase()
|
||||
|
||||
// Check values before updating metadata
|
||||
await sleep(3000)
|
||||
const initialQuery = {
|
||||
query: `query {
|
||||
token(id: "${datatokenAddress}"){
|
||||
id,
|
||||
symbol,
|
||||
name,
|
||||
decimals,
|
||||
address,
|
||||
cap,
|
||||
supply,
|
||||
isDatatoken,
|
||||
nft {id},
|
||||
minter,
|
||||
paymentManager,
|
||||
paymentCollector,
|
||||
publishMarketFeeAddress,
|
||||
publishMarketFeeAmount,
|
||||
templateId,
|
||||
holderCount,
|
||||
orderCount,
|
||||
orders {id},
|
||||
fixedRateExchanges {id},
|
||||
dispensers {id},
|
||||
createdTimestamp,
|
||||
tx,
|
||||
eventIndex,
|
||||
block,
|
||||
lastPriceValue
|
||||
}}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
await sleep(2000)
|
||||
const dt = (await initialResponse.json()).data.token
|
||||
|
||||
const tx: TransactionReceipt = await web3.eth.getTransactionReceipt(dt.tx)
|
||||
assert(dt.id === datatokenAddress, 'incorrect value for: id')
|
||||
assert(dt.symbol, 'incorrect value for: symbol')
|
||||
assert(dt.name, 'incorrect value for: name')
|
||||
assert(dt.decimals === 18, 'incorrect value for: decimals')
|
||||
assert(dt.address === datatokenAddress, 'incorrect value for: address')
|
||||
assert(dt.cap === cap, 'incorrect value for: cap')
|
||||
assert(dt.supply === '0', 'incorrect value for: supply')
|
||||
assert(dt.isDatatoken === true, 'incorrect value for: isDatatoken')
|
||||
assert(dt.nft.id === erc721Address, 'incorrect value for: nft.id')
|
||||
assert(dt.minter[0] === publisher, 'incorrect value for: minter')
|
||||
assert(dt.paymentManager === null, 'incorrect value for: paymentManager')
|
||||
assert(
|
||||
dt.paymentCollector === null,
|
||||
'incorrect value for: paymentCollector'
|
||||
)
|
||||
assert(
|
||||
dt.publishMarketFeeAddress === marketPlaceFeeAddress,
|
||||
'incorrect value for: publishMarketFeeAddress'
|
||||
)
|
||||
assert(
|
||||
dt.publishMarketFeeAmount === publishMarketFeeAmount,
|
||||
'incorrect value for: publishMarketFeeAmount'
|
||||
)
|
||||
assert(
|
||||
parseInt(dt.templateId) === templateIndex,
|
||||
'incorrect value for: templateId'
|
||||
)
|
||||
assert(dt.holderCount === '0', 'incorrect value for: holderCount')
|
||||
assert(dt.orderCount === '0', 'incorrect value for: orderCount')
|
||||
assert(dt.orders, 'incorrect value for: orders')
|
||||
assert(dt.fixedRateExchanges, 'incorrect value for: fixedRateExchanges')
|
||||
assert(dt.dispensers, 'incorrect value for: dispensers')
|
||||
assert(dt.createdTimestamp >= time, 'incorrect value for: createdTimestamp')
|
||||
assert(
|
||||
dt.createdTimestamp < time + 5,
|
||||
'incorrect value for: createdTimestamp'
|
||||
)
|
||||
assert(tx.from === publisher, 'incorrect value for: tx')
|
||||
assert(tx.to === factoryAddress, 'incorrect value for: tx')
|
||||
assert(tx.blockNumber >= blockNumber, 'incorrect value for: tx')
|
||||
assert(dt.block >= blockNumber, 'incorrect value for: block')
|
||||
assert(dt.block < blockNumber + 50, 'incorrect value for: block')
|
||||
assert(dt.lastPriceValue === '0', 'incorrect value for: lastPriceValue')
|
||||
assert(
|
||||
dt.eventIndex !== null && dt.eventIndex > 0,
|
||||
'incorrect value for: eventIndex'
|
||||
)
|
||||
})
|
||||
|
||||
it('Correct Datatoken fields after updating metadata', async () => {
|
||||
// create the files encrypted string
|
||||
const chain = await web3.eth.getChainId()
|
||||
let providerResponse = await ProviderInstance.encrypt(
|
||||
assetUrl,
|
||||
chain,
|
||||
providerUrl
|
||||
)
|
||||
ddo.services[0].files = await providerResponse
|
||||
ddo.services[0].datatokenAddress = datatokenAddress
|
||||
// update ddo and set the right did
|
||||
ddo.nftAddress = erc721Address
|
||||
ddo.id =
|
||||
'did:op:' +
|
||||
SHA256(web3.utils.toChecksumAddress(erc721Address) + chain.toString(10))
|
||||
|
||||
providerResponse = await ProviderInstance.encrypt(ddo, chain, providerUrl)
|
||||
const encryptedResponse = await providerResponse
|
||||
const metadataHash = getHash(JSON.stringify(ddo))
|
||||
await nft.setMetadata(
|
||||
erc721Address,
|
||||
publisher,
|
||||
0,
|
||||
providerUrl,
|
||||
'',
|
||||
'0x2',
|
||||
encryptedResponse,
|
||||
'0x' + metadataHash
|
||||
)
|
||||
|
||||
// Check values before updating metadata
|
||||
await sleep(3000)
|
||||
const initialQuery = {
|
||||
query: `query {
|
||||
token(id: "${datatokenAddress}"){
|
||||
id,
|
||||
symbol,
|
||||
name,
|
||||
decimals,
|
||||
address,
|
||||
cap,
|
||||
supply,
|
||||
isDatatoken,
|
||||
nft {id},
|
||||
minter,
|
||||
paymentManager,
|
||||
paymentCollector,
|
||||
publishMarketFeeAddress,
|
||||
publishMarketFeeAmount,
|
||||
templateId,
|
||||
holderCount,
|
||||
orderCount,
|
||||
orders {id},
|
||||
fixedRateExchanges {id},
|
||||
dispensers {id},
|
||||
createdTimestamp,
|
||||
tx,
|
||||
eventIndex,
|
||||
block,
|
||||
lastPriceValue
|
||||
}}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
await sleep(3000)
|
||||
const dt = (await initialResponse.json()).data.token
|
||||
|
||||
const tx: TransactionReceipt = await web3.eth.getTransactionReceipt(dt.tx)
|
||||
assert(dt.id === datatokenAddress, 'incorrect value for: id')
|
||||
assert(dt.symbol, 'incorrect value for: symbol')
|
||||
assert(dt.name, 'incorrect value for: name')
|
||||
assert(dt.decimals === 18, 'incorrect value for: decimals')
|
||||
assert(dt.address === datatokenAddress, 'incorrect value for: address')
|
||||
assert(dt.cap === cap, 'incorrect value for: cap')
|
||||
assert(dt.supply === '0', 'incorrect value for: supply')
|
||||
assert(dt.isDatatoken === true, 'incorrect value for: isDatatoken')
|
||||
assert(dt.nft.id === erc721Address, 'incorrect value for: nft.id')
|
||||
assert(dt.minter[0] === publisher, 'incorrect value for: minter')
|
||||
assert(dt.paymentManager === null, 'incorrect value for: paymentManager')
|
||||
assert(
|
||||
dt.paymentCollector === null,
|
||||
'incorrect value for: paymentCollector'
|
||||
)
|
||||
assert(
|
||||
dt.publishMarketFeeAddress === marketPlaceFeeAddress,
|
||||
'incorrect value for: publishMarketFeeAddress'
|
||||
)
|
||||
assert(
|
||||
dt.publishMarketFeeAmount === publishMarketFeeAmount,
|
||||
'incorrect value for: publishMarketFeeAmount'
|
||||
)
|
||||
assert(
|
||||
parseInt(dt.templateId) === templateIndex,
|
||||
'incorrect value for: templateId'
|
||||
)
|
||||
assert(dt.holderCount === '0', 'incorrect value for: holderCount')
|
||||
assert(dt.orderCount === '0', 'incorrect value for: orderCount')
|
||||
assert(dt.orders, 'incorrect value for: orders')
|
||||
assert(dt.fixedRateExchanges, 'incorrect value for: fixedRateExchanges')
|
||||
assert(dt.dispensers, 'incorrect value for: dispensers')
|
||||
assert(dt.createdTimestamp >= time, 'incorrect value for: createdTimestamp')
|
||||
assert(
|
||||
dt.createdTimestamp < time + 5,
|
||||
'incorrect value for: createdTimestamp'
|
||||
)
|
||||
assert(tx.from === publisher, 'incorrect value for: tx')
|
||||
assert(tx.to === factoryAddress, 'incorrect value for: tx')
|
||||
assert(tx.blockNumber >= blockNumber, 'incorrect value for: tx')
|
||||
assert(dt.block >= blockNumber, 'incorrect value for: block')
|
||||
assert(dt.block < blockNumber + 50, 'incorrect value for: block')
|
||||
assert(dt.lastPriceValue === '0', 'incorrect value for: lastPriceValue')
|
||||
assert(
|
||||
dt.eventIndex !== null && dt.eventIndex > 0,
|
||||
'incorrect value for: eventIndex'
|
||||
)
|
||||
})
|
||||
|
||||
it('Check datatoken orders are updated correctly after publishing & ordering a datatoken with fees', async () => {
|
||||
// Publish a datatoken for publishingMarketFeeToken
|
||||
const nftParams1: NftCreateData = {
|
||||
name: 'newNFT1',
|
||||
symbol: 'newTST1',
|
||||
templateIndex,
|
||||
tokenURI: '',
|
||||
transferable: true,
|
||||
owner: publisher
|
||||
}
|
||||
const erc20Params1: DatatokenCreateParams = {
|
||||
templateIndex,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
paymentCollector: ZERO_ADDRESS,
|
||||
feeToken: ZERO_ADDRESS,
|
||||
minter: publisher,
|
||||
mpFeeAddress: ZERO_ADDRESS
|
||||
}
|
||||
const result1 = await Factory.createNftWithDatatoken(
|
||||
publisher,
|
||||
nftParams1,
|
||||
erc20Params1
|
||||
)
|
||||
await sleep(3000)
|
||||
const publishingTokenAddress = result1.events.TokenCreated.returnValues[0]
|
||||
const publishingDatatoken = new Datatoken(web3, 8996)
|
||||
|
||||
// Start with publishing the datatoken used for startOrder
|
||||
const nftParams: NftCreateData = {
|
||||
name: 'newNFT',
|
||||
symbol: 'newTST',
|
||||
templateIndex,
|
||||
tokenURI: '',
|
||||
transferable: true,
|
||||
owner: publisher
|
||||
}
|
||||
const erc20Params: DatatokenCreateParams = {
|
||||
templateIndex,
|
||||
cap: '100000',
|
||||
feeAmount: '0.2',
|
||||
paymentCollector: ZERO_ADDRESS,
|
||||
feeToken: publishingTokenAddress,
|
||||
minter: publisher,
|
||||
mpFeeAddress: publisher
|
||||
}
|
||||
const result = await Factory.createNftWithDatatoken(
|
||||
publisher,
|
||||
nftParams,
|
||||
erc20Params
|
||||
)
|
||||
await sleep(3000)
|
||||
const newDtAddress = result.events.TokenCreated.returnValues[0]
|
||||
|
||||
const datatoken = new Datatoken(web3, 8996)
|
||||
|
||||
await datatoken.approve(
|
||||
newDtAddress,
|
||||
publishingTokenAddress,
|
||||
'100000000000000000000000000',
|
||||
user1
|
||||
)
|
||||
await publishingDatatoken.approve(
|
||||
publishingTokenAddress,
|
||||
newDtAddress,
|
||||
'100000000000000000000000000',
|
||||
user1
|
||||
)
|
||||
await datatoken.mint(newDtAddress, publisher, '100', user1)
|
||||
await publishingDatatoken.mint(
|
||||
publishingTokenAddress,
|
||||
publisher,
|
||||
'100',
|
||||
user1
|
||||
)
|
||||
const user1balance = await datatoken.balance(newDtAddress, user1)
|
||||
const user2balance = await datatoken.balance(newDtAddress, user2)
|
||||
assert(Number(user1balance) === 100, 'Invalid user1 balance')
|
||||
assert(Number(user2balance) === 0, 'Invalid user2 balance')
|
||||
|
||||
const user1balanceOfPublishing = await datatoken.balance(
|
||||
publishingTokenAddress,
|
||||
user1
|
||||
)
|
||||
const user2balanceOfPublishing = await datatoken.balance(
|
||||
publishingTokenAddress,
|
||||
user2
|
||||
)
|
||||
assert(Number(user1balanceOfPublishing) === 100, 'Invalid user1 balance')
|
||||
assert(Number(user2balanceOfPublishing) === 0, 'Invalid user2 balance')
|
||||
|
||||
const query = {
|
||||
query: `query {token(id: "${newDtAddress.toLowerCase()}"){id,orderCount,orders {id, nftOwner{id}, lastPriceToken{id}, eventIndex}, eventIndex}}`
|
||||
}
|
||||
|
||||
await sleep(3000)
|
||||
let response = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(query)
|
||||
})
|
||||
await sleep(3000)
|
||||
const initialToken = (await response.json()).data.token
|
||||
|
||||
assert(initialToken, 'Invalid initialToken')
|
||||
assert(initialToken.orderCount === '0', 'Invalid initial orderCount')
|
||||
assert(initialToken.orders.length === 0, 'Invalid initial orders')
|
||||
assert(
|
||||
initialToken.eventIndex !== null && initialToken.eventIndex > 0,
|
||||
'Invalid eventIndex'
|
||||
)
|
||||
|
||||
const providerData = JSON.stringify({ timeout: 0 })
|
||||
const providerFeeToken = ZERO_ADDRESS
|
||||
const providerFeeAmount = '10000'
|
||||
const providerValidUntil = '0'
|
||||
const message = web3.utils.soliditySha3(
|
||||
{ t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) },
|
||||
{ t: 'address', v: user3 },
|
||||
{ t: 'address', v: providerFeeToken },
|
||||
{ t: 'uint256', v: providerFeeAmount },
|
||||
{ t: 'uint256', v: providerValidUntil }
|
||||
)
|
||||
assert(message, 'Invalid message')
|
||||
const { v, r, s } = await signHash(web3, message, user3)
|
||||
const setProviderFee: ProviderFees = {
|
||||
providerFeeAddress: user3,
|
||||
providerFeeToken,
|
||||
providerFeeAmount,
|
||||
v,
|
||||
r,
|
||||
s,
|
||||
providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData)),
|
||||
validUntil: providerValidUntil
|
||||
}
|
||||
const consumeMarketFees = {
|
||||
consumeMarketFeeAddress: publisher,
|
||||
consumeMarketFeeToken: publishingTokenAddress,
|
||||
consumeMarketFeeAmount: '20000'
|
||||
}
|
||||
assert(setProviderFee, 'Invalid setProviderFee')
|
||||
const orderTx = await datatoken.startOrder(
|
||||
newDtAddress,
|
||||
user1,
|
||||
user2,
|
||||
1,
|
||||
setProviderFee,
|
||||
consumeMarketFees
|
||||
)
|
||||
assert(orderTx, 'Invalid orderTx')
|
||||
const orderId = `${orderTx.transactionHash.toLowerCase()}-${newDtAddress.toLowerCase()}-${user1.toLowerCase()}-${orderTx.events.OrderStarted.logIndex.toFixed(
|
||||
1
|
||||
)}`
|
||||
|
||||
await sleep(3000)
|
||||
response = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(query)
|
||||
})
|
||||
await sleep(3000)
|
||||
|
||||
const token = (await response.json()).data.token
|
||||
|
||||
assert(token, 'Invalid token')
|
||||
assert(token.orderCount === '1', 'Invalid orderCount after order')
|
||||
assert(token.orders[0].id === orderId)
|
||||
assert(token.orders[0].lastPriceToken.id === ZERO_ADDRESS)
|
||||
assert(token.orders[0].nftOwner.id === publisher, 'invalid nftOwner')
|
||||
assert(token.orders[0].eventIndex === 0, 'invalid order eventIndex')
|
||||
assert(token.eventIndex !== null, 'Invalid eventIndex')
|
||||
assert(
|
||||
token.eventIndex !== token.orders[0].eventIndex,
|
||||
'Invalid log indeces'
|
||||
)
|
||||
const orderQuery = {
|
||||
query: `query {order(id:"${orderId}"){id, publishingMarket{id}, publishingMarketToken{id}, publishingMarketAmmount, consumerMarket{id}, consumerMarketToken{id}, consumerMarketAmmount, eventIndex}}`
|
||||
}
|
||||
await sleep(3000)
|
||||
const orderResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(orderQuery)
|
||||
})
|
||||
await sleep(3000)
|
||||
const queryResult = await orderResponse.json()
|
||||
const order = queryResult.data.order
|
||||
assert(
|
||||
order.publishingMarket.id === erc20Params.mpFeeAddress.toLowerCase(),
|
||||
'incorrect publish market fee address'
|
||||
)
|
||||
assert(
|
||||
order.publishingMarketToken.id === erc20Params.feeToken.toLowerCase(),
|
||||
'incorrect publish market fee token'
|
||||
)
|
||||
assert(
|
||||
order.publishingMarketAmmount === erc20Params.feeAmount,
|
||||
'incorrect publish market fee amount'
|
||||
)
|
||||
assert(
|
||||
order.consumerMarket.id ===
|
||||
consumeMarketFees.consumeMarketFeeAddress.toLowerCase(),
|
||||
'incorrect consume market fee address'
|
||||
)
|
||||
assert(
|
||||
order.consumerMarketToken.id ===
|
||||
consumeMarketFees.consumeMarketFeeToken.toLowerCase(),
|
||||
'incorrect consume market fee token'
|
||||
)
|
||||
assert(
|
||||
order.consumerMarketAmmount === '0.00000000000002',
|
||||
'incorrect consume market fee amount'
|
||||
)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,534 @@
|
|||
import {
|
||||
DatatokenCreateParams,
|
||||
NftFactory,
|
||||
NftCreateData,
|
||||
sleep,
|
||||
ZERO_ADDRESS,
|
||||
Dispenser,
|
||||
Datatoken,
|
||||
DispenserParams
|
||||
} from '@oceanprotocol/lib'
|
||||
import DispenserTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json'
|
||||
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
|
||||
import { assert } from 'chai'
|
||||
import Web3 from 'web3'
|
||||
import { homedir } from 'os'
|
||||
import fs from 'fs'
|
||||
import { fetch } from 'cross-fetch'
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
import { AbiItem } from 'web3-utils/types'
|
||||
|
||||
const sleepMs = 1800
|
||||
|
||||
const data = JSON.parse(
|
||||
fs.readFileSync(
|
||||
process.env.ADDRESS_FILE ||
|
||||
`${homedir}/.ocean/ocean-contracts/artifacts/address.json`,
|
||||
'utf8'
|
||||
)
|
||||
)
|
||||
|
||||
const addresses = data.development
|
||||
const web3 = new Web3('http://127.0.0.1:8545')
|
||||
|
||||
const subgraphUrl =
|
||||
'http://127.0.0.1:9000/subgraphs/name/oceanprotocol/ocean-subgraph'
|
||||
|
||||
describe('Dispenser tests', async () => {
|
||||
const nftName = 'test-Fixed-Price-NFT'
|
||||
const nftSymbol = 'TST-FIXED'
|
||||
const tokenURI = 'https://oceanprotocol.com/nft/fixed'
|
||||
const cap = '10000'
|
||||
const feeAmount = '0.2'
|
||||
const templateIndex = 1
|
||||
const dispenserAddress = addresses.Dispenser.toLowerCase()
|
||||
let dtAddress: string
|
||||
let marketPlaceFeeAddress: string
|
||||
let dt
|
||||
let Factory: NftFactory
|
||||
let factoryAddress: string
|
||||
let accounts: string[]
|
||||
let publisher: string
|
||||
let nftAddress: string
|
||||
let time: number
|
||||
let blockNumber: number
|
||||
let dispenser: Dispenser
|
||||
let dispenserId: string
|
||||
let datatoken: Datatoken
|
||||
let user1: string
|
||||
let user2: string
|
||||
|
||||
before(async () => {
|
||||
factoryAddress = addresses.ERC721Factory.toLowerCase()
|
||||
Factory = new NftFactory(factoryAddress, web3)
|
||||
accounts = await web3.eth.getAccounts()
|
||||
publisher = accounts[0].toLowerCase()
|
||||
marketPlaceFeeAddress = accounts[1].toLowerCase()
|
||||
user1 = accounts[2].toLowerCase()
|
||||
user2 = accounts[3].toLowerCase()
|
||||
})
|
||||
|
||||
it('should initialize Dispenser and datatoken class', async () => {
|
||||
dispenser = new Dispenser(
|
||||
addresses.Dispenser,
|
||||
web3,
|
||||
8996,
|
||||
null,
|
||||
DispenserTemplate.abi as AbiItem[]
|
||||
)
|
||||
assert(dispenser.getDefaultAbi() !== null)
|
||||
|
||||
datatoken = new Datatoken(web3, 8996, null, ERC20Template.abi as AbiItem[])
|
||||
assert(datatoken.getDefaultAbi() !== null)
|
||||
})
|
||||
|
||||
it('Deploying an NFT with ERC20', async () => {
|
||||
const date = new Date()
|
||||
time = Math.floor(date.getTime() / 1000)
|
||||
blockNumber = await web3.eth.getBlockNumber()
|
||||
|
||||
const nftParams: NftCreateData = {
|
||||
name: nftName,
|
||||
symbol: nftSymbol,
|
||||
templateIndex: 1,
|
||||
tokenURI,
|
||||
transferable: true,
|
||||
owner: publisher
|
||||
}
|
||||
const erc20Params: DatatokenCreateParams = {
|
||||
templateIndex,
|
||||
cap,
|
||||
feeAmount,
|
||||
paymentCollector: ZERO_ADDRESS,
|
||||
feeToken: ZERO_ADDRESS,
|
||||
minter: publisher,
|
||||
mpFeeAddress: marketPlaceFeeAddress
|
||||
}
|
||||
|
||||
const tx = await Factory.createNftWithDatatoken(
|
||||
publisher,
|
||||
nftParams,
|
||||
erc20Params
|
||||
)
|
||||
const nftTemplate = await Factory.getNFTTemplate(nftParams.templateIndex)
|
||||
assert(tx.events.NFTCreated.event === 'NFTCreated')
|
||||
assert(tx.events.TokenCreated.event === 'TokenCreated')
|
||||
nftAddress = tx.events.NFTCreated.returnValues.newTokenAddress.toLowerCase()
|
||||
dtAddress =
|
||||
tx.events.TokenCreated.returnValues.newTokenAddress.toLowerCase()
|
||||
|
||||
// Check NFT values
|
||||
await sleep(sleepMs)
|
||||
const nftQuery = {
|
||||
query: `query {
|
||||
nft(id:"${nftAddress}"){
|
||||
id,
|
||||
symbol,
|
||||
name,
|
||||
tokenUri,
|
||||
owner{id},
|
||||
creator{id},
|
||||
address,
|
||||
providerUrl,
|
||||
assetState,
|
||||
managerRole,
|
||||
erc20DeployerRole,
|
||||
storeUpdateRole,
|
||||
metadataRole,
|
||||
template,
|
||||
transferable,
|
||||
createdTimestamp,
|
||||
tx,
|
||||
eventIndex,
|
||||
block,
|
||||
orderCount}}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(nftQuery)
|
||||
})
|
||||
const nft = (await initialResponse.json()).data.nft
|
||||
const nftTx: TransactionReceipt = await web3.eth.getTransactionReceipt(
|
||||
nft.tx
|
||||
)
|
||||
assert(nft.id === nftAddress, 'incorrect value for: id')
|
||||
assert(nft.symbol === nftSymbol, 'incorrect value for: symbol')
|
||||
assert(nft.name === nftName, 'incorrect value for: name')
|
||||
assert(nft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
|
||||
assert(nft.owner.id === publisher, 'incorrect value for: owner')
|
||||
assert(nft.creator.id === publisher, 'incorrect value for: creator')
|
||||
assert(nft.managerRole[0] === publisher, 'incorrect value for: managerRole')
|
||||
assert(
|
||||
nft.erc20DeployerRole[0] === factoryAddress,
|
||||
'incorrect value for: erc20DeployerRole'
|
||||
)
|
||||
assert(nft.storeUpdateRole === null, 'incorrect value for: storeUpdateRole')
|
||||
assert(nft.metadataRole === null, 'incorrect value for: metadataRole')
|
||||
assert(
|
||||
nft.template === nftTemplate.templateAddress.toLowerCase(),
|
||||
'incorrect value for: template'
|
||||
)
|
||||
assert(nft.transferable === true, 'incorrect value for: transferable')
|
||||
assert(nft.createdTimestamp >= time, 'incorrect value: createdTimestamp')
|
||||
assert(nft.createdTimestamp < time + 5, 'incorrect value: createdTimestamp')
|
||||
assert(nftTx.from === publisher, 'incorrect value for: tx')
|
||||
assert(nftTx.to === factoryAddress, 'incorrect value for: tx')
|
||||
assert(nftTx.blockNumber >= blockNumber, 'incorrect value for: tx')
|
||||
assert(nft.block >= blockNumber, 'incorrect value for: block')
|
||||
assert(nft.block < blockNumber + 50, 'incorrect value for: block')
|
||||
assert(nft.orderCount === '0', 'incorrect value for: orderCount')
|
||||
assert(
|
||||
nft.eventIndex !== null && nft.eventIndex > 0,
|
||||
'Invalid eventIndex for NFT creation'
|
||||
)
|
||||
})
|
||||
|
||||
it('Test all DT Fields after deploying', async () => {
|
||||
// Check Datatoken Values
|
||||
const dtQuery = {
|
||||
query: `query {
|
||||
token(id: "${dtAddress}"){
|
||||
id,
|
||||
symbol,
|
||||
name,
|
||||
decimals,
|
||||
address,
|
||||
cap,
|
||||
supply,
|
||||
isDatatoken,
|
||||
nft {id},
|
||||
minter,
|
||||
paymentManager,
|
||||
paymentCollector,
|
||||
publishMarketFeeAddress,
|
||||
publishMarketFeeAmount,
|
||||
templateId,
|
||||
holderCount,
|
||||
orderCount,
|
||||
orders {id},
|
||||
fixedRateExchanges {id},
|
||||
dispensers {id},
|
||||
createdTimestamp,
|
||||
tx,
|
||||
eventIndex,
|
||||
block,
|
||||
lastPriceValue
|
||||
}}`
|
||||
}
|
||||
const dtResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(dtQuery)
|
||||
})
|
||||
dt = (await dtResponse.json()).data.token
|
||||
|
||||
const dtTx: TransactionReceipt = await web3.eth.getTransactionReceipt(dt.tx)
|
||||
|
||||
assert(dt.id === dtAddress, 'incorrect value for: id')
|
||||
assert(dt.symbol, 'incorrect value for: symbol')
|
||||
assert(dt.name, 'incorrect value for: name')
|
||||
assert(dt.decimals === 18, 'incorrect value for: decimals')
|
||||
assert(dt.address === dtAddress, 'incorrect value for: address')
|
||||
assert(dt.cap === cap, 'incorrect value for: cap')
|
||||
assert(dt.supply === '0', 'incorrect value for: supply')
|
||||
assert(dt.isDatatoken === true, 'incorrect value for: isDatatoken')
|
||||
assert(dt.nft.id === nftAddress, 'incorrect value for: nft.id')
|
||||
assert(dt.minter[0] === publisher, 'incorrect value for: minter')
|
||||
assert(dt.paymentManager === null, 'incorrect value for: paymentManager')
|
||||
assert(
|
||||
dt.paymentCollector === null,
|
||||
'incorrect value for: paymentCollector'
|
||||
)
|
||||
assert(
|
||||
dt.publishMarketFeeAddress === marketPlaceFeeAddress,
|
||||
'incorrect value for: publishMarketFeeAddress'
|
||||
)
|
||||
assert(
|
||||
dt.publishMarketFeeAmount === feeAmount,
|
||||
'incorrect value for: publishMarketFeeAmount'
|
||||
)
|
||||
|
||||
assert(
|
||||
parseInt(dt.templateId) === templateIndex,
|
||||
'incorrect value for: templateId'
|
||||
)
|
||||
assert(dt.holderCount === '0', 'incorrect value for: holderCount')
|
||||
assert(dt.orderCount === '0', 'incorrect value for: orderCount')
|
||||
assert(dt.orders, 'incorrect value for: orders')
|
||||
assert(dt.fixedRateExchanges, 'incorrect value for: fixedRateExchanges')
|
||||
assert(dt.dispensers, 'incorrect value for: dispensers')
|
||||
assert(dt.createdTimestamp >= time, 'incorrect value for: createdTimestamp')
|
||||
assert(
|
||||
dt.createdTimestamp < time + 5,
|
||||
'incorrect value for: createdTimestamp'
|
||||
)
|
||||
assert(dtTx.from === publisher, 'incorrect value for: tx')
|
||||
assert(dtTx.to === factoryAddress, 'incorrect value for: tx')
|
||||
assert(dtTx.blockNumber >= blockNumber, 'incorrect value for: tx')
|
||||
assert(dt.block >= blockNumber, 'incorrect value for: block')
|
||||
assert(dt.block < blockNumber + 50, 'incorrect value for: block')
|
||||
assert(dt.lastPriceValue === '0', 'incorrect value for: lastPriceValue')
|
||||
assert(
|
||||
dt.eventIndex !== null && dt.eventIndex > 0,
|
||||
'incorrect value for: eventIndex'
|
||||
)
|
||||
})
|
||||
|
||||
it('Make user1 minter', async () => {
|
||||
await datatoken.addMinter(dtAddress, publisher, user1)
|
||||
|
||||
assert((await datatoken.getPermissions(dtAddress, user1)).minter === true)
|
||||
await sleep(sleepMs)
|
||||
const minterQuery = {
|
||||
query: `query {token(id: "${dtAddress}"){minter{id}, eventIndex}}`
|
||||
}
|
||||
|
||||
const minterResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(minterQuery)
|
||||
})
|
||||
const dt = (await minterResponse.json()).data.token
|
||||
assert(dt.minter[1] === user1, 'incorrect value for: minter')
|
||||
assert(dt.eventIndex !== null, 'incorrect value for: eventIndex')
|
||||
})
|
||||
|
||||
it('Create dispenser', async () => {
|
||||
const maxTokens = '921'
|
||||
const maxBalance = '9032'
|
||||
const dispenserParams: DispenserParams = {
|
||||
maxTokens,
|
||||
maxBalance,
|
||||
withMint: true
|
||||
}
|
||||
const tx = (
|
||||
await datatoken.createDispenser(
|
||||
dtAddress,
|
||||
publisher,
|
||||
dispenserAddress,
|
||||
dispenserParams
|
||||
)
|
||||
).events.NewDispenser
|
||||
await sleep(sleepMs)
|
||||
assert(tx, 'Cannot create dispenser')
|
||||
dispenserId = `${dispenserAddress}-${dtAddress}`
|
||||
|
||||
const dispenserQuery = {
|
||||
query: `query {dispenser(id: "${dispenserId}"){
|
||||
id
|
||||
contract
|
||||
active
|
||||
owner
|
||||
token {
|
||||
id
|
||||
}
|
||||
allowedSwapper
|
||||
isMinter
|
||||
maxTokens
|
||||
maxBalance
|
||||
balance
|
||||
block
|
||||
createdTimestamp
|
||||
tx
|
||||
eventIndex
|
||||
dispenses {
|
||||
id
|
||||
}
|
||||
__typename
|
||||
}}`
|
||||
}
|
||||
const graphResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(dispenserQuery)
|
||||
})
|
||||
const response = (await graphResponse.json()).data.dispenser
|
||||
|
||||
assert(response.id === dispenserId, 'incorrect value for: id')
|
||||
assert(response.contract === dispenserAddress, 'incorrect value: contract')
|
||||
assert(response.active === true, 'incorrect value for: active')
|
||||
assert(response.owner === publisher, 'incorrect value for: owner')
|
||||
assert(response.token.id === dtAddress, 'incorrect value for: token.id')
|
||||
assert(response.allowedSwapper === ZERO_ADDRESS, 'incorrect allowedSwapper')
|
||||
assert(response.isMinter === true, 'incorrect value for: isMinter')
|
||||
assert(response.maxTokens === web3.utils.fromWei(maxTokens), 'maxTokens')
|
||||
assert(response.maxBalance === web3.utils.fromWei(maxBalance), 'maxBalance')
|
||||
assert(response.balance === '0', 'maxBalance')
|
||||
assert(response.block === tx.blockNumber, 'wrong block')
|
||||
assert(response.createdTimestamp >= time, 'incorrect: createdTimestamp')
|
||||
assert(response.createdTimestamp < time + 15, 'incorrect: createdTimestamp')
|
||||
assert(response.tx === tx.transactionHash, 'incorrect value for: tx')
|
||||
assert(
|
||||
response.eventIndex !== null && response.eventIndex > 0,
|
||||
'incorrect value for: eventIndex'
|
||||
)
|
||||
assert(response.dispenses.length === 0, 'incorrect value for: dispenses')
|
||||
assert(response.__typename === 'Dispenser', 'incorrect value: __typename')
|
||||
})
|
||||
|
||||
it('Deactivates dispenser', async () => {
|
||||
const deactiveQuery = {
|
||||
query: `query {dispenser(id: "${dispenserId}"){active, eventIndex}}`
|
||||
}
|
||||
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(deactiveQuery)
|
||||
})
|
||||
const initialActive = (await initialResponse.json()).data.dispenser.active
|
||||
assert(initialActive === true, 'incorrect value for: initialActive')
|
||||
|
||||
// Deactivate exchange
|
||||
const tx = await dispenser.deactivate(dtAddress, publisher)
|
||||
const status = await dispenser.status(dtAddress)
|
||||
assert(status.active === false, 'Dispenser is still active')
|
||||
await sleep(sleepMs)
|
||||
// Check the updated value for active
|
||||
const updatedResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(deactiveQuery)
|
||||
})
|
||||
const updatedActive = (await updatedResponse.json()).data.dispenser
|
||||
assert(updatedActive.active === false, 'incorrect value for: updatedActive')
|
||||
assert(updatedActive.eventIndex !== null, 'incorrect value for: eventIndex')
|
||||
assert(
|
||||
updatedActive.eventIndex === tx.events.DispenserDeactivated.logIndex,
|
||||
'incorrect value for: eventIndex'
|
||||
)
|
||||
})
|
||||
|
||||
it('Activates dispenser', async () => {
|
||||
const activeQuery = {
|
||||
query: `query {dispenser(id: "${dispenserId}"){active, eventIndex}}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(activeQuery)
|
||||
})
|
||||
const initialActive = (await initialResponse.json()).data.dispenser
|
||||
assert(initialActive.active === false, 'incorrect value for: initialActive')
|
||||
assert(initialActive.eventIndex !== null, 'incorrect value for: eventIndex')
|
||||
|
||||
// Activate dispenser
|
||||
const tx = await dispenser.activate(dtAddress, '100', '100', publisher)
|
||||
await sleep(sleepMs)
|
||||
|
||||
// Check the updated value for active
|
||||
const updatedResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(activeQuery)
|
||||
})
|
||||
const updatedActive = (await updatedResponse.json()).data.dispenser
|
||||
assert(updatedActive.active === true, 'incorrect value for: updatedActive')
|
||||
assert(updatedActive.eventIndex !== null, 'incorrect value for: eventIndex')
|
||||
assert(
|
||||
updatedActive.eventIndex === tx.events.DispenserActivated.logIndex,
|
||||
'incorrect value for: eventIndex'
|
||||
)
|
||||
})
|
||||
|
||||
it('User2 gets datatokens from the dispenser', async () => {
|
||||
const amount = '3'
|
||||
const dispenseQuery = {
|
||||
query: `query {dispenser(id: "${dispenserId}"){
|
||||
dispenses{
|
||||
id
|
||||
dispenser{id}
|
||||
user {id}
|
||||
amount
|
||||
block
|
||||
createdTimestamp
|
||||
tx
|
||||
eventIndex
|
||||
__typename
|
||||
}}}`
|
||||
}
|
||||
// Check initial values before dispense
|
||||
const response1 = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(dispenseQuery)
|
||||
})
|
||||
await sleep(sleepMs)
|
||||
const before = (await response1.json()).data.dispenser.dispenses
|
||||
assert(before.length === 0, 'incorrect value for: dispenses')
|
||||
|
||||
const tx = await dispenser.dispense(dtAddress, user2, amount, user2)
|
||||
await sleep(sleepMs)
|
||||
|
||||
// Check values after dispense
|
||||
const response2 = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(dispenseQuery)
|
||||
})
|
||||
const dispense = (await response2.json()).data.dispenser.dispenses[0]
|
||||
|
||||
assert(
|
||||
dispense.id ===
|
||||
`${
|
||||
tx.transactionHash
|
||||
}-${dispenserId}-${tx.events.TokensDispensed.logIndex.toFixed(1)}`,
|
||||
'wrong id'
|
||||
)
|
||||
assert(dispense.dispenser.id === dispenserId, 'incorrect value for: user')
|
||||
assert(dispense.user.id === user2, 'incorrect value for: user')
|
||||
assert(dispense.amount === amount, 'incorrect value for: user')
|
||||
assert(dispense.block === tx.blockNumber, 'incorrect value for: block')
|
||||
assert(dispense.createdTimestamp >= time, 'incorrect: createdTimestamp')
|
||||
assert(dispense.createdTimestamp < time + 15, 'incorrect: createdTimestamp')
|
||||
assert(dispense.tx === tx.transactionHash, 'incorrect value for: tx')
|
||||
assert(dispense.eventIndex !== null, 'incorrect value for: eventIndex')
|
||||
assert(dispense.__typename === 'DispenserTransaction', 'wrong __typename')
|
||||
})
|
||||
|
||||
it('Owner withdraws all of the datatokens', async () => {
|
||||
await dispenser.ownerWithdraw(dtAddress, publisher)
|
||||
await sleep(sleepMs)
|
||||
|
||||
// Check balance after owner withdraw
|
||||
const balanceQuery = {
|
||||
query: `query {dispenser(id: "${dispenserId}"){balance, eventIndex}}`
|
||||
}
|
||||
|
||||
const response = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(balanceQuery)
|
||||
})
|
||||
const balance = (await response.json()).data.dispenser
|
||||
assert(balance.balance === '0', 'incorrect value for: balance')
|
||||
assert(balance.eventIndex !== null, 'incorrect value for: eventIndex')
|
||||
})
|
||||
|
||||
it('Updates allowed swapper', async () => {
|
||||
const swapperQuery = {
|
||||
query: `query {dispenser(id: "${dispenserId}"){allowedSwapper, eventIndex}}`
|
||||
}
|
||||
// Check initial allowedSwapper
|
||||
const swapperResponse1 = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(swapperQuery)
|
||||
})
|
||||
const allowedSwapper1 = (await swapperResponse1.json()).data.dispenser
|
||||
.allowedSwapper
|
||||
assert(
|
||||
allowedSwapper1 === ZERO_ADDRESS,
|
||||
'incorrect value for: allowedSwapper'
|
||||
)
|
||||
|
||||
const tx = await dispenser.setAllowedSwapper(dtAddress, publisher, user1)
|
||||
await sleep(sleepMs)
|
||||
|
||||
const swapperResponse2 = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(swapperQuery)
|
||||
})
|
||||
const allowedSwapper2 = (await swapperResponse2.json()).data.dispenser
|
||||
|
||||
assert(
|
||||
allowedSwapper2.allowedSwapper === user1,
|
||||
'incorrect value for: allowedSwapper 2'
|
||||
)
|
||||
assert(
|
||||
allowedSwapper2.eventIndex !== null &&
|
||||
allowedSwapper2.eventIndex ===
|
||||
tx.events.DispenserAllowedSwapperChanged.logIndex,
|
||||
'incorrect value for: eventIndex'
|
||||
)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,165 @@
|
|||
import {
|
||||
Router,
|
||||
NftFactory,
|
||||
calculateEstimatedGas,
|
||||
sendTx,
|
||||
sleep
|
||||
} from '@oceanprotocol/lib'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
import { assert } from 'chai'
|
||||
import Web3 from 'web3'
|
||||
import { homedir } from 'os'
|
||||
import fs from 'fs'
|
||||
import { fetch } from 'cross-fetch'
|
||||
|
||||
const data = JSON.parse(
|
||||
fs.readFileSync(
|
||||
process.env.ADDRESS_FILE ||
|
||||
`${homedir}/.ocean/ocean-contracts/artifacts/address.json`,
|
||||
'utf8'
|
||||
)
|
||||
)
|
||||
|
||||
const addresses = data.development
|
||||
const web3 = new Web3('http://127.0.0.1:8545')
|
||||
|
||||
const subgraphUrl =
|
||||
'http://127.0.0.1:9000/subgraphs/name/oceanprotocol/ocean-subgraph'
|
||||
|
||||
const minAbi = [
|
||||
{
|
||||
constant: false,
|
||||
inputs: [
|
||||
{ name: 'to', type: 'address' },
|
||||
{ name: 'value', type: 'uint256' }
|
||||
],
|
||||
name: 'mint',
|
||||
outputs: [{ name: '', type: 'bool' }],
|
||||
payable: false,
|
||||
stateMutability: 'nonpayable',
|
||||
type: 'function'
|
||||
}
|
||||
] as AbiItem[]
|
||||
|
||||
async function getSubgraphApprovedTokens() {
|
||||
const tokens: string[] = []
|
||||
const initialQuery = {
|
||||
query: `query{
|
||||
opcs{
|
||||
approvedTokens{
|
||||
id
|
||||
}
|
||||
}
|
||||
}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
const info = (await initialResponse.json()).data.opcs[0].approvedTokens
|
||||
for (let i = 0; i < info.length; i++) tokens.push(info[i].id)
|
||||
return tokens
|
||||
}
|
||||
|
||||
describe('FactoryRouter tests', async () => {
|
||||
let factory
|
||||
let router: Router
|
||||
let ownerAccount: string
|
||||
let Alice: string
|
||||
let Bob: string
|
||||
let datatokenAddress
|
||||
// let nft1, nft2, nft3
|
||||
// let chainId
|
||||
// const configHelper = new ConfigHelper()
|
||||
// const config = configHelper.getConfig('development')
|
||||
|
||||
before(async () => {
|
||||
const accounts = await web3.eth.getAccounts()
|
||||
// chainId = await web3.eth.getChainId()
|
||||
ownerAccount = accounts[0]
|
||||
Alice = accounts[1]
|
||||
Bob = accounts[2]
|
||||
|
||||
const tokenContract = new web3.eth.Contract(minAbi, addresses.Ocean)
|
||||
const estGas = await calculateEstimatedGas(
|
||||
ownerAccount,
|
||||
tokenContract.methods.mint,
|
||||
Alice,
|
||||
web3.utils.toWei('100000')
|
||||
)
|
||||
await sendTx(
|
||||
ownerAccount,
|
||||
estGas,
|
||||
web3,
|
||||
1,
|
||||
tokenContract.methods.mint,
|
||||
Alice,
|
||||
web3.utils.toWei('100000')
|
||||
)
|
||||
await sendTx(
|
||||
ownerAccount,
|
||||
estGas,
|
||||
web3,
|
||||
1,
|
||||
tokenContract.methods.mint,
|
||||
Bob,
|
||||
web3.utils.toWei('100000')
|
||||
)
|
||||
router = new Router(addresses.Router, web3)
|
||||
// nftFactory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
factory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
})
|
||||
|
||||
it('Ocean token should be in the approve token list', async () => {
|
||||
// since we can only lock once, we test if tx fails or not
|
||||
// so if there is already a lock, skip it
|
||||
const tokens = await getSubgraphApprovedTokens()
|
||||
assert(tokens.includes(addresses.Ocean.toLowerCase()))
|
||||
assert(tokens.length === 1)
|
||||
})
|
||||
it('Owner should add another token in the approved list', async () => {
|
||||
const nftName = 'testNFT'
|
||||
const nftSymbol = 'TST'
|
||||
const marketPlaceFeeAddress = '0x1230000000000000000000000000000000000000'
|
||||
const feeToken = '0x3210000000000000000000000000000000000000'
|
||||
const publishMarketFeeAmount = '0.1'
|
||||
const cap = '10000'
|
||||
const templateIndex = 1
|
||||
const result = await factory.createNftWithDatatoken(
|
||||
Alice,
|
||||
{
|
||||
name: nftName,
|
||||
symbol: nftSymbol,
|
||||
templateIndex,
|
||||
tokenURI: '',
|
||||
transferable: true,
|
||||
owner: Alice
|
||||
},
|
||||
{
|
||||
templateIndex,
|
||||
cap,
|
||||
feeAmount: publishMarketFeeAmount,
|
||||
paymentCollector: '0x0000000000000000000000000000000000000000',
|
||||
feeToken,
|
||||
minter: Alice,
|
||||
mpFeeAddress: marketPlaceFeeAddress,
|
||||
name: 'DT1',
|
||||
symbol: 'DT1'
|
||||
}
|
||||
)
|
||||
datatokenAddress = result.events.TokenCreated.returnValues[0].toLowerCase()
|
||||
await router.addApprovedToken(ownerAccount, datatokenAddress)
|
||||
await sleep(2000)
|
||||
const tokens = await getSubgraphApprovedTokens()
|
||||
assert(tokens.includes(datatokenAddress.toLowerCase()))
|
||||
assert(tokens.length === 2)
|
||||
})
|
||||
|
||||
it('Owner should remove token from the approved list', async () => {
|
||||
await router.removeApprovedToken(ownerAccount, datatokenAddress)
|
||||
await sleep(2000)
|
||||
const tokens = await getSubgraphApprovedTokens()
|
||||
assert(!tokens.includes(datatokenAddress.toLowerCase()))
|
||||
assert(tokens.length === 1)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,760 @@
|
|||
import {
|
||||
DatatokenCreateParams,
|
||||
NftFactory,
|
||||
NftCreateData,
|
||||
sleep,
|
||||
FreCreationParams,
|
||||
ZERO_ADDRESS,
|
||||
FixedRateExchange,
|
||||
Datatoken
|
||||
} from '@oceanprotocol/lib'
|
||||
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
|
||||
import { assert } from 'chai'
|
||||
import Web3 from 'web3'
|
||||
import { homedir } from 'os'
|
||||
import fs from 'fs'
|
||||
import { fetch } from 'cross-fetch'
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
import { AbiItem } from 'web3-utils/types'
|
||||
import BN from 'bn.js'
|
||||
|
||||
const sleepMs = 1700
|
||||
|
||||
const data = JSON.parse(
|
||||
fs.readFileSync(
|
||||
process.env.ADDRESS_FILE ||
|
||||
`${homedir}/.ocean/ocean-contracts/artifacts/address.json`,
|
||||
'utf8'
|
||||
)
|
||||
)
|
||||
|
||||
const addresses = data.development
|
||||
const web3 = new Web3('http://127.0.0.1:8545')
|
||||
|
||||
const subgraphUrl =
|
||||
'http://127.0.0.1:9000/subgraphs/name/oceanprotocol/ocean-subgraph'
|
||||
|
||||
describe('Fixed Rate Exchange tests', async () => {
|
||||
const nftName = 'test-Fixed-Price-NFT'
|
||||
const nftSymbol = 'TST-FIXED'
|
||||
const tokenURI = 'https://oceanprotocol.com/nft/fixed'
|
||||
const cap = '10000'
|
||||
const feeAmount = '0.2'
|
||||
const price = '123'
|
||||
const publishMarketSwapFee = '0.003'
|
||||
const templateIndex = 1
|
||||
const dtAmount = '10'
|
||||
// const datatoken = new Datatoken(web3, 8996)
|
||||
let datatokenAddress: string
|
||||
let fixedRateAddress: string
|
||||
let baseTokenAddress: string
|
||||
let marketPlaceFeeAddress: string
|
||||
let fixedRateId: string
|
||||
let dt
|
||||
let Factory: NftFactory
|
||||
let factoryAddress: string
|
||||
let accounts: string[]
|
||||
let publisher: string
|
||||
let erc721Address: string
|
||||
let nftAddress: string
|
||||
let time: number
|
||||
let blockNumber: number
|
||||
let exchangeContract: string
|
||||
let exchangeId: string
|
||||
let transactionHash: string
|
||||
let fixedRate: FixedRateExchange
|
||||
let user1: string
|
||||
|
||||
before(async () => {
|
||||
factoryAddress = addresses.ERC721Factory.toLowerCase()
|
||||
fixedRateAddress = addresses.FixedPrice.toLowerCase()
|
||||
baseTokenAddress = addresses.MockDAI.toLowerCase()
|
||||
Factory = new NftFactory(factoryAddress, web3)
|
||||
accounts = await web3.eth.getAccounts()
|
||||
publisher = accounts[0].toLowerCase()
|
||||
marketPlaceFeeAddress = accounts[1].toLowerCase()
|
||||
user1 = accounts[2].toLowerCase()
|
||||
})
|
||||
|
||||
it('Deploying a Fixed Rate Exchange & Test NFT Fields', async () => {
|
||||
const date = new Date()
|
||||
time = Math.floor(date.getTime() / 1000)
|
||||
blockNumber = await web3.eth.getBlockNumber()
|
||||
|
||||
const nftParams: NftCreateData = {
|
||||
name: nftName,
|
||||
symbol: nftSymbol,
|
||||
templateIndex: 1,
|
||||
tokenURI,
|
||||
transferable: true,
|
||||
owner: publisher
|
||||
}
|
||||
const erc20Params: DatatokenCreateParams = {
|
||||
templateIndex,
|
||||
cap,
|
||||
feeAmount,
|
||||
paymentCollector: ZERO_ADDRESS,
|
||||
feeToken: ZERO_ADDRESS,
|
||||
minter: publisher,
|
||||
mpFeeAddress: marketPlaceFeeAddress
|
||||
}
|
||||
const fixedRateParams: FreCreationParams = {
|
||||
fixedRateAddress,
|
||||
baseTokenAddress,
|
||||
owner: publisher,
|
||||
marketFeeCollector: marketPlaceFeeAddress,
|
||||
baseTokenDecimals: 18,
|
||||
datatokenDecimals: 18,
|
||||
fixedRate: price,
|
||||
marketFee: publishMarketSwapFee,
|
||||
allowedConsumer: ZERO_ADDRESS,
|
||||
withMint: true
|
||||
}
|
||||
|
||||
const result = await Factory.createNftWithDatatokenWithFixedRate(
|
||||
publisher,
|
||||
nftParams,
|
||||
erc20Params,
|
||||
fixedRateParams
|
||||
)
|
||||
transactionHash = result.transactionHash.toLowerCase()
|
||||
erc721Address = result.events.NFTCreated.returnValues[0]
|
||||
datatokenAddress = result.events.TokenCreated.returnValues[0].toLowerCase()
|
||||
|
||||
exchangeContract =
|
||||
result.events.NewFixedRate.returnValues.exchangeContract.toLowerCase()
|
||||
exchangeId =
|
||||
result.events.NewFixedRate.returnValues.exchangeId.toLowerCase()
|
||||
|
||||
fixedRateId = `${exchangeContract}-${exchangeId}`
|
||||
const nftTemplate = await Factory.getNFTTemplate(nftParams.templateIndex)
|
||||
|
||||
// Check NFT values
|
||||
await sleep(sleepMs)
|
||||
nftAddress = erc721Address.toLowerCase()
|
||||
const nftQuery = {
|
||||
query: `query {
|
||||
nft(id:"${nftAddress}"){
|
||||
id,
|
||||
symbol,
|
||||
name,
|
||||
tokenUri,
|
||||
owner{id},
|
||||
creator{id},
|
||||
address,
|
||||
providerUrl,
|
||||
assetState,
|
||||
managerRole,
|
||||
erc20DeployerRole,
|
||||
storeUpdateRole,
|
||||
metadataRole,
|
||||
template,
|
||||
transferable,
|
||||
createdTimestamp,
|
||||
tx,
|
||||
eventIndex,
|
||||
block,
|
||||
orderCount}}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(nftQuery)
|
||||
})
|
||||
const nft = (await initialResponse.json()).data.nft
|
||||
const nftTx: TransactionReceipt = await web3.eth.getTransactionReceipt(
|
||||
nft.tx
|
||||
)
|
||||
assert(nft.id === nftAddress, 'incorrect value for: id')
|
||||
assert(nft.symbol === nftSymbol, 'incorrect value for: symbol')
|
||||
assert(nft.name === nftName, 'incorrect value for: name')
|
||||
assert(nft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
|
||||
assert(nft.owner.id === publisher, 'incorrect value for: owner')
|
||||
assert(nft.creator.id === publisher, 'incorrect value for: creator')
|
||||
assert(nft.managerRole[0] === publisher, 'incorrect value for: managerRole')
|
||||
assert(
|
||||
nft.erc20DeployerRole[0] === factoryAddress,
|
||||
'incorrect value for: erc20DeployerRole'
|
||||
)
|
||||
assert(nft.storeUpdateRole === null, 'incorrect value for: storeUpdateRole')
|
||||
assert(nft.metadataRole === null, 'incorrect value for: metadataRole')
|
||||
assert(
|
||||
nft.template === nftTemplate.templateAddress.toLowerCase(),
|
||||
'incorrect value for: template'
|
||||
)
|
||||
assert(nft.transferable === true, 'incorrect value for: transferable')
|
||||
assert(
|
||||
nft.createdTimestamp >= time,
|
||||
'incorrect value for: createdTimestamp'
|
||||
)
|
||||
assert(
|
||||
nft.createdTimestamp < time + 5,
|
||||
'incorrect value for: createdTimestamp'
|
||||
)
|
||||
assert(nftTx.from === publisher, 'incorrect value for: tx')
|
||||
assert(nftTx.to === factoryAddress, 'incorrect value for: tx')
|
||||
assert(nftTx.blockNumber >= blockNumber, 'incorrect value for: tx')
|
||||
assert(nft.block >= blockNumber, 'incorrect value for: block')
|
||||
assert(nft.block < blockNumber + 50, 'incorrect value for: block')
|
||||
assert(nft.orderCount === '0', 'incorrect value for: orderCount')
|
||||
assert(
|
||||
nft.eventIndex !== null && nft.eventIndex > 0,
|
||||
'incorrect value for: eventIndex'
|
||||
)
|
||||
})
|
||||
|
||||
it('Test DT Fields after deploying Fixed rate exchange', async () => {
|
||||
// Check Datatoken Values
|
||||
const dtQuery = {
|
||||
query: `query {
|
||||
token(id: "${datatokenAddress}"){
|
||||
id,
|
||||
symbol,
|
||||
name,
|
||||
decimals,
|
||||
address,
|
||||
cap,
|
||||
supply,
|
||||
isDatatoken,
|
||||
nft {id},
|
||||
minter,
|
||||
paymentManager,
|
||||
paymentCollector,
|
||||
publishMarketFeeAddress,
|
||||
publishMarketFeeAmount,
|
||||
templateId,
|
||||
holderCount,
|
||||
orderCount,
|
||||
orders {id},
|
||||
fixedRateExchanges {id},
|
||||
dispensers {id},
|
||||
createdTimestamp,
|
||||
tx,
|
||||
eventIndex,
|
||||
block,
|
||||
lastPriceToken,
|
||||
lastPriceValue
|
||||
}}`
|
||||
}
|
||||
const dtResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(dtQuery)
|
||||
})
|
||||
dt = (await dtResponse.json()).data.token
|
||||
|
||||
const dtTx: TransactionReceipt = await web3.eth.getTransactionReceipt(dt.tx)
|
||||
|
||||
assert(dt.id === datatokenAddress, 'incorrect value for: id')
|
||||
assert(dt.symbol, 'incorrect value for: symbol')
|
||||
assert(dt.name, 'incorrect value for: name')
|
||||
assert(dt.decimals === 18, 'incorrect value for: decimals')
|
||||
assert(dt.address === datatokenAddress, 'incorrect value for: address')
|
||||
assert(dt.cap === cap, 'incorrect value for: cap')
|
||||
assert(dt.supply === '0', 'incorrect value for: supply')
|
||||
assert(dt.isDatatoken === true, 'incorrect value for: isDatatoken')
|
||||
assert(dt.nft.id === nftAddress, 'incorrect value for: nft.id')
|
||||
assert(dt.minter[0] === publisher, 'incorrect value for: minter')
|
||||
assert(dt.paymentManager === null, 'incorrect value for: paymentManager')
|
||||
assert(
|
||||
dt.paymentCollector === null,
|
||||
'incorrect value for: paymentCollector'
|
||||
)
|
||||
assert(
|
||||
dt.publishMarketFeeAddress === marketPlaceFeeAddress,
|
||||
'incorrect value for: publishMarketFeeAddress'
|
||||
)
|
||||
assert(
|
||||
dt.publishMarketFeeAmount === feeAmount,
|
||||
'incorrect value for: publishMarketFeeAmount'
|
||||
)
|
||||
|
||||
assert(
|
||||
parseInt(dt.templateId) === templateIndex,
|
||||
'incorrect value for: templateId'
|
||||
)
|
||||
assert(dt.holderCount === '0', 'incorrect value for: holderCount')
|
||||
assert(dt.orderCount === '0', 'incorrect value for: orderCount')
|
||||
assert(dt.orders, 'incorrect value for: orders')
|
||||
assert(dt.fixedRateExchanges, 'incorrect value for: fixedRateExchanges')
|
||||
assert(dt.dispensers, 'incorrect value for: dispensers')
|
||||
assert(dt.createdTimestamp >= time, 'incorrect value for: createdTimestamp')
|
||||
assert(
|
||||
dt.createdTimestamp < time + 5,
|
||||
'incorrect value for: createdTimestamp'
|
||||
)
|
||||
assert(dtTx.from === publisher, 'incorrect value for: tx')
|
||||
assert(dtTx.to === factoryAddress, 'incorrect value for: tx')
|
||||
assert(dtTx.blockNumber >= blockNumber, 'incorrect value for: tx')
|
||||
assert(dt.block >= blockNumber, 'incorrect value for: block')
|
||||
assert(dt.block < blockNumber + 50, 'incorrect value for: block')
|
||||
assert(dt.lastPriceValue === '0', 'incorrect value for: lastPriceValue')
|
||||
assert(
|
||||
dt.eventIndex !== null && dt.eventIndex > 0,
|
||||
'incorrect value for: eventIndex'
|
||||
)
|
||||
})
|
||||
|
||||
it('Test fixedRateExchanges Fields', async () => {
|
||||
const fixedQuery = {
|
||||
query: `query {
|
||||
fixedRateExchange(id: "${fixedRateId}"){
|
||||
id
|
||||
contract
|
||||
exchangeId
|
||||
owner {
|
||||
id
|
||||
}
|
||||
datatoken {
|
||||
id
|
||||
}
|
||||
baseToken {
|
||||
id
|
||||
}
|
||||
datatokenSupply
|
||||
baseTokenSupply
|
||||
datatokenBalance
|
||||
baseTokenBalance
|
||||
price
|
||||
active
|
||||
totalSwapValue
|
||||
allowedSwapper
|
||||
withMint
|
||||
isMinter
|
||||
updates {
|
||||
id
|
||||
}
|
||||
swaps {
|
||||
id
|
||||
}
|
||||
createdTimestamp
|
||||
tx
|
||||
eventIndex
|
||||
block
|
||||
publishMarketFeeAddress
|
||||
publishMarketSwapFee
|
||||
}
|
||||
}`
|
||||
}
|
||||
const fixedResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(fixedQuery)
|
||||
})
|
||||
const fixed = (await fixedResponse.json()).data.fixedRateExchange
|
||||
const fixedTx: TransactionReceipt = await web3.eth.getTransactionReceipt(
|
||||
fixed.tx
|
||||
)
|
||||
// Test Fixed Rate Exchange Values
|
||||
assert(fixed.id === fixedRateId, 'incorrect value for: id')
|
||||
assert(fixed.contract === exchangeContract, 'incorrect value for: contract')
|
||||
assert(fixed.exchangeId === exchangeId, 'incorrect value for: exchangeId')
|
||||
assert(fixed.owner.id === publisher, 'incorrect value for: owner.id')
|
||||
assert(
|
||||
fixed.datatoken.id === datatokenAddress,
|
||||
'incorrect value for: datatoken.id'
|
||||
)
|
||||
assert(
|
||||
fixed.baseToken.id === baseTokenAddress,
|
||||
'incorrect value for: baseToken.id'
|
||||
)
|
||||
assert(
|
||||
fixed.datatokenSupply ===
|
||||
'115792089237316195423570985008687900000000000000000000000000',
|
||||
'incorrect value for: datatokenSupply'
|
||||
)
|
||||
assert(
|
||||
fixed.baseTokenSupply === '0',
|
||||
'incorrect value for: baseTokenSupply'
|
||||
)
|
||||
assert(
|
||||
fixed.datatokenBalance === '0',
|
||||
'incorrect value for: datatokenBalance'
|
||||
)
|
||||
assert(
|
||||
fixed.baseTokenBalance === '0',
|
||||
'incorrect value for: baseTokenBalance'
|
||||
)
|
||||
assert(fixed.price === price, 'incorrect value for: price')
|
||||
assert(fixed.active === true, 'incorrect value for: active')
|
||||
assert(fixed.totalSwapValue === '0', 'incorrect value for: totalSwapValue')
|
||||
assert(
|
||||
fixed.allowedSwapper === ZERO_ADDRESS,
|
||||
'incorrect value for: allowedSwapper'
|
||||
)
|
||||
assert(fixed.withMint === true, 'incorrect value for: withMint')
|
||||
assert(fixed.isMinter === null, 'incorrect value for: isMinter')
|
||||
assert(fixed.updates, 'incorrect value for: updates.id')
|
||||
assert(fixed.swaps, 'incorrect value for: swaps')
|
||||
assert(
|
||||
fixed.createdTimestamp >= time,
|
||||
'incorrect value for: createdTimestamp'
|
||||
)
|
||||
assert(
|
||||
fixed.createdTimestamp < time + 5,
|
||||
'incorrect value for: createdTimestamp'
|
||||
)
|
||||
assert(fixed.tx === transactionHash, 'incorrect value for: tx')
|
||||
assert(fixed.block >= blockNumber, 'incorrect value for: block')
|
||||
assert(fixed.block < blockNumber + 50, 'incorrect value for: block')
|
||||
assert(
|
||||
fixed.publishMarketFeeAddress === marketPlaceFeeAddress,
|
||||
'incorrect value for: publishMarketFeeAddress'
|
||||
)
|
||||
assert(
|
||||
fixed.publishMarketSwapFee === publishMarketSwapFee,
|
||||
'incorrect value for: publishMarketSwapFee'
|
||||
)
|
||||
assert(fixedTx.from === publisher, 'incorrect value for: tx')
|
||||
assert(fixedTx.to === factoryAddress, 'incorrect value for: tx')
|
||||
assert(
|
||||
fixed.eventIndex !== null && fixed.eventIndex > 0,
|
||||
'incorrect value for: eventIndex'
|
||||
)
|
||||
})
|
||||
|
||||
it('Updates Fixed Rate Price', async () => {
|
||||
fixedRate = new FixedRateExchange(fixedRateAddress, web3, 8996)
|
||||
const priceQuery = {
|
||||
query: `query {fixedRateExchange(id: "${fixedRateId}"){
|
||||
price
|
||||
updates(orderBy: createdTimestamp, orderDirection: desc){
|
||||
exchangeId {
|
||||
id
|
||||
}
|
||||
oldPrice
|
||||
newPrice
|
||||
eventIndex
|
||||
}
|
||||
}}`
|
||||
}
|
||||
|
||||
// Check initial price
|
||||
const priceResponse1 = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(priceQuery)
|
||||
})
|
||||
const fixedResponse1 = (await priceResponse1.json()).data.fixedRateExchange
|
||||
|
||||
const price1 = fixedResponse1.price
|
||||
const updates1 = fixedResponse1.updates[0]
|
||||
|
||||
assert(price1 === price, 'incorrect value for: price 1')
|
||||
assert(
|
||||
updates1.exchangeId.id === fixedRateId,
|
||||
'incorrect value: initial fixedRateId'
|
||||
)
|
||||
assert(updates1.oldPrice === null, 'incorrect value: initial oldPrice')
|
||||
assert(updates1.newPrice === null, 'incorrect value: initial oldPrice')
|
||||
|
||||
// Update price
|
||||
const newPrice = '999'
|
||||
const tx = await fixedRate.setRate(publisher, exchangeId, newPrice)
|
||||
await sleep(sleepMs)
|
||||
|
||||
// Check price after first update
|
||||
const priceResponse2 = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(priceQuery)
|
||||
})
|
||||
const fixedResponse2 = (await priceResponse2.json()).data.fixedRateExchange
|
||||
const price2 = fixedResponse2.price
|
||||
const updates2 = fixedResponse2.updates[0]
|
||||
|
||||
assert(price2 === newPrice, 'incorrect value for: price 2')
|
||||
assert(
|
||||
updates2.exchangeId.id === fixedRateId,
|
||||
'incorrect value: 2nd fixedRateId'
|
||||
)
|
||||
assert(updates2.oldPrice === price1, 'incorrect value: 2nd oldPrice')
|
||||
assert(updates2.newPrice === newPrice, 'incorrect value: 2nd newPrice')
|
||||
assert(
|
||||
updates2.eventIndex === tx.events.ExchangeRateChanged.logIndex,
|
||||
'incorrect value: 2nd eventIndex'
|
||||
)
|
||||
|
||||
// Update price a 2nd time
|
||||
const newPrice2 = '1' // '5.123'
|
||||
const tx2 = await fixedRate.setRate(publisher, exchangeId, newPrice2)
|
||||
await sleep(sleepMs)
|
||||
|
||||
// Check price after 2nd update
|
||||
const priceResponse3 = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(priceQuery)
|
||||
})
|
||||
|
||||
const fixedResponse3 = (await priceResponse3.json()).data.fixedRateExchange
|
||||
const price3 = fixedResponse3.price
|
||||
const updates3 = fixedResponse3.updates[0]
|
||||
|
||||
assert(price3 === newPrice2, 'incorrect value for: price 3')
|
||||
assert(
|
||||
updates3.exchangeId.id === fixedRateId,
|
||||
'incorrect value: 3rd fixedRateId'
|
||||
)
|
||||
assert(updates3.oldPrice === newPrice, 'incorrect value: 3rd oldPrice')
|
||||
assert(updates3.newPrice === newPrice2, 'incorrect value: 3rd newPrice')
|
||||
assert(
|
||||
updates3.eventIndex === tx2.events.ExchangeRateChanged.logIndex,
|
||||
'incorrect value: 3nd eventIndex'
|
||||
)
|
||||
})
|
||||
|
||||
it('User1 buys a datatoken', async () => {
|
||||
const swapsQuery = {
|
||||
query: `query {fixedRateExchange(id: "${fixedRateId}"){
|
||||
swaps{
|
||||
id
|
||||
exchangeId{id}
|
||||
by{id}
|
||||
baseTokenAmount
|
||||
dataTokenAmount
|
||||
block
|
||||
createdTimestamp
|
||||
tx
|
||||
eventIndex
|
||||
oceanFeeAmount
|
||||
marketFeeAmount
|
||||
consumeMarketFeeAmount
|
||||
__typename
|
||||
}
|
||||
}}`
|
||||
}
|
||||
// Check initial swaps
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(swapsQuery)
|
||||
})
|
||||
const initialSwaps = (await initialResponse.json()).data.fixedRateExchange
|
||||
.swaps
|
||||
assert(initialSwaps.length === 0, 'incorrect value for: initialSwaps')
|
||||
|
||||
const datatoken = new Datatoken(web3, 8996)
|
||||
// Mint datatokens as initial supply is 0
|
||||
await datatoken.mint(datatokenAddress, publisher, '100')
|
||||
await datatoken.approve(
|
||||
datatokenAddress,
|
||||
fixedRateAddress,
|
||||
'100',
|
||||
publisher
|
||||
)
|
||||
|
||||
const daiContract = new web3.eth.Contract(
|
||||
MockERC20.abi as AbiItem[],
|
||||
addresses.MockDAI
|
||||
)
|
||||
// user1 need DAI so that they can buy the datatoken
|
||||
await daiContract.methods
|
||||
.transfer(user1, web3.utils.toWei('100'))
|
||||
.send({ from: publisher })
|
||||
await daiContract.methods
|
||||
.approve(fixedRateAddress, web3.utils.toWei('10000000'))
|
||||
.send({ from: user1 })
|
||||
|
||||
// user1 has no DTs before buying one
|
||||
let user1Balance = await datatoken.balance(datatokenAddress, user1)
|
||||
assert(user1Balance === '0', 'incorrect value for: user1Balance')
|
||||
|
||||
const tx = (
|
||||
await fixedRate.buyDatatokens(user1, exchangeId, dtAmount, '100')
|
||||
).events?.Swapped
|
||||
|
||||
const oceanFeeAmount = web3.utils.fromWei(
|
||||
new BN(tx.returnValues.oceanFeeAmount)
|
||||
)
|
||||
const marketFeeAmount = web3.utils.fromWei(
|
||||
new BN(tx.returnValues.marketFeeAmount)
|
||||
)
|
||||
const consumeMarketFeeAmount = web3.utils.fromWei(
|
||||
new BN(tx.returnValues.consumeMarketFeeAmount)
|
||||
)
|
||||
|
||||
await sleep(sleepMs)
|
||||
user1Balance = await datatoken.balance(datatokenAddress, user1)
|
||||
// user1 has 1 datatoken
|
||||
assert(user1Balance === dtAmount, 'incorrect value for: user1Balance')
|
||||
|
||||
// Check updated swaps
|
||||
const updatedResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(swapsQuery)
|
||||
})
|
||||
const swaps = (await updatedResponse.json()).data.fixedRateExchange.swaps[0]
|
||||
const swappedAmount = web3.utils.fromWei(
|
||||
new BN(tx.returnValues.baseTokenSwappedAmount)
|
||||
)
|
||||
assert(
|
||||
swaps.id ===
|
||||
`${tx.transactionHash}-${fixedRateId}-${tx.logIndex.toFixed(1)}`,
|
||||
'incorrect: id'
|
||||
)
|
||||
assert(swaps.exchangeId.id === fixedRateId, 'incorrect: exchangeId')
|
||||
assert(swaps.by.id === user1, 'incorrect value for: id')
|
||||
assert(swaps.baseTokenAmount === swappedAmount, 'incorrect baseTokenAmount')
|
||||
assert(swaps.dataTokenAmount === dtAmount, 'incorrect: dataTokenAmount')
|
||||
assert(swaps.block === tx.blockNumber, 'incorrect value for: block')
|
||||
assert(swaps.createdTimestamp >= time, 'incorrect: createdTimestamp')
|
||||
assert(swaps.createdTimestamp < time + 25, 'incorrect: createdTimestamp 2')
|
||||
assert(swaps.oceanFeeAmount === oceanFeeAmount, 'incorrect: oceanFeeAmount')
|
||||
assert(swaps.marketFeeAmount === marketFeeAmount, 'wrong marketFeeAmount')
|
||||
assert(
|
||||
swaps.consumeMarketFeeAmount === consumeMarketFeeAmount,
|
||||
'wrong consumeMarketFeeAmount'
|
||||
)
|
||||
assert(swaps.tx === tx.transactionHash, 'incorrect value for: tx')
|
||||
assert(swaps.eventIndex === tx.logIndex, 'incorrect value for: eventIndex')
|
||||
assert(swaps.__typename === 'FixedRateExchangeSwap', 'incorrect __typename')
|
||||
})
|
||||
|
||||
it('Deactivate Minting', async () => {
|
||||
const mintingQuery = {
|
||||
query: `query {fixedRateExchange(id: "${fixedRateId}"){withMint, eventIndex}}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(mintingQuery)
|
||||
})
|
||||
const initialMint = (await initialResponse.json()).data.fixedRateExchange
|
||||
.withMint
|
||||
assert(initialMint === true, 'incorrect value for: initialMint')
|
||||
|
||||
// Activate minting
|
||||
const tx = await fixedRate.deactivateMint(publisher, exchangeId)
|
||||
await sleep(sleepMs)
|
||||
|
||||
// Check the updated value for active
|
||||
const updatedResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(mintingQuery)
|
||||
})
|
||||
|
||||
const updatedMint = (await updatedResponse.json()).data.fixedRateExchange
|
||||
assert(updatedMint.withMint === false, 'incorrect value for: updatedMint')
|
||||
assert(
|
||||
updatedMint.eventIndex === tx.events.ExchangeMintStateChanged.logIndex,
|
||||
'incorrect value for: eventIndex'
|
||||
)
|
||||
})
|
||||
it('Activate Minting', async () => {
|
||||
const mintingQuery = {
|
||||
query: `query {fixedRateExchange(id: "${fixedRateId}"){withMint, eventIndex}}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(mintingQuery)
|
||||
})
|
||||
const initialMint = (await initialResponse.json()).data.fixedRateExchange
|
||||
.withMint
|
||||
assert(initialMint === false, 'incorrect value for: initialMint')
|
||||
|
||||
// Activate minting
|
||||
const tx = await fixedRate.activateMint(publisher, exchangeId)
|
||||
await sleep(sleepMs)
|
||||
|
||||
// Check the updated value for active
|
||||
const updatedResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(mintingQuery)
|
||||
})
|
||||
const updatedMint = (await updatedResponse.json()).data.fixedRateExchange
|
||||
assert(updatedMint.withMint === true, 'incorrect value for: updatedMint')
|
||||
assert(
|
||||
updatedMint.eventIndex === tx.events.ExchangeMintStateChanged.logIndex,
|
||||
'incorrect value for: eventIndex'
|
||||
)
|
||||
})
|
||||
|
||||
it('Updates allowed swapper', async () => {
|
||||
const swapperQuery = {
|
||||
query: `query {fixedRateExchange(id: "${fixedRateId}"){allowedSwapper, eventIndex}}`
|
||||
}
|
||||
// Check initial allowedSwapper
|
||||
const swapperResponse1 = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(swapperQuery)
|
||||
})
|
||||
const allowedSwapper1 = (await swapperResponse1.json()).data
|
||||
.fixedRateExchange.allowedSwapper
|
||||
assert(
|
||||
allowedSwapper1 === ZERO_ADDRESS,
|
||||
'incorrect value for: allowedSwapper'
|
||||
)
|
||||
|
||||
const tx = await fixedRate.setAllowedSwapper(publisher, exchangeId, user1)
|
||||
await sleep(sleepMs)
|
||||
|
||||
const swapperResponse2 = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(swapperQuery)
|
||||
})
|
||||
const allowedSwapper2 = (await swapperResponse2.json()).data
|
||||
.fixedRateExchange
|
||||
|
||||
assert(
|
||||
allowedSwapper2.allowedSwapper === user1,
|
||||
'incorrect value for: allowedSwapper 2'
|
||||
)
|
||||
assert(
|
||||
allowedSwapper2.eventIndex ===
|
||||
tx.events.ExchangeAllowedSwapperChanged.logIndex,
|
||||
'incorrect value for: eventIndex'
|
||||
)
|
||||
})
|
||||
it('Deactivates exchange', async () => {
|
||||
const deactiveQuery = {
|
||||
query: `query {fixedRateExchange(id: "${fixedRateId}"){active, eventIndex}}`
|
||||
}
|
||||
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(deactiveQuery)
|
||||
})
|
||||
const initialActive = (await initialResponse.json()).data.fixedRateExchange
|
||||
.active
|
||||
assert(initialActive === true, 'incorrect value for: initialActive')
|
||||
|
||||
// Deactivate exchange
|
||||
await fixedRate.deactivate(publisher, exchangeId)
|
||||
await sleep(sleepMs)
|
||||
|
||||
// Check the updated value for active
|
||||
const updatedResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(deactiveQuery)
|
||||
})
|
||||
const updatedActive = (await updatedResponse.json()).data.fixedRateExchange
|
||||
|
||||
assert(updatedActive.active === false, 'incorrect value for: updatedActive')
|
||||
assert(
|
||||
updatedActive.eventIndex !== null && updatedActive.eventIndex >= 0,
|
||||
'incorrect value: eventIndex'
|
||||
)
|
||||
})
|
||||
|
||||
it('Activates exchange', async () => {
|
||||
const activeQuery = {
|
||||
query: `query {fixedRateExchange(id: "${fixedRateId}"){active, eventIndex}}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(activeQuery)
|
||||
})
|
||||
const initialActive = (await initialResponse.json()).data.fixedRateExchange
|
||||
.active
|
||||
assert(initialActive === false, 'incorrect value for: initialActive')
|
||||
|
||||
// Activate exchange
|
||||
await fixedRate.activate(publisher, exchangeId)
|
||||
await sleep(sleepMs)
|
||||
|
||||
// Check the updated value for active
|
||||
const updatedResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(activeQuery)
|
||||
})
|
||||
const updatedActive = (await updatedResponse.json()).data.fixedRateExchange
|
||||
assert(updatedActive.active === true, 'incorrect value for: updatedActive')
|
||||
assert(
|
||||
updatedActive.eventIndex !== null && updatedActive.eventIndex >= 0,
|
||||
'incorrect value: eventIndex'
|
||||
)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,337 @@
|
|||
import {
|
||||
DatatokenCreateParams,
|
||||
ProviderInstance,
|
||||
Nft,
|
||||
NftFactory,
|
||||
NftCreateData,
|
||||
getHash,
|
||||
sleep
|
||||
} from '@oceanprotocol/lib'
|
||||
import { assert } from 'chai'
|
||||
import Web3 from 'web3'
|
||||
import { SHA256 } from 'crypto-js'
|
||||
import { homedir } from 'os'
|
||||
import fs from 'fs'
|
||||
import { fetch } from 'cross-fetch'
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
|
||||
const data = JSON.parse(
|
||||
fs.readFileSync(
|
||||
process.env.ADDRESS_FILE ||
|
||||
`${homedir}/.ocean/ocean-contracts/artifacts/address.json`,
|
||||
'utf8'
|
||||
)
|
||||
)
|
||||
|
||||
const addresses = data.development
|
||||
const web3 = new Web3('http://127.0.0.1:8545')
|
||||
|
||||
const providerUrl = 'http://172.15.0.4:8030'
|
||||
const subgraphUrl =
|
||||
'http://127.0.0.1:9000/subgraphs/name/oceanprotocol/ocean-subgraph'
|
||||
const assetUrl = [
|
||||
{
|
||||
type: 'url',
|
||||
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
const ddo = {
|
||||
'@context': ['https://w3id.org/did/v1'],
|
||||
id: 'did:op:efba17455c127a885ec7830d687a8f6e64f5ba559f8506f8723c1f10f05c049c',
|
||||
version: '4.0.0',
|
||||
chainId: 4,
|
||||
nftAddress: '0x0',
|
||||
metadata: {
|
||||
created: '2021-12-20T14:35:20Z',
|
||||
updated: '2021-12-20T14:35:20Z',
|
||||
type: 'dataset',
|
||||
name: 'dfgdfgdg',
|
||||
description: 'd dfgd fgd dfg dfgdfgd dfgdf',
|
||||
tags: [''],
|
||||
author: 'dd',
|
||||
license: 'https://market.oceanprotocol.com/terms',
|
||||
additionalInformation: {
|
||||
termsAndConditions: true
|
||||
}
|
||||
},
|
||||
services: [
|
||||
{
|
||||
id: 'notAnId',
|
||||
type: 'access',
|
||||
files: '',
|
||||
datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3',
|
||||
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
|
||||
timeout: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
let nftTemplate
|
||||
|
||||
describe('NFT tests', async () => {
|
||||
const nftName = 'testNFT'
|
||||
const nftSymbol = 'TST'
|
||||
const tokenURI = 'https://oceanprotocol.com/nft/'
|
||||
let datatokenAddress: string
|
||||
let nft: Nft
|
||||
let Factory: NftFactory
|
||||
let factoryAddress: string
|
||||
let accounts: string[]
|
||||
let publisher: string
|
||||
let erc721Address: string
|
||||
let nftAddress: string
|
||||
let time: number
|
||||
let blockNumber: number
|
||||
|
||||
before(async () => {
|
||||
nft = new Nft(web3)
|
||||
factoryAddress = addresses.ERC721Factory.toLowerCase()
|
||||
Factory = new NftFactory(factoryAddress, web3)
|
||||
accounts = await web3.eth.getAccounts()
|
||||
publisher = accounts[0].toLowerCase()
|
||||
})
|
||||
|
||||
it('Should publish an NFT & datatoken', async () => {
|
||||
const date = new Date()
|
||||
time = Math.floor(date.getTime() / 1000)
|
||||
blockNumber = await web3.eth.getBlockNumber()
|
||||
|
||||
const nftParams: NftCreateData = {
|
||||
name: nftName,
|
||||
symbol: nftSymbol,
|
||||
templateIndex: 1,
|
||||
tokenURI,
|
||||
transferable: true,
|
||||
owner: publisher
|
||||
}
|
||||
const erc20Params: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
paymentCollector: '0x0000000000000000000000000000000000000000',
|
||||
feeToken: '0x0000000000000000000000000000000000000000',
|
||||
minter: publisher,
|
||||
mpFeeAddress: '0x0000000000000000000000000000000000000000'
|
||||
}
|
||||
const result = await Factory.createNftWithDatatoken(
|
||||
publisher,
|
||||
nftParams,
|
||||
erc20Params
|
||||
)
|
||||
erc721Address = result.events.NFTCreated.returnValues[0]
|
||||
datatokenAddress = result.events.TokenCreated.returnValues[0]
|
||||
nftTemplate = await Factory.getNFTTemplate(nftParams.templateIndex)
|
||||
// Check values before updating metadata
|
||||
await sleep(3000)
|
||||
nftAddress = erc721Address.toLowerCase()
|
||||
const initialQuery = {
|
||||
query: `query {
|
||||
nft(id:"${nftAddress}"){
|
||||
id,
|
||||
symbol,
|
||||
name,
|
||||
tokenUri,
|
||||
owner{id},
|
||||
creator{id},
|
||||
address,
|
||||
providerUrl,
|
||||
assetState,
|
||||
managerRole,
|
||||
erc20DeployerRole,
|
||||
storeUpdateRole,
|
||||
metadataRole,
|
||||
template,
|
||||
transferable,
|
||||
createdTimestamp,
|
||||
tx,
|
||||
eventIndex,
|
||||
block,
|
||||
orderCount}}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
await sleep(3000)
|
||||
const nft = (await initialResponse.json()).data.nft
|
||||
const tx: TransactionReceipt = await web3.eth.getTransactionReceipt(nft.tx)
|
||||
assert(nft.id === nftAddress, 'incorrect value for: id')
|
||||
assert(nft.symbol === nftSymbol, 'incorrect value for: symbol')
|
||||
assert(nft.name === nftName, 'incorrect value for: name')
|
||||
assert(nft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
|
||||
assert(nft.owner.id === publisher, 'incorrect value for: owner')
|
||||
assert(nft.creator.id === publisher, 'incorrect value for: creator')
|
||||
assert(nft.managerRole[0] === publisher, 'incorrect value for: managerRole')
|
||||
assert(
|
||||
nft.erc20DeployerRole[0] === factoryAddress,
|
||||
'incorrect value for: erc20DeployerRole'
|
||||
)
|
||||
assert(nft.storeUpdateRole === null, 'incorrect value for: storeUpdateRole')
|
||||
assert(nft.metadataRole === null, 'incorrect value for: metadataRole')
|
||||
assert(
|
||||
nft.template === nftTemplate.templateAddress.toLowerCase(),
|
||||
'incorrect value for: template'
|
||||
)
|
||||
assert(nft.transferable === true, 'incorrect value for: transferable')
|
||||
assert(
|
||||
nft.createdTimestamp >= time,
|
||||
'incorrect value for: createdTimestamp'
|
||||
)
|
||||
assert(
|
||||
nft.createdTimestamp < time + 5,
|
||||
'incorrect value for: createdTimestamp'
|
||||
)
|
||||
assert(tx.from === publisher, 'incorrect value for: tx')
|
||||
assert(tx.to === factoryAddress, 'incorrect value for: tx')
|
||||
assert(tx.blockNumber >= blockNumber, 'incorrect value for: tx')
|
||||
assert(nft.block >= blockNumber, 'incorrect value for: block')
|
||||
assert(nft.block < blockNumber + 50, 'incorrect value for: block')
|
||||
assert(nft.orderCount === '0', 'incorrect value for: orderCount')
|
||||
assert(
|
||||
nft.eventIndex !== null && nft.eventIndex > 0,
|
||||
'Invalid eventIndex for NFT creation'
|
||||
)
|
||||
})
|
||||
|
||||
it('Update metadata', async () => {
|
||||
const chain = await web3.eth.getChainId()
|
||||
// create the files encrypted string
|
||||
let providerResponse = await ProviderInstance.encrypt(
|
||||
assetUrl,
|
||||
chain,
|
||||
providerUrl
|
||||
)
|
||||
ddo.services[0].files = await providerResponse
|
||||
ddo.services[0].datatokenAddress = datatokenAddress
|
||||
// update ddo and set the right did
|
||||
ddo.nftAddress = erc721Address
|
||||
ddo.id =
|
||||
'did:op:' +
|
||||
SHA256(web3.utils.toChecksumAddress(erc721Address) + chain.toString(10))
|
||||
|
||||
providerResponse = await ProviderInstance.encrypt(ddo, chain, providerUrl)
|
||||
const encryptedResponse = await providerResponse
|
||||
const metadataHash = getHash(JSON.stringify(ddo))
|
||||
await nft.setMetadata(
|
||||
erc721Address,
|
||||
publisher,
|
||||
0,
|
||||
providerUrl,
|
||||
'',
|
||||
'0x2',
|
||||
encryptedResponse,
|
||||
'0x' + metadataHash
|
||||
)
|
||||
|
||||
// graph tests here
|
||||
await sleep(3000)
|
||||
const query = {
|
||||
query: `query {
|
||||
nft(id:"${nftAddress}"){
|
||||
id,
|
||||
symbol,
|
||||
name,
|
||||
tokenUri,
|
||||
owner{id},
|
||||
creator{id},
|
||||
address,
|
||||
providerUrl,
|
||||
assetState,
|
||||
managerRole,
|
||||
erc20DeployerRole,
|
||||
storeUpdateRole,
|
||||
metadataRole,
|
||||
template,
|
||||
transferable,
|
||||
createdTimestamp,
|
||||
tx,
|
||||
eventIndex,
|
||||
block,
|
||||
orderCount}}`
|
||||
}
|
||||
const response = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(query)
|
||||
})
|
||||
await sleep(3000)
|
||||
const updatedNft = (await response.json()).data.nft
|
||||
const tx: TransactionReceipt = await web3.eth.getTransactionReceipt(
|
||||
updatedNft.tx
|
||||
)
|
||||
assert(updatedNft.id === nftAddress, 'incorrect value for: id')
|
||||
assert(updatedNft.symbol === nftSymbol, 'incorrect value for: symbol')
|
||||
assert(updatedNft.name === nftName, 'incorrect value for: name')
|
||||
assert(updatedNft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
|
||||
assert(updatedNft.owner.id === publisher, 'incorrect value for: owner')
|
||||
assert(updatedNft.creator.id === publisher, 'incorrect value for: creator')
|
||||
assert(
|
||||
updatedNft.managerRole[0] === publisher,
|
||||
'incorrect value for: managerRole'
|
||||
)
|
||||
assert(
|
||||
updatedNft.erc20DeployerRole[0] === factoryAddress,
|
||||
'incorrect value for: erc20DeployerRole'
|
||||
)
|
||||
assert(
|
||||
updatedNft.storeUpdateRole === null,
|
||||
'incorrect value for: storeUpdateRole'
|
||||
)
|
||||
assert(
|
||||
updatedNft.metadataRole === null,
|
||||
'incorrect value for: metadataRole'
|
||||
)
|
||||
assert(
|
||||
updatedNft.template === nftTemplate.templateAddress.toLowerCase(),
|
||||
'incorrect value for: template'
|
||||
)
|
||||
assert(
|
||||
updatedNft.transferable === true,
|
||||
'incorrect value for: transferable'
|
||||
)
|
||||
assert(
|
||||
updatedNft.createdTimestamp >= time,
|
||||
'incorrect value for: createdTimestamp'
|
||||
)
|
||||
assert(
|
||||
updatedNft.createdTimestamp < time + 5,
|
||||
'incorrect value for: createdTimestamp'
|
||||
)
|
||||
assert(tx.from === publisher, 'incorrect value for: tx')
|
||||
assert(tx.to === factoryAddress, 'incorrect value for: tx')
|
||||
assert(tx.blockNumber >= blockNumber, 'incorrect value for: tx')
|
||||
assert(updatedNft.block >= blockNumber, 'incorrect value for: block')
|
||||
assert(updatedNft.block < blockNumber + 50, 'incorrect value for: block')
|
||||
assert(updatedNft.orderCount === '0', 'incorrect value for: orderCount')
|
||||
assert(
|
||||
updatedNft.eventIndex !== null && updatedNft.eventIndex > 0,
|
||||
'Invalid eventIndex for NFT update'
|
||||
)
|
||||
})
|
||||
|
||||
it('Set a key/value in erc725 store', async () => {
|
||||
await nft.setData(nftAddress, publisher, 'test_key', 'test_value')
|
||||
await sleep(2000)
|
||||
const query = {
|
||||
query: `query {
|
||||
nft(id:"${nftAddress}"){
|
||||
nftData{
|
||||
id
|
||||
key
|
||||
value
|
||||
}
|
||||
eventIndex
|
||||
}
|
||||
}`
|
||||
}
|
||||
const response = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(query)
|
||||
})
|
||||
const updatedNft = (await response.json()).data.nft
|
||||
assert(updatedNft.nftData.key !== null, 'incorrect value for key')
|
||||
assert(
|
||||
updatedNft.eventIndex !== null && updatedNft.eventIndex > 0,
|
||||
'Invalid eventIndex for NFT update'
|
||||
)
|
||||
})
|
||||
})
|
|
@ -1,14 +1,15 @@
|
|||
import {
|
||||
// Aquarius,
|
||||
// Datatoken,
|
||||
Erc20CreateParams,
|
||||
Datatoken,
|
||||
DatatokenCreateParams,
|
||||
ProviderInstance,
|
||||
// ProviderFees,
|
||||
ProviderFees,
|
||||
Nft,
|
||||
NftFactory,
|
||||
NftCreateData,
|
||||
getHash,
|
||||
sleep
|
||||
sleep,
|
||||
ZERO_ADDRESS,
|
||||
signHash
|
||||
} from '@oceanprotocol/lib'
|
||||
import { assert } from 'chai'
|
||||
import Web3 from 'web3'
|
||||
|
@ -26,7 +27,6 @@ const data = JSON.parse(
|
|||
)
|
||||
|
||||
const addresses = data.development
|
||||
// const aquarius = new Aquarius('http://127.0.0.1:5000')
|
||||
const web3 = new Web3('http://127.0.0.1:8545')
|
||||
|
||||
const providerUrl = 'http://172.15.0.4:8030'
|
||||
|
@ -71,12 +71,31 @@ const ddo = {
|
|||
}
|
||||
|
||||
describe('Simple Publish & consume test', async () => {
|
||||
let datatokenAddress: string
|
||||
let datatoken: Datatoken
|
||||
let nft: Nft
|
||||
let Factory: NftFactory
|
||||
let accounts: string[]
|
||||
let publisherAccount: string
|
||||
let newOwnerAccount: string
|
||||
let user1: string
|
||||
let user2: string
|
||||
let user3: string
|
||||
let user4: string
|
||||
|
||||
before(async () => {
|
||||
nft = new Nft(web3)
|
||||
Factory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
accounts = await web3.eth.getAccounts()
|
||||
publisherAccount = accounts[0]
|
||||
newOwnerAccount = accounts[1].toLowerCase()
|
||||
user1 = accounts[2]
|
||||
user2 = accounts[3]
|
||||
user3 = accounts[4]
|
||||
user4 = accounts[5]
|
||||
})
|
||||
|
||||
it('should publish a dataset (create NFT + ERC20)', async () => {
|
||||
const nft = new Nft(web3)
|
||||
// const datatoken = new Datatoken(web3)
|
||||
const Factory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
const accounts = await web3.eth.getAccounts()
|
||||
const publisherAccount = accounts[0]
|
||||
// const consumerAccount = accounts[1]
|
||||
const nftParams: NftCreateData = {
|
||||
name: 'testNFT',
|
||||
|
@ -86,7 +105,7 @@ describe('Simple Publish & consume test', async () => {
|
|||
transferable: true,
|
||||
owner: publisherAccount
|
||||
}
|
||||
const erc20Params: Erc20CreateParams = {
|
||||
const erc20Params: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
|
@ -95,26 +114,30 @@ describe('Simple Publish & consume test', async () => {
|
|||
minter: publisherAccount,
|
||||
mpFeeAddress: '0x0000000000000000000000000000000000000000'
|
||||
}
|
||||
const result = await Factory.createNftWithErc20(
|
||||
const result = await Factory.createNftWithDatatoken(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
erc20Params
|
||||
)
|
||||
const erc721Address = result.events.NFTCreated.returnValues[0]
|
||||
const datatokenAddress = result.events.TokenCreated.returnValues[0]
|
||||
datatokenAddress = result.events.TokenCreated.returnValues[0]
|
||||
|
||||
const chain = await web3.eth.getChainId()
|
||||
// create the files encrypted string
|
||||
let providerResponse = await ProviderInstance.encrypt(assetUrl, providerUrl)
|
||||
let providerResponse = await ProviderInstance.encrypt(
|
||||
assetUrl,
|
||||
chain,
|
||||
providerUrl
|
||||
)
|
||||
ddo.services[0].files = await providerResponse
|
||||
ddo.services[0].datatokenAddress = datatokenAddress
|
||||
// update ddo and set the right did
|
||||
ddo.nftAddress = erc721Address
|
||||
const chain = await web3.eth.getChainId()
|
||||
ddo.id =
|
||||
'did:op:' +
|
||||
SHA256(web3.utils.toChecksumAddress(erc721Address) + chain.toString(10))
|
||||
|
||||
providerResponse = await ProviderInstance.encrypt(ddo, providerUrl)
|
||||
providerResponse = await ProviderInstance.encrypt(ddo, chain, providerUrl)
|
||||
const encryptedResponse = await providerResponse
|
||||
const metadataHash = getHash(JSON.stringify(ddo))
|
||||
await nft.setMetadata(
|
||||
|
@ -127,78 +150,28 @@ describe('Simple Publish & consume test', async () => {
|
|||
encryptedResponse,
|
||||
'0x' + metadataHash
|
||||
)
|
||||
// const resolvedDDO = await aquarius.waitForAqua(ddo.id)
|
||||
// assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
|
||||
|
||||
// graph tests here
|
||||
await sleep(2000)
|
||||
await sleep(3000)
|
||||
const graphNftToken = erc721Address.toLowerCase()
|
||||
const query = {
|
||||
query: `query {
|
||||
nft(id:"${graphNftToken}"){symbol,id}}`
|
||||
nft(id:"${graphNftToken}"){symbol,id,eventIndex}}`
|
||||
}
|
||||
const response = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(query)
|
||||
})
|
||||
await sleep(3000)
|
||||
const queryResult = await response.json()
|
||||
assert(queryResult.data.nft.id === graphNftToken)
|
||||
|
||||
/*
|
||||
|
||||
// mint 1 ERC20 and send it to the consumer
|
||||
await datatoken.mint(datatokenAddress, publisherAccount, '1', consumerAccount)
|
||||
// initialize provider
|
||||
const initializeData = await ProviderInstance.initialize(
|
||||
resolvedDDO.id,
|
||||
resolvedDDO.services[0].id,
|
||||
0,
|
||||
consumerAccount,
|
||||
providerUrl
|
||||
assert(
|
||||
queryResult.data.nft.eventIndex !== null &&
|
||||
queryResult.data.nft.eventIndex > 0,
|
||||
'Invalid eventIndex for NFT creation'
|
||||
)
|
||||
const providerFees: ProviderFees = {
|
||||
providerFeeAddress: initializeData.providerFee.providerFeeAddress,
|
||||
providerFeeToken: initializeData.providerFee.providerFeeToken,
|
||||
providerFeeAmount: initializeData.providerFee.providerFeeAmount,
|
||||
v: initializeData.providerFee.v,
|
||||
r: initializeData.providerFee.r,
|
||||
s: initializeData.providerFee.s,
|
||||
providerData: initializeData.providerFee.providerData,
|
||||
validUntil: initializeData.providerFee.validUntil
|
||||
}
|
||||
// make the payment
|
||||
const txid = await datatoken.startOrder(
|
||||
datatokenAddress,
|
||||
consumerAccount,
|
||||
consumerAccount,
|
||||
0,
|
||||
providerFees
|
||||
)
|
||||
// get the url
|
||||
const downloadURL = await ProviderInstance.getDownloadUrl(
|
||||
ddo.id,
|
||||
consumerAccount,
|
||||
ddo.services[0].id,
|
||||
0,
|
||||
txid.transactionHash,
|
||||
providerUrl,
|
||||
web3
|
||||
)
|
||||
assert(downloadURL, 'Provider getDownloadUrl failed')
|
||||
try {
|
||||
const fileData = await downloadFile(downloadURL)
|
||||
} catch (e) {
|
||||
assert.fail('Download failed')
|
||||
}
|
||||
*/
|
||||
})
|
||||
it('should publish and transfer an NFT', async () => {
|
||||
const nft = new Nft(web3)
|
||||
const Factory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
const accounts = await web3.eth.getAccounts()
|
||||
const publisherAccount = accounts[0]
|
||||
const newOwnerAccount = accounts[1].toLowerCase()
|
||||
|
||||
const nftParams: NftCreateData = {
|
||||
name: 'testNFT',
|
||||
symbol: 'TST',
|
||||
|
@ -207,7 +180,7 @@ describe('Simple Publish & consume test', async () => {
|
|||
transferable: true,
|
||||
owner: publisherAccount
|
||||
}
|
||||
const erc20Params: Erc20CreateParams = {
|
||||
const erc20Params: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
|
@ -216,43 +189,53 @@ describe('Simple Publish & consume test', async () => {
|
|||
minter: publisherAccount,
|
||||
mpFeeAddress: '0x0000000000000000000000000000000000000000'
|
||||
}
|
||||
const result = await Factory.createNftWithErc20(
|
||||
const result = await Factory.createNftWithDatatoken(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
erc20Params
|
||||
)
|
||||
await sleep(2000)
|
||||
await sleep(3000)
|
||||
const erc721Address = result.events.NFTCreated.returnValues[0]
|
||||
const datatokenAddress = result.events.TokenCreated.returnValues[0]
|
||||
const graphNftToken = erc721Address.toLowerCase()
|
||||
|
||||
const queryOriginalOwner = {
|
||||
query: `query {
|
||||
nft(id:"${graphNftToken}"){symbol,id,owner}}`
|
||||
nft(id:"${graphNftToken}"){symbol,id,owner{id},eventIndex}}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(queryOriginalOwner)
|
||||
})
|
||||
await sleep(3000)
|
||||
const initialResult = await initialResponse.json()
|
||||
// Checking original owner account has been set correctly
|
||||
assert(
|
||||
initialResult.data.nft.owner.toLowerCase() ===
|
||||
initialResult.data.nft.owner.id.toLowerCase() ===
|
||||
publisherAccount.toLowerCase()
|
||||
)
|
||||
assert(
|
||||
initialResult.data.nft.eventIndex !== null &&
|
||||
initialResult.data.nft.eventIndex > 0,
|
||||
'Invalid eventIndex for NFT creation'
|
||||
)
|
||||
|
||||
// create the files encrypted string
|
||||
let providerResponse = await ProviderInstance.encrypt(assetUrl, providerUrl)
|
||||
const chain = await web3.eth.getChainId()
|
||||
let providerResponse = await ProviderInstance.encrypt(
|
||||
assetUrl,
|
||||
chain,
|
||||
providerUrl
|
||||
)
|
||||
ddo.services[0].files = await providerResponse
|
||||
ddo.services[0].datatokenAddress = datatokenAddress
|
||||
// update ddo and set the right did
|
||||
ddo.nftAddress = erc721Address
|
||||
const chain = await web3.eth.getChainId()
|
||||
ddo.id =
|
||||
'did:op:' +
|
||||
SHA256(web3.utils.toChecksumAddress(erc721Address) + chain.toString(10))
|
||||
|
||||
providerResponse = await ProviderInstance.encrypt(ddo, providerUrl)
|
||||
providerResponse = await ProviderInstance.encrypt(ddo, chain, providerUrl)
|
||||
const encryptedResponse = await providerResponse
|
||||
const metadataHash = getHash(JSON.stringify(ddo))
|
||||
await nft.setMetadata(
|
||||
|
@ -265,20 +248,268 @@ describe('Simple Publish & consume test', async () => {
|
|||
encryptedResponse,
|
||||
'0x' + metadataHash
|
||||
)
|
||||
await sleep(2000)
|
||||
await sleep(3000)
|
||||
|
||||
// Transfer the NFT
|
||||
await nft.transferNft(graphNftToken, publisherAccount, newOwnerAccount)
|
||||
await sleep(2000)
|
||||
await sleep(3000)
|
||||
const query2 = {
|
||||
query: `query {
|
||||
nft(id:"${graphNftToken}"){symbol,id,owner, transferable}}`
|
||||
nft(id:"${graphNftToken}"){symbol,id,owner{id}, transferable, eventIndex}}`
|
||||
}
|
||||
const response = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(query2)
|
||||
})
|
||||
await sleep(3000)
|
||||
const queryResult = await response.json()
|
||||
assert(queryResult.data.nft.owner === newOwnerAccount)
|
||||
assert(queryResult.data.nft.owner.id === newOwnerAccount)
|
||||
assert(
|
||||
queryResult.data.nft.eventIndex !== null &&
|
||||
queryResult.data.nft.eventIndex > 0,
|
||||
'Invalid eventIndex for NFT creation'
|
||||
)
|
||||
})
|
||||
|
||||
it('should save provider fees after startOrder is called', async () => {
|
||||
datatoken = new Datatoken(web3, 8996)
|
||||
await datatoken.mint(datatokenAddress, publisherAccount, '100', user1)
|
||||
const user1Balance = await datatoken.balance(datatokenAddress, user1)
|
||||
assert(user1Balance === '100', 'user1 has no datatokens')
|
||||
|
||||
const providerData = JSON.stringify({ timeout: 0 })
|
||||
const providerFeeToken = ZERO_ADDRESS
|
||||
const providerFeeAmount = '10000'
|
||||
const providerValidUntil = '0'
|
||||
const message = web3.utils.soliditySha3(
|
||||
{ t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) },
|
||||
{ t: 'address', v: user3 },
|
||||
{ t: 'address', v: providerFeeToken },
|
||||
{ t: 'uint256', v: providerFeeAmount },
|
||||
{ t: 'uint256', v: providerValidUntil }
|
||||
)
|
||||
const { v, r, s } = await signHash(web3, message, user3)
|
||||
const setProviderFee: ProviderFees = {
|
||||
providerFeeAddress: user3,
|
||||
providerFeeToken,
|
||||
providerFeeAmount,
|
||||
v,
|
||||
r,
|
||||
s,
|
||||
providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData)),
|
||||
validUntil: providerValidUntil
|
||||
}
|
||||
const orderTx = await datatoken.startOrder(
|
||||
datatokenAddress,
|
||||
user1,
|
||||
user2,
|
||||
1,
|
||||
setProviderFee
|
||||
)
|
||||
await sleep(3000)
|
||||
const orderId = `${orderTx.transactionHash.toLowerCase()}-${datatokenAddress.toLowerCase()}-${user1.toLowerCase()}-${orderTx.events.OrderStarted.logIndex.toFixed(
|
||||
1
|
||||
)}`
|
||||
const query = {
|
||||
query: `query {order(id:"${orderId}"){id, providerFee, lastPriceToken{id}, eventIndex}}`
|
||||
}
|
||||
|
||||
await sleep(3000)
|
||||
const response = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(query)
|
||||
})
|
||||
await sleep(3000)
|
||||
const queryResult = await response.json()
|
||||
|
||||
const providerFeeJSON = JSON.parse(queryResult.data.order.providerFee)
|
||||
const lastPriceToken = queryResult.data.order.lastPriceToken.id
|
||||
|
||||
assert(lastPriceToken === ZERO_ADDRESS, 'Wrong lastPriceToken')
|
||||
|
||||
assert(
|
||||
providerFeeJSON.providerFeeAddress.toLowerCase() ===
|
||||
setProviderFee.providerFeeAddress.toLowerCase(),
|
||||
'Wrong providerFeeAddress set'
|
||||
)
|
||||
assert(
|
||||
providerFeeJSON.providerFeeAmount.toLowerCase() ===
|
||||
setProviderFee.providerFeeAmount.toLowerCase(),
|
||||
'Wrong providerFeeAmount set'
|
||||
)
|
||||
assert(
|
||||
providerFeeJSON.providerFeeToken.toLowerCase() ===
|
||||
setProviderFee.providerFeeToken.toLowerCase(),
|
||||
'Wrong providerFeeToken set'
|
||||
)
|
||||
assert(
|
||||
queryResult.data.order.eventIndex !== null,
|
||||
'Invalid eventIndex for order'
|
||||
)
|
||||
})
|
||||
|
||||
it('should save provider fees after calling reuseOrder on a using a previous txId', async () => {
|
||||
await datatoken.mint(datatokenAddress, publisherAccount, '100', user4)
|
||||
const user4Balance = await datatoken.balance(datatokenAddress, user4)
|
||||
assert(user4Balance === '100', 'publisherAccount has no datatokens')
|
||||
|
||||
const providerData = JSON.stringify({ timeout: 0 })
|
||||
const providerFeeToken = ZERO_ADDRESS
|
||||
let providerFeeAmount = '90'
|
||||
let providerValidUntil = '0'
|
||||
let message = web3.utils.soliditySha3(
|
||||
{ t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) },
|
||||
{ t: 'address', v: user3 },
|
||||
{ t: 'address', v: providerFeeToken },
|
||||
{ t: 'uint256', v: providerFeeAmount },
|
||||
{ t: 'uint256', v: providerValidUntil }
|
||||
)
|
||||
let { v, r, s } = await signHash(web3, message, user3)
|
||||
const setInitialProviderFee: ProviderFees = {
|
||||
providerFeeAddress: user3,
|
||||
providerFeeToken,
|
||||
providerFeeAmount,
|
||||
v,
|
||||
r,
|
||||
s,
|
||||
providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData)),
|
||||
validUntil: providerValidUntil
|
||||
}
|
||||
|
||||
const orderTx = await datatoken.startOrder(
|
||||
datatokenAddress,
|
||||
user4,
|
||||
user2,
|
||||
1,
|
||||
setInitialProviderFee
|
||||
)
|
||||
assert(orderTx.transactionHash, 'Failed to start order')
|
||||
|
||||
// Check initial provider fee has been set correctly
|
||||
const orderId = `${orderTx.transactionHash.toLowerCase()}-${datatokenAddress.toLowerCase()}-${user4.toLowerCase()}-${orderTx.events.OrderStarted.logIndex.toFixed(
|
||||
1
|
||||
)}`
|
||||
|
||||
const initialQuery = {
|
||||
query: `query {order(id:"${orderId}"){id, providerFee, lastPriceToken{id}, eventIndex}}`
|
||||
}
|
||||
await sleep(3000)
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
await sleep(3000)
|
||||
const initialQueryResult = await initialResponse.json()
|
||||
const initialProviderFeeJSON = JSON.parse(
|
||||
initialQueryResult.data.order.providerFee
|
||||
)
|
||||
const lastPriceToken = initialQueryResult.data.order.lastPriceToken.id
|
||||
|
||||
assert(lastPriceToken === ZERO_ADDRESS, 'Wrong initial lastPriceToken set')
|
||||
assert(
|
||||
initialProviderFeeJSON.providerFeeAddress.toLowerCase() ===
|
||||
setInitialProviderFee.providerFeeAddress.toLowerCase(),
|
||||
'Wrong initial providerFeeAddress set'
|
||||
)
|
||||
assert(
|
||||
initialProviderFeeJSON.providerFeeAmount.toLowerCase() ===
|
||||
setInitialProviderFee.providerFeeAmount.toLowerCase(),
|
||||
'Wrong initial providerFeeAmount set'
|
||||
)
|
||||
assert(
|
||||
initialProviderFeeJSON.providerFeeToken.toLowerCase() ===
|
||||
setInitialProviderFee.providerFeeToken.toLowerCase(),
|
||||
'Wrong initial providerFeeToken set'
|
||||
)
|
||||
assert(
|
||||
initialQueryResult.data.order.eventIndex !== null,
|
||||
'Invalid eventIndex for order'
|
||||
)
|
||||
|
||||
providerFeeAmount = '990000'
|
||||
providerValidUntil = '10000'
|
||||
message = web3.utils.soliditySha3(
|
||||
{ t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) },
|
||||
{ t: 'address', v: user3 },
|
||||
{ t: 'address', v: providerFeeToken },
|
||||
{ t: 'uint256', v: providerFeeAmount },
|
||||
{ t: 'uint256', v: providerValidUntil }
|
||||
)
|
||||
const msgResult = await signHash(web3, message, user3)
|
||||
v = msgResult.v
|
||||
r = msgResult.r
|
||||
s = msgResult.s
|
||||
|
||||
const setNewProviderFee: ProviderFees = {
|
||||
providerFeeAddress: user3,
|
||||
providerFeeToken,
|
||||
providerFeeAmount,
|
||||
v,
|
||||
r,
|
||||
s,
|
||||
providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData)),
|
||||
validUntil: providerValidUntil
|
||||
}
|
||||
|
||||
const reusedOrder = await datatoken.reuseOrder(
|
||||
datatokenAddress,
|
||||
user4,
|
||||
orderTx.transactionHash,
|
||||
setNewProviderFee
|
||||
)
|
||||
|
||||
assert(reusedOrder.events.OrderReused.event === 'OrderReused')
|
||||
assert(reusedOrder.events.ProviderFee.event === 'ProviderFee')
|
||||
|
||||
sleep(4000)
|
||||
// Check the new provider fee has been set in OrderReuse
|
||||
|
||||
const reuseQuery = {
|
||||
query: `query {orderReuse(id:"${
|
||||
reusedOrder.transactionHash
|
||||
}-${reusedOrder.events.OrderReused.logIndex.toFixed(
|
||||
1
|
||||
)}"){id, providerFee, eventIndex}}`
|
||||
}
|
||||
|
||||
await sleep(2000)
|
||||
const response = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(reuseQuery)
|
||||
})
|
||||
|
||||
const reuseQueryResult = await response.json()
|
||||
|
||||
const reuseProviderFeeJSON = JSON.parse(
|
||||
reuseQueryResult.data.orderReuse.providerFee
|
||||
)
|
||||
|
||||
assert(
|
||||
reuseProviderFeeJSON.providerFeeAddress.toLowerCase() ===
|
||||
setNewProviderFee.providerFeeAddress.toLowerCase(),
|
||||
'New providerFeeAddress set in reuse order is wrong'
|
||||
)
|
||||
assert(
|
||||
reuseProviderFeeJSON.providerFeeAmount.toLowerCase() ===
|
||||
setNewProviderFee.providerFeeAmount.toLowerCase(),
|
||||
'New providerFeeAmount set in reuse order is wrong'
|
||||
)
|
||||
assert(
|
||||
reuseProviderFeeJSON.providerFeeToken.toLowerCase() ===
|
||||
setNewProviderFee.providerFeeToken.toLowerCase(),
|
||||
'New providerFeeToken set in reuse order is wrong'
|
||||
)
|
||||
assert(
|
||||
reuseQueryResult.data.orderReuse.eventIndex !== null,
|
||||
'Invalid eventIndex for reuse order'
|
||||
)
|
||||
assert(
|
||||
reuseQueryResult.data.orderReuse.eventIndex === 0,
|
||||
'Invalid reuse order event index'
|
||||
)
|
||||
assert(
|
||||
initialQueryResult.data.order.eventIndex === 0,
|
||||
'Invalid start order event index'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
import {
|
||||
DatatokenCreateParams,
|
||||
Nft,
|
||||
NftFactory,
|
||||
NftCreateData,
|
||||
sleep
|
||||
} from '@oceanprotocol/lib'
|
||||
import { assert } from 'chai'
|
||||
import Web3 from 'web3'
|
||||
import { homedir } from 'os'
|
||||
import fs from 'fs'
|
||||
import { fetch } from 'cross-fetch'
|
||||
|
||||
const data = JSON.parse(
|
||||
fs.readFileSync(
|
||||
process.env.ADDRESS_FILE ||
|
||||
`${homedir}/.ocean/ocean-contracts/artifacts/address.json`,
|
||||
'utf8'
|
||||
)
|
||||
)
|
||||
|
||||
const addresses = data.development
|
||||
const web3 = new Web3('http://127.0.0.1:8545')
|
||||
|
||||
const subgraphUrl =
|
||||
'http://127.0.0.1:9000/subgraphs/name/oceanprotocol/ocean-subgraph'
|
||||
|
||||
describe('Tests coverage without provider/aquarius', async () => {
|
||||
let nft: Nft
|
||||
let Factory: NftFactory
|
||||
let accounts: string[]
|
||||
let publisherAccount: string
|
||||
let newOwnerAccount: string
|
||||
let time: number
|
||||
|
||||
before(async () => {
|
||||
nft = new Nft(web3)
|
||||
Factory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
accounts = await web3.eth.getAccounts()
|
||||
publisherAccount = accounts[0]
|
||||
newOwnerAccount = accounts[1].toLowerCase()
|
||||
const date = new Date()
|
||||
time = Math.floor(date.getTime() / 1000)
|
||||
})
|
||||
|
||||
it('should publish a dataset (create NFT + ERC20)', async () => {
|
||||
const nftParams: NftCreateData = {
|
||||
name: 'testNFT',
|
||||
symbol: 'TST',
|
||||
templateIndex: 1,
|
||||
tokenURI: '',
|
||||
transferable: true,
|
||||
owner: publisherAccount
|
||||
}
|
||||
const erc20Params: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
paymentCollector: '0x0000000000000000000000000000000000000000',
|
||||
feeToken: '0x0000000000000000000000000000000000000000',
|
||||
minter: publisherAccount,
|
||||
mpFeeAddress: '0x0000000000000000000000000000000000000000'
|
||||
}
|
||||
const result = await Factory.createNftWithDatatoken(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
erc20Params
|
||||
)
|
||||
const erc721Address = result.events.NFTCreated.returnValues[0]
|
||||
|
||||
// graph tests here
|
||||
await sleep(3000)
|
||||
const graphNftToken = erc721Address.toLowerCase()
|
||||
const query = {
|
||||
query: `query {
|
||||
nft(id:"${graphNftToken}"){symbol,id,eventIndex}}`
|
||||
}
|
||||
const response = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(query)
|
||||
})
|
||||
await sleep(3000)
|
||||
const queryResult = await response.json()
|
||||
assert(queryResult.data.nft.id === graphNftToken)
|
||||
assert(
|
||||
queryResult.data.nft.eventIndex !== null &&
|
||||
queryResult.data.nft.eventIndex > 0
|
||||
)
|
||||
})
|
||||
|
||||
it('should publish and transfer an NFT', async () => {
|
||||
const nftParams: NftCreateData = {
|
||||
name: 'testNFT',
|
||||
symbol: 'TST',
|
||||
templateIndex: 1,
|
||||
tokenURI: '',
|
||||
transferable: true,
|
||||
owner: publisherAccount
|
||||
}
|
||||
const erc20Params: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
paymentCollector: '0x0000000000000000000000000000000000000000',
|
||||
feeToken: '0x0000000000000000000000000000000000000000',
|
||||
minter: publisherAccount,
|
||||
mpFeeAddress: '0x0000000000000000000000000000000000000000'
|
||||
}
|
||||
const result = await Factory.createNftWithDatatoken(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
erc20Params
|
||||
)
|
||||
await sleep(3000)
|
||||
const erc721Address = result.events.NFTCreated.returnValues[0]
|
||||
const nftAddress = erc721Address.toLowerCase()
|
||||
|
||||
// Transfer the NFT
|
||||
const tx = await nft.transferNft(
|
||||
nftAddress,
|
||||
publisherAccount,
|
||||
newOwnerAccount
|
||||
)
|
||||
|
||||
await sleep(3000)
|
||||
const query2 = {
|
||||
query: `query {
|
||||
nft(id:"${nftAddress}"){
|
||||
symbol,
|
||||
id,
|
||||
owner{id},
|
||||
transferable,
|
||||
transferHistory(orderBy: timestamp, orderDirection: desc){id,nft,oldOwner,newOwner,txId,eventIndex,timestamp,block}
|
||||
}}`
|
||||
}
|
||||
const response = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(query2)
|
||||
})
|
||||
await sleep(3000)
|
||||
const queryResult = await response.json()
|
||||
const transferHistory = queryResult.data.nft.transferHistory[0]
|
||||
|
||||
assert(queryResult.data.nft.owner.id === newOwnerAccount)
|
||||
assert(
|
||||
transferHistory.id ===
|
||||
`${nftAddress}-${
|
||||
tx.transactionHash
|
||||
}-${tx.events.Transfer.logIndex.toFixed(1)}`,
|
||||
'Invalid transferHistory Id'
|
||||
)
|
||||
assert(transferHistory.txId === tx.transactionHash, 'invalid txId')
|
||||
assert(
|
||||
transferHistory.eventIndex === tx.events.Transfer.logIndex,
|
||||
'invalid eventIndex'
|
||||
)
|
||||
assert(transferHistory.timestamp)
|
||||
|
||||
assert(transferHistory.timestamp >= time - 500, 'incorrect value timestamp')
|
||||
assert(transferHistory.timestamp < time + 500, 'incorrect value timestamp')
|
||||
assert(transferHistory.block === tx.blockNumber, 'blockNumber')
|
||||
})
|
||||
})
|
|
@ -0,0 +1,829 @@
|
|||
import {
|
||||
VeOcean,
|
||||
VeAllocate,
|
||||
NftFactory,
|
||||
calculateEstimatedGas,
|
||||
sendTx,
|
||||
approve,
|
||||
ConfigHelper,
|
||||
sleep,
|
||||
VeFeeDistributor
|
||||
} from '@oceanprotocol/lib'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
import { HttpProvider } from 'web3-providers-http'
|
||||
import { assert } from 'chai'
|
||||
import Web3 from 'web3'
|
||||
import { homedir } from 'os'
|
||||
import fs from 'fs'
|
||||
import { fetch } from 'cross-fetch'
|
||||
import veDelegation from '@oceanprotocol/contracts/artifacts/contracts/ve/veDelegation.vy/veDelegation.json'
|
||||
|
||||
const data = JSON.parse(
|
||||
fs.readFileSync(
|
||||
process.env.ADDRESS_FILE ||
|
||||
`${homedir}/.ocean/ocean-contracts/artifacts/address.json`,
|
||||
'utf8'
|
||||
)
|
||||
)
|
||||
|
||||
const addresses = data.development
|
||||
const web3 = new Web3('http://127.0.0.1:8545')
|
||||
|
||||
const subgraphUrl =
|
||||
'http://127.0.0.1:9000/subgraphs/name/oceanprotocol/ocean-subgraph'
|
||||
|
||||
function evmMine() {
|
||||
const provider = web3.currentProvider as HttpProvider
|
||||
return new Promise((resolve, reject) => {
|
||||
provider.send(
|
||||
{
|
||||
jsonrpc: '2.0',
|
||||
method: 'evm_mine',
|
||||
id: new Date().getTime()
|
||||
},
|
||||
(error, result) => {
|
||||
if (error) {
|
||||
return reject(error)
|
||||
}
|
||||
return resolve(result)
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
function evmIncreaseTime(seconds) {
|
||||
const provider = web3.currentProvider as HttpProvider
|
||||
return new Promise((resolve, reject) => {
|
||||
provider.send(
|
||||
{
|
||||
method: 'evm_increaseTime',
|
||||
params: [seconds],
|
||||
jsonrpc: '2.0',
|
||||
id: new Date().getTime()
|
||||
},
|
||||
(error, result) => {
|
||||
if (error) {
|
||||
return reject(error)
|
||||
}
|
||||
return evmMine().then(() => resolve(result))
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
async function getTotalLockedOcean() {
|
||||
const initialQuery = {
|
||||
query: `query{
|
||||
globalStatistics{
|
||||
totalOceanLocked
|
||||
}
|
||||
}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
const data = (await initialResponse.json()).data.globalStatistics
|
||||
if (data.length == 0) return 0
|
||||
|
||||
return data[0].totalOceanLocked
|
||||
}
|
||||
const minAbi = [
|
||||
{
|
||||
constant: false,
|
||||
inputs: [
|
||||
{ name: 'to', type: 'address' },
|
||||
{ name: 'value', type: 'uint256' }
|
||||
],
|
||||
name: 'mint',
|
||||
outputs: [{ name: '', type: 'bool' }],
|
||||
payable: false,
|
||||
stateMutability: 'nonpayable',
|
||||
type: 'function'
|
||||
}
|
||||
] as AbiItem[]
|
||||
|
||||
describe('veOcean tests', async () => {
|
||||
let nftFactory
|
||||
let veOcean: VeOcean
|
||||
let delegateContract
|
||||
let veAllocate: VeAllocate
|
||||
let veFeeDistributor: VeFeeDistributor
|
||||
let ownerAccount: string
|
||||
let Alice: string
|
||||
let Bob: string
|
||||
let nft1, nft2, nft3
|
||||
let chainId
|
||||
const configHelper = new ConfigHelper()
|
||||
const config = configHelper.getConfig('development')
|
||||
|
||||
before(async () => {
|
||||
const accounts = await web3.eth.getAccounts()
|
||||
chainId = await web3.eth.getChainId()
|
||||
ownerAccount = accounts[0]
|
||||
Alice = accounts[1]
|
||||
Bob = accounts[2]
|
||||
delegateContract = new web3.eth.Contract(
|
||||
veDelegation.abi as AbiItem[],
|
||||
addresses.veDelegation
|
||||
)
|
||||
|
||||
const tokenContract = new web3.eth.Contract(minAbi, addresses.Ocean)
|
||||
const estGas = await calculateEstimatedGas(
|
||||
ownerAccount,
|
||||
tokenContract.methods.mint,
|
||||
Alice,
|
||||
web3.utils.toWei('100000')
|
||||
)
|
||||
await sendTx(
|
||||
ownerAccount,
|
||||
estGas,
|
||||
web3,
|
||||
1,
|
||||
tokenContract.methods.mint,
|
||||
Alice,
|
||||
web3.utils.toWei('100000')
|
||||
)
|
||||
await sendTx(
|
||||
ownerAccount,
|
||||
estGas,
|
||||
web3,
|
||||
1,
|
||||
tokenContract.methods.mint,
|
||||
Bob,
|
||||
web3.utils.toWei('100000')
|
||||
)
|
||||
veOcean = new VeOcean(addresses.veOCEAN, web3)
|
||||
veAllocate = new VeAllocate(addresses.veAllocate, web3)
|
||||
nftFactory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
veFeeDistributor = new VeFeeDistributor(addresses.veFeeDistributor, web3)
|
||||
})
|
||||
|
||||
it('Alice should lock 100 Ocean', async () => {
|
||||
// since we can only lock once, we test if tx fails or not
|
||||
// so if there is already a lock, skip it
|
||||
const totalOceanLockedBefore = await getTotalLockedOcean()
|
||||
let currentBalance = await veOcean.getLockedAmount(Alice)
|
||||
let currentLock = await veOcean.lockEnd(Alice)
|
||||
const amount = '100'
|
||||
await approve(
|
||||
web3,
|
||||
config,
|
||||
Alice,
|
||||
addresses.Ocean,
|
||||
addresses.veOCEAN,
|
||||
amount
|
||||
)
|
||||
const timestamp = Math.floor(Date.now() / 1000)
|
||||
const unlockTime = timestamp + 7 * 86400
|
||||
|
||||
if (parseInt(currentBalance) > 0 || currentLock > 0) {
|
||||
// we already have some locked tokens, so our transaction should fail
|
||||
try {
|
||||
await veOcean.lockTokens(Alice, amount, unlockTime)
|
||||
assert(false, 'This should fail!')
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
}
|
||||
} else {
|
||||
await veOcean.lockTokens(Alice, amount, unlockTime)
|
||||
}
|
||||
currentBalance = await veOcean.getLockedAmount(Alice)
|
||||
currentLock = await veOcean.lockEnd(Alice)
|
||||
await sleep(2000)
|
||||
const totalOceanLockedAfter = await getTotalLockedOcean()
|
||||
assert(
|
||||
parseFloat(totalOceanLockedAfter) > parseFloat(totalOceanLockedBefore),
|
||||
'After (' +
|
||||
totalOceanLockedAfter +
|
||||
') shold be higher then ' +
|
||||
totalOceanLockedBefore
|
||||
)
|
||||
assert(
|
||||
parseFloat(totalOceanLockedAfter) ==
|
||||
parseFloat(totalOceanLockedBefore + amount),
|
||||
'Invalid totalOceanLockedAfter (' + totalOceanLockedAfter + ')'
|
||||
)
|
||||
const initialQuery = {
|
||||
query: `query {
|
||||
veOCEANs(id:"${Alice.toLowerCase()}"){
|
||||
id,
|
||||
lockedAmount,
|
||||
unlockTime
|
||||
}
|
||||
}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
const info = (await initialResponse.json()).data.veOCEANs
|
||||
assert(info[0].id === Alice.toLowerCase())
|
||||
assert(info[0].lockedAmount === currentBalance)
|
||||
assert(info[0].unlockTime === currentLock)
|
||||
})
|
||||
|
||||
it('Alice should increase the lock time', async () => {
|
||||
const currentLock = await veOcean.lockEnd(Alice)
|
||||
const newLock = parseInt(String(currentLock)) + 7 * 86400
|
||||
await veOcean.increaseUnlockTime(Alice, newLock)
|
||||
const newCurrentLock = await veOcean.lockEnd(Alice)
|
||||
await sleep(2000)
|
||||
const initialQuery = {
|
||||
query: `query {
|
||||
veOCEANs(id:"${Alice.toLowerCase()}"){
|
||||
id,
|
||||
lockedAmount,
|
||||
unlockTime
|
||||
}
|
||||
}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
const info = (await initialResponse.json()).data.veOCEANs
|
||||
assert(
|
||||
info[0].unlockTime === newCurrentLock,
|
||||
'Expected lock ' +
|
||||
newCurrentLock +
|
||||
' to equal subgraph value ' +
|
||||
info[0].unlockTime
|
||||
)
|
||||
})
|
||||
|
||||
it('Alice should increase the locked amount', async () => {
|
||||
const amount = '200'
|
||||
await approve(
|
||||
web3,
|
||||
config,
|
||||
Alice,
|
||||
addresses.Ocean,
|
||||
addresses.veOCEAN,
|
||||
amount
|
||||
)
|
||||
await veOcean.increaseAmount(Alice, amount)
|
||||
const newCurrentBalance = await veOcean.getLockedAmount(Alice)
|
||||
const newCurrentLock = await veOcean.lockEnd(Alice)
|
||||
await sleep(2000)
|
||||
const initialQuery = {
|
||||
query: `query {
|
||||
veOCEANs(id:"${Alice.toLowerCase()}"){
|
||||
id,
|
||||
lockedAmount,
|
||||
unlockTime
|
||||
}
|
||||
}`
|
||||
}
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
const info = (await initialResponse.json()).data.veOCEANs
|
||||
assert(
|
||||
info[0].unlockTime === newCurrentLock,
|
||||
'Expected lock ' +
|
||||
newCurrentLock +
|
||||
' to equal subgraph value ' +
|
||||
info[0].unlockTime
|
||||
)
|
||||
assert(
|
||||
info[0].lockedAmount === newCurrentBalance,
|
||||
'Expected balance ' +
|
||||
newCurrentBalance +
|
||||
' to equal subgraph value ' +
|
||||
info[0].lockedAmount
|
||||
)
|
||||
})
|
||||
|
||||
it('Alice should publish 3 NFTs', async () => {
|
||||
// publish 3 nfts
|
||||
nft1 = await nftFactory.createNFT(Alice, {
|
||||
name: 'testNft1',
|
||||
symbol: 'TSTF1',
|
||||
templateIndex: 1,
|
||||
tokenURI: '',
|
||||
transferable: true,
|
||||
owner: Alice
|
||||
})
|
||||
nft2 = await nftFactory.createNFT(Alice, {
|
||||
name: 'testNft2',
|
||||
symbol: 'TSTF2',
|
||||
templateIndex: 1,
|
||||
tokenURI: '',
|
||||
transferable: true,
|
||||
owner: Alice
|
||||
})
|
||||
nft3 = await nftFactory.createNFT(Alice, {
|
||||
name: 'testNft3',
|
||||
symbol: 'TSTF3',
|
||||
templateIndex: 1,
|
||||
tokenURI: '',
|
||||
transferable: true,
|
||||
owner: Alice
|
||||
})
|
||||
})
|
||||
|
||||
it('Alice should allocate 10% to NFT1', async () => {
|
||||
const tx = await veAllocate.setAllocation(Alice, '1000', nft1, chainId)
|
||||
const newTotalAllocation = await veAllocate.getTotalAllocation(Alice)
|
||||
await sleep(2000)
|
||||
let initialQuery = {
|
||||
query: `query {
|
||||
veAllocateUsers(id:"${Alice.toLowerCase()}"){
|
||||
id,
|
||||
allocatedTotal
|
||||
eventIndex
|
||||
}
|
||||
}`
|
||||
}
|
||||
let initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
let info = (await initialResponse.json()).data.veAllocateUsers
|
||||
assert(
|
||||
info[0].allocatedTotal === newTotalAllocation,
|
||||
'Expected totalAllocation ' +
|
||||
newTotalAllocation +
|
||||
' to equal subgraph value ' +
|
||||
info[0].allocatedTotal
|
||||
)
|
||||
assert(info[0].eventIndex === tx.events.AllocationSet.logIndex)
|
||||
initialQuery = {
|
||||
query: `query {
|
||||
veAllocations(
|
||||
where: {allocationUser:"${Alice.toLowerCase()}", chainId:"${chainId}", nftAddress:"${nft1.toLowerCase()}"}
|
||||
){
|
||||
id,
|
||||
allocated,
|
||||
eventIndex
|
||||
}
|
||||
}`
|
||||
}
|
||||
initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
info = (await initialResponse.json()).data.veAllocations
|
||||
assert(
|
||||
info[0].allocated === '1000',
|
||||
'Expected totalAllocation 1000 to equal subgraph value ' +
|
||||
info[0].allocatedTotal
|
||||
)
|
||||
assert(info[0].eventIndex === tx.events.AllocationSet.logIndex)
|
||||
})
|
||||
|
||||
it('Alice should allocate 10% to NFT2 and 20% to NFT3', async () => {
|
||||
const tx = await veAllocate.setBatchAllocation(
|
||||
Alice,
|
||||
['1000', '2000'],
|
||||
[nft2, nft3],
|
||||
[chainId, chainId]
|
||||
)
|
||||
const totalAllocation = await veAllocate.getTotalAllocation(Alice)
|
||||
|
||||
await sleep(2000)
|
||||
let initialQuery = {
|
||||
query: `query {
|
||||
veAllocateUsers(id:"${Alice.toLowerCase()}"){
|
||||
id,
|
||||
allocatedTotal,
|
||||
eventIndex
|
||||
}
|
||||
}`
|
||||
}
|
||||
let initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
let info = (await initialResponse.json()).data.veAllocateUsers
|
||||
assert(
|
||||
info[0].allocatedTotal === totalAllocation,
|
||||
'Expected totalAllocation ' +
|
||||
totalAllocation +
|
||||
' to equal subgraph value ' +
|
||||
info[0].allocatedTotal
|
||||
)
|
||||
assert(info[0].eventIndex === tx.events.AllocationSetMultiple.logIndex)
|
||||
initialQuery = {
|
||||
query: `query {
|
||||
veAllocations(
|
||||
where: {allocationUser:"${Alice.toLowerCase()}", chainId:"${chainId}", nftAddress:"${nft2.toLowerCase()}"}
|
||||
){
|
||||
id,
|
||||
allocated,
|
||||
eventIndex
|
||||
}
|
||||
}`
|
||||
}
|
||||
initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
info = (await initialResponse.json()).data.veAllocations
|
||||
assert(
|
||||
info[0].allocated === '1000',
|
||||
'Expected totalAllocation 1000 to equal subgraph value ' +
|
||||
info[0].allocatedTotal
|
||||
)
|
||||
assert(info[0].eventIndex === tx.events.AllocationSetMultiple.logIndex)
|
||||
initialQuery = {
|
||||
query: `query {
|
||||
veAllocations(
|
||||
where: {allocationUser:"${Alice.toLowerCase()}", chainId:"${chainId}", nftAddress:"${nft3.toLowerCase()}"}
|
||||
){
|
||||
id,
|
||||
allocated
|
||||
}
|
||||
}`
|
||||
}
|
||||
initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
info = (await initialResponse.json()).data.veAllocations
|
||||
assert(
|
||||
info[0].allocated === '2000',
|
||||
'Expected totalAllocation 1000 to equal subgraph value ' +
|
||||
info[0].allocatedTotal
|
||||
)
|
||||
})
|
||||
|
||||
it('Alice should advance chain one day', async () => {
|
||||
await evmIncreaseTime(60 * 60 * 24)
|
||||
})
|
||||
|
||||
it('Alice should add ocean rewards to feeDistrib', async () => {
|
||||
// mint 10 ocean and send them to feeDistrib
|
||||
let tokenContract = new web3.eth.Contract(minAbi, addresses.Ocean)
|
||||
let estGas = await calculateEstimatedGas(
|
||||
ownerAccount,
|
||||
tokenContract.methods.mint,
|
||||
addresses.veFeeDistributor,
|
||||
web3.utils.toWei('10')
|
||||
)
|
||||
await sendTx(
|
||||
ownerAccount,
|
||||
estGas,
|
||||
web3,
|
||||
1,
|
||||
tokenContract.methods.mint,
|
||||
addresses.veFeeDistributor,
|
||||
web3.utils.toWei('10')
|
||||
)
|
||||
const minAbiFee = [
|
||||
{
|
||||
name: 'checkpoint_token',
|
||||
outputs: [],
|
||||
inputs: [],
|
||||
stateMutability: 'nonpayable',
|
||||
type: 'function',
|
||||
gas: 820723
|
||||
},
|
||||
{
|
||||
name: 'checkpoint_total_supply',
|
||||
outputs: [],
|
||||
inputs: [],
|
||||
stateMutability: 'nonpayable',
|
||||
type: 'function',
|
||||
gas: 10592405
|
||||
}
|
||||
] as AbiItem[]
|
||||
tokenContract = new web3.eth.Contract(minAbiFee, addresses.veFeeDistributor)
|
||||
estGas = await calculateEstimatedGas(
|
||||
ownerAccount,
|
||||
tokenContract.methods.checkpoint_token
|
||||
)
|
||||
|
||||
await sendTx(
|
||||
ownerAccount,
|
||||
estGas,
|
||||
web3,
|
||||
1,
|
||||
tokenContract.methods.checkpoint_token
|
||||
)
|
||||
estGas = await calculateEstimatedGas(
|
||||
ownerAccount,
|
||||
tokenContract.methods.checkpoint_total_supply
|
||||
)
|
||||
await sendTx(
|
||||
ownerAccount,
|
||||
estGas,
|
||||
web3,
|
||||
1,
|
||||
tokenContract.methods.checkpoint_total_supply
|
||||
)
|
||||
})
|
||||
|
||||
it('Alice should advance chain 7 day', async () => {
|
||||
await evmIncreaseTime(60 * 60 * 24 * 7)
|
||||
})
|
||||
|
||||
it('Alice should add again ocean rewards to feeDistrib', async () => {
|
||||
// mint 20 ocean and send them to feeDistrib
|
||||
let tokenContract = new web3.eth.Contract(minAbi, addresses.Ocean)
|
||||
let estGas = await calculateEstimatedGas(
|
||||
ownerAccount,
|
||||
tokenContract.methods.mint,
|
||||
addresses.veFeeDistributor,
|
||||
web3.utils.toWei('20')
|
||||
)
|
||||
await sendTx(
|
||||
ownerAccount,
|
||||
estGas,
|
||||
web3,
|
||||
1,
|
||||
tokenContract.methods.mint,
|
||||
addresses.veFeeDistributor,
|
||||
web3.utils.toWei('20')
|
||||
)
|
||||
const minAbiFee = [
|
||||
{
|
||||
name: 'checkpoint_token',
|
||||
outputs: [],
|
||||
inputs: [],
|
||||
stateMutability: 'nonpayable',
|
||||
type: 'function',
|
||||
gas: 820723
|
||||
},
|
||||
{
|
||||
name: 'checkpoint_total_supply',
|
||||
outputs: [],
|
||||
inputs: [],
|
||||
stateMutability: 'nonpayable',
|
||||
type: 'function',
|
||||
gas: 10592405
|
||||
}
|
||||
] as AbiItem[]
|
||||
tokenContract = new web3.eth.Contract(minAbiFee, addresses.veFeeDistributor)
|
||||
estGas = await calculateEstimatedGas(
|
||||
ownerAccount,
|
||||
tokenContract.methods.checkpoint_token
|
||||
)
|
||||
await sendTx(
|
||||
ownerAccount,
|
||||
estGas,
|
||||
web3,
|
||||
1,
|
||||
tokenContract.methods.checkpoint_token
|
||||
)
|
||||
estGas = await calculateEstimatedGas(
|
||||
ownerAccount,
|
||||
tokenContract.methods.checkpoint_total_supply
|
||||
)
|
||||
await sendTx(
|
||||
ownerAccount,
|
||||
estGas,
|
||||
web3,
|
||||
1,
|
||||
tokenContract.methods.checkpoint_total_supply
|
||||
)
|
||||
})
|
||||
|
||||
it('Alice should advance chain 7 day', async () => {
|
||||
await evmIncreaseTime(60 * 60 * 24 * 7)
|
||||
})
|
||||
|
||||
it('Alice should claim rewards', async () => {
|
||||
await veFeeDistributor.claim(Alice)
|
||||
})
|
||||
it('Alice should withdraw locked tokens', async () => {
|
||||
await evmIncreaseTime(60 * 60 * 24 * 7)
|
||||
const totalOceanLockedBefore = await getTotalLockedOcean()
|
||||
await veOcean.withdraw(Alice)
|
||||
await sleep(2000)
|
||||
const totalOceanLockedAfter = await getTotalLockedOcean()
|
||||
assert(
|
||||
parseFloat(totalOceanLockedAfter) < parseFloat(totalOceanLockedBefore),
|
||||
'After (' +
|
||||
totalOceanLockedAfter +
|
||||
') shold be lower then ' +
|
||||
totalOceanLockedBefore
|
||||
)
|
||||
})
|
||||
|
||||
it('Alice should lock 100 Ocean and Delegate them to Bob', async () => {
|
||||
// since we can only lock once, we test if tx fails or not
|
||||
// so if there is already a lock, skip it
|
||||
let currentBalance = await veOcean.getLockedAmount(Alice)
|
||||
let currentLock = await veOcean.lockEnd(Alice)
|
||||
const amount = '100'
|
||||
await approve(
|
||||
web3,
|
||||
config,
|
||||
Alice,
|
||||
addresses.Ocean,
|
||||
addresses.veOCEAN,
|
||||
amount
|
||||
)
|
||||
const timestamp = Math.floor(Date.now() / 1000)
|
||||
const unlockTime = timestamp + 30 * 86400
|
||||
|
||||
if (parseInt(currentBalance) > 0 || currentLock > 0) {
|
||||
// we already have some locked tokens, so our transaction should fail
|
||||
try {
|
||||
await veOcean.lockTokens(Alice, amount, unlockTime)
|
||||
assert(false, 'This should fail!')
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
}
|
||||
} else {
|
||||
await veOcean.lockTokens(Alice, amount, unlockTime)
|
||||
}
|
||||
currentBalance = await veOcean.getLockedAmount(Alice)
|
||||
currentLock = await veOcean.lockEnd(Alice)
|
||||
await sleep(2000)
|
||||
const initialQuery = {
|
||||
query: `query {
|
||||
veOCEANs(id:"${Alice.toLowerCase()}"){
|
||||
id,
|
||||
lockedAmount,
|
||||
unlockTime
|
||||
}
|
||||
}`
|
||||
}
|
||||
await sleep(2000)
|
||||
|
||||
const initialResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(initialQuery)
|
||||
})
|
||||
await sleep(2000)
|
||||
const info = (await initialResponse.json()).data.veOCEANs
|
||||
assert(info[0].id === Alice.toLowerCase(), 'ID is incorrect')
|
||||
assert(info[0].lockedAmount === currentBalance, 'LockedAmount is incorrect')
|
||||
assert(info[0].unlockTime === currentLock, 'Unlock time is not correct')
|
||||
|
||||
const lockTime = await veOcean.lockEnd(Alice)
|
||||
const extLockTime = Number(lockTime) + 31556926
|
||||
|
||||
await delegateContract.methods.setApprovalForAll(Alice, true).send({
|
||||
from: Alice
|
||||
})
|
||||
|
||||
await veOcean.increaseUnlockTime(Alice, extLockTime)
|
||||
|
||||
const initalBoostExpiry = extLockTime - 100000
|
||||
let estGas = await calculateEstimatedGas(
|
||||
Alice,
|
||||
delegateContract.methods.create_boost,
|
||||
Alice,
|
||||
Bob,
|
||||
5000,
|
||||
0,
|
||||
initalBoostExpiry,
|
||||
0
|
||||
)
|
||||
|
||||
const tx3 = await sendTx(
|
||||
Alice,
|
||||
estGas,
|
||||
web3,
|
||||
1,
|
||||
delegateContract.methods.create_boost,
|
||||
Alice,
|
||||
Bob,
|
||||
5000,
|
||||
0,
|
||||
initalBoostExpiry,
|
||||
0
|
||||
)
|
||||
|
||||
assert(tx3, 'Transaction failed')
|
||||
assert(tx3.events.DelegateBoost, 'No Delegate boost event')
|
||||
const tokenId = tx3.events.DelegateBoost.returnValues._token_id
|
||||
await evmIncreaseTime(60)
|
||||
// extend boost
|
||||
estGas = await calculateEstimatedGas(
|
||||
Alice,
|
||||
delegateContract.methods.extend_boost,
|
||||
tokenId,
|
||||
10000,
|
||||
extLockTime,
|
||||
0
|
||||
)
|
||||
|
||||
const tx4 = await sendTx(
|
||||
Alice,
|
||||
estGas,
|
||||
web3,
|
||||
1,
|
||||
delegateContract.methods.extend_boost,
|
||||
tokenId,
|
||||
10000,
|
||||
extLockTime,
|
||||
0
|
||||
)
|
||||
|
||||
assert(tx4, 'Transaction failed')
|
||||
assert(tx4.events.ExtendBoost, 'No ExtendBoost event')
|
||||
await evmIncreaseTime(60)
|
||||
// burn it
|
||||
estGas = await calculateEstimatedGas(
|
||||
Alice,
|
||||
delegateContract.methods.cancel_boost,
|
||||
tokenId
|
||||
)
|
||||
|
||||
const tx5 = await sendTx(
|
||||
Alice,
|
||||
estGas,
|
||||
web3,
|
||||
1,
|
||||
delegateContract.methods.cancel_boost,
|
||||
tokenId
|
||||
)
|
||||
|
||||
assert(tx5, 'Transaction failed')
|
||||
assert(tx5.events.BurnBoost, 'No BurnBoost event')
|
||||
|
||||
await sleep(3000)
|
||||
const delegateQuery = {
|
||||
query: `query{
|
||||
veDelegations(where:{delegator:"${Alice.toLowerCase()}"}){
|
||||
id
|
||||
delegator {
|
||||
id
|
||||
}
|
||||
receiver{
|
||||
id
|
||||
}
|
||||
amount
|
||||
tokenId
|
||||
cancelTime
|
||||
expireTime
|
||||
updates(orderBy:timestamp orderDirection:asc){
|
||||
id
|
||||
block
|
||||
timestamp
|
||||
tx
|
||||
eventIndex
|
||||
sender
|
||||
amount
|
||||
cancelTime
|
||||
expireTime
|
||||
type
|
||||
}
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
const delegateResponse = await fetch(subgraphUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(delegateQuery)
|
||||
})
|
||||
const resp = await delegateResponse.json()
|
||||
const delegations = resp.data.veDelegations
|
||||
|
||||
assert(delegations.length > 0, 'No veDelegations')
|
||||
assert(
|
||||
delegations[0].tokenId.toLowerCase() ==
|
||||
tx3.events.DelegateBoost.returnValues._token_id.toLowerCase(),
|
||||
'Invalid tokenID'
|
||||
)
|
||||
assert(delegations[0].amount == '0', 'Invalid amount, should be 0')
|
||||
assert(delegations[0].updates.length > 0, 'No updates')
|
||||
// check updates. first is create boost
|
||||
assert(
|
||||
delegations[0].updates[0].type == 0,
|
||||
'Invalid type. should be createBoost'
|
||||
)
|
||||
assert(
|
||||
delegations[0].updates[0].cancelTime ==
|
||||
tx3.events.DelegateBoost.returnValues._cancel_time,
|
||||
'Invalid cancelTime'
|
||||
)
|
||||
assert(
|
||||
delegations[0].updates[0].expireTime ==
|
||||
tx3.events.DelegateBoost.returnValues._expire_time,
|
||||
'Invalid expireTime'
|
||||
)
|
||||
assert(
|
||||
web3.utils.toWei(delegations[0].updates[0].amount) ==
|
||||
tx3.events.DelegateBoost.returnValues._amount,
|
||||
'Invalid amount'
|
||||
)
|
||||
// check extend boos update
|
||||
assert(
|
||||
delegations[0].updates[1].type == 1,
|
||||
'Invalid type. should be extend Boost'
|
||||
)
|
||||
assert(
|
||||
delegations[0].updates[1].cancelTime ==
|
||||
tx4.events.ExtendBoost.returnValues._cancel_time,
|
||||
'Invalid cancelTime for extend boost'
|
||||
)
|
||||
assert(
|
||||
delegations[0].updates[1].expireTime ==
|
||||
tx4.events.ExtendBoost.returnValues._expire_time,
|
||||
'Invalid expireTime for extend boost'
|
||||
)
|
||||
assert(
|
||||
web3.utils.toWei(delegations[0].updates[1].amount) ==
|
||||
tx4.events.ExtendBoost.returnValues._amount,
|
||||
'Invalid amount for extend boost'
|
||||
)
|
||||
// check burn
|
||||
assert(delegations[0].updates[2].type == 2, 'Invalid type. should be burn')
|
||||
})
|
||||
})
|
|
@ -19,8 +19,8 @@ describe('Ending tests', () => {
|
|||
let result: any
|
||||
let lastblock
|
||||
it('Get Graph status', async () => {
|
||||
await sleep(1000) // let graph ingest our last transactions
|
||||
lastblock = await web3.eth.getBlockNumber()
|
||||
await sleep(3000) // let graph ingest our last transactions
|
||||
const query = {
|
||||
query: `query {
|
||||
_meta{hasIndexingErrors,
|
||||
|
@ -36,10 +36,10 @@ describe('Ending tests', () => {
|
|||
result = await response.json()
|
||||
})
|
||||
|
||||
it('Make sure that graph has no sync errors', async () => {
|
||||
it('Make sure that graph has no index errors', async () => {
|
||||
assert(result.data._meta.hasIndexingErrors == false)
|
||||
})
|
||||
it('Make sure that graph has synced to last block', async () => {
|
||||
assert(result.data._meta.block.number === lastblock)
|
||||
assert(result.data._meta.block.number >= lastblock)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -0,0 +1,278 @@
|
|||
import {
|
||||
DatatokenCreateParams,
|
||||
NftFactory,
|
||||
NftCreateData,
|
||||
sleep,
|
||||
FreCreationParams,
|
||||
ZERO_ADDRESS,
|
||||
FixedRateExchange,
|
||||
Datatoken,
|
||||
ProviderFees,
|
||||
signHash
|
||||
} from '@oceanprotocol/lib'
|
||||
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
|
||||
import { assert } from 'chai'
|
||||
import Web3 from 'web3'
|
||||
import { homedir } from 'os'
|
||||
import fs from 'fs'
|
||||
import { fetch } from 'cross-fetch'
|
||||
import { AbiItem } from 'web3-utils/types'
|
||||
|
||||
const sleepMs = 1700
|
||||
|
||||
const data = JSON.parse(
|
||||
fs.readFileSync(
|
||||
process.env.ADDRESS_FILE ||
|
||||
`${homedir}/.ocean/ocean-contracts/artifacts/address.json`,
|
||||
'utf8'
|
||||
)
|
||||
)
|
||||
async function userQuery(user: string) {
|
||||
const query = {
|
||||
query: `query {
|
||||
user(id:"${user}"){
|
||||
id
|
||||
tokenBalancesOwned {id}
|
||||
orders {id, lastPriceToken{id}}
|
||||
freSwaps {id}
|
||||
totalOrders
|
||||
totalSales
|
||||
__typename
|
||||
}}`
|
||||
}
|
||||
const response = await fetch(
|
||||
'http://127.0.0.1:9000/subgraphs/name/oceanprotocol/ocean-subgraph',
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify(query)
|
||||
}
|
||||
)
|
||||
const data = (await response.json()).data.user
|
||||
return data
|
||||
}
|
||||
|
||||
const addresses = data.development
|
||||
const web3 = new Web3('http://127.0.0.1:8545')
|
||||
|
||||
describe('User tests', async () => {
|
||||
const nftName = 'test-Fixed-Price-NFT'
|
||||
const nftSymbol = 'TST-FIXED'
|
||||
const tokenURI = 'https://oceanprotocol.com/nft/fixed'
|
||||
const cap = '10000'
|
||||
const feeAmount = '0.2'
|
||||
const price = '3'
|
||||
const publishMarketSwapFee = '0.003'
|
||||
const templateIndex = 1
|
||||
const dtAmount = '10'
|
||||
// const datatoken = new Datatoken(web3, 8996)
|
||||
let datatokenAddress: string
|
||||
let fixedRateAddress: string
|
||||
let baseTokenAddress: string
|
||||
let feeAddress: string
|
||||
let Factory: NftFactory
|
||||
let factoryAddress: string
|
||||
let accounts: string[]
|
||||
let contractDeployer: string
|
||||
let publisher: string
|
||||
let exchangeId: string
|
||||
let fixedRate: FixedRateExchange
|
||||
let user1: string
|
||||
let user2: string
|
||||
let user3: string
|
||||
|
||||
before(async () => {
|
||||
factoryAddress = addresses.ERC721Factory.toLowerCase()
|
||||
fixedRateAddress = addresses.FixedPrice.toLowerCase()
|
||||
baseTokenAddress = addresses.MockDAI.toLowerCase()
|
||||
Factory = new NftFactory(factoryAddress, web3)
|
||||
accounts = await web3.eth.getAccounts()
|
||||
contractDeployer = accounts[0].toLowerCase()
|
||||
feeAddress = accounts[1].toLowerCase()
|
||||
// Using different accounts from other tests to ensure that all user fields start at null
|
||||
publisher = accounts[6].toLowerCase()
|
||||
user1 = accounts[7].toLowerCase()
|
||||
user2 = accounts[8].toLowerCase()
|
||||
user3 = accounts[9].toLowerCase()
|
||||
})
|
||||
|
||||
it('Deploying a Fixed Rate Exchange & Test User Fields', async () => {
|
||||
const nftParams: NftCreateData = {
|
||||
name: nftName,
|
||||
symbol: nftSymbol,
|
||||
templateIndex: 1,
|
||||
tokenURI,
|
||||
transferable: true,
|
||||
owner: publisher
|
||||
}
|
||||
const erc20Params: DatatokenCreateParams = {
|
||||
templateIndex,
|
||||
cap,
|
||||
feeAmount,
|
||||
paymentCollector: ZERO_ADDRESS,
|
||||
feeToken: ZERO_ADDRESS,
|
||||
minter: publisher,
|
||||
mpFeeAddress: feeAddress
|
||||
}
|
||||
const fixedRateParams: FreCreationParams = {
|
||||
fixedRateAddress,
|
||||
baseTokenAddress,
|
||||
owner: publisher,
|
||||
marketFeeCollector: feeAddress,
|
||||
baseTokenDecimals: 18,
|
||||
datatokenDecimals: 18,
|
||||
fixedRate: price,
|
||||
marketFee: publishMarketSwapFee,
|
||||
allowedConsumer: ZERO_ADDRESS,
|
||||
withMint: true
|
||||
}
|
||||
|
||||
const result = await Factory.createNftWithDatatokenWithFixedRate(
|
||||
publisher,
|
||||
nftParams,
|
||||
erc20Params,
|
||||
fixedRateParams
|
||||
)
|
||||
datatokenAddress = result.events.TokenCreated.returnValues[0].toLowerCase()
|
||||
|
||||
exchangeId =
|
||||
result.events.NewFixedRate.returnValues.exchangeId.toLowerCase()
|
||||
|
||||
// Check User values
|
||||
await sleep(sleepMs)
|
||||
const user = await userQuery(publisher)
|
||||
|
||||
assert(user.id === publisher, 'incorrect value for: id')
|
||||
assert(user.tokenBalancesOwned.length === 0, 'incorrect tokenBalancesOwned')
|
||||
assert(user.orders.length === 0, 'incorrect value for: orders')
|
||||
assert(user.freSwaps.length === 0, 'incorrect value for: freSwaps')
|
||||
assert(user.totalOrders === '0', 'incorrect value for: totalOrders')
|
||||
assert(user.totalSales === '0', 'incorrect value for: totalSales')
|
||||
assert(user.__typename === 'User', 'incorrect value for: __typename')
|
||||
})
|
||||
|
||||
it('User1 buys a datatoken', async () => {
|
||||
const datatoken = new Datatoken(web3, 8996)
|
||||
// Mint datatokens as initial supply is 0
|
||||
await datatoken.mint(datatokenAddress, publisher, '100')
|
||||
await datatoken.approve(
|
||||
datatokenAddress,
|
||||
fixedRateAddress,
|
||||
'100',
|
||||
publisher
|
||||
)
|
||||
|
||||
const daiContract = new web3.eth.Contract(
|
||||
MockERC20.abi as AbiItem[],
|
||||
addresses.MockDAI
|
||||
)
|
||||
// user1 need DAI so that they can buy the datatoken
|
||||
await daiContract.methods
|
||||
.transfer(user1, web3.utils.toWei('100'))
|
||||
.send({ from: contractDeployer })
|
||||
await daiContract.methods
|
||||
.approve(fixedRateAddress, web3.utils.toWei('10000000'))
|
||||
.send({ from: user1 })
|
||||
|
||||
// user1 has no DTs before buying one
|
||||
let user1Balance = await datatoken.balance(datatokenAddress, user1)
|
||||
assert(user1Balance === '0', 'incorrect value for: user1Balance')
|
||||
|
||||
fixedRate = new FixedRateExchange(fixedRateAddress, web3, 8996)
|
||||
await fixedRate.buyDatatokens(user1, exchangeId, dtAmount, '100')
|
||||
await sleep(sleepMs)
|
||||
|
||||
user1Balance = await datatoken.balance(datatokenAddress, user1)
|
||||
// user1 has 1 datatoken
|
||||
assert(user1Balance === dtAmount, 'incorrect value for: user1Balance')
|
||||
|
||||
// Check User values
|
||||
const user = await userQuery(user1)
|
||||
|
||||
assert(user.id === user1, 'incorrect value for: id')
|
||||
assert(user.tokenBalancesOwned.length === 0, 'incorrect tokenBalancesOwned')
|
||||
assert(user.orders.length === 0, 'incorrect value for: orders')
|
||||
assert(user.freSwaps.length === 1, 'incorrect value for: freSwaps')
|
||||
assert(user.totalOrders === '0', 'incorrect value for: totalOrders')
|
||||
assert(user.totalSales === '0', 'incorrect value for: totalSales')
|
||||
assert(user.__typename === 'User', 'incorrect value for: __typename')
|
||||
})
|
||||
it('Check user fields after publishing & ordering a datatoken', async () => {
|
||||
// Start with publishing a new datatoken
|
||||
const nftParams: NftCreateData = {
|
||||
name: 'newNFT',
|
||||
symbol: 'newTST',
|
||||
templateIndex,
|
||||
tokenURI: '',
|
||||
transferable: true,
|
||||
owner: publisher
|
||||
}
|
||||
const erc20Params: DatatokenCreateParams = {
|
||||
templateIndex,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
paymentCollector: ZERO_ADDRESS,
|
||||
feeToken: ZERO_ADDRESS,
|
||||
minter: publisher,
|
||||
mpFeeAddress: feeAddress
|
||||
}
|
||||
const result = await Factory.createNftWithDatatoken(
|
||||
publisher,
|
||||
nftParams,
|
||||
erc20Params
|
||||
)
|
||||
const newDtAddress = result.events.TokenCreated.returnValues[0]
|
||||
|
||||
const datatoken = new Datatoken(web3, 8996)
|
||||
await datatoken.mint(newDtAddress, publisher, '100', user3)
|
||||
const user1balance = await datatoken.balance(newDtAddress, user3)
|
||||
assert(Number(user1balance) === 100, 'Invalid user1 balance')
|
||||
|
||||
const providerData = JSON.stringify({ timeout: 0 })
|
||||
const providerFeeToken = ZERO_ADDRESS
|
||||
const providerFeeAmount = '10000'
|
||||
const providerValidUntil = '0'
|
||||
const message = web3.utils.soliditySha3(
|
||||
{ t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) },
|
||||
{ t: 'address', v: feeAddress },
|
||||
{ t: 'address', v: providerFeeToken },
|
||||
{ t: 'uint256', v: providerFeeAmount },
|
||||
{ t: 'uint256', v: providerValidUntil }
|
||||
)
|
||||
assert(message, 'Invalid message')
|
||||
const { v, r, s } = await signHash(web3, message, feeAddress)
|
||||
const setProviderFee: ProviderFees = {
|
||||
providerFeeAddress: feeAddress,
|
||||
providerFeeToken,
|
||||
providerFeeAmount,
|
||||
v,
|
||||
r,
|
||||
s,
|
||||
providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData)),
|
||||
validUntil: providerValidUntil
|
||||
}
|
||||
assert(setProviderFee, 'Invalid setProviderFee')
|
||||
const orderTx = await datatoken.startOrder(
|
||||
newDtAddress,
|
||||
user3,
|
||||
user2,
|
||||
1,
|
||||
setProviderFee
|
||||
)
|
||||
assert(orderTx.events.OrderStarted, 'Invalid orderTx')
|
||||
|
||||
await sleep(2000)
|
||||
|
||||
const user = await userQuery(user3)
|
||||
assert(user.id === user3, 'incorrect value for: id')
|
||||
assert(user.tokenBalancesOwned.length === 0, 'incorrect tokenBalancesOwned')
|
||||
assert(user.orders.length === 1, 'incorrect value for: orders')
|
||||
assert(user.freSwaps.length === 0, 'incorrect value for: freSwaps')
|
||||
assert(user.totalOrders === '1', 'incorrect value for: totalOrders')
|
||||
assert(user.totalSales === '0', 'incorrect value for: totalSales')
|
||||
assert(user.__typename === 'User', 'incorrect value for: __typename')
|
||||
assert(
|
||||
user.orders[0].lastPriceToken.id === ZERO_ADDRESS,
|
||||
'incorrect value for: lastPriceToken'
|
||||
)
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue