Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Organize directory structure #64

Merged
merged 15 commits into from
Aug 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
**/node_modules
# Keep environment variables out of version control
**/.env
/prisma/dev.db
/prisma/dev.db-journal
/prisma/dev.db-shm
/prisma/dev.db-wal
/prisma/prisma/dev.db
/prisma/prisma/dev.db-journal
/prisma/prisma/dev.db-shm
/prisma/prisma/dev.db-wal
**/.vscode
/dev.crt
/dev.key
/generated
/prisma/client
/prisma/node_modules
/docker-compose-data
**/.DS_Store
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings

DATABASE_URL="prisma://localhost:8088?api_key=x5aol207TyRdhHuanAXlpTgVWDcK8jm2rVKJOQGbwaMqfvZbmGJnIbwBjUxYaBrFx1XOfyF4" # arbitrary api key
DATABASE_URL="file:./dev.db"
CHAIN_DEFINITION_URL="file:./sample/chainDefinitions/goerli.json"
AMQP_BROKER_URL="amqp://localhost"
API_URL="http://localhost:8000"
Expand Down
12 changes: 6 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
node_modules
# Keep environment variables out of version control
.env
/prisma/dev.db
/prisma/dev.db-journal
/prisma/dev.db-shm
/prisma/dev.db-wal
/prisma/prisma/dev.db
/prisma/prisma/dev.db-journal
/prisma/prisma/dev.db-shm
/prisma/prisma/dev.db-wal
/.vscode/launch.json
/dev.crt
/dev.key
/generated
/prisma/client
/prisma/node_modules
/docker-compose-data
.DS_Store
7 changes: 4 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ WORKDIR /Corvette
COPY . .
RUN apk add npm && \
corepack enable && \
cat prisma/schema.prisma | \
cat prisma/prisma/schema.prisma | \
awk '/generator[[:space:]]+[^[:space:]]+[[:space:]]*\{/{ print; print " binaryTargets = [\"native\", \"linux-musl-openssl-3.0.x\"]"; next }1' | \
awk '/datasource[[:space:]]+[^[:space:]]+[[:space:]]*\{/{ flag=1 } /}/ { flag=0 } (flag && /provider[[:space:]]*=/) { print " provider = \"postgresql\""; next } (flag && /directUrl[[:space:]]*=/) { next } { print }' \
> prisma/schema.prisma.new && \
mv prisma/schema.prisma.new prisma/schema.prisma && \
> prisma/prisma/schema.prisma.new && \
mv prisma/prisma/schema.prisma.new prisma/prisma/schema.prisma && \
deno task prisma format && \
deno task prisma generate

