mirror of
https://github.com/cerc-io/watcher-ts
synced 2025-07-28 11:02:07 +00:00
Generate entities from YAML templates and lint support in generated watchers (#253)
* Add lint files generation. * Fix lint errors in generated code. * Load default entities from yaml files. Co-authored-by: prathamesh <prathamesh.musale0@gmail.com>
This commit is contained in:
parent
11d16b9870
commit
338cef9954
@ -43,11 +43,19 @@
|
|||||||
|
|
||||||
## Demo
|
## Demo
|
||||||
|
|
||||||
* Install required packages:
|
* In root of the repository:
|
||||||
|
|
||||||
```bash
|
* Install required packages:
|
||||||
yarn
|
|
||||||
```
|
```bash
|
||||||
|
yarn
|
||||||
|
```
|
||||||
|
|
||||||
|
* Build files:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn build
|
||||||
|
```
|
||||||
|
|
||||||
* Generate a watcher from a contract file:
|
* Generate a watcher from a contract file:
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
"graphql": "^15.5.0",
|
"graphql": "^15.5.0",
|
||||||
"graphql-compose": "^9.0.3",
|
"graphql-compose": "^9.0.3",
|
||||||
"handlebars": "^4.7.7",
|
"handlebars": "^4.7.7",
|
||||||
|
"js-yaml": "^4.0.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"node-fetch": "^2",
|
"node-fetch": "^2",
|
||||||
"solc": "^0.8.7-fixed",
|
"solc": "^0.8.7-fixed",
|
||||||
"ts-node": "^10.2.1",
|
"ts-node": "^10.2.1",
|
||||||
@ -32,6 +34,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@openzeppelin/contracts": "^4.3.2",
|
"@openzeppelin/contracts": "^4.3.2",
|
||||||
|
"@types/js-yaml": "^4.0.3",
|
||||||
"@types/node": "^16.9.0",
|
"@types/node": "^16.9.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.25.0",
|
"@typescript-eslint/eslint-plugin": "^4.25.0",
|
||||||
"@typescript-eslint/parser": "^4.25.0",
|
"@typescript-eslint/parser": "^4.25.0",
|
||||||
|
66
packages/codegen/src/data/entities/BlockProgress.yaml
Normal file
66
packages/codegen/src/data/entities/BlockProgress.yaml
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
className: BlockProgress
|
||||||
|
implements: BlockProgressInterface
|
||||||
|
indexOn:
|
||||||
|
- columns:
|
||||||
|
- blockHash
|
||||||
|
unique: true
|
||||||
|
- columns:
|
||||||
|
- blockNumber
|
||||||
|
- columns:
|
||||||
|
- parentHash
|
||||||
|
columns:
|
||||||
|
- name: blockHash
|
||||||
|
pgType: varchar
|
||||||
|
tsType: string
|
||||||
|
columnType: Column
|
||||||
|
columnOptions:
|
||||||
|
- option: length
|
||||||
|
value: 66
|
||||||
|
- name: parentHash
|
||||||
|
pgType: varchar
|
||||||
|
tsType: string
|
||||||
|
columnType: Column
|
||||||
|
columnOptions:
|
||||||
|
- option: length
|
||||||
|
value: 66
|
||||||
|
- name: blockNumber
|
||||||
|
pgType: integer
|
||||||
|
tsType: number
|
||||||
|
columnType: Column
|
||||||
|
- name: blockTimestamp
|
||||||
|
pgType: integer
|
||||||
|
tsType: number
|
||||||
|
columnType: Column
|
||||||
|
- name: numEvents
|
||||||
|
pgType: integer
|
||||||
|
tsType: number
|
||||||
|
columnType: Column
|
||||||
|
- name: numProcessedEvents
|
||||||
|
pgType: integer
|
||||||
|
tsType: number
|
||||||
|
columnType: Column
|
||||||
|
- name: lastProcessedEventIndex
|
||||||
|
pgType: integer
|
||||||
|
tsType: number
|
||||||
|
columnType: Column
|
||||||
|
- name: isComplete
|
||||||
|
pgType: boolean
|
||||||
|
tsType: boolean
|
||||||
|
columnType: Column
|
||||||
|
- name: isPruned
|
||||||
|
pgType: boolean
|
||||||
|
tsType: boolean
|
||||||
|
columnType: Column
|
||||||
|
columnOptions:
|
||||||
|
- option: default
|
||||||
|
value: false
|
||||||
|
imports:
|
||||||
|
- toImport:
|
||||||
|
- Entity
|
||||||
|
- PrimaryGeneratedColumn
|
||||||
|
- Column
|
||||||
|
- Index
|
||||||
|
from: typeorm
|
||||||
|
- toImport:
|
||||||
|
- BlockProgressInterface
|
||||||
|
from: '@vulcanize/util'
|
31
packages/codegen/src/data/entities/Contract.yaml
Normal file
31
packages/codegen/src/data/entities/Contract.yaml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
className: Contract
|
||||||
|
indexOn:
|
||||||
|
- columns:
|
||||||
|
- address
|
||||||
|
unique: true
|
||||||
|
columns:
|
||||||
|
- name: address
|
||||||
|
pgType: varchar
|
||||||
|
tsType: string
|
||||||
|
columnType: Column
|
||||||
|
columnOptions:
|
||||||
|
- option: length
|
||||||
|
value: 42
|
||||||
|
- name: kind
|
||||||
|
pgType: varchar
|
||||||
|
tsType: string
|
||||||
|
columnType: Column
|
||||||
|
columnOptions:
|
||||||
|
- option: length
|
||||||
|
value: 8
|
||||||
|
- name: startingBlock
|
||||||
|
pgType: integer
|
||||||
|
tsType: number
|
||||||
|
columnType: Column
|
||||||
|
imports:
|
||||||
|
- toImport:
|
||||||
|
- Entity
|
||||||
|
- PrimaryGeneratedColumn
|
||||||
|
- Column
|
||||||
|
- Index
|
||||||
|
from: typeorm
|
63
packages/codegen/src/data/entities/Event.yaml
Normal file
63
packages/codegen/src/data/entities/Event.yaml
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
className: Event
|
||||||
|
indexOn:
|
||||||
|
- columns:
|
||||||
|
- block
|
||||||
|
- contract
|
||||||
|
- columns:
|
||||||
|
- block
|
||||||
|
- contract
|
||||||
|
- eventName
|
||||||
|
columns:
|
||||||
|
- name: block
|
||||||
|
tsType: BlockProgress
|
||||||
|
columnType: ManyToOne
|
||||||
|
lhs: ()
|
||||||
|
rhs: BlockProgress
|
||||||
|
- name: txHash
|
||||||
|
pgType: varchar
|
||||||
|
tsType: string
|
||||||
|
columnType: Column
|
||||||
|
columnOptions:
|
||||||
|
- option: length
|
||||||
|
value: 66
|
||||||
|
- name: index
|
||||||
|
pgType: integer
|
||||||
|
tsType: number
|
||||||
|
columnType: Column
|
||||||
|
- name: contract
|
||||||
|
pgType: varchar
|
||||||
|
tsType: string
|
||||||
|
columnType: Column
|
||||||
|
columnOptions:
|
||||||
|
- option: length
|
||||||
|
value: 42
|
||||||
|
- name: eventName
|
||||||
|
pgType: varchar
|
||||||
|
tsType: string
|
||||||
|
columnType: Column
|
||||||
|
columnOptions:
|
||||||
|
- option: length
|
||||||
|
value: 256
|
||||||
|
- name: eventInfo
|
||||||
|
pgType: text
|
||||||
|
tsType: string
|
||||||
|
columnType: Column
|
||||||
|
- name: extraInfo
|
||||||
|
pgType: text
|
||||||
|
tsType: string
|
||||||
|
columnType: Column
|
||||||
|
- name: proof
|
||||||
|
pgType: text
|
||||||
|
tsType: string
|
||||||
|
columnType: Column
|
||||||
|
imports:
|
||||||
|
- toImport:
|
||||||
|
- Entity
|
||||||
|
- PrimaryGeneratedColumn
|
||||||
|
- Column
|
||||||
|
- Index
|
||||||
|
- ManyToOne
|
||||||
|
from: typeorm
|
||||||
|
- toImport:
|
||||||
|
- BlockProgress
|
||||||
|
from: ./BlockProgress
|
46
packages/codegen/src/data/entities/SyncStatus.yaml
Normal file
46
packages/codegen/src/data/entities/SyncStatus.yaml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
className: SyncStatus
|
||||||
|
implements: SyncStatusInterface
|
||||||
|
indexOn: []
|
||||||
|
columns:
|
||||||
|
- name: chainHeadBlockHash
|
||||||
|
pgType: varchar
|
||||||
|
tsType: string
|
||||||
|
columnType: Column
|
||||||
|
columnOptions:
|
||||||
|
- option: length
|
||||||
|
value: 66
|
||||||
|
- name: chainHeadBlockNumber
|
||||||
|
pgType: integer
|
||||||
|
tsType: number
|
||||||
|
columnType: Column
|
||||||
|
- name: latestIndexedBlockHash
|
||||||
|
pgType: varchar
|
||||||
|
tsType: string
|
||||||
|
columnType: Column
|
||||||
|
columnOptions:
|
||||||
|
- option: length
|
||||||
|
value: 66
|
||||||
|
- name: latestIndexedBlockNumber
|
||||||
|
pgType: integer
|
||||||
|
tsType: number
|
||||||
|
columnType: Column
|
||||||
|
- name: latestCanonicalBlockHash
|
||||||
|
pgType: varchar
|
||||||
|
tsType: string
|
||||||
|
columnType: Column
|
||||||
|
columnOptions:
|
||||||
|
- option: length
|
||||||
|
value: 66
|
||||||
|
- name: latestCanonicalBlockNumber
|
||||||
|
pgType: integer
|
||||||
|
tsType: number
|
||||||
|
columnType: Column
|
||||||
|
imports:
|
||||||
|
- toImport:
|
||||||
|
- Entity
|
||||||
|
- PrimaryGeneratedColumn
|
||||||
|
- Column
|
||||||
|
from: typeorm
|
||||||
|
- toImport:
|
||||||
|
- SyncStatusInterface
|
||||||
|
from: '@vulcanize/util'
|
@ -5,6 +5,7 @@
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
import yaml from 'js-yaml';
|
||||||
import Handlebars from 'handlebars';
|
import Handlebars from 'handlebars';
|
||||||
import { Writable } from 'stream';
|
import { Writable } from 'stream';
|
||||||
|
|
||||||
@ -12,6 +13,7 @@ import { getTsForSol, getPgForTs } from './utils/type-mappings';
|
|||||||
import { Param } from './utils/types';
|
import { Param } from './utils/types';
|
||||||
|
|
||||||
const TEMPLATE_FILE = './templates/entity-template.handlebars';
|
const TEMPLATE_FILE = './templates/entity-template.handlebars';
|
||||||
|
const TABLES_DIR = './data/entities';
|
||||||
|
|
||||||
export class Entity {
|
export class Entity {
|
||||||
_entities: Array<any>;
|
_entities: Array<any>;
|
||||||
@ -44,7 +46,7 @@ export class Entity {
|
|||||||
|
|
||||||
entityObject.imports.push(
|
entityObject.imports.push(
|
||||||
{
|
{
|
||||||
toImport: ['Entity', 'PrimaryGeneratedColumn', 'Column', 'Index'],
|
toImport: new Set(['Entity', 'PrimaryGeneratedColumn', 'Column', 'Index']),
|
||||||
from: 'typeorm'
|
from: 'typeorm'
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -106,16 +108,6 @@ export class Entity {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use bigintTransformer for bigint types.
|
|
||||||
if (tsType === 'bigint') {
|
|
||||||
columnOptions.push(
|
|
||||||
{
|
|
||||||
option: 'transformer',
|
|
||||||
value: 'bigintTransformer'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
pgType,
|
pgType,
|
||||||
@ -136,7 +128,8 @@ export class Entity {
|
|||||||
name: 'value',
|
name: 'value',
|
||||||
pgType: pgReturnType,
|
pgType: pgReturnType,
|
||||||
tsType: tsReturnType,
|
tsType: tsReturnType,
|
||||||
columnType: 'Column'
|
columnType: 'Column',
|
||||||
|
columnOptions: []
|
||||||
});
|
});
|
||||||
|
|
||||||
entityObject.columns.push({
|
entityObject.columns.push({
|
||||||
@ -152,6 +145,31 @@ export class Entity {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
entityObject.columns.forEach((column: any) => {
|
||||||
|
if (column.tsType === 'bigint') {
|
||||||
|
column.columnOptions.push(
|
||||||
|
{
|
||||||
|
option: 'transformer',
|
||||||
|
value: 'bigintTransformer'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const importObject = entityObject.imports.find((element: any) => {
|
||||||
|
return element.from === '@vulcanize/util';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (importObject) {
|
||||||
|
importObject.toImport.add('bigintTransformer');
|
||||||
|
} else {
|
||||||
|
entityObject.imports.push(
|
||||||
|
{
|
||||||
|
toImport: new Set(['bigintTransformer']),
|
||||||
|
from: '@vulcanize/util'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this._entities.push(entityObject);
|
this._entities.push(entityObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,362 +194,22 @@ export class Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_addEventEntity (): void {
|
_addEventEntity (): void {
|
||||||
const entity: any = {
|
const entity = yaml.load(fs.readFileSync(path.resolve(__dirname, TABLES_DIR, 'Event.yaml'), 'utf8'));
|
||||||
className: 'Event',
|
|
||||||
indexOn: [],
|
|
||||||
columns: [],
|
|
||||||
imports: []
|
|
||||||
};
|
|
||||||
|
|
||||||
entity.imports.push(
|
|
||||||
{
|
|
||||||
toImport: ['Entity', 'PrimaryGeneratedColumn', 'Column', 'Index', 'ManyToOne'],
|
|
||||||
from: 'typeorm'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
toImport: ['BlockProgress'],
|
|
||||||
from: './BlockProgress'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
entity.indexOn.push(
|
|
||||||
{
|
|
||||||
columns: ['block', 'contract']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
columns: ['block', 'contract', 'eventName']
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'block',
|
|
||||||
tsType: 'BlockProgress',
|
|
||||||
columnType: 'ManyToOne',
|
|
||||||
lhs: '()',
|
|
||||||
rhs: 'BlockProgress'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'txHash',
|
|
||||||
pgType: 'varchar',
|
|
||||||
tsType: 'string',
|
|
||||||
columnType: 'Column',
|
|
||||||
columnOptions: [
|
|
||||||
{
|
|
||||||
option: 'length',
|
|
||||||
value: 66
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'index',
|
|
||||||
pgType: 'integer',
|
|
||||||
tsType: 'number',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'contract',
|
|
||||||
pgType: 'varchar',
|
|
||||||
tsType: 'string',
|
|
||||||
columnType: 'Column',
|
|
||||||
columnOptions: [
|
|
||||||
{
|
|
||||||
option: 'length',
|
|
||||||
value: 42
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'eventName',
|
|
||||||
pgType: 'varchar',
|
|
||||||
tsType: 'string',
|
|
||||||
columnType: 'Column',
|
|
||||||
columnOptions: [
|
|
||||||
{
|
|
||||||
option: 'length',
|
|
||||||
value: 256
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'eventInfo',
|
|
||||||
pgType: 'text',
|
|
||||||
tsType: 'string',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'extraInfo',
|
|
||||||
pgType: 'text',
|
|
||||||
tsType: 'string',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'proof',
|
|
||||||
pgType: 'text',
|
|
||||||
tsType: 'string',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
this._entities.push(entity);
|
this._entities.push(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
_addSyncStatusEntity (): void {
|
_addSyncStatusEntity (): void {
|
||||||
const entity: any = {
|
const entity = yaml.load(fs.readFileSync(path.resolve(__dirname, TABLES_DIR, 'SyncStatus.yaml'), 'utf8'));
|
||||||
className: 'SyncStatus',
|
|
||||||
implements: 'SyncStatusInterface',
|
|
||||||
indexOn: [],
|
|
||||||
columns: [],
|
|
||||||
imports: []
|
|
||||||
};
|
|
||||||
|
|
||||||
entity.imports.push({
|
|
||||||
toImport: ['Entity', 'PrimaryGeneratedColumn', 'Column'],
|
|
||||||
from: 'typeorm'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.imports.push({
|
|
||||||
toImport: ['SyncStatusInterface'],
|
|
||||||
from: '@vulcanize/util'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'chainHeadBlockHash',
|
|
||||||
pgType: 'varchar',
|
|
||||||
tsType: 'string',
|
|
||||||
columnType: 'Column',
|
|
||||||
columnOptions: [
|
|
||||||
{
|
|
||||||
option: 'length',
|
|
||||||
value: 66
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'chainHeadBlockNumber',
|
|
||||||
pgType: 'integer',
|
|
||||||
tsType: 'number',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'latestIndexedBlockHash',
|
|
||||||
pgType: 'varchar',
|
|
||||||
tsType: 'string',
|
|
||||||
columnType: 'Column',
|
|
||||||
columnOptions: [
|
|
||||||
{
|
|
||||||
option: 'length',
|
|
||||||
value: 66
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'latestIndexedBlockNumber',
|
|
||||||
pgType: 'integer',
|
|
||||||
tsType: 'number',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'latestCanonicalBlockHash',
|
|
||||||
pgType: 'varchar',
|
|
||||||
tsType: 'string',
|
|
||||||
columnType: 'Column',
|
|
||||||
columnOptions: [
|
|
||||||
{
|
|
||||||
option: 'length',
|
|
||||||
value: 66
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'latestCanonicalBlockNumber',
|
|
||||||
pgType: 'integer',
|
|
||||||
tsType: 'number',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
this._entities.push(entity);
|
this._entities.push(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
_addContractEntity (): void {
|
_addContractEntity (): void {
|
||||||
const entity: any = {
|
const entity = yaml.load(fs.readFileSync(path.resolve(__dirname, TABLES_DIR, 'Contract.yaml'), 'utf8'));
|
||||||
className: 'Contract',
|
|
||||||
indexOn: [],
|
|
||||||
columns: [],
|
|
||||||
imports: []
|
|
||||||
};
|
|
||||||
|
|
||||||
entity.imports.push({
|
|
||||||
toImport: ['Entity', 'PrimaryGeneratedColumn', 'Column', 'Index'],
|
|
||||||
from: 'typeorm'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.indexOn.push(
|
|
||||||
{
|
|
||||||
columns: ['address'],
|
|
||||||
unique: true
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'address',
|
|
||||||
pgType: 'varchar',
|
|
||||||
tsType: 'string',
|
|
||||||
columnType: 'Column',
|
|
||||||
columnOptions: [
|
|
||||||
{
|
|
||||||
option: 'length',
|
|
||||||
value: 42
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'kind',
|
|
||||||
pgType: 'varchar',
|
|
||||||
tsType: 'string',
|
|
||||||
columnType: 'Column',
|
|
||||||
columnOptions: [
|
|
||||||
{
|
|
||||||
option: 'length',
|
|
||||||
value: 8
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'startingBlock',
|
|
||||||
pgType: 'integer',
|
|
||||||
tsType: 'number',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
this._entities.push(entity);
|
this._entities.push(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
_addBlockProgressEntity (): void {
|
_addBlockProgressEntity (): void {
|
||||||
const entity: any = {
|
const entity = yaml.load(fs.readFileSync(path.resolve(__dirname, TABLES_DIR, 'BlockProgress.yaml'), 'utf8'));
|
||||||
className: 'BlockProgress',
|
|
||||||
implements: 'BlockProgressInterface',
|
|
||||||
indexOn: [],
|
|
||||||
columns: [],
|
|
||||||
imports: []
|
|
||||||
};
|
|
||||||
|
|
||||||
entity.imports.push({
|
|
||||||
toImport: ['Entity', 'PrimaryGeneratedColumn', 'Column', 'Index'],
|
|
||||||
from: 'typeorm'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.imports.push({
|
|
||||||
toImport: ['BlockProgressInterface'],
|
|
||||||
from: '@vulcanize/util'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.indexOn.push(
|
|
||||||
{
|
|
||||||
columns: ['blockHash'],
|
|
||||||
unique: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
columns: ['blockNumber']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
columns: ['parentHash']
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'blockHash',
|
|
||||||
pgType: 'varchar',
|
|
||||||
tsType: 'string',
|
|
||||||
columnType: 'Column',
|
|
||||||
columnOptions: [
|
|
||||||
{
|
|
||||||
option: 'length',
|
|
||||||
value: 66
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'parentHash',
|
|
||||||
pgType: 'varchar',
|
|
||||||
tsType: 'string',
|
|
||||||
columnType: 'Column',
|
|
||||||
columnOptions: [
|
|
||||||
{
|
|
||||||
option: 'length',
|
|
||||||
value: 66
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'blockNumber',
|
|
||||||
pgType: 'integer',
|
|
||||||
tsType: 'number',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'blockTimestamp',
|
|
||||||
pgType: 'integer',
|
|
||||||
tsType: 'number',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'numEvents',
|
|
||||||
pgType: 'integer',
|
|
||||||
tsType: 'number',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'numProcessedEvents',
|
|
||||||
pgType: 'integer',
|
|
||||||
tsType: 'number',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'lastProcessedEventIndex',
|
|
||||||
pgType: 'integer',
|
|
||||||
tsType: 'number',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'isComplete',
|
|
||||||
pgType: 'boolean',
|
|
||||||
tsType: 'boolean',
|
|
||||||
columnType: 'Column'
|
|
||||||
});
|
|
||||||
|
|
||||||
entity.columns.push({
|
|
||||||
name: 'isPruned',
|
|
||||||
pgType: 'boolean',
|
|
||||||
tsType: 'boolean',
|
|
||||||
columnType: 'Column',
|
|
||||||
columnOptions: [
|
|
||||||
{
|
|
||||||
option: 'default',
|
|
||||||
value: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
this._entities.push(entity);
|
this._entities.push(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import { exportReadme } from './readme';
|
|||||||
import { exportEvents } from './events';
|
import { exportEvents } from './events';
|
||||||
import { exportJobRunner } from './job-runner';
|
import { exportJobRunner } from './job-runner';
|
||||||
import { exportWatchContract } from './watch-contract';
|
import { exportWatchContract } from './watch-contract';
|
||||||
|
import { exportLint } from './lint';
|
||||||
import { registerHandlebarHelpers } from './utils/handlebar-helpers';
|
import { registerHandlebarHelpers } from './utils/handlebar-helpers';
|
||||||
|
|
||||||
const main = async (): Promise<void> => {
|
const main = async (): Promise<void> => {
|
||||||
@ -196,6 +197,17 @@ function generateWatcher (data: string, visitor: Visitor, argv: any) {
|
|||||||
? fs.createWriteStream(path.join(outputDir, 'src/cli/watch-contract.ts'))
|
? fs.createWriteStream(path.join(outputDir, 'src/cli/watch-contract.ts'))
|
||||||
: process.stdout;
|
: process.stdout;
|
||||||
exportWatchContract(outStream);
|
exportWatchContract(outStream);
|
||||||
|
|
||||||
|
let rcOutStream;
|
||||||
|
let ignoreOutStream;
|
||||||
|
if (outputDir) {
|
||||||
|
rcOutStream = fs.createWriteStream(path.join(outputDir, '.eslintrc.json'));
|
||||||
|
ignoreOutStream = fs.createWriteStream(path.join(outputDir, '.eslintignore'));
|
||||||
|
} else {
|
||||||
|
rcOutStream = process.stdout;
|
||||||
|
ignoreOutStream = process.stdout;
|
||||||
|
}
|
||||||
|
exportLint(rcOutStream, ignoreOutStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
main().catch(err => {
|
main().catch(err => {
|
||||||
|
28
packages/codegen/src/lint.ts
Normal file
28
packages/codegen/src/lint.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2021 Vulcanize, Inc.
|
||||||
|
//
|
||||||
|
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import Handlebars from 'handlebars';
|
||||||
|
import { Writable } from 'stream';
|
||||||
|
|
||||||
|
const RC_TEMPLATE_FILE = './templates/eslintrc-template.handlebars';
|
||||||
|
const IGNORE_TEMPLATE_FILE = './templates/eslintignore-template.handlebars';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the .eslintrc.json and .eslintignore file generated from a template to respective streams.
|
||||||
|
* @param rcOutStream A writable output stream to write the .eslintrc.json file to.
|
||||||
|
* @param ignoreOutStream A writable output stream to write the .eslintignore file to.
|
||||||
|
*/
|
||||||
|
export function exportLint (rcOutStream: Writable, ignoreOutStream: Writable): void {
|
||||||
|
const rcTemplateString = fs.readFileSync(path.resolve(__dirname, RC_TEMPLATE_FILE)).toString();
|
||||||
|
const rcTemplate = Handlebars.compile(rcTemplateString);
|
||||||
|
const rcString = rcTemplate({});
|
||||||
|
rcOutStream.write(rcString);
|
||||||
|
|
||||||
|
const ignoreTemplateString = fs.readFileSync(path.resolve(__dirname, IGNORE_TEMPLATE_FILE)).toString();
|
||||||
|
const ignoreTemplate = Handlebars.compile(ignoreTemplateString);
|
||||||
|
const ignoreString = ignoreTemplate({});
|
||||||
|
ignoreOutStream.write(ignoreString);
|
||||||
|
}
|
@ -44,6 +44,10 @@ export class Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{{#each queries as | query |}}
|
{{#each queries as | query |}}
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
{{#if (banTypeCheck (capitalize query.name tillIndex=1)) }}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
{{/if}}
|
||||||
async get{{capitalize query.name tillIndex=1}} ({ blockHash, contractAddress
|
async get{{capitalize query.name tillIndex=1}} ({ blockHash, contractAddress
|
||||||
{{~#each query.params}}, {{this.name~}} {{/each}} }: { blockHash: string, contractAddress: string
|
{{~#each query.params}}, {{this.name~}} {{/each}} }: { blockHash: string, contractAddress: string
|
||||||
{{~#each query.params}}, {{this.name~}}: {{this.type~}} {{/each}} }): Promise<{{capitalize query.name tillIndex=1}} | undefined> {
|
{{~#each query.params}}, {{this.name~}}: {{this.type~}} {{/each}} }): Promise<{{capitalize query.name tillIndex=1}} | undefined> {
|
||||||
@ -54,14 +58,18 @@ export class Database {
|
|||||||
{{#each query.params}}
|
{{#each query.params}}
|
||||||
{{this.name}}{{#unless @last}},{{/unless}}
|
{{this.name}}{{#unless @last}},{{/unless}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
{{~#each queries as | query |}}
|
{{~#each queries as | query |}}
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
{{#if (banTypeCheck (capitalize query.name tillIndex=1)) }}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
{{/if}}
|
||||||
async save{{capitalize query.name tillIndex=1}} ({ blockHash, contractAddress
|
async save{{capitalize query.name tillIndex=1}} ({ blockHash, contractAddress
|
||||||
{{~#each query.params}}, {{this.name~}} {{/each}}, value, proof}: DeepPartial<{{capitalize query.name tillIndex=1}}>): Promise<{{capitalize query.name tillIndex=1}}> {
|
{{~#each query.params}}, {{this.name~}} {{/each}}, value, proof }: DeepPartial<{{capitalize query.name tillIndex=1}}>): Promise<{{capitalize query.name tillIndex=1}}> {
|
||||||
const repo = this._conn.getRepository({{capitalize query.name tillIndex=1}});
|
const repo = this._conn.getRepository({{capitalize query.name tillIndex=1}});
|
||||||
const entity = repo.create({ blockHash, contractAddress
|
const entity = repo.create({ blockHash, contractAddress
|
||||||
{{~#each query.params}}, {{this.name~}} {{/each}}, value, proof });
|
{{~#each query.params}}, {{this.name~}} {{/each}}, value, proof });
|
||||||
@ -184,9 +192,9 @@ export class Database {
|
|||||||
}, new Map<string, string>());
|
}, new Map<string, string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
_setPropColMaps () {
|
_setPropColMaps (): void {
|
||||||
{{#each queries as | query |}}
|
{{#each queries as | query |}}
|
||||||
this._propColMaps['{{capitalize query.name tillIndex=1}}'] = this._getPropertyColumnMapForEntity('{{capitalize query.name tillIndex=1}}');
|
this._propColMaps.{{capitalize query.name tillIndex=1}} = this._getPropertyColumnMapForEntity('{{capitalize query.name tillIndex=1}}');
|
||||||
{{/each}}
|
{{/each}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
import { {{~#each import.toImport}} {{this}} {{~#unless @last}}, {{~/unless}} {{~/each}} } from '{{import.from}}';
|
import { {{~#each import.toImport}} {{this}} {{~#unless @last}}, {{~/unless}} {{~/each}} } from '{{import.from}}';
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
import { bigintTransformer } from '@vulcanize/util';
|
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
{{#each indexOn as | index |}}
|
{{#each indexOn as | index |}}
|
||||||
{{#if index.columns}}
|
{{#if index.columns}}
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
# Don't lint build output.
|
||||||
|
dist
|
27
packages/codegen/src/templates/eslintrc-template.handlebars
Normal file
27
packages/codegen/src/templates/eslintrc-template.handlebars
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es2021": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"semistandard",
|
||||||
|
"plugin:@typescript-eslint/recommended"
|
||||||
|
],
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 12,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"@typescript-eslint"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
"@typescript-eslint/explicit-module-boundary-types": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"allowArgumentsExplicitlyTypedAsAny": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -7,11 +7,11 @@ import debug from 'debug';
|
|||||||
import { JsonFragment } from '@ethersproject/abi';
|
import { JsonFragment } from '@ethersproject/abi';
|
||||||
import { DeepPartial } from 'typeorm';
|
import { DeepPartial } from 'typeorm';
|
||||||
import JSONbig from 'json-bigint';
|
import JSONbig from 'json-bigint';
|
||||||
import { BigNumber, ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import { BaseProvider } from '@ethersproject/providers';
|
import { BaseProvider } from '@ethersproject/providers';
|
||||||
|
|
||||||
import { EthClient } from '@vulcanize/ipld-eth-client';
|
import { EthClient } from '@vulcanize/ipld-eth-client';
|
||||||
import { getStorageValue, GetStorageAt, StorageLayout } from '@vulcanize/solidity-mapper';
|
import { StorageLayout } from '@vulcanize/solidity-mapper';
|
||||||
import { EventInterface, Indexer as BaseIndexer, ValueResult, UNKNOWN_EVENT_NAME } from '@vulcanize/util';
|
import { EventInterface, Indexer as BaseIndexer, ValueResult, UNKNOWN_EVENT_NAME } from '@vulcanize/util';
|
||||||
|
|
||||||
import { Database } from './database';
|
import { Database } from './database';
|
||||||
@ -101,7 +101,6 @@ export class Indexer {
|
|||||||
{{#each queries as | query |}}
|
{{#each queries as | query |}}
|
||||||
async {{query.name}} (blockHash: string, contractAddress: string
|
async {{query.name}} (blockHash: string, contractAddress: string
|
||||||
{{~#each query.params}}, {{this.name~}}: {{this.type~}} {{/each}}): Promise<ValueResult> {
|
{{~#each query.params}}, {{this.name~}}: {{this.type~}} {{/each}}): Promise<ValueResult> {
|
||||||
|
|
||||||
const entity = await this._db.get{{capitalize query.name tillIndex=1}}({ blockHash, contractAddress
|
const entity = await this._db.get{{capitalize query.name tillIndex=1}}({ blockHash, contractAddress
|
||||||
{{~#each query.params}}, {{this.name~}} {{~/each}} });
|
{{~#each query.params}}, {{this.name~}} {{~/each}} });
|
||||||
if (entity) {
|
if (entity) {
|
||||||
@ -119,21 +118,22 @@ export class Indexer {
|
|||||||
const contract = new ethers.Contract(contractAddress, this._abi, this._ethProvider);
|
const contract = new ethers.Contract(contractAddress, this._abi, this._ethProvider);
|
||||||
|
|
||||||
const { block: { number } } = await this._ethClient.getBlockByHash(blockHash);
|
const { block: { number } } = await this._ethClient.getBlockByHash(blockHash);
|
||||||
const blockNumber = BigNumber.from(number).toNumber();
|
const blockNumber = ethers.BigNumber.from(number).toNumber();
|
||||||
|
|
||||||
|
{{#if (compare query.returnType 'bigint')}}
|
||||||
let value = await contract.{{query.name}}(
|
let value = await contract.{{query.name}}(
|
||||||
{{~#each query.params}}{{this.name}}, {{/each}}{ blockTag: blockNumber });
|
{{~#each query.params}}{{this.name}}, {{/each}}{ blockTag: blockNumber });
|
||||||
|
|
||||||
{{~#if (compare query.returnType 'bigint')}}
|
|
||||||
|
|
||||||
value = value.toString();
|
value = value.toString();
|
||||||
value = BigInt(value);
|
value = BigInt(value);
|
||||||
|
{{else}}
|
||||||
|
const value = await contract.{{query.name}}(
|
||||||
|
{{~#each query.params}}{{this.name}}, {{/each}}{ blockTag: blockNumber });
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
const result: ValueResult = { value };
|
const result: ValueResult = { value };
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{~#if (compare query.mode @root.constants.MODE_STORAGE)}}
|
{{~#if (compare query.mode @root.constants.MODE_STORAGE)}}
|
||||||
|
|
||||||
const result = await this._baseIndexer.getStorageValue(
|
const result = await this._baseIndexer.getStorageValue(
|
||||||
this._storageLayout,
|
this._storageLayout,
|
||||||
blockHash,
|
blockHash,
|
||||||
@ -152,9 +152,9 @@ export class Indexer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
async triggerIndexingOnEvent (event: Event): Promise<void> {
|
async triggerIndexingOnEvent (event: Event): Promise<void> {
|
||||||
// TODO: Implement custom hooks.
|
// TODO: Implement custom hooks.
|
||||||
|
assert(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
async processEvent (event: Event): Promise<void> {
|
async processEvent (event: Event): Promise<void> {
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"lint": "eslint .",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"server": "DEBUG=vulcanize:* ts-node src/server.ts",
|
"server": "DEBUG=vulcanize:* ts-node src/server.ts",
|
||||||
"job-runner": "DEBUG=vulcanize:* ts-node src/job-runner.ts",
|
"job-runner": "DEBUG=vulcanize:* ts-node src/job-runner.ts",
|
||||||
@ -21,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/vulcanize/watcher-ts#readme",
|
"homepage": "https://github.com/vulcanize/watcher-ts#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/client": "^3.3.19",
|
"@ethersproject/providers": "5.3.0",
|
||||||
"@vulcanize/cache": "^0.1.0",
|
"@vulcanize/cache": "^0.1.0",
|
||||||
"@vulcanize/ipld-eth-client": "^0.1.0",
|
"@vulcanize/ipld-eth-client": "^0.1.0",
|
||||||
"@vulcanize/solidity-mapper": "^0.1.0",
|
"@vulcanize/solidity-mapper": "^0.1.0",
|
||||||
@ -33,13 +34,24 @@
|
|||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"graphql": "^15.5.0",
|
"graphql": "^15.5.0",
|
||||||
"graphql-import-node": "^0.0.4",
|
"graphql-import-node": "^0.0.4",
|
||||||
|
"json-bigint": "^1.0.0",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
|
"typeorm": "^0.2.32",
|
||||||
"yargs": "^17.0.1"
|
"yargs": "^17.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ethersproject/abi": "^5.3.0",
|
"@ethersproject/abi": "^5.3.0",
|
||||||
"@types/express": "^4.17.11",
|
"@types/express": "^4.17.11",
|
||||||
"@types/yargs": "^17.0.0",
|
"@types/yargs": "^17.0.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^4.25.0",
|
||||||
|
"@typescript-eslint/parser": "^4.25.0",
|
||||||
|
"eslint": "^7.27.0",
|
||||||
|
"eslint-config-semistandard": "^15.0.1",
|
||||||
|
"eslint-config-standard": "^16.0.3",
|
||||||
|
"eslint-plugin-import": "^2.23.3",
|
||||||
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
"eslint-plugin-promise": "^5.1.0",
|
||||||
|
"eslint-plugin-standard": "^5.0.0",
|
||||||
"ts-node": "^10.0.0",
|
"ts-node": "^10.0.0",
|
||||||
"typescript": "^4.3.2"
|
"typescript": "^4.3.2"
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,12 @@
|
|||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
import Handlebars from 'handlebars';
|
import Handlebars from 'handlebars';
|
||||||
|
|
||||||
|
import { bannedTypes } from './types';
|
||||||
|
|
||||||
export function registerHandlebarHelpers (): void {
|
export function registerHandlebarHelpers (): void {
|
||||||
Handlebars.registerHelper('compare', compareHelper);
|
Handlebars.registerHelper('compare', compareHelper);
|
||||||
Handlebars.registerHelper('capitalize', capitalizeHelper);
|
Handlebars.registerHelper('capitalize', capitalizeHelper);
|
||||||
|
Handlebars.registerHelper('banTypeCheck', banTypeCheckHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,3 +53,7 @@ function capitalizeHelper (value: string, options: any): string {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function banTypeCheckHelper (value: string): boolean {
|
||||||
|
return bannedTypes.has(value);
|
||||||
|
}
|
||||||
|
@ -6,3 +6,7 @@ export interface Param {
|
|||||||
name: string;
|
name: string;
|
||||||
type: string;
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const bannedTypes = new Set([
|
||||||
|
'Symbol'
|
||||||
|
]);
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
"homepage": "https://github.com/vulcanize/watcher-ts#readme",
|
"homepage": "https://github.com/vulcanize/watcher-ts#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/client": "^3.3.19",
|
"@apollo/client": "^3.3.19",
|
||||||
|
"@ethersproject/providers": "5.3.0",
|
||||||
"@types/lodash": "^4.14.168",
|
"@types/lodash": "^4.14.168",
|
||||||
"@vulcanize/cache": "^0.1.0",
|
"@vulcanize/cache": "^0.1.0",
|
||||||
"@vulcanize/ipld-eth-client": "^0.1.0",
|
"@vulcanize/ipld-eth-client": "^0.1.0",
|
||||||
@ -63,7 +64,6 @@
|
|||||||
"@ethersproject/abi": "^5.3.0",
|
"@ethersproject/abi": "^5.3.0",
|
||||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||||
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
||||||
"@openzeppelin/contracts": "^4.3.1",
|
|
||||||
"@types/express": "^4.17.11",
|
"@types/express": "^4.17.11",
|
||||||
"@types/json-bigint": "^1.0.0",
|
"@types/json-bigint": "^1.0.0",
|
||||||
"@types/yargs": "^17.0.0",
|
"@types/yargs": "^17.0.0",
|
||||||
|
10
yarn.lock
10
yarn.lock
@ -1979,11 +1979,6 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz#371c67ebffe50f551c3146a9eec5fe6ffe862e92"
|
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz#371c67ebffe50f551c3146a9eec5fe6ffe862e92"
|
||||||
integrity sha512-tAG9LWg8+M2CMu7hIsqHPaTyG4uDzjr6mhvH96LvOpLZZj6tgzTluBt+LsCf1/QaYrlis6pITvpIaIhE+iZB+Q==
|
integrity sha512-tAG9LWg8+M2CMu7hIsqHPaTyG4uDzjr6mhvH96LvOpLZZj6tgzTluBt+LsCf1/QaYrlis6pITvpIaIhE+iZB+Q==
|
||||||
|
|
||||||
"@openzeppelin/contracts@^4.3.1":
|
|
||||||
version "4.3.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.3.1.tgz#c01f791ce6c9d3989ac1a643267501dbe336b9e3"
|
|
||||||
integrity sha512-QjgbPPlmDK2clK1hzjw2ROfY8KA5q+PfhDUUxZFEBCZP9fi6d5FuNoh/Uq0oCTMEKPmue69vhX2jcl0N/tFKGw==
|
|
||||||
|
|
||||||
"@openzeppelin/contracts@^4.3.2":
|
"@openzeppelin/contracts@^4.3.2":
|
||||||
version "4.3.2"
|
version "4.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.3.2.tgz#ff80affd6d352dbe1bbc5b4e1833c41afd6283b6"
|
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.3.2.tgz#ff80affd6d352dbe1bbc5b4e1833c41afd6283b6"
|
||||||
@ -2400,6 +2395,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-1.8.0.tgz#682477dbbbd07cd032731cb3b0e7eaee3d026b69"
|
resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-1.8.0.tgz#682477dbbbd07cd032731cb3b0e7eaee3d026b69"
|
||||||
integrity sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA==
|
integrity sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA==
|
||||||
|
|
||||||
|
"@types/js-yaml@^4.0.3":
|
||||||
|
version "4.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.3.tgz#9f33cd6fbf0d5ec575dc8c8fc69c7fec1b4eb200"
|
||||||
|
integrity sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg==
|
||||||
|
|
||||||
"@types/json-bigint@^1.0.0":
|
"@types/json-bigint@^1.0.0":
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/json-bigint/-/json-bigint-1.0.0.tgz#7a4726540cc6fe47cfa54b9b3022b89cf7fe1517"
|
resolved "https://registry.yarnpkg.com/@types/json-bigint/-/json-bigint-1.0.0.tgz#7a4726540cc6fe47cfa54b9b3022b89cf7fe1517"
|
||||||
|
Loading…
Reference in New Issue
Block a user