Skip to content

Commit 2488e74

Browse files
chore: merge main
2 parents 393e7dc + d036a31 commit 2488e74

31 files changed

+1042
-560
lines changed

.eslintrc.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
env:
2+
browser: true
3+
es2021: true
4+
extends:
5+
- eslint:recommended
6+
- plugin:@typescript-eslint/recommended
7+
overrides: []
8+
parser: '@typescript-eslint/parser'
9+
parserOptions:
10+
ecmaVersion: latest
11+
sourceType: module
12+
plugins:
13+
- '@typescript-eslint'
14+
ignorePatterns:
15+
- "src/types/"
16+
rules:
17+
indent:
18+
- error
19+
- 2
20+
linebreak-style:
21+
- error
22+
- unix
23+
quotes:
24+
- error
25+
- double
26+
semi:
27+
- error
28+
- always

.github/workflows/test.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,18 @@ jobs:
1616
- name: Update
1717
run: sudo apt update
1818
- name: Install OS dependencies
19-
run: sudo apt install -y python3-dev
19+
run: sudo apt install -y python3-dev nodejs
2020

2121
- uses: actions/checkout@v3
2222
with:
2323
submodules: recursive
2424

25+
- name: Install linter dependencies
26+
run: yarn install
27+
28+
- name: Lint TypeScript
29+
run: yarn lint
30+
2531
- name: Start-up local test environment
2632
uses: isbang/[email protected]
2733
with:

docker-compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ services:
5656
"postgres":
5757
condition: service_healthy
5858
"subquery-node":
59-
condition: service_started
59+
condition: service_healthy
6060
restart: always
6161
environment:
6262
DB_USER: "subquery"
@@ -134,4 +134,4 @@ services:
134134
WASM_RELAYER_MNEMONIC: "all expect burger grit believe forest match math holiday polar roof soccer thank focus note lion gesture dream bounce pony whip scale group refuse"
135135
expose:
136136
- 3000 # REST API https://hermes.informal.systems/rest-api.html#endpoints
137-
- 3001 # prometheus telemetry
137+
- 3001 # prometheus telemetry

