Skip to content
This repository has been archived by the owner on Jul 1, 2023. It is now read-only.

Commit

Permalink
Merge pull request #86 from dbpunk-labs/feat/event_index
Browse files Browse the repository at this point in the history
feat: add create event db
  • Loading branch information
imotai authored Jun 22, 2023
2 parents 52e9239 + 39c0f6f commit 2e038de
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 3 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "db3.js",
"version": "0.3.9",
"version": "0.3.10",
"description": "DB3 Network Javascript API",
"author": "dbpunk labs",
"keywords": [
Expand Down
14 changes: 14 additions & 0 deletions src/client/client_v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,17 @@ export async function scanGcRecords(
const response = await client.provider.scanGcRecords(start, limit)
return response.records
}

/**
*
* Get the contract sync status
*
*
* @param client - the instance of client
* @returns the records
*
**/
export async function getContractSyncStatus(client: Client) {
const response = await client.indexer.getContractSyncStatus()
return response.statusList
}
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ export {

export {
createDocumentDatabase,
createEventDatabase,
showDatabase,
createCollection,
showCollection,
getDatabase,
getCollection,
} from './store/database_v2'

export { Index, IndexType } from './proto/db3_database_v2'
Expand Down
13 changes: 12 additions & 1 deletion src/provider/indexer_provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ import {
GrpcWebOptions,
} from '@protobuf-ts/grpcweb-transport'
import { IndexerNodeClient } from '../proto/db3_indexer.client'
import { RunQueryRequest, GetSystemStatusRequest } from '../proto/db3_indexer'
import {
RunQueryRequest,
GetSystemStatusRequest,
GetContractSyncStatusRequest,
} from '../proto/db3_indexer'
import { Query } from '../proto/db3_database_v2'

export class IndexerProvider {
Expand All @@ -46,9 +50,16 @@ export class IndexerProvider {
const { response } = await this.client.runQuery(request)
return response
}

async getSystemStatus() {
const request: GetSystemStatusRequest = {}
const { response } = await this.client.getSystemStatus(request)
return response
}

async getContractSyncStatus() {
const request: GetContractSyncStatusRequest = {}
const { response } = await this.client.getContractSyncStatus(request)
return response
}
}
9 changes: 9 additions & 0 deletions src/provider/storage_provider_v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
ScanGcRecordRequest,
GetSystemStatusRequest,
SetupRequest,
GetDatabaseRequest,
} from '../proto/db3_storage'
import { fromHEX, toHEX } from '../crypto/crypto_utils'
import { DB3Account } from '../account/types'
Expand Down Expand Up @@ -202,6 +203,14 @@ export class StorageProviderV2 {
return response
}

async getDatabase(addr: string) {
const request: GetDatabaseRequest = {
addr,
}
const { response } = await this.client.getDatabase(request)
return response
}

parseMutationBody(body: MutationBody) {
const typedMsg = new TextDecoder().decode(body.payload)
const typedData = JSON.parse(typedMsg)
Expand Down
134 changes: 134 additions & 0 deletions src/store/database_v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,84 @@ import {
DocumentMask,
Mutation_BodyWrapper,
DocumentDatabaseMutation,
EventDatabaseMutation,
} from '../proto/db3_mutation_v2'

import { Client } from '../client/types'
import { toHEX, fromHEX } from '../crypto/crypto_utils'
import { Index } from '../proto/db3_database_v2'

/**
*
* Create an event database to store contract events
*
* ```ts
* const {db, result} = await createEventDatabase(client, "my_db")
* ```
* @param client - the db3 client instance
* @param desc - the description for the database
* @returns the {@link CreateDBResult}
*
**/
export async function createEventDatabase(
client: Client,
desc: string,
contractAddress: string,
tables: string[],
abi: string,
evmNodeUrl: string
) {
const collections = tables.map((name) => {
const collection: CollectionMutation = {
indexFields: [],
collectionName: name,
}
return collection
})

const mutation: EventDatabaseMutation = {
contractAddress,
ttl: '0',
desc,
tables: collections,
eventsJsonAbi: abi,
evmNodeUrl,
}
const body: Mutation_BodyWrapper = {
body: {
oneofKind: 'eventDatabaseMutation',
eventDatabaseMutation: mutation,
},
dbAddress: new Uint8Array(0),
}

const dm: Mutation = {
action: MutationAction.CreateEventDB,
bodies: [body],
}

const payload = Mutation.toBinary(dm)
const response = await client.provider.sendMutation(
payload,
client.nonce.toString()
)
if (response.code == 0) {
client.nonce += 1
return {
db: {
addr: response.items[0].value,
client,
} as Database,
result: {
id: response.id,
block: response.block,
order: response.order,
} as MutationResult,
}
} else {
throw new Error('fail to create database')
}
}
/**
*
* Create a document database to group the collections
Expand Down Expand Up @@ -84,6 +156,68 @@ export async function createDocumentDatabase(client: Client, desc: string) {
}
}

/**
*
* Get the collection by an db address and collection name
*
* ```ts
* const database = await getCollection("0x....", "col1", client)
* ```
* @param addr - a hex format string address
* @param name - the name of collection
* @param client- the db3 client instance
* @returns the {@link Database}[]
*
**/
export async function getCollection(
addr: string,
name: string,
client: Client
) {
const db = await getDatabase(addr, client)
const collections = await showCollection(db)
const targetCollections = collections.filter((item) => item.name === name)
if (targetCollections.length > 0) {
return targetCollections[0]
} else {
throw new Error(
'db with addr ' + addr + ' has no collection with name ' + name
)
}
}
/**
*
* Get the database by an address
*
* ```ts
* const database = await getDatabase("0x....", client)
* ```
* @param addr - a hex format string address
* @param client- the db3 client instance
* @returns the {@link Database}[]
*
**/
export async function getDatabase(addr: string, client: Client) {
const response = await client.provider.getDatabase(addr)
const db = response.database
if (!db) {
throw new Error('db with addr ' + addr + ' does not exist')
}
if (db.database.oneofKind === 'docDb') {
return {
addr,
client,
internal: db,
}
} else {
return {
addr,
client,
internal: db,
}
}
}

/**
*
* Query the all databases created by an address
Expand Down
4 changes: 4 additions & 0 deletions src/store/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,7 @@ export type QueryResult<T = DocumentData> = {
docs: Array<DocumentEntry<T>>
collection: Collection
}

export type EventDatabaseOption = {
ttl: string
}
23 changes: 23 additions & 0 deletions tests/client_v2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
getStorageNodeStatus,
getIndexNodeStatus,
configRollup,
getContractSyncStatus,
} from '../src/client/client_v2'
import {
addDoc,
Expand All @@ -36,6 +37,7 @@ import {
import { createRandomAccount } from '../src/account/db3_account'
import {
createDocumentDatabase,
createEventDatabase,
showDatabase,
createCollection,
} from '../src/store/database_v2'
Expand All @@ -59,6 +61,27 @@ describe('test db3.js client module', () => {
return client
}

test('create event db smoke test', async () => {
const client = await createTestClient()
expect(1).toBe(client.nonce)
const abi = `
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"}]
`
const evmNodeUrl =
'wss://polygon-mainnet.g.alchemy.com/v2/EH9ZSJ0gS7a1DEIohAWMbhP33lK6qHj9'
const response = await createEventDatabase(
client,
'desc',
'0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',
['Transfer', 'Deposit', 'Approval', 'Withdrawal'],
abi,
evmNodeUrl
)
console.log(response)
await new Promise((r) => setTimeout(r, 10000))
console.log(await getContractSyncStatus(client))
})

test('create client smoke test', async () => {
const client = await createTestClient()
expect(1).toBe(client.nonce)
Expand Down
6 changes: 6 additions & 0 deletions tests/database_v2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import {
showDatabase,
createCollection,
showCollection,
getDatabase,
getCollection,
} from '../src/store/database_v2'

import { Index, IndexType } from '../src/proto/db3_database_v2'
Expand All @@ -51,6 +53,8 @@ describe('test db3.js sdk database', () => {
expect(databases2[0].addr).toBe(db.addr)
expect(databases2[0].internal.database.oneofKind).toBe('docDb')
expect(databases2[0].internal.database.docDb.desc).toBe('test_db')
const database2 = await getDatabase(db.addr, client)
expect(database2.addr).toBe(db.addr)
})

test('collection smoke test from sdk', async () => {
Expand All @@ -72,6 +76,8 @@ describe('test db3.js sdk database', () => {
expect(collection).toBeDefined()
expect(result).toBeDefined()
expect(result.id).toBeTruthy()
const collection2 = await getCollection(db.addr, 'col1', client)
expect(collection.name).toBe(collection2.name)
}
})
})

0 comments on commit 2e038de

Please sign in to comment.