mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
auto create and update hiero topic
This commit is contained in:
parent
b17c381f6c
commit
c06f82bf29
@ -2,10 +2,16 @@ import { GraphQLClient } from 'graphql-request'
|
||||
import { SignJWT } from 'jose'
|
||||
|
||||
import { CONFIG } from '../../config'
|
||||
import { communitySchema, type Community, homeCommunityGraphqlQuery } from './community.schema'
|
||||
import {
|
||||
communitySchema,
|
||||
type Community,
|
||||
homeCommunityGraphqlQuery,
|
||||
setHomeCommunityTopicId
|
||||
} from './community.schema'
|
||||
import { getLogger, Logger } from 'log4js'
|
||||
import { LOG4JS_BASE_CATEGORY } from '../../config/const'
|
||||
import * as v from 'valibot'
|
||||
import { HieroId, Uuidv4 } from '../../schemas/typeGuard.schema'
|
||||
|
||||
// Source: https://refactoring.guru/design-patterns/singleton/typescript/example
|
||||
// and ../federation/client/FederationClientFactory.ts
|
||||
@ -53,9 +59,7 @@ export class BackendClient {
|
||||
public async getHomeCommunityDraft(): Promise<Community> {
|
||||
this.logger.info('check home community on backend')
|
||||
const { data, errors } = await this.client.rawRequest<{ homeCommunity: Community }>(
|
||||
homeCommunityGraphqlQuery,
|
||||
{}, // empty variables
|
||||
await this.getRequestHeader(),
|
||||
homeCommunityGraphqlQuery, {}, await this.getRequestHeader(),
|
||||
)
|
||||
if (errors) {
|
||||
throw errors[0]
|
||||
@ -63,8 +67,15 @@ export class BackendClient {
|
||||
return v.parse(communitySchema, data.homeCommunity)
|
||||
}
|
||||
|
||||
public async setHomeCommunityTopicId(topicId: HieroId) {
|
||||
|
||||
public async setHomeCommunityTopicId(uuid: Uuidv4, hieroTopicId: HieroId): Promise<Community> {
|
||||
this.logger.info('update home community on backend')
|
||||
const { data, errors } = await this.client.rawRequest<{ updateHomeCommunity: Community }>(
|
||||
setHomeCommunityTopicId, { uuid, hieroTopicId }, await this.getRequestHeader(),
|
||||
)
|
||||
if (errors) {
|
||||
throw errors[0]
|
||||
}
|
||||
return v.parse(communitySchema, data.updateHomeCommunity)
|
||||
}
|
||||
|
||||
private async getRequestHeader(): Promise<{
|
||||
|
||||
@ -12,7 +12,7 @@ import { hieroIdSchema, uuidv4Schema } from '../../schemas/typeGuard.schema'
|
||||
*/
|
||||
export const communitySchema = v.object({
|
||||
uuid: uuidv4Schema,
|
||||
topicId: v.optional(hieroIdSchema, ''),
|
||||
topicId: v.nullish(hieroIdSchema),
|
||||
foreign: v.boolean('expect boolean type'),
|
||||
createdAt: dateSchema,
|
||||
})
|
||||
@ -31,3 +31,14 @@ export const homeCommunityGraphqlQuery = gql`
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const setHomeCommunityTopicId = gql`
|
||||
mutation ($uuid: string, $hieroTopicId: string){
|
||||
updateHomeCommunity(uuid: $uuid, hieroTopicId: $hieroTopicId) {
|
||||
uuid
|
||||
topicId
|
||||
foreign
|
||||
creationDate
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
@ -85,9 +85,9 @@ export class HieroClient {
|
||||
return balance
|
||||
}
|
||||
|
||||
public async getTopicInfo(topicId: HieroTopicId): Promise<TopicInfoOutput> {
|
||||
public async getTopicInfo(topicId: HieroId): Promise<TopicInfoOutput> {
|
||||
const info = await new TopicInfoQuery()
|
||||
.setTopicId(new TopicId(topicId.getShardNum(), topicId.getRealmNum(), topicId.getTopicNum()))
|
||||
.setTopicId(TopicId.fromString(topicId))
|
||||
.execute(this.client)
|
||||
this.logger.debug(JSON.stringify(info, null, 2))
|
||||
return parse(topicInfoSchema, {
|
||||
@ -108,9 +108,10 @@ export class HieroClient {
|
||||
return parse(hieroIdSchema, createReceipt.topicId?.toString())
|
||||
}
|
||||
|
||||
public async updateTopic(): Promise<void> {
|
||||
public async updateTopic(topicId: HieroId): Promise<void> {
|
||||
let transaction = new TopicUpdateTransaction()
|
||||
transaction.setExpirationTime(new Date(new Date().getTime() + MIN_AUTORENEW_PERIOD * 1000))
|
||||
transaction.setTopicId(TopicId.fromString(topicId))
|
||||
transaction = await transaction.freezeWithSigner(this.wallet)
|
||||
transaction = await transaction.signWithSigner(this.wallet)
|
||||
const updateResponse = await transaction.executeWithSigner(this.wallet)
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import * as v from 'valibot'
|
||||
import { hieroIdSchema } from '../../schemas/typeGuard.schema'
|
||||
import { dateSchema } from '../../schemas/typeConverter.schema'
|
||||
|
||||
// schema definitions for exporting data from hiero request as json back to caller
|
||||
/*export const dateStringSchema = v.pipe(
|
||||
@ -7,28 +8,12 @@ import { hieroIdSchema } from '../../schemas/typeGuard.schema'
|
||||
v.transform(in: string | Date)
|
||||
|
||||
)*/
|
||||
export const dateStringSchema = v.pipe(
|
||||
v.union([v.string('expect valid date string'), v.instance(Date, 'expect Date object')]),
|
||||
v.transform<string | Date, string>((input) => {
|
||||
let date: Date
|
||||
if (input instanceof Date) {
|
||||
date = input
|
||||
} else {
|
||||
date = new Date(input)
|
||||
}
|
||||
if (isNaN(date.getTime())) {
|
||||
throw new Error('invalid date')
|
||||
}
|
||||
return date.toISOString()
|
||||
}),
|
||||
)
|
||||
|
||||
export const positiveNumberSchema = v.pipe(v.number(), v.minValue(0))
|
||||
|
||||
export const topicInfoSchema = v.object({
|
||||
topicId: hieroIdSchema,
|
||||
sequenceNumber: positiveNumberSchema,
|
||||
expirationTime: dateStringSchema,
|
||||
expirationTime: dateSchema,
|
||||
autoRenewPeriod: v.optional(positiveNumberSchema, 0),
|
||||
autoRenewAccountId: v.optional(hieroIdSchema, '0.0.0'),
|
||||
})
|
||||
|
||||
@ -1 +1,3 @@
|
||||
export const LOG4JS_BASE_CATEGORY = 'dlt'
|
||||
// 7 days
|
||||
export const MIN_TOPIC_EXPIRE_MILLISECONDS_FOR_UPDATE = 1000 * 60 * 60 * 24 * 7
|
||||
@ -12,6 +12,7 @@ import { KeyPairCacheManager } from './KeyPairCacheManager'
|
||||
import { keyGenerationSeedSchema } from './schemas/base.schema'
|
||||
import { isPortOpenRetry } from './utils/network'
|
||||
import { appRoutes } from './server'
|
||||
import { MIN_TOPIC_EXPIRE_MILLISECONDS_FOR_UPDATE } from './config/const'
|
||||
|
||||
async function main() {
|
||||
// configure log4js
|
||||
@ -36,13 +37,28 @@ async function main() {
|
||||
if (!backend) {
|
||||
throw new Error('cannot create backend client')
|
||||
}
|
||||
const hieroClient = HieroClient.getInstance()
|
||||
if (!hieroClient) {
|
||||
throw new Error('cannot create hiero client')
|
||||
}
|
||||
// wait for backend server
|
||||
await isPortOpenRetry(CONFIG.BACKEND_SERVER_URL)
|
||||
const homeCommunity = await backend.getHomeCommunityDraft()
|
||||
let homeCommunity = await backend.getHomeCommunityDraft()
|
||||
// on missing topicId, create one
|
||||
if (!homeCommunity.topicId) {
|
||||
const topicId = await HieroClient.getInstance().createTopic()
|
||||
|
||||
const topicId = await hieroClient.createTopic()
|
||||
homeCommunity = await backend.setHomeCommunityTopicId(homeCommunity.uuid, topicId)
|
||||
} else {
|
||||
// if topic exist, check if we need to update it
|
||||
let topicInfo = await hieroClient.getTopicInfo(homeCommunity.topicId)
|
||||
if (topicInfo.expirationTime.getTime() - new Date().getTime() < MIN_TOPIC_EXPIRE_MILLISECONDS_FOR_UPDATE) {
|
||||
await hieroClient.updateTopic(homeCommunity.topicId)
|
||||
topicInfo = await hieroClient.getTopicInfo(homeCommunity.topicId)
|
||||
logger.info('updated topic info, new expiration time: %s', topicInfo.expirationTime.toLocaleDateString())
|
||||
}
|
||||
}
|
||||
if (!homeCommunity.topicId) {
|
||||
throw new Error('still no topic id, after creating topic and update community in backend.')
|
||||
}
|
||||
KeyPairCacheManager.getInstance().setHomeCommunityTopicId(homeCommunity.topicId)
|
||||
logger.info('home community topic: %s', homeCommunity.topicId)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user