Skip to content

Commit bb218a8

Browse files
authored
chore: update docs (#58)
1 parent db43843 commit bb218a8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+341
-304
lines changed

.env.example

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
NODE_ENV?
2+
TEST_GOLDRUSH_API_KEY?
3+
PORT?

.prettierrc.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@
1717
"vueIndentScriptAndStyle": false,
1818
"endOfLine": "lf",
1919
"embeddedLanguageFormatting": "auto",
20-
"singleAttributePerLine": false
20+
"singleAttributePerLine": false,
21+
"plugins": ["@trivago/prettier-plugin-sort-imports"]
2122
}

README.md

+15-57
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
<div align="center">
2-
<img alt="GoldRush Kit Logo" src="assets/goldrush-decoder-banner.png" style="max-width: 100%;"/>
2+
<img alt="GoldRush Kit Logo" src="./assets/goldrush-decoder-banner.png" style="max-width: 100%;"/>
33
</div>
44

55
<p align="center">
66
<img src="https://img.shields.io/github/license/covalenthq/goldrush-decoder" alt="MIT">
77
</p>
88

99
<h1 align="center">
10-
Decode unstructured, raw event logs into structured data with a simple API.
10+
Decode unstructured, raw event logs into structured data with a simple API.
1111
</h1>
1212

1313
<div align="center">
14-
Open-source. Public Good. 200+ Chains.
14+
Open-source. Public Good. 200+ Chains.
1515
</div>
1616

