From ba64d232bb4257b25a815334ea2d277d856acaa5 Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux <hugo@trentesaux.fr> Date: Wed, 6 Dec 2023 15:51:51 +0100 Subject: [PATCH] [feat] add smith certs by copy-pasting certs --- README.md | 11 +- ...14613514-Data.js => 1701873131980-Data.js} | 24 ++- schema.graphql | 18 ++ src/genesis.ts | 8 +- src/main.ts | 169 +++++++++++++++++- src/model/generated/index.ts | 3 + src/model/generated/smithCert.model.ts | 23 ++- .../generated/smithCertCreation.model.ts | 19 ++ src/model/generated/smithCertRemoval.model.ts | 19 ++ src/model/generated/smithCertRenewal.model.ts | 19 ++ 10 files changed, 305 insertions(+), 8 deletions(-) rename db/migrations/{1701814613514-Data.js => 1701873131980-Data.js} (88%) create mode 100644 src/model/generated/smithCertCreation.model.ts create mode 100644 src/model/generated/smithCertRemoval.model.ts create mode 100644 src/model/generated/smithCertRenewal.model.ts diff --git a/README.md b/README.md index cd0ba00..5fd76e2 100644 --- a/README.md +++ b/README.md @@ -120,10 +120,17 @@ See https://duniter.org/wiki/duniter-v2/indexers/duniter-squid/ - [ ] membership.MembershipRequested - [ ] membership.MembershipRevoked - [ ] membership.PendingMembershipExpired + - [ ] smithMembership.MembershipAcquired + - [ ] smithMembership.MembershipExpired + - [ ] smithMembership.MembershipRenewed + - [ ] smithMembership.MembershipRequested + - [ ] smithMembership.MembershipRevoked + - [ ] smithMembership.PendingMembershipExpired - [x] account.AccountLinked - [x] account.AccountUnlinked - [x] cert.NewCert TODO if the cert is already existing, what to do? - [x] cert.RenewedCert - [x] cert.RemovedCert - - [ ] smithCert.NewCert - - [ ] smithCert.RenewedCert + - [x] smithCert.NewCert + - [x] smithCert.RenewedCert + - [x] smithCert.RemovedCert diff --git a/db/migrations/1701814613514-Data.js b/db/migrations/1701873131980-Data.js similarity index 88% rename from db/migrations/1701814613514-Data.js rename to db/migrations/1701873131980-Data.js index 26e545b..5daca7d 100644 --- a/db/migrations/1701814613514-Data.js +++ b/db/migrations/1701873131980-Data.js @@ -1,5 +1,5 @@ -module.exports = class Data1701814613514 { - name = 'Data1701814613514' +module.exports = class Data1701873131980 { + name = 'Data1701873131980' async up(db) { await db.query(`CREATE TABLE "event" ("id" character varying NOT NULL, "index" integer NOT NULL, "phase" text NOT NULL, "pallet" text NOT NULL, "name" text NOT NULL, "args" jsonb, "args_str" text array, "block_id" character varying, "extrinsic_id" character varying, "call_id" character varying, CONSTRAINT "PK_30c2f3bbaf6d34a55f8ae6e4614" PRIMARY KEY ("id"))`) @@ -47,7 +47,13 @@ module.exports = class Data1701814613514 { await db.query(`CREATE TABLE "cert" ("id" character varying NOT NULL, "active" boolean NOT NULL, "created_on" integer NOT NULL, "expire_on" integer NOT NULL, "issuer_id" character varying, "receiver_id" character varying, CONSTRAINT "PK_6a0ce80cc860598b4f16c00998c" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_70592e488b2e75cd8a2fa79826" ON "cert" ("issuer_id") `) await db.query(`CREATE INDEX "IDX_262e29ab91c8ebc727cc518f2f" ON "cert" ("receiver_id") `) - await db.query(`CREATE TABLE "smith_cert" ("id" character varying NOT NULL, "issuer_id" character varying, "receiver_id" character varying, CONSTRAINT "PK_ae2ef36c9f6d40348c86230fd35" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "smith_cert_creation" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "cert_id" character varying, CONSTRAINT "PK_8216944178a0c558d9d2936125b" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_4ce4665e97ce9d1f711ea638c3" ON "smith_cert_creation" ("cert_id") `) + await db.query(`CREATE TABLE "smith_cert_renewal" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "cert_id" character varying, CONSTRAINT "PK_163e552bb48db2b26dc20dde54b" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_e5ad5606c3f0bc6d67653496f6" ON "smith_cert_renewal" ("cert_id") `) + await db.query(`CREATE TABLE "smith_cert_removal" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "cert_id" character varying, CONSTRAINT "PK_3f66d1fbae04ed3095e48d223b7" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_2cdaac89065f75d23428631378" ON "smith_cert_removal" ("cert_id") `) + await db.query(`CREATE TABLE "smith_cert" ("id" character varying NOT NULL, "active" boolean NOT NULL, "created_on" integer NOT NULL, "expire_on" integer NOT NULL, "issuer_id" character varying, "receiver_id" character varying, CONSTRAINT "PK_ae2ef36c9f6d40348c86230fd35" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_ae67cbd087fcea0e1ec2f70cd0" ON "smith_cert" ("issuer_id") `) await db.query(`CREATE INDEX "IDX_5e414c1d12af16165881a16b63" ON "smith_cert" ("receiver_id") `) await db.query(`CREATE TABLE "change_owner_key" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "identity_id" character varying, "previous_id" character varying, "next_id" character varying, CONSTRAINT "PK_bc0eb6d98434c5b8b2250752395" PRIMARY KEY ("id"))`) @@ -81,6 +87,9 @@ module.exports = class Data1701814613514 { await db.query(`ALTER TABLE "cert_removal" ADD CONSTRAINT "FK_2efb6397676a3b82bde7631ed03" FOREIGN KEY ("cert_id") REFERENCES "cert"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "cert" ADD CONSTRAINT "FK_70592e488b2e75cd8a2fa798261" FOREIGN KEY ("issuer_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "cert" ADD CONSTRAINT "FK_262e29ab91c8ebc727cc518f2fb" FOREIGN KEY ("receiver_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "smith_cert_creation" ADD CONSTRAINT "FK_4ce4665e97ce9d1f711ea638c35" FOREIGN KEY ("cert_id") REFERENCES "smith_cert"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "smith_cert_renewal" ADD CONSTRAINT "FK_e5ad5606c3f0bc6d67653496f6b" FOREIGN KEY ("cert_id") REFERENCES "smith_cert"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "smith_cert_removal" ADD CONSTRAINT "FK_2cdaac89065f75d234286313789" FOREIGN KEY ("cert_id") REFERENCES "smith_cert"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "smith_cert" ADD CONSTRAINT "FK_ae67cbd087fcea0e1ec2f70cd04" FOREIGN KEY ("issuer_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "smith_cert" ADD CONSTRAINT "FK_5e414c1d12af16165881a16b638" FOREIGN KEY ("receiver_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "change_owner_key" ADD CONSTRAINT "FK_af577baa612d86d98a1ae583438" FOREIGN KEY ("identity_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) @@ -138,6 +147,12 @@ module.exports = class Data1701814613514 { await db.query(`DROP TABLE "cert"`) await db.query(`DROP INDEX "public"."IDX_70592e488b2e75cd8a2fa79826"`) await db.query(`DROP INDEX "public"."IDX_262e29ab91c8ebc727cc518f2f"`) + await db.query(`DROP TABLE "smith_cert_creation"`) + await db.query(`DROP INDEX "public"."IDX_4ce4665e97ce9d1f711ea638c3"`) + await db.query(`DROP TABLE "smith_cert_renewal"`) + await db.query(`DROP INDEX "public"."IDX_e5ad5606c3f0bc6d67653496f6"`) + await db.query(`DROP TABLE "smith_cert_removal"`) + await db.query(`DROP INDEX "public"."IDX_2cdaac89065f75d23428631378"`) await db.query(`DROP TABLE "smith_cert"`) await db.query(`DROP INDEX "public"."IDX_ae67cbd087fcea0e1ec2f70cd0"`) await db.query(`DROP INDEX "public"."IDX_5e414c1d12af16165881a16b63"`) @@ -172,6 +187,9 @@ module.exports = class Data1701814613514 { await db.query(`ALTER TABLE "cert_removal" DROP CONSTRAINT "FK_2efb6397676a3b82bde7631ed03"`) await db.query(`ALTER TABLE "cert" DROP CONSTRAINT "FK_70592e488b2e75cd8a2fa798261"`) await db.query(`ALTER TABLE "cert" DROP CONSTRAINT "FK_262e29ab91c8ebc727cc518f2fb"`) + await db.query(`ALTER TABLE "smith_cert_creation" DROP CONSTRAINT "FK_4ce4665e97ce9d1f711ea638c35"`) + await db.query(`ALTER TABLE "smith_cert_renewal" DROP CONSTRAINT "FK_e5ad5606c3f0bc6d67653496f6b"`) + await db.query(`ALTER TABLE "smith_cert_removal" DROP CONSTRAINT "FK_2cdaac89065f75d234286313789"`) await db.query(`ALTER TABLE "smith_cert" DROP CONSTRAINT "FK_ae67cbd087fcea0e1ec2f70cd04"`) await db.query(`ALTER TABLE "smith_cert" DROP CONSTRAINT "FK_5e414c1d12af16165881a16b638"`) await db.query(`ALTER TABLE "change_owner_key" DROP CONSTRAINT "FK_af577baa612d86d98a1ae583438"`) diff --git a/schema.graphql b/schema.graphql index 29d7a91..a1d52cf 100644 --- a/schema.graphql +++ b/schema.graphql @@ -207,6 +207,24 @@ type CertRemoval @entity { type SmithCert @entity { issuer: Identity! receiver: Identity! + active: Boolean! + createdOn: Int! + expireOn: Int! + creation: [SmithCertCreation!] @derivedFrom(field: "cert") + renewal: [SmithCertRenewal!] @derivedFrom(field: "cert") + removal: [SmithCertRemoval!] @derivedFrom(field: "cert") +} +type SmithCertCreation @entity { + cert: SmithCert! @index + blockNumber: Int! +} +type SmithCertRenewal @entity { + cert: SmithCert! @index + blockNumber: Int! +} +type SmithCertRemoval @entity { + cert: SmithCert! @index + blockNumber: Int! } "Membership" diff --git a/src/genesis.ts b/src/genesis.ts index d959e6b..5a3e9b3 100644 --- a/src/genesis.ts +++ b/src/genesis.ts @@ -2,6 +2,7 @@ import type { Address, IdtyIndex, Ctx } from "./main"; import { readFileSync } from "fs"; import { Account, Cert, SmithCert, Identity, Membership, SmithMembership, Transfer, ChangeOwnerKey } from "./model"; import path from "path/posix"; +import { constants } from "./types"; // define genesis interfaces // duniter build-spec --chain gdev_dev 1> ./specs.json @@ -121,7 +122,7 @@ export async function saveGenesis(ctx: Ctx) { let old_account = accounts.get(old_account_id); if (old_account == null) { // this can happen if the old account is emptied from its content - old_account = new Account({id: old_account_id}); + old_account = new Account({ id: old_account_id }); accounts.set(old_account_id, old_account); } chok.push( @@ -156,11 +157,16 @@ export async function saveGenesis(ctx: Ctx) { // collect smith certs for (const [receiver_index, certs_received] of Object.entries(genesis.smithCert.certsByReceiver)) { for (const [issuer_index, expiration_block] of Object.entries(certs_received)) { + // WARN null smith cert expiration block + let non_null_expiration_block: number = expiration_block as number ?? 2102400; smithCerts.push( new SmithCert({ id: `genesis-${issuer_index}-${receiver_index}`, + active: true, issuer: identities.get(parseInt(issuer_index)), receiver: identities.get(parseInt(receiver_index)), + createdOn: 0, + expireOn: non_null_expiration_block, }) ); } diff --git a/src/main.ts b/src/main.ts index 174a82c..99f5cf4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,7 +3,20 @@ import { StoreWithCache, TypeormDatabaseWithCache } from "@belopash/typeorm-stor import * as ss58 from "@subsquid/ss58"; import assert from "assert"; import { processor, ProcessorContext } from "./processor"; -import { Account, Cert, CertCreation, CertRemoval, CertRenewal, ChangeOwnerKey, Identity, Transfer } from "./model"; +import { + Account, + Cert, + CertCreation, + CertRemoval, + CertRenewal, + SmithCert, + SmithCertCreation, + SmithCertRemoval, + SmithCertRenewal, + ChangeOwnerKey, + Identity, + Transfer, +} from "./model"; import { events as events_t, calls as calls_t, constants } from "./types"; import { saveBlock, saveExtrinsic, saveCall, saveEvent } from "./giant-squid"; import { saveGenesis } from "./genesis"; @@ -45,6 +58,9 @@ processor.run(new TypeormDatabaseWithCache(), async (ctx) => { certCreation: [], certRenewal: [], certRemoval: [], + smithCertCreation: [], + smithCertRenewal: [], + smithCertRemoval: [], accountLink: [], accountUnlink: [], }; @@ -60,6 +76,10 @@ processor.run(new TypeormDatabaseWithCache(), async (ctx) => { certCreation: [], certRenewal: [], certRemoval: [], + smithCert: new Map(), + smithCertCreation: [], + smithCertRenewal: [], + smithCertRemoval: [], }; await prepareData(ctx, ndata, data); @@ -97,6 +117,9 @@ interface NewData { certCreation: CertCreationEvent[]; certRenewal: CertRenewalEvent[]; certRemoval: CertRemovalEvent[]; + smithCertCreation: CertCreationEvent[]; + smithCertRenewal: CertRenewalEvent[]; + smithCertRemoval: CertRemovalEvent[]; accountLink: AccountLinkEvent[]; accountUnlink: AccountUnlinkEvent[]; } @@ -163,6 +186,10 @@ interface Data { certCreation: CertCreation[]; certRenewal: CertRenewal[]; certRemoval: CertRemoval[]; + smithCert: Map<[IdtyIndex, IdtyIndex], Cert>; + smithCertCreation: CertCreation[]; + smithCertRenewal: CertRenewal[]; + smithCertRemoval: CertRemoval[]; } // ================================================================================ @@ -224,6 +251,7 @@ function getNewData(ctx: Ctx, ndata: NewData) { }); break; + // ====================================================== Identity // ===== Identity.IdtyCreated case events_t.identity.idtyCreated.name: let newI: { idtyIndex: IdtyIndex; ownerKey: Address }; @@ -327,6 +355,64 @@ function getNewData(ctx: Ctx, ndata: NewData) { }); break; + // ====================================================== SmithCert + // ===== SmithCert.NewCert + case events_t.smithCert.newCert.name: + let scert: { issuer: IdtyIndex; receiver: IdtyIndex }; + if (events_t.smithCert.newCert.v700.is(event)) { + scert = events_t.smithCert.newCert.v700.decode(event); + } else { + throw new Error("Unsupported spec"); + } + ndata.smithCertCreation.push({ + id: event.id, // the id of the cert will be this forever + issuerId: scert.issuer, + receiverId: scert.receiver, + createdOn: block.header.height, + expireOn: block.header.height + constants.smithCert.validityPeriod.v700.get(event.block), + }); + break; + + // ===== SmithCert.RenewCert + case events_t.smithCert.renewedCert.name: + let srecert: { issuer: IdtyIndex; receiver: IdtyIndex }; + if (events_t.smithCert.renewedCert.v700.is(event)) { + srecert = events_t.smithCert.renewedCert.v700.decode(event); + } else { + throw new Error("Unsupported spec"); + } + ndata.smithCertRenewal.push({ + id: event.id, + issuerId: srecert.issuer, + receiverId: srecert.receiver, + blockNumber: block.header.height, + expireOn: block.header.height + constants.smithCert.validityPeriod.v700.get(event.block), + }); + break; + + // ===== SmithCert.RemovedCert + case events_t.smithCert.removedCert.name: + let sremcert: { + issuer: IdtyIndex; + issuerIssuedCount: number; + receiver: IdtyIndex; + receiverReceivedCount: number; + expiration: boolean; + }; + if (events_t.smithCert.removedCert.v700.is(event)) { + sremcert = events_t.smithCert.removedCert.v700.decode(event); + } else { + throw new Error("Unsupported spec"); + } + ndata.smithCertRemoval.push({ + id: event.id, + issuerId: sremcert.issuer, + receiverId: sremcert.receiver, + blockNumber: block.header.height, + }); + break; + + // ====================================================== Account // ===== Account.AccountLinked case events_t.account.accountLinked.name: let acclink: { who: Address; identity: IdtyIndex }; @@ -373,6 +459,9 @@ async function prepareData(ctx: Ctx, newData: NewData, data: Data) { await createCerts(ctx, newData, data); await createCertRenewals(ctx, newData, data); await createCertRemovals(ctx, newData, data); + await createSmithCerts(ctx, newData, data); + await createSmithCertRenewals(ctx, newData, data); + await createSmithCertRemovals(ctx, newData, data); await updateAccountLinks(ctx, newData, data); await updateAccountUnlinks(ctx, newData, data); } @@ -441,6 +530,7 @@ async function storeData(ctx: Ctx, data: Data) { await ctx.store.upsert([...data.identities.values()]); // certs can have been changed (renewed, removed...) await ctx.store.upsert([...data.cert.values()]); + await ctx.store.upsert([...data.smithCert.values()]); // INSERT = these object can not exist before await ctx.store.insert(data.transfers); @@ -448,6 +538,9 @@ async function storeData(ctx: Ctx, data: Data) { await ctx.store.insert(data.certCreation); await ctx.store.insert(data.certRenewal); await ctx.store.insert(data.certRemoval); + await ctx.store.insert(data.smithCertCreation); + await ctx.store.insert(data.smithCertRenewal); + await ctx.store.insert(data.smithCertRemoval); } // ============================================================================================================= @@ -627,6 +720,80 @@ async function createCertRemovals(ctx: Ctx, newData: NewData, data: Data) { } } +// copy of non-smith version +async function createSmithCerts(ctx: Ctx, newData: NewData, data: Data) { + for (let c of newData.smithCertCreation) { + let { id, issuerId, receiverId, createdOn, expireOn } = c; + let cert = await ctx.store.findOne(SmithCert, { + relations: { issuer: true, receiver: true }, + where: { issuer: { index: issuerId }, receiver: { index: receiverId } }, + }); + if (cert == null) { + let issuer = await getIdtyByIndexOrFail(ctx, data, issuerId); + let receiver = await getIdtyByIndexOrFail(ctx, data, receiverId); + cert = new SmithCert({ + id, + active: true, + issuer, + receiver, + createdOn, + expireOn, + }); + } else { + cert.active = true; + cert.createdOn = createdOn; + cert.expireOn = expireOn; + } + data.cert.set([issuerId, receiverId], cert); + data.certCreation.push( + new SmithCertCreation({ + id, + cert, + blockNumber: createdOn, + }) + ); + } +} +// copy of non-smith version +async function createSmithCertRenewals(ctx: Ctx, newData: NewData, data: Data) { + for (let c of newData.smithCertRenewal) { + let { id, issuerId, receiverId, blockNumber, expireOn } = c; + let cert = await ctx.store.findOneOrFail(SmithCert, { + relations: { issuer: true, receiver: true }, + where: { issuer: { index: issuerId }, receiver: { index: receiverId } }, + }); + cert.expireOn = expireOn; + data.cert.set([issuerId, receiverId], cert); + data.certRenewal.push( + new SmithCertRenewal({ + id, + cert, + blockNumber, + }) + ); + } +} +// copy of non-smith version +async function createSmithCertRemovals(ctx: Ctx, newData: NewData, data: Data) { + for (let c of newData.smithCertRemoval) { + let { id, issuerId, receiverId, blockNumber } = c; + let cert = await ctx.store.findOneOrFail(SmithCert, { + relations: { issuer: true, receiver: true }, + where: { issuer: { index: issuerId }, receiver: { index: receiverId } }, + }); + cert.active = false; + cert.expireOn = blockNumber; + data.cert.set([issuerId, receiverId], cert); + data.certRenewal.push( + new CertRemoval({ + id, + cert, + blockNumber, + }) + ); + } +} + async function updateAccountLinks(ctx: Ctx, newData: NewData, data: Data) { for (let l of newData.accountLink) { // we can link an identity to a non-existing account diff --git a/src/model/generated/index.ts b/src/model/generated/index.ts index 92ffc73..f83dc7f 100644 --- a/src/model/generated/index.ts +++ b/src/model/generated/index.ts @@ -15,5 +15,8 @@ export * from "./certCreation.model" export * from "./certRenewal.model" export * from "./certRemoval.model" export * from "./smithCert.model" +export * from "./smithCertCreation.model" +export * from "./smithCertRenewal.model" +export * from "./smithCertRemoval.model" export * from "./membership.model" export * from "./smithMembership.model" diff --git a/src/model/generated/smithCert.model.ts b/src/model/generated/smithCert.model.ts index 1a22caa..8e546c5 100644 --- a/src/model/generated/smithCert.model.ts +++ b/src/model/generated/smithCert.model.ts @@ -1,5 +1,8 @@ -import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_} from "typeorm" +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_, OneToMany as OneToMany_} from "typeorm" import {Identity} from "./identity.model" +import {SmithCertCreation} from "./smithCertCreation.model" +import {SmithCertRenewal} from "./smithCertRenewal.model" +import {SmithCertRemoval} from "./smithCertRemoval.model" /** * Smith certification @@ -20,4 +23,22 @@ export class SmithCert { @Index_() @ManyToOne_(() => Identity, {nullable: true}) receiver!: Identity + + @Column_("bool", {nullable: false}) + active!: boolean + + @Column_("int4", {nullable: false}) + createdOn!: number + + @Column_("int4", {nullable: false}) + expireOn!: number + + @OneToMany_(() => SmithCertCreation, e => e.cert) + creation!: SmithCertCreation[] + + @OneToMany_(() => SmithCertRenewal, e => e.cert) + renewal!: SmithCertRenewal[] + + @OneToMany_(() => SmithCertRemoval, e => e.cert) + removal!: SmithCertRemoval[] } diff --git a/src/model/generated/smithCertCreation.model.ts b/src/model/generated/smithCertCreation.model.ts new file mode 100644 index 0000000..501792f --- /dev/null +++ b/src/model/generated/smithCertCreation.model.ts @@ -0,0 +1,19 @@ +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_} from "typeorm" +import {SmithCert} from "./smithCert.model" + +@Entity_() +export class SmithCertCreation { + constructor(props?: Partial<SmithCertCreation>) { + Object.assign(this, props) + } + + @PrimaryColumn_() + id!: string + + @Index_() + @ManyToOne_(() => SmithCert, {nullable: true}) + cert!: SmithCert + + @Column_("int4", {nullable: false}) + blockNumber!: number +} diff --git a/src/model/generated/smithCertRemoval.model.ts b/src/model/generated/smithCertRemoval.model.ts new file mode 100644 index 0000000..91f6290 --- /dev/null +++ b/src/model/generated/smithCertRemoval.model.ts @@ -0,0 +1,19 @@ +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_} from "typeorm" +import {SmithCert} from "./smithCert.model" + +@Entity_() +export class SmithCertRemoval { + constructor(props?: Partial<SmithCertRemoval>) { + Object.assign(this, props) + } + + @PrimaryColumn_() + id!: string + + @Index_() + @ManyToOne_(() => SmithCert, {nullable: true}) + cert!: SmithCert + + @Column_("int4", {nullable: false}) + blockNumber!: number +} diff --git a/src/model/generated/smithCertRenewal.model.ts b/src/model/generated/smithCertRenewal.model.ts new file mode 100644 index 0000000..c3b706b --- /dev/null +++ b/src/model/generated/smithCertRenewal.model.ts @@ -0,0 +1,19 @@ +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_} from "typeorm" +import {SmithCert} from "./smithCert.model" + +@Entity_() +export class SmithCertRenewal { + constructor(props?: Partial<SmithCertRenewal>) { + Object.assign(this, props) + } + + @PrimaryColumn_() + id!: string + + @Index_() + @ManyToOne_(() => SmithCert, {nullable: true}) + cert!: SmithCert + + @Column_("int4", {nullable: false}) + blockNumber!: number +} -- GitLab