-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #61 from firstbatchxyz/erhant/examples
Added micro example
- Loading branch information
Showing
29 changed files
with
7,404 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Contract to connect to | ||
CONTRACT_TXID=<your-contract> | ||
|
||
# Path to the Arweave wallet | ||
WALLET_PATH=<./path/to/wallet.json> | ||
|
||
# Redis URL for the caching layer | ||
REDIS_URL=<redis-url> | ||
|
||
# Warp's log level | ||
WARP_LOG_LEVEL=info |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
node_modules | ||
build | ||
cache | ||
logs | ||
|
||
dump.rdb | ||
|
||
.vscode | ||
.DS_Store | ||
|
||
!src/cache | ||
|
||
.env | ||
tmp.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"extension": ["ts"], | ||
"require": "ts-node/register", | ||
"spec": "test/**/*.ts", | ||
"timeout": 100000, | ||
"exit": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
# HollowDB Micro | ||
|
||
This backend implementation uses [Micro](https://github.com/vercel/micro) which is a very lightweight server for NodeJS by Vercel, tailored towards usage within a container & supports Unix Domain Socket. It supports almost the CRUD operations as exposed by HollowDB. | ||
|
||
## Usage | ||
|
||
First, you need an Arweave wallet. Provide the path to the wallet with the `WALLET_PATH` environment variable. | ||
|
||
> [!NOTE] | ||
> | ||
> By convention you can put your wallet under the `config` folder as `wallet.json`, which is where the server will look for if no path is specified: | ||
> | ||
> ```sh | ||
> cat your-wallet.json > ./config/wallet.json | ||
> ``` | ||
Then, install the packages. | ||
```sh | ||
yarn install | ||
``` | ||
Finally, start the server with: | ||
|
||
```sh | ||
CONTRACT_TXID="your-contract" yarn start | ||
``` | ||
|
||
### Configurations | ||
|
||
There are several environment variables to configure the server. You can provide them within the command line, or via `.env` file. An example is given [here](./.env.example). | ||
|
||
- `WALLET_PATH=path/to/wallet.json` <br> HollowDB requires an Arweave wallet, specified by this variable. If none is given, it defaults to `./config/wallet.json`. | ||
|
||
- `REDIS_URL=<redis-url>` <br> You need a Redis server running before you start the server, the URL to the server can be provided with a `REDIS_URL` environment variable. The connection URL defaults to `redis://default:redispw@localhost:6379`. | ||
|
||
- `WARP_LOG_LEVEL=<log-level>` <br> By default Warp will log at `info` level, but you can change it via the `WARP_LOG_LEVEL` environment variable. Options are the known levels of `debug`, `error`, `fatal`, `info`, `none`, `silly`, `trace` and `warn`. | ||
|
||
### Changing the Address | ||
|
||
The listened address defaults to `0.0.0.0:3000`, and this can be overridden via `-l` option. | ||
|
||
```sh | ||
# listen to another TCP endpoint | ||
yarn start -l tcp://hostname:port | ||
|
||
# listen to UNIX Domain Socket (more performant) | ||
yarn start -l unix:/path/to/socket.sock | ||
``` | ||
|
||
## Endpoints | ||
|
||
Due to how tiny [Micro](https://github.com/vercel/micro) is, it does not come with routing; so we instead provide the `route` within the POST body. The interface for the POST body, along with the interface of returned data if there is one, is provided below. | ||
|
||
- [`GET`](#get) | ||
- [`GET_MANY`](#get_many) | ||
- [`PUT`](#put) | ||
- [`PUT_MANY`](#put_many) | ||
- [`UPDATE`](#update) | ||
- [`REMOVE`](#remove) | ||
- [`STATE`](#state) | ||
|
||
### `GET` | ||
|
||
```ts | ||
interface { | ||
route: "GET", | ||
data: { | ||
key: string | ||
} | ||
} | ||
|
||
// response body | ||
interface { | ||
value: any | ||
} | ||
``` | ||
|
||
Returns the value at the given key. | ||
|
||
> [!TIP] | ||
> | ||
> Alternatively, any HTTP GET request with a non-empty URI is treated as a key query, where the URI represents the key. For example, a GET request at `http://localhost:3000/key-name` returns the value stored at key `key-name`. | ||
### `GET_MANY` | ||
|
||
```ts | ||
interface { | ||
route: "GET_MANY", | ||
data: { | ||
keys: string[] | ||
} | ||
} | ||
|
||
// response body | ||
interface { | ||
values: any[] | ||
} | ||
``` | ||
|
||
Returns the values at the given `keys`. | ||
|
||
### `PUT` | ||
|
||
```ts | ||
interface { | ||
route: "PUT", | ||
data: { | ||
key: string, | ||
value: any | ||
} | ||
} | ||
``` | ||
|
||
Puts `value` at the given `key`. The key must not exist already, or it must have `null` stored at it. | ||
|
||
### `PUT_MANY` | ||
|
||
```ts | ||
interface { | ||
route: "PUT_MANY", | ||
data: { | ||
keys: string[], | ||
values: any[] | ||
} | ||
} | ||
``` | ||
|
||
Updates given `keys` with the provided `values`. No key must exist already in the database. | ||
|
||
### `UPDATE` | ||
|
||
```ts | ||
interface { | ||
route: "UPDATE", | ||
data: { | ||
key: string, | ||
value: any, | ||
proof?: object | ||
} | ||
} | ||
``` | ||
|
||
Updates a `key` with the provided `value` and an optional `proof`. | ||
|
||
### `REMOVE` | ||
|
||
```ts | ||
interface { | ||
route: "REMOVE", | ||
data: { | ||
key: string, | ||
proof?: object | ||
} | ||
} | ||
``` | ||
|
||
Removes the value at `key`, along with an optional `proof`. | ||
|
||
### `STATE` | ||
|
||
```ts | ||
interface { | ||
route: "STATE" | ||
} | ||
``` | ||
|
||
Syncs & fetches the latest contract state, and returns it. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# hide yo wallet | ||
*.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
{ | ||
"name": "hollowdb-examples-micro", | ||
"author": "FirstBatch Team <[email protected]>", | ||
"private": true, | ||
"contributors": [ | ||
"Erhan Tezcan <[email protected]>" | ||
], | ||
"dependencies": { | ||
"axios": "^1.6.2", | ||
"dotenv": "^16.3.1", | ||
"hollowdb": "^1.3.2", | ||
"http-status-codes": "^2.3.0", | ||
"ioredis": "^5.3.2", | ||
"micro": "^10.0.1", | ||
"warp-contracts": "^1.4.28", | ||
"warp-contracts-redis": "^0.3.4" | ||
}, | ||
"main": "build/src/index.js", | ||
"scripts": { | ||
"precompile": "yarn clean", | ||
"compile": "npx tsc", | ||
"prestart": "yarn compile", | ||
"start": "npx micro", | ||
"test": "npx mocha --bail", | ||
"clean": "rm -rf ./build" | ||
}, | ||
"devDependencies": { | ||
"@types/chai": "^4.3.5", | ||
"@types/mocha": "^10.0.1", | ||
"@types/node": "^18.16.3", | ||
"@types/test-listen": "^1.1.0", | ||
"arlocal": "^1.1.60", | ||
"chai": "^4.3.7", | ||
"hollowdb-prover": "^0.1.4", | ||
"mocha": "^10.2.0", | ||
"test-listen": "^1.1.0", | ||
"ts-node": "^10.9.1", | ||
"typescript": "^5.0.4", | ||
"warp-contracts-plugin-deploy": "^1.0.8" | ||
}, | ||
"prettier": { | ||
"printWidth": 120 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { CacheOptions } from "warp-contracts"; | ||
import { RedisCache, RedisOptions } from "warp-contracts-redis"; | ||
import { Redis } from "ioredis"; | ||
import config from "../config"; | ||
import { CacheTypes } from "../types"; | ||
|
||
/** | ||
* Utility to create Warp Redis caches. | ||
* | ||
* @param contractTxId contract transaction id to be used as prefix in the keys | ||
* @param client optional client to used a self-managed cache, i.e. you are responsible from | ||
* opening and closing the client. | ||
* @returns caches | ||
*/ | ||
export function createCaches(contractTxId: string, client?: Redis): CacheTypes<RedisCache> { | ||
const defaultCacheOptions: CacheOptions = { | ||
inMemory: true, | ||
subLevelSeparator: "|", | ||
dbLocation: "redis.micro", | ||
}; | ||
|
||
// if a client exists, use it; otherwise connect via URL | ||
const redisOptions: RedisOptions = client ? { client } : { url: config.REDIS_URL }; | ||
|
||
return { | ||
state: new RedisCache( | ||
{ | ||
...defaultCacheOptions, | ||
dbLocation: `${contractTxId}.state`, | ||
}, | ||
redisOptions | ||
), | ||
contract: new RedisCache( | ||
{ | ||
...defaultCacheOptions, | ||
dbLocation: `${contractTxId}.contract`, | ||
}, | ||
redisOptions | ||
), | ||
src: new RedisCache( | ||
{ | ||
...defaultCacheOptions, | ||
dbLocation: `${contractTxId}.src`, | ||
}, | ||
redisOptions | ||
), | ||
kvFactory: (contractTxId: string) => | ||
new RedisCache( | ||
{ | ||
...defaultCacheOptions, | ||
dbLocation: `${contractTxId}.kv`, | ||
}, | ||
redisOptions | ||
), | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import type { LoggerFactory } from "warp-contracts"; | ||
|
||
export default { | ||
/** Redis URL to connect to. Defaults to `redis://default:redispw@localhost:6379`. */ | ||
REDIS_URL: process.env.REDIS_URL || "redis://default:redispw@localhost:6379", | ||
/** Path to Arweave wallet. */ | ||
WALLET_PATH: process.env.WALLET_PATH || "./config/wallet.json", | ||
/** Log level for underlying Warp. */ | ||
WARP_LOG_LEVEL: (process.env.WARP_LOG_LEVEL || "info") as Parameters<typeof LoggerFactory.INST.logLevel>[0], | ||
/** Arweave port for `arlocal`. */ | ||
ARWEAVE_PORT: 3169, | ||
} as const; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// load env variables (put this at top) | ||
import "dotenv/config"; | ||
|
||
import { Redis } from "ioredis"; | ||
import { readFileSync } from "fs"; | ||
import { SDK } from "hollowdb"; | ||
import type { JWKInterface } from "warp-contracts"; | ||
|
||
import makeServer from "./server"; | ||
import config from "./config"; | ||
import { makeWarp } from "./util"; | ||
import { createCaches } from "./cache"; | ||
|
||
const contractTxId = process.env.CONTRACT_TXID; | ||
if (!contractTxId) { | ||
throw new Error("Please provide CONTRACT_TXID environment variable."); | ||
} | ||
const redisClient = new Redis(config.REDIS_URL, { | ||
lazyConnect: false, // explicitly connect | ||
}); | ||
const caches = createCaches(contractTxId, redisClient); | ||
const wallet = JSON.parse(readFileSync(config.WALLET_PATH, "utf-8")) as JWKInterface; | ||
const warp = makeWarp(caches); | ||
const hollowdb = new SDK(wallet, contractTxId, warp); | ||
|
||
// module.exports needed by Micro | ||
module.exports = makeServer(hollowdb, contractTxId); |
Oops, something went wrong.