Expand All @@ -21,6 +21,7 @@ ENTRYPOINT [ "deno", "run", "--allow-env", "--allow-read", "--allow-net", "--all

FROM common as api
ENV API_URL="http://0.0.0.0:80"
RUN deno cache api.ts
EXPOSE 80
ENTRYPOINT [ "deno", "run", "--allow-env", "--allow-read", "--allow-net", "--allow-ffi", "api.ts" ]

Expand Down
37 changes: 18 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,32 @@ To run Corvette, you must have Deno and Node.js with corepack enabled installed
included. In that case, you must install `yarn` separately with your
package manager.

Before you can run the components, you must apply the database migrations to
your DB. Adjust the database provider in `prisma/schema.prisma`, copy the
configuration from the example `.env.example` to `.env`, and configure
`DATABASE_URL` accordingly. Only SQLite (for development only) and PostgreSQL
has been tested at the moment.
If you intend to run the components without `deno task dev`, you must apply the
database migrations to your DB. Adjust the database provider in
`prisma/prisma/schema.prisma`, copy the configuration from the example
`.env.example` to `.env`, and configure `DATABASE_URL` accordingly. Only SQLite
and PostgreSQL has been tested at the moment.

After database configuration, run `deno task prisma db push`. Your database
will be populated with required tables.


## Running the application for development

A convenience script (`app.ts`) for running all the components (except for web
at the moment) is provided, along with a deno task (`deno task serve`) that
runs this script with required permissions. After applying the database
migrations and configuring `.env`, start the components with `deno task serve`.
The database will automatically be connected with the default configuration.
The script will also launch an instance of an embedded AMQP broker
(https://deno.land/x/lop/mod.ts) and a webhook receiver for testing
(`testWebhookReceiver.ts`) on http://localhost:8888.
A convenience script (`dev.ts`) for running all the components (except for web
at the moment) is provided, along with a deno task (`deno task dev`) that runs
this script with required permissions. After configuring `.env`, start the
components with `deno task dev`. The database will automatically be connected
with the default configuration. The script will also launch an instance of an
embedded AMQP broker (https://deno.land/x/lop/mod.ts) and a webhook receiver
for development (`devTools/testWebhookReceiver.ts`) on http://localhost:8888.

The web component can be started with `deno task serve-web`.
The web component can be started with `deno task dev-web`.

The components will be started using the configuration defined in `.env` file
by default. The configuration may also be overrided by providing the
environment variables in the command line (such as
`BLOCK_FINALITY=finalized deno task serve`.)
`BLOCK_FINALITY=finalized deno task dev`.)


## Running components independently & for production
Expand All @@ -63,13 +62,13 @@ of the same components sharing the same network, DB, and message queue may also
be run simultaneously to achieve failsafe and/or load balancing.

Before running the components, you must generate the Prisma client. You must do
this each time you change the `prisma/schema.prisma` file or Prisma version.
Generate the client with `deno task prisma generate`. You must also prepare the
database and configure the components accordingly.
this each time you change the `prisma/prisma/schema.prisma` file or Prisma
version. Generate the client with `deno task prisma generate`. You must also
prepare the database and configure the components accordingly.

You also need an AMQP 0-9-1 compliant message broker (such as RabbitMQ.) For
testing, you may also use [lop](https://deno.land/x/lop/mod.ts), which is run
when running the application with `deno task serve`:
when running the application with `deno task dev`:
`deno run -A https://deno.land/x/lop/mod.ts`.

To configure each of the components with different configurations, you may need
Expand Down
40 changes: 25 additions & 15 deletions api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@ import { oakCors } from "https://deno.land/x/cors@v1.2.2/mod.ts";
import { Buffer } from "node:buffer";

import { stringify as losslessJsonStringify } from "npm:lossless-json";
import { getAddress, keccak256, toHex } from "npm:viem";
import { getAddress, keccak256, toHex } from "viem";

import type { PrismaClient } from "./prisma-shim.ts";
import type { PrismaClient } from "./prisma/shim.ts";

import { serializeEventResponse } from "./EventResponse.ts";
import { formatAbiItemPrototype } from "./abitype.ts";
import { validateEventRequest } from "./apiSchema.ts";
import { validateEventRequest } from "./constants/apiSchema.ts";
import { serializeEventResponse } from "./messages/EventResponse.ts";
import { formatAbiItemPrototype } from "./utils/abiUtils.ts";
import {
ApiBehindReverseProxyEnvKey,
ApiUrlEnvKey,
combinedEnv,
} from "./envUtils.ts";
} from "./utils/envUtils.ts";
import {
ApiLoggerName,
defaultLogFormatter,
getInternalLoggers,
getLoggingLevel,
} from "./logUtils.ts";
import { runWithPrisma } from "./runHelpers.ts";
} from "./utils/logUtils.ts";
import { runWithPrisma } from "./utils/runUtils.ts";

export function api(prisma: PrismaClient) {
const hexToBuffer = (hex: string): Buffer => {
Expand Down Expand Up @@ -71,28 +71,38 @@ export function api(prisma: PrismaClient) {

ctx.response.body = losslessJsonStringify((await prisma.event.findMany({
where: {
blockHash: request.blockHash && hexToBuffer(request.blockHash),
blockHash: (request.blockHash && hexToBuffer(request.blockHash)) as
| Buffer
| undefined,
blockNumber: request.blockIndex ?? { gte: blockFrom, lte: blockTo },
logIndex: request.logIndex,
txHash: request.transactionHash && hexToBuffer(request.transactionHash),
sourceAddress: request.sourceAddress &&
hexToBuffer(request.sourceAddress),
abiHash: (request.abiHash && hexToBuffer(request.abiHash)) ??
txHash:
(request.transactionHash && hexToBuffer(request.transactionHash)) as
| Buffer
| undefined,
sourceAddress:
(request.sourceAddress && hexToBuffer(request.sourceAddress)) as
| Buffer
| undefined,
abiHash: ((request.abiHash && hexToBuffer(request.abiHash)) ??
(request.abiSignature &&
Buffer.from(
keccak256(
new TextEncoder().encode(request.abiSignature),
"bytes",
),
)),
))) as Buffer | undefined,
},
include: { Abi: true },
})).map((evt) =>
serializeEventResponse({
address: evt.sourceAddress,
sigHash: evt.abiHash,
abi: evt.Abi.json,
topics: [evt.topic1, evt.topic2, evt.topic3],
topics: [evt.topic3, evt.topic2, evt.topic1].reduce(
(acc, x) => x != undefined ? [x, ...acc] : [],
[] as Uint8Array[],
),
data: evt.data,
logIndex: BigInt(evt.logIndex),
blockNumber: BigInt(evt.blockNumber),
Expand Down
2 changes: 1 addition & 1 deletion apiSchema.ts → constants/apiSchema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Ajv, { type JSONSchemaType } from "https://esm.sh/ajv@8.12.0";
import ajvFormats from "https://esm.sh/ajv-formats@2.1.1";
import Ajv, { type JSONSchemaType } from "https://esm.sh/ajv@8.12.0";

const ajv = new Ajv({ allowUnionTypes: true });
ajvFormats(ajv);
Expand Down
File renamed without changes.
Loading