docs/introduction.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ Postgraphile plugins also play a critical role; in particular, the [connection-f
4040
### Pagination
4141
The graphql API implements [the connections specification](https://relay.dev/graphql/connections.htm) for pagination (see: [GraphQL pagination docs](https://graphql.org/learn/pagination/#end-of-list-counts-and-connections) for more).
4242

43-
!!! tip It is recommended to prefer using pagination operators by default (e.g. `first: <limit>`) to avoid unnecessary delays in query responses.
43+
!!! tip
44+
It is recommended to prefer using pagination operators by default (e.g. `first: <limit>`) to avoid unnecessary delays in query responses.
4445

4546
### Filtering
4647

k8s/subquery/templates/name/node.sts.yml renamed to k8s/subquery/templates/node/node.sts.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ spec:
2424
containers:
2525
- name: node
2626
image: "{{ .Values.subquery.node.image }}:{{ .Values.subquery.node.tag }}"
27-
args: ["-f=/app", "--db-schema=app", "--batch-size=1"]
27+
args: ["-f=/app", "--db-schema=app", "--batch-size={{ .Values.subquery.node.batchSize }}"]
2828
envFrom:
2929
- configMapRef:
3030
name: subquery-node-config

k8s/subquery/values.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ subquery:
55
startBlock: "827201"
66
networkEndpoint: https://rpc-dorado.fetch.ai:443
77
chainId: "dorado-1"
8+
batchSize: 1
89

910
api:
1011
image: gcr.io/fetch-ai-sandbox/subquery-api

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
"description": "This is the Fetch Ledger SubQuery project, an indexer for the Fetch network.",
55
"main": "dist/index.js",
66
"scripts": {
7+
"lint": "yarn eslint ./src",
8+
"lint:fix": "yarn eslint --fix ./src",
79
"build": "subql build",
810
"prepack": "rm -rf dist && npm build",
911
"test": "jest",
@@ -22,6 +24,9 @@
2224
"devDependencies": {
2325
"@cosmjs/stargate": "^0.28.9",
2426
"@subql/cli": "^1.1.0",
27+
"@typescript-eslint/eslint-plugin": "^5.40.0",
28+
"@typescript-eslint/parser": "^5.40.0",
29+
"eslint": "^8.25.0",
2530
"typescript": "^4.7.4"
2631
},
2732
"dependencies": {

project.yaml

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ repository: https://github.com/fetchai/ledger-subquery
1414
schema:
1515
file: ./schema.graphql
1616
network:
17-
chainId: dorado-1
18-
endpoint: https://rpc-dorado.fetch.ai:443
17+
chainId: fetchchain
18+
endpoint: http://fetch-node:26657
1919
chainTypes: # This is a beta feature that allows support for any Cosmos chain by importing the correct protobuf messages
2020
cosmos.slashing.v1beta1:
2121
file: "./proto/cosmos/slashing/v1beta1/tx.proto"
@@ -25,7 +25,7 @@ network:
2525
dictionary: https://api.subquery.network/sq/subquery/cosmos-fetch-ai-dictionary
2626
dataSources:
2727
- kind: cosmos/Runtime
28-
startBlock: 827201
28+
startBlock: 1
2929
mapping:
3030
file: "./dist/index.js"
3131
handlers:
@@ -38,32 +38,42 @@ dataSources:
3838
- handler: handleEvent
3939
kind: cosmos/EventHandler
4040
- handler: handleGovProposalVote
41-
kind: cosmos/MessageHandler
41+
kind: cosmos/EventHandler
4242
filter:
43-
type: "/cosmos.gov.v1beta1.MsgVote"
43+
type: "proposal_vote"
44+
messageFilter:
45+
type: "/cosmos.gov.v1beta1.MsgVote"
4446
- handler: handleDistDelegatorClaim
45-
kind: cosmos/MessageHandler
47+
kind: cosmos/EventHandler
4648
filter:
47-
type: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"
48-
- handler: handleExecuteContractMessage
49-
kind: cosmos/MessageHandler
49+
type: "withdraw_rewards"
50+
messageFilter:
51+
type: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"
52+
- handler: handleExecuteContractEvent
53+
kind: cosmos/EventHandler
5054
filter:
51-
type: "/cosmwasm.wasm.v1.MsgExecuteContract"
55+
type: "execute"
56+
messageFilter:
57+
type: "/cosmwasm.wasm.v1.MsgExecuteContract"
5258
- handler: handleLegacyBridgeSwap
53-
kind: cosmos/MessageHandler
59+
kind: cosmos/EventHandler
5460
filter:
55-
type: "/cosmwasm.wasm.v1.MsgExecuteContract"
56-
# Filter to only messages with the swap function call
57-
contractCall: "swap" # The name of the contract function that was called
61+
type: "execute"
62+
messageFilter:
63+
type: "/cosmwasm.wasm.v1.MsgExecuteContract"
64+
# Filter to only messages with the swap function call
65+
contractCall: "swap"
5866
- handler: handleNativeTransfer
59-
kind: cosmos/MessageHandler
67+
kind: cosmos/EventHandler
6068
filter:
61-
type: "/cosmos.bank.v1beta1.MsgSend"
69+
type: "transfer"
70+
messageFilter:
71+
type: "/cosmos.bank.v1beta1.MsgSend"
6272
- handler: handleDelegatorWithdrawRewardEvent
6373
kind: cosmos/EventHandler
6474
filter:
6575
type: "withdraw_rewards"
66-
# TODO: perhaps merge this handler config and that of Cw20BalanceTransfer
76+
# TODO: perhaps merge this handler config and that of Cw20BalanceTransfer
6777
- handler: handleCw20Transfer
6878
kind: cosmos/EventHandler
6979
filter:

scripts/genesis.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
db_port = env_db_port or args.db_port
3939
db_user = env_db_user or args.db_user
4040
db_pass = env_db_pass or args.db_pass
41-
db_schema = env_db_schema or args.db_schema
41+
db_schema = env_db_schema or args.db_schema or "app"
4242
db_name = env_db_name or args.db_name
4343

4444
# TODO: progress indicators (?)
@@ -53,7 +53,7 @@
5353
"dbname": db_name,
5454
"user": db_user,
5555
"password": db_pass,
56-
"options": "-c search_path=app"
56+
"options": f"-c search_path={db_schema}"
5757
}
5858

5959

scripts/node-entrypoint.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ if [[ ! -z "${NETWORK_ENDPOINT}" ]]; then
1818
fi
1919

2020
# run the main node
21-
exec /sbin/tini -- /usr/local/lib/node_modules/@subql/node-cosmos/bin/run
21+
exec /sbin/tini -- /usr/local/lib/node_modules/@subql/node-cosmos/bin/run "$@"

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
//Exports all handler functions
2-
export * from './mappings/mappingHandlers'
2+
export * from "./mappings/mappingHandlers";

src/mappings/bank/balanceChange.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import {CosmosEvent} from "@subql/types-cosmos";
2+
import {NativeBalanceChange, Transaction} from "../../types";
3+
import {checkBalancesAccount, messageId, parseCoins} from "../utils";
4+
5+
export async function saveNativeBalanceEvent(id: string, address: string, amount: bigint, denom: string, event: CosmosEvent) {
6+
await checkBalancesAccount(address, event.block.block.header.chainId);
7+
const nativeBalanceChangeEntity = NativeBalanceChange.create({
8+
id,
9+
balanceOffset: amount.valueOf(),
10+
denom,
11+
accountId: address,
12+
eventId: `${messageId(event)}-${event.idx}`,
13+
blockId: event.block.block.id,
14+
transactionId: event.tx.hash,
15+
});
16+
await nativeBalanceChangeEntity.save();
17+
}
18+
19+
async function saveNativeFeesEvent(event: CosmosEvent) {
20+
const transaction = await Transaction.get(event.tx.hash);
21+
const fees = transaction.fees[0], signer = transaction.signerAddress;
22+
const amount = fees.amount, denom = fees.denom;
23+
await saveNativeBalanceEvent(`${event.tx.hash}-fee`, signer, BigInt(0) - BigInt(amount), denom, event);
24+
}
25+
26+
export async function handleNativeBalanceDecrement(event: CosmosEvent): Promise<void> {
27+
logger.info(`[handleNativeBalanceDecrement] (tx ${event.tx.hash}): indexing event ${event.idx + 1} / ${event.tx.tx.events.length}`);
28+
logger.debug(`[handleNativeBalanceDecrement] (event.event): ${JSON.stringify(event.event, null, 2)}`);
29+
logger.debug(`[handleNativeBalanceDecrement] (event.log): ${JSON.stringify(event.log, null, 2)}`);
30+
31+
// sample event.event.attributes:
32+
// [
33+
// {"key":"spender","value":"fetch1jv65s3grqf6v6jl3dp4t6c9t9rk99cd85zdctg"},
34+
// {"key":"amount","value":"75462013217046121atestfet"},
35+
// {"key":"spender","value":"fetch1wurz7uwmvchhc8x0yztc7220hxs9jxdjdsrqmn"},
36+
// {"key":"amount","value":"100atestfet"}
37+
// ]
38+
const spendEvents = [];
39+
for (const [i, e] of Object.entries(event.event.attributes)) {
40+
if (e.key !== "spender") {
41+
continue;
42+
}
43+
const spender = e.value;
44+
const amountStr = event.event.attributes[parseInt(i) + 1].value;
45+
46+
const coin = parseCoins(amountStr)[0];
47+
const amount = BigInt(0) - BigInt(coin.amount); // save a negative amount for a "spend" event
48+
spendEvents.push({spender: spender, amount: amount, denom: coin.denom});
49+
}
50+
51+
52+
for (const [i, spendEvent] of Object.entries(spendEvents)) {
53+
await saveNativeBalanceEvent(`${messageId(event)}-spend-${i}`, spendEvent.spender, spendEvent.amount, spendEvent.denom, event);
54+
}
55+
await saveNativeFeesEvent(event);
56+
}
57+
58+
export async function handleNativeBalanceIncrement(event: CosmosEvent): Promise<void> {
59+
logger.info(`[handleNativeBalanceIncrement] (tx ${event.tx.hash}): indexing event ${event.idx + 1} / ${event.tx.tx.events.length}`);
60+
logger.debug(`[handleNativeBalanceIncrement] (event.event): ${JSON.stringify(event.event, null, 2)}`);
61+
logger.debug(`[handleNativeBalanceIncrement] (event.log): ${JSON.stringify(event.log, null, 2)}`);
62+
63+
// sample event.event.attributes:
64+
// [
65+
// {"key":"receiver","value":"fetch1jv65s3grqf6v6jl3dp4t6c9t9rk99cd85zdctg"},
66+
// {"key":"amount","value":"75462013217046121atestfet"},
67+
// {"key":"receiver","value":"fetch1wurz7uwmvchhc8x0yztc7220hxs9jxdjdsrqmn"},
68+
// {"key":"amount","value":"100atestfet"}
69+
// ]
70+
const receiveEvents = [];
71+
for (const [i, e] of Object.entries(event.event.attributes)) {
72+
if (e.key !== "receiver") {
73+
continue;
74+
}
75+
const receiver = e.value;
76+
const amountStr = event.event.attributes[parseInt(i) + 1].value;
77+
78+
const coin = parseCoins(amountStr)[0];
79+
const amount = BigInt(coin.amount);
80+
receiveEvents.push({receiver: receiver, amount: amount, denom: coin.denom});
81+
}
82+
83+
84+
for (const [i, receiveEvent] of Object.entries(receiveEvents)) {
85+
await saveNativeBalanceEvent(`${messageId(event)}-receive-${i}`, receiveEvent.receiver, receiveEvent.amount, receiveEvent.denom, event);
86+
}
87+
await saveNativeFeesEvent(event);
88+
}

src/mappings/bank/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./transfer";
2+
export * from "./balanceChange";

src/mappings/bank/transfer.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import {CosmosEvent, CosmosMessage} from "@subql/types-cosmos";
2+
import {NativeTransferMsg} from "../types";
3+
import {messageId} from "../utils";
4+
import {NativeTransfer} from "../../types";
5+
6+
export async function handleNativeTransfer(event: CosmosEvent): Promise<void> {
7+
const msg: CosmosMessage<NativeTransferMsg> = event.msg;
8+
logger.info(`[handleNativeTransfer] (tx ${msg.tx.hash}): indexing message ${msg.idx + 1} / ${msg.tx.decodedTx.body.messages.length}`);
9+
logger.debug(`[handleNativeTransfer] (msg.msg): ${JSON.stringify(msg.msg, null, 2)}`);
10+
11+
const fromAddress = msg.msg?.decodedMsg?.fromAddress;
12+
const toAddress = msg.msg?.decodedMsg?.toAddress;
13+
const amounts = msg.msg?.decodedMsg?.amount;
14+
15+
if (!fromAddress || !amounts || !toAddress) {
16+
logger.warn(`[handleNativeTransfer] (tx ${event.tx.hash}): cannot index event (event.event): ${JSON.stringify(event.event, null, 2)}`);
17+
return;
18+
}
19+
20+
// workaround: assuming one denomination per transfer message
21+
const denom = amounts[0].denom;
22+
const id = messageId(msg);
23+
const transferEntity = NativeTransfer.create({
24+
id,
25+
toAddress,
26+
fromAddress,
27+
amounts,
28+
denom,
29+
messageId: id,
30+
transactionId: msg.tx.hash,
31+
blockId: msg.block.block.id
32+
});
33+
34+
await transferEntity.save();
35+
}

src/mappings/dist/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./rewards";

0 commit comments

Comments
 (0)