1717
<br>
@@ -39,9 +39,9 @@ This repository contains the logic for decoding a `raw_log_event` of a transacti
3939
```ts
4040
GoldRushDecoder.on(
4141
"<protocol-name>:<EventName>",
42-
["<chain_name_1>", "<chain_name_2>"],
42+
["<chain_name_1>", "<chain_name_2>", ...],
4343
ABI as Abi,
44-
async (log_event, tx, chain_name, covalent_client): Promise<EventType> => {
44+
async (log_event, tx, chain_name, covalent_client, options): Promise<EventType> => {
4545
<!-- decoding logic -->
4646
}
4747
);
@@ -52,33 +52,28 @@ This repository contains the logic for decoding a `raw_log_event` of a transacti
5252
1. **Event Id**: A case-sensitive string concatenation of the `protocol name` with the `event name` by a `:`.
5353
2. **Chain Names**: An array of all the chains the defined decoding function will run for.
5454
3. **ABI**: The ABI of the contract on which the event exists.
55-
4. **Decoding Function**: The actual decoding function, it has 3 arguments passed to it:
55+
4. **Decoding Function**: The actual decoding function, it has 5 arguments passed to it:
5656
1. `log_event`: The raw log event that is being decoded.
5757
2. `tx`: The transaction object that generated this log.
5858
3. `chain_name`: Name of the chain to which the log belongs to.
5959
4. `covalent_client`: The covalent client created with your covalent API key.
60+
5. `options`: Query parameters attached to the request for refining the response. These are of the following types
61+
1. `raw_logs`: A `boolean` that attaches the raw log of the event along with the decoded response
62+
2. `min_usd`: A minimum number value for a transaction to have to be decoded
6063

6164
3. `fallback`: Creates a fallback function for the specified event name. This function is not linked to any chain or contract. Its declaration is:
6265

6366
```ts
6467
GoldRushDecoder.fallback(
6568
"EventName",
6669
ABI as Abi,
67-
async (log_event, tx, chain_name, covalent_client): Promise<EventType> => {
70+
async (log_event, tx, chain_name, covalent_client, options): Promise<EventType> => {
6871
<!-- decoding logic -->
6972
}
7073
);
7174
```
7275

73-
The method has 3 arguments:
74-
75-
1. **Event Name**: A case-sensitive name of the event to be decoded.
76-
2. **ABI**: The ABI of the contract on which the event exists.
77-
3. **Decoding Function**: The actual decoding function, it has 3 arguments passed to it:
78-
1. `log_event`: The raw log event that is being decoded.
79-
2. `tx`: The transaction object that generated this log.
80-
3. `chain_name`: Name of the chain to which the log belongs to.
81-
4. `covalent_client`: The covalent client created with your covalent API key.
76+
The fallback method has all the same arguments as the [`on`](./README.md#knowledge-primer) arguments excluding the `Chain Names` array
8277

8378
4. `decode`: The function that chooses which decoding function needs to be called for which log event. It collects all the decoded events for a transaction and returns them in an array of structured data. It is run when the API server receives a request.
8479

@@ -92,7 +87,7 @@ Follow the following steps to start the development server of the **GoldRush Dec
9287
yarn install
9388
```
9489

95-
2. Setup the environmental variables. Refer to [.env.example](.env.example) for the list of environmental variables and store them in `.env` at the root level of the repository.
90+
2. Setup the environmental variables. Refer to [.env.example](./.env.example) for the list of environmental variables and store them in `.env` at the root level of the repository.
9691

9792
3. Start the server
9893

@@ -104,7 +99,7 @@ Follow the following steps to start the development server of the **GoldRush Dec
10499

105100
### 2. API Endpoints
106101

107-
1. `/api/v1`: The default endpoint for the v1 of the server. A header of the key `x-covalent-api-key` with the value as the [Covalent API key](https://www.covalenthq.com/platform/apikey/) is **mandatory** for the Decoder to work.
102+
1. `/api/v1`: The default endpoint for the v1 of the server. A header of the key `x-goldrush-api-key` with the value as the [GoldRush API key](https://goldrush.dev/platform/apikey/) is **mandatory** for the Decoder to work.
108103

109104
1. `/tx/decode`: Decodes a transaction of a chain.
110105

@@ -115,7 +110,7 @@ Follow the following steps to start the development server of the **GoldRush Dec
115110

116111
```bash
117112
curl --location 'http://localhost:<PORT>/api/v1/tx/decode' \
118-
--header 'x-covalent-api-key: <COVALENT_API_KEY>' \
113+
--header 'x-goldrush-api-key: <GOLDRUSH_API_KEY>' \
119114
--header 'Content-Type: application/json' \
120115
--data '{
121116
"chain_name": "<CHAIN_NAME>",
@@ -140,44 +135,7 @@ Follow the following steps to add a Decoding logic for an event from a contract
140135

141136
This will modify the configs added to the [Protocols](services/protocols) folder. A config will be added to `${protocol_name}.configs.ts`. A sample decoder with a dummy event name (`<EVENT NAME>`) will be added to `${protocol_name}.decoders.ts`. Along with this, a test file `${protocol_name}.test.ts` will also be created which needs to be fixed so that the test passes.
142137

143-
4. In `${protocol_name}.decoders.ts`, a decoding logic declaration (`Decoder.on(...) {...}`) will be exposed wherein the decoding logic needs to be implemented. The return type of the decoding function expects:
144-
145-
```ts
146-
export interface EventType {
147-
category: DECODED_EVENT_CATEGORY;
148-
action: DECODED_ACTION;
149-
name: string;
150-
protocol?: {
151-
name: string;
152-
logo: string;
153-
};
154-
tokens?: {
155-
heading: string;
156-
value: string;
157-
decimals: number;
158-
ticker_symbol: string | null;
159-
ticker_logo: string | null;
160-
pretty: string;
161-
}[];
162-
nfts?: {
163-
heading: string;
164-
collection_name: string | null;
165-
token_identifier: string | null;
166-
collection_address: string;
167-
images: {
168-
default: string | null;
169-
256: string | null;
170-
512: string | null;
171-
1024: string | null;
172-
};
173-
}[];
174-
details?: {
175-
heading: string;
176-
value: string;
177-
type: "address" | "text";
178-
}[];
179-
}
180-
```
138+
4. In `${protocol_name}.decoders.ts`, a decoding logic declaration (`Decoder.on(...)`) will be exposed wherein the decoding logic needs to be implemented. The return type of the decoding function expects the return type [`EventType`](./services/decoder/decoder.types.ts):
181139

182140
## Contributing
183141

api/index.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1+
import { txRouter } from "../microservices/tx/tx.routes";
2+
import { GoldRushDecoder } from "../services";
3+
import { timestampParser } from "../utils/functions";
4+
import cors from "cors";
5+
import { config as dotenvConfig } from "dotenv";
16
import express, {
27
type Express,
38
type Request,
49
type Response,
510
type NextFunction,
611
} from "express";
7-
import cors from "cors";
8-
import { config as dotenvConfig } from "dotenv";
9-
import { GoldRushDecoder } from "../services";
10-
import { txRouter } from "../microservices/tx/tx.routes";
11-
import { timestampParser } from "../utils/functions";
1212

1313
dotenvConfig();
1414

assets/goldrush-decoder-banner.png

-84.6 KB
Loading

microservices/tx/tx.routes.ts

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
import {
2-
Router,
3-
type Request,
4-
type Response,
5-
type NextFunction,
6-
} from "express";
71
import { validateQuery } from "../../middlewares";
82
import {
9-
type DecodeTXRequest,
103
decodeTXBodySchema,
114
decodeTXHeadersSchema,
12-
type DecodeTXHeaders,
135
decodeTXQuerySchema,
6+
type DecodeTXHeaders,
147
type DecodeTXQuery,
8+
type DecodeTXRequest,
159
} from "./tx.schema";
1610
import { decodeLogsFromTx, fetchTxFromHash } from "./tx.service";
1711
import { type Chain } from "@covalenthq/client-sdk";
12+
import {
13+
Router,
14+
type NextFunction,
15+
type Request,
16+
type Response,
17+
} from "express";
1818

1919
export const txRouter = Router();
2020

@@ -24,16 +24,16 @@ const handleDecode = async (
2424
next: NextFunction
2525
) => {
2626
try {
27-
const covalentApiKey = (req.headers as DecodeTXHeaders)[
28-
"x-covalent-api-key"
27+
const goldrushApiKey = (req.headers as DecodeTXHeaders)[
28+
"x-goldrush-api-key"
2929
];
3030
const raw_logs = (req.query as DecodeTXQuery)["raw_logs"] === "true";
3131
const min_usd = (req.query as DecodeTXQuery)["min_usd"] ?? 0;
3232
const { chain_name, tx_hash } = req.body as DecodeTXRequest;
3333
const tx = await fetchTxFromHash(
3434
chain_name as Chain,
3535
tx_hash,
36-
covalentApiKey
36+
goldrushApiKey
3737
);
3838
const {
3939
log_events,
@@ -46,7 +46,7 @@ const handleDecode = async (
4646
const events = await decodeLogsFromTx(
4747
chain_name as Chain,
4848
tx,
49-
covalentApiKey,
49+
goldrushApiKey,
5050
{
5151
raw_logs,
5252
min_usd,

microservices/tx/tx.schema.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ export const decodeTXBodySchema = yup.object({
1212
export type DecodeTXRequest = yup.InferType<typeof decodeTXBodySchema>;
1313

1414
export const decodeTXHeadersSchema = yup.object({
15-
"x-covalent-api-key": yup
15+
"x-goldrush-api-key": yup
1616
.string()
1717
.trim()
18-
.required("x-covalent-api-key is required"),
18+
.required("x-goldrush-api-key is required"),
1919
});
2020

2121
export type DecodeTXHeaders = yup.InferType<typeof decodeTXHeadersSchema>;

microservices/tx/tx.service.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { GoldRushDecoder } from "../../services";
2+
import { type QueryOptions } from "../../services/decoder/decoder.types";
23
import {
34
CovalentClient,
45
type Chain,
56
type Transaction,
67
} from "@covalenthq/client-sdk";
7-
import { type QueryOptions } from "../../services/decoder/decoder.types";
88

99
export const fetchTxFromHash = async (
1010
chain_name: Chain,
@@ -39,13 +39,13 @@ export const fetchTxFromHash = async (
3939
export const decodeLogsFromTx = async (
4040
chain_name: Chain,
4141
tx: Transaction,
42-
covalentApiKey: string,
42+
apiKey: string,
4343
options: QueryOptions
4444
) => {
4545
const events = await GoldRushDecoder.decode(
4646
chain_name,
4747
tx,
48-
covalentApiKey,
48+
apiKey,
4949
options
5050
);
5151
return events;

middlewares/validate-query.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
2-
3-
import { type ObjectSchema, type ValidationError } from "yup";
42
import { type Request, type Response, type NextFunction } from "express";
3+
import { type ObjectSchema, type ValidationError } from "yup";
4+
55
type RequestLocations = "query" | "body" | "params" | "headers";
66

77
/**

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@covalent/goldrush-decoder",
33
"version": "1.0.0",
4-
"description": "",
4+
"description": "Decode unstructured, raw event logs into structured data with a simple API. Open-source. Public Good. 200+ Chains.",
55
"scripts": {
66
"add-config": "ts-node ./scripts/add-config.ts",
77
"build": "tsc",
@@ -24,6 +24,7 @@
2424
"yup": "^1.3.2"
2525
},
2626
"devDependencies": {
27+
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
2728
"@types/cors": "^2.8.14",
2829
"@types/express": "^4.17.19",
2930
"@types/jest": "^29.5.8",

scripts/add-config.ts

+17-33
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,21 @@
1+
import prettierConfig from "../.prettierrc.json";
2+
import { type Configs } from "../services/decoder/decoder.types";
3+
import { slugify } from "../utils/functions";
14
import { Chains, type Chain } from "@covalenthq/client-sdk";
25
import { prompt } from "enquirer";
36
import { existsSync, mkdirSync, writeFileSync } from "fs";
47
import { join } from "path";
58
import { format, type Options } from "prettier";
6-
import prettierConfig from "../.prettierrc.json";
7-
import { slugify } from "../utils/functions";
8-
import { type Configs } from "../services/decoder/decoder.types";
99
import * as yup from "yup";
1010

11-
const writeInFile = async (
12-
path: string,
13-
name: string,
14-
content: string,
15-
pretty: boolean
16-
) => {
11+
const writeInFile = async (path: string, name: string, content: string) => {
1712
if (!existsSync(path)) {
1813
mkdirSync(path);
1914
}
20-
const formattedContent = pretty
21-
? await format(content, {
22-
parser: "typescript",
23-
...(prettierConfig as Options),
24-
})
25-
: content;
15+
const formattedContent = await format(content, {
16+
parser: "typescript",
17+
...(prettierConfig as Options),
18+
});
2619
writeFileSync(join(path, name), formattedContent, "utf-8");
2720
};
2821

@@ -146,33 +139,25 @@ const chainNameSchema = yup
146139

147140
if (!exists) {
148141
const eventName: string = "<EVENT NAME>";
149-
const abiContent: string = `[]`;
142+
const abiContent: string = `export const ABI = [] as const`;
150143
const configsContent: string = `import{type Configs}from"../../decoder.types";\n\nconst configs:Configs=[{address:"${address}",is_factory:${is_factory},protocol_name:"${protocol_name}",chain_name:"${chain_name}"}];\n\nexport default configs;`;
151-
const decodersContent: string = `import{GoldRushDecoder}from"../../decoder";import{type EventType}from"../../decoder.types";import{DECODED_ACTION,DECODED_EVENT_CATEGORY}from"../../decoder.constants";import{decodeEventLog,type Abi}from"viem";import ABI from "./abis/${protocol_name}.abi.json";\n\nGoldRushDecoder.on("${protocol_name}:${eventName}",["${chain_name}"],ABI as Abi,async(log_event,tx,chain_name,covalent_client,options):Promise<EventType> =>{const{raw_log_data,raw_log_topics}=log_event;\n\nconst{args:decoded}=decodeEventLog({abi:ABI,topics:raw_log_topics as[],data:raw_log_data as \`0x\${string}\`,eventName:"${eventName}"})as{eventName:"${eventName}";args:{}};\n\nreturn{action:DECODED_ACTION.SWAPPED,category:DECODED_EVENT_CATEGORY.DEX,name:"${eventName}",protocol:{logo:log_event.sender_logo_url as string,name:log_event.sender_name as string},...(options.raw_logs?{raw_log:log_event}:{})};});`;
152-
const testContent: string = `import request from"supertest";import app from"../../../../api";import{type EventType}from"../../decoder.types";\n\ndescribe("${protocol_name}",()=>{test("${chain_name}:${eventName}",async()=>{const res=await request(app).post("/api/v1/tx/decode").set({"x-covalent-api-key":process.env.TEST_COVALENT_API_KEY}).send({chain_name:"${chain_name}",tx_hash:"<ENTER TX HASH FOR TESTING>"});const{events}=res.body as{events:EventType[]};const event=events.find(({name})=>name==="${eventName}");if(!event){throw Error("Event not found")}const testAdded:boolean=false;expect(testAdded).toEqual(true)})});`;
144+
const decodersContent: string = `import{GoldRushDecoder}from"../../decoder";import{DECODED_ACTION,DECODED_EVENT_CATEGORY}from"../../decoder.constants";import{type EventType}from"../../decoder.types";import{ABI}from"./abis/${protocol_name}.abi";import{decodeEventLog,type Abi}from"viem";\n\nGoldRushDecoder.on(":${eventName}",["${chain_name}"],ABI as Abi,async(log_event,tx,chain_name,covalent_client,options):Promise<EventType> =>{const{raw_log_data,raw_log_topics}=log_event;\n\nconst{args:decoded}=decodeEventLog({abi:ABI,topics:raw_log_topics as[],data:raw_log_data as \`0x\${string}\`,eventName:"${eventName}"})as{eventName:"${eventName}";args:{}};\n\nreturn{action:DECODED_ACTION.SWAPPED,category:DECODED_EVENT_CATEGORY.DEX,name:"${eventName}",protocol:{logo:log_event.sender_logo_url as string,name:log_event.sender_name as string},...(options.raw_logs?{raw_log:log_event}:{})};});`;
145+
const testContent: string = `import app from"../../../../api";import{type EventType}from"../../decoder.types";import request from"supertest";\n\ndescribe("${protocol_name}",()=>{test("${chain_name}:${eventName}",async()=>{const res=await request(app).post("/api/v1/tx/decode").set({"x-goldrush-api-key":process.env.TEST_GOLDRUSH_API_KEY}).send({chain_name:"${chain_name}",tx_hash:"<ENTER TX HASH FOR TESTING>"});const{events}=res.body as{events:EventType[]};const event=events.find(({name})=>name==="${eventName}");if(!event){throw Error("Event not found")}const testAdded:boolean=false;expect(testAdded).toEqual(true)})});`;
153146
await writeInFile(
154147
protocolDir,
155148
`${protocol_name}.decoders.ts`,
156-
decodersContent,
157-
true
149+
decodersContent
158150
);
159151
await writeInFile(
160152
protocolDir,
161153
`${protocol_name}.configs.ts`,
162-
configsContent,
163-
true
164-
);
165-
await writeInFile(
166-
protocolDir,
167-
`${protocol_name}.test.ts`,
168-
testContent,
169-
true
154+
configsContent
170155
);
156+
await writeInFile(protocolDir, `${protocol_name}.test.ts`, testContent);
171157
await writeInFile(
172158
join(protocolDir, "abis"),
173-
`${protocol_name}.abi.json`,
174-
abiContent,
175-
false
159+
`${protocol_name}.abi.ts`,
160+
abiContent
176161
);
177162
customLog(`Created '${protocol_name}' successfully!`, "success");
178163
} else {
@@ -190,8 +175,7 @@ const chainNameSchema = yup
190175
await writeInFile(
191176
protocolDir,
192177
`${protocol_name}.configs.ts`,
193-
configsContent,
194-
true
178+
configsContent
195179
);
196180
customLog(
197181
`Added a config to '${protocol_name}' successfully!`,

0 commit comments

Comments
 (0)