mirror of
https://github.com/IT4Change/gradido.git
synced 2026-04-06 01:25:28 +00:00
add option, fix type errors because of changes regarding need of communityId on some places
This commit is contained in:
parent
f45705e714
commit
10334f5a46
@ -1,5 +1,5 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { loadCryptoKeys, MemoryBlock } from 'gradido-blockchain-js'
|
||||
import { InMemoryBlockchainProvider, loadCryptoKeys, MemoryBlock } from 'gradido-blockchain-js'
|
||||
import { configure, getLogger, Logger } from 'log4js'
|
||||
import * as v from 'valibot'
|
||||
import { CONFIG } from '../config'
|
||||
@ -80,6 +80,7 @@ export async function checkGradidoNode(
|
||||
|
||||
// ask gradido node if community blockchain was created
|
||||
try {
|
||||
InMemoryBlockchainProvider.getInstance().getBlockchain(homeCommunity.uuid)
|
||||
if (
|
||||
!(await clients.gradidoNode.getTransaction({
|
||||
transactionId: 1,
|
||||
|
||||
@ -9,7 +9,6 @@ import { HieroClient } from '../client/hiero/HieroClient'
|
||||
import { CONFIG } from '../config'
|
||||
import {
|
||||
GRADIDO_NODE_HOME_FOLDER_NAME,
|
||||
GRADIDO_NODE_RUNTIME_PATH,
|
||||
LOG4JS_BASE_CATEGORY,
|
||||
} from '../config/const'
|
||||
import { checkFileExist, checkPathExist } from '../utils/filesystem'
|
||||
@ -37,7 +36,7 @@ export async function initGradidoNode(clients: AppContextClients): Promise<void>
|
||||
// write Hedera Address Book
|
||||
exportHederaAddressbooks(gradidoNodeHomeFolder, clients.hiero),
|
||||
// check GradidoNode Runtime, download when missing
|
||||
ensureGradidoNodeRuntimeAvailable(GRADIDO_NODE_RUNTIME_PATH),
|
||||
ensureGradidoNodeRuntimeAvailable(GradidoNodeProcess.getRuntimePathFileName()),
|
||||
// export communities to GradidoNode Folder
|
||||
exportCommunities(gradidoNodeHomeFolder, clients.backend),
|
||||
])
|
||||
|
||||
@ -8,7 +8,7 @@ import { LOG4JS_BASE_CATEGORY } from '../../config/const'
|
||||
import { AddressType } from '../../data/AddressType.enum'
|
||||
import { Uuidv4Hash } from '../../data/Uuidv4Hash'
|
||||
import { addressTypeSchema, confirmedTransactionSchema } from '../../schemas/typeConverter.schema'
|
||||
import { Hex32, Hex32Input, HieroId, hex32Schema } from '../../schemas/typeGuard.schema'
|
||||
import { Hex32, Hex32Input, Uuidv4, hex32Schema } from '../../schemas/typeGuard.schema'
|
||||
import { isPortOpenRetry } from '../../utils/network'
|
||||
import { GradidoNodeErrorCodes } from './GradidoNodeErrorCodes'
|
||||
import {
|
||||
@ -75,7 +75,7 @@ export class GradidoNodeClient {
|
||||
const response = await this.rpcCall<{ transaction: string }>('getTransaction', parameter)
|
||||
if (response.isSuccess()) {
|
||||
// this.logger.debug('result: ', response.result.transaction)
|
||||
return v.parse(confirmedTransactionSchema, response.result.transaction)
|
||||
return v.parse(confirmedTransactionSchema, { base64: response.result.transaction, communityId: parameter.communityId })
|
||||
}
|
||||
if (response.isError()) {
|
||||
if (response.error.code === GradidoNodeErrorCodes.TRANSACTION_NOT_FOUND) {
|
||||
@ -88,19 +88,19 @@ export class GradidoNodeClient {
|
||||
/**
|
||||
* getLastTransaction
|
||||
* get the last confirmed transaction from a specific community
|
||||
* @param hieroTopic the community hiero topic id
|
||||
* @param communityId the community id
|
||||
* @returns the last confirmed transaction or undefined if blockchain for community is empty or not found
|
||||
* @throws GradidoNodeRequestError
|
||||
*/
|
||||
|
||||
public async getLastTransaction(hieroTopic: HieroId): Promise<ConfirmedTransaction | undefined> {
|
||||
public async getLastTransaction(communityId: Uuidv4): Promise<ConfirmedTransaction | undefined> {
|
||||
const parameter = {
|
||||
format: 'base64',
|
||||
topic: hieroTopic,
|
||||
communityId,
|
||||
}
|
||||
const response = await this.rpcCall<{ transaction: string }>('getLastTransaction', parameter)
|
||||
if (response.isSuccess()) {
|
||||
return v.parse(confirmedTransactionSchema, response.result.transaction)
|
||||
return v.parse(confirmedTransactionSchema, { base64: response.result.transaction, communityId: parameter.communityId })
|
||||
}
|
||||
if (response.isError()) {
|
||||
if (response.error.code === GradidoNodeErrorCodes.GRADIDO_NODE_ERROR) {
|
||||
@ -115,7 +115,7 @@ export class GradidoNodeClient {
|
||||
* get list of confirmed transactions from a specific community
|
||||
* @param input fromTransactionId is the id of the first transaction to return
|
||||
* @param input maxResultCount is the max number of transactions to return
|
||||
* @param input topic is the community hiero topic id
|
||||
* @param input communityId is the community id
|
||||
* @returns list of confirmed transactions
|
||||
* @throws GradidoNodeRequestError
|
||||
* @example
|
||||
@ -123,7 +123,7 @@ export class GradidoNodeClient {
|
||||
* const transactions = await getTransactions({
|
||||
* fromTransactionId: 1,
|
||||
* maxResultCount: 100,
|
||||
* topic: communityUuid,
|
||||
* communityId: communityUuid,
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
@ -137,7 +137,7 @@ export class GradidoNodeClient {
|
||||
parameter,
|
||||
)
|
||||
return result.transactions.map((transactionBase64) =>
|
||||
v.parse(confirmedTransactionSchema, transactionBase64),
|
||||
v.parse(confirmedTransactionSchema, { base64: transactionBase64, communityId: parameter.communityId }),
|
||||
)
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ export class GradidoNodeClient {
|
||||
parameter,
|
||||
)
|
||||
return response.transactions.map((transactionBase64) =>
|
||||
v.parse(confirmedTransactionSchema, transactionBase64),
|
||||
v.parse(confirmedTransactionSchema, { base64: transactionBase64, communityId: parameter.communityId }),
|
||||
)
|
||||
}
|
||||
|
||||
@ -173,15 +173,15 @@ export class GradidoNodeClient {
|
||||
* can be used to check if user/account exists on blockchain
|
||||
* look also for gmw, auf and deferred transfer accounts
|
||||
* @param pubkey the public key of the user or account
|
||||
* @param hieroTopic the community hiero topic id
|
||||
* @param communityId the community id
|
||||
* @returns the address type of the user/account, AddressType.NONE if not found
|
||||
* @throws GradidoNodeRequestError
|
||||
*/
|
||||
|
||||
public async getAddressType(pubkey: Hex32Input, hieroTopic: HieroId): Promise<AddressType> {
|
||||
public async getAddressType(pubkey: Hex32Input, communityId: Uuidv4): Promise<AddressType> {
|
||||
const parameter = {
|
||||
pubkey: v.parse(hex32Schema, pubkey),
|
||||
topic: hieroTopic,
|
||||
communityId,
|
||||
}
|
||||
const response = await this.rpcCallResolved<{ addressType: string }>(
|
||||
'getAddressType',
|
||||
@ -194,17 +194,17 @@ export class GradidoNodeClient {
|
||||
* findUserByNameHash
|
||||
* find a user by name hash
|
||||
* @param nameHash the name hash of the user
|
||||
* @param hieroTopic the community hiero topic id
|
||||
* @param communityId the community id
|
||||
* @returns the public key of the user as hex32 string or undefined if user is not found
|
||||
* @throws GradidoNodeRequestError
|
||||
*/
|
||||
public async findUserByNameHash(
|
||||
nameHash: Uuidv4Hash,
|
||||
hieroTopic: HieroId,
|
||||
communityId: Uuidv4,
|
||||
): Promise<Hex32 | undefined> {
|
||||
const parameter = {
|
||||
nameHash: nameHash.getAsHexString(),
|
||||
topic: hieroTopic,
|
||||
communityId,
|
||||
}
|
||||
const response = await this.rpcCall<{ pubkey: string; timeUsed: string }>(
|
||||
'findUserByNameHash',
|
||||
|
||||
@ -10,6 +10,7 @@ import {
|
||||
LOG4JS_BASE_CATEGORY,
|
||||
} from '../../config/const'
|
||||
import { delay } from '../../utils/time'
|
||||
import path from 'node:path'
|
||||
/**
|
||||
* A Singleton class defines the `getInstance` method that lets clients access
|
||||
* the unique singleton instance.
|
||||
@ -43,6 +44,20 @@ export class GradidoNodeProcess {
|
||||
return GradidoNodeProcess.instance
|
||||
}
|
||||
|
||||
public static getRuntimePathFileName(): string {
|
||||
const isWindows = process.platform === 'win32'
|
||||
const binaryName = isWindows ? 'GradidoNode.exe' : 'GradidoNode'
|
||||
|
||||
return path.join(
|
||||
__dirname,
|
||||
'..',
|
||||
'..',
|
||||
'gradido_node',
|
||||
'bin',
|
||||
binaryName,
|
||||
)
|
||||
}
|
||||
|
||||
public start() {
|
||||
if (this.proc) {
|
||||
this.logger.warn('GradidoNodeProcess already running.')
|
||||
@ -57,6 +72,7 @@ export class GradidoNodeProcess {
|
||||
SERVER_JSON_RPC_PORT: CONFIG.DLT_NODE_SERVER_PORT.toString(),
|
||||
USERPROFILE: CONFIG.DLT_GRADIDO_NODE_SERVER_HOME_FOLDER,
|
||||
HOME: CONFIG.DLT_GRADIDO_NODE_SERVER_HOME_FOLDER,
|
||||
UNSECURE_ALLOW_CORS_ALL: CONFIG.DLT_GRADIDO_NODE_SERVER_ALLOW_CORS ? '1' : '0',
|
||||
},
|
||||
onExit(_proc, exitCode, signalCode, error) {
|
||||
logger.warn(`GradidoNodeProcess exited with code ${exitCode} and signalCode ${signalCode}`)
|
||||
|
||||
@ -1,18 +1,20 @@
|
||||
import { beforeAll, describe, expect, it } from 'bun:test'
|
||||
import * as v from 'valibot'
|
||||
import {
|
||||
HieroId,
|
||||
HieroTransactionIdString,
|
||||
Uuidv4,
|
||||
hieroIdSchema,
|
||||
hieroTransactionIdStringSchema,
|
||||
uuidv4Schema,
|
||||
} from '../../schemas/typeGuard.schema'
|
||||
import { transactionIdentifierSchema } from './input.schema'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
let topic: HieroId
|
||||
const topicString = '0.0.261'
|
||||
let communityId: Uuidv4
|
||||
const uuidv4String = uuidv4()
|
||||
let hieroTransactionId: HieroTransactionIdString
|
||||
beforeAll(() => {
|
||||
topic = v.parse(hieroIdSchema, topicString)
|
||||
communityId = v.parse(uuidv4Schema, uuidv4String)
|
||||
hieroTransactionId = v.parse(hieroTransactionIdStringSchema, '0.0.261-1755348116-1281621')
|
||||
})
|
||||
|
||||
@ -21,26 +23,26 @@ describe('transactionIdentifierSchema ', () => {
|
||||
expect(
|
||||
v.parse(transactionIdentifierSchema, {
|
||||
transactionId: 1,
|
||||
topic: topicString,
|
||||
communityId,
|
||||
}),
|
||||
).toEqual({
|
||||
transactionId: 1,
|
||||
hieroTransactionId: undefined,
|
||||
topic,
|
||||
communityId,
|
||||
})
|
||||
})
|
||||
it('valid, transaction identified by hieroTransactionId and topic', () => {
|
||||
expect(
|
||||
v.parse(transactionIdentifierSchema, {
|
||||
hieroTransactionId: '0.0.261-1755348116-1281621',
|
||||
topic: topicString,
|
||||
communityId,
|
||||
}),
|
||||
).toEqual({
|
||||
hieroTransactionId,
|
||||
topic,
|
||||
communityId,
|
||||
})
|
||||
})
|
||||
it('invalid, missing topic', () => {
|
||||
it('invalid, missing communityId', () => {
|
||||
expect(() =>
|
||||
v.parse(transactionIdentifierSchema, {
|
||||
transactionId: 1,
|
||||
@ -53,7 +55,7 @@ describe('transactionIdentifierSchema ', () => {
|
||||
v.parse(transactionIdentifierSchema, {
|
||||
transactionId: 1,
|
||||
hieroTransactionId: '0.0.261-1755348116-1281621',
|
||||
topic,
|
||||
communityId,
|
||||
}),
|
||||
).toThrowError(new Error('expect transactionNr or hieroTransactionId not both'))
|
||||
})
|
||||
|
||||
@ -20,7 +20,7 @@ import { getLogger, Logger } from 'log4js'
|
||||
import * as v from 'valibot'
|
||||
import { CONFIG } from '../../config'
|
||||
import { LOG4JS_BASE_CATEGORY } from '../../config/const'
|
||||
import { HieroId, hieroIdSchema } from '../../schemas/typeGuard.schema'
|
||||
import { HieroId, hieroIdSchema, Uuidv4 } from '../../schemas/typeGuard.schema'
|
||||
import { durationInMinutesFromDates, printTimeDuration } from '../../utils/time'
|
||||
import { GradidoNodeClient } from '../GradidoNode/GradidoNodeClient'
|
||||
import { GradidoNodeProcess } from '../GradidoNode/GradidoNodeProcess'
|
||||
@ -72,6 +72,7 @@ export class HieroClient {
|
||||
|
||||
public async sendMessage(
|
||||
topicId: HieroId,
|
||||
communityId: Uuidv4,
|
||||
transaction: GradidoTransaction,
|
||||
): Promise<TransactionId | null> {
|
||||
const timeUsed = new Profiler()
|
||||
@ -102,7 +103,7 @@ export class HieroClient {
|
||||
// after 10 seconds, else restart GradidoNode
|
||||
setTimeout(async () => {
|
||||
const transaction = await GradidoNodeClient.getInstance().getTransaction({
|
||||
topic: topicId,
|
||||
communityId,
|
||||
hieroTransactionId: sendResponse.transactionId.toString(),
|
||||
})
|
||||
if (!transaction) {
|
||||
|
||||
@ -90,6 +90,13 @@ export const configSchema = v.object({
|
||||
v.string('The home folder for the gradido dlt node server'),
|
||||
path.join(__dirname, '..', '..', 'gradido_node'),
|
||||
),
|
||||
DLT_GRADIDO_NODE_SERVER_ALLOW_CORS: v.optional(
|
||||
v.pipe(
|
||||
v.string('Whether to allow CORS for the gradido dlt node server'),
|
||||
v.transform<string, boolean>((input: string) => input === 'true'),
|
||||
),
|
||||
'false',
|
||||
),
|
||||
BACKEND_PORT: v.optional(
|
||||
v.pipe(
|
||||
v.string('A valid port on which the backend server is running'),
|
||||
|
||||
@ -54,6 +54,9 @@ export class KeyPairIdentifierLogic {
|
||||
return this.identifier.seed
|
||||
}
|
||||
|
||||
getCommunityId(): Uuidv4 {
|
||||
return this.identifier.communityId
|
||||
}
|
||||
getCommunityTopicId(): HieroId {
|
||||
return this.identifier.communityTopicId
|
||||
}
|
||||
@ -76,7 +79,7 @@ export class KeyPairIdentifierLogic {
|
||||
return this.getSeed()
|
||||
}
|
||||
getCommunityKey(): string {
|
||||
return this.getCommunityTopicId()
|
||||
return this.getCommunityId()
|
||||
}
|
||||
getCommunityUserKey(): string {
|
||||
return this.deriveCommunityUserHash(0)
|
||||
@ -107,7 +110,7 @@ export class KeyPairIdentifierLogic {
|
||||
)
|
||||
}
|
||||
const resultString =
|
||||
this.identifier.communityTopicId +
|
||||
this.identifier.communityId +
|
||||
this.identifier.account.userUuid.replace(/-/g, '') +
|
||||
accountNr.toString()
|
||||
return new MemoryBlock(resultString).calculateHash().convertToHex()
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { KeyPairEd25519 } from 'gradido-blockchain-js'
|
||||
import { HieroId } from '../../schemas/typeGuard.schema'
|
||||
import { Uuidv4 } from '../../schemas/typeGuard.schema'
|
||||
|
||||
export abstract class AbstractRemoteKeyPairRole {
|
||||
protected topic: HieroId
|
||||
public constructor(communityTopicId: HieroId) {
|
||||
this.topic = communityTopicId
|
||||
protected communityId: Uuidv4
|
||||
public constructor(communityId: Uuidv4) {
|
||||
this.communityId = communityId
|
||||
}
|
||||
public abstract retrieveKeyPair(): Promise<KeyPairEd25519>
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ export class ForeignCommunityKeyPairRole extends AbstractRemoteKeyPairRole {
|
||||
public async retrieveKeyPair(): Promise<KeyPairEd25519> {
|
||||
const transactionIdentifier = {
|
||||
transactionId: 1,
|
||||
topic: this.topic,
|
||||
communityId: this.communityId,
|
||||
}
|
||||
const firstTransaction =
|
||||
await GradidoNodeClient.getInstance().getTransaction(transactionIdentifier)
|
||||
|
||||
@ -7,7 +7,7 @@ import { AbstractRemoteKeyPairRole } from './AbstractRemoteKeyPair.role'
|
||||
|
||||
export class RemoteAccountKeyPairRole extends AbstractRemoteKeyPairRole {
|
||||
public constructor(private identifier: IdentifierAccount) {
|
||||
super(identifier.communityTopicId)
|
||||
super(identifier.communityId)
|
||||
}
|
||||
|
||||
public async retrieveKeyPair(): Promise<KeyPairEd25519> {
|
||||
@ -17,7 +17,7 @@ export class RemoteAccountKeyPairRole extends AbstractRemoteKeyPairRole {
|
||||
|
||||
const accountPublicKey = await GradidoNodeClient.getInstance().findUserByNameHash(
|
||||
new Uuidv4Hash(this.identifier.account.userUuid),
|
||||
this.topic,
|
||||
this.communityId,
|
||||
)
|
||||
if (accountPublicKey) {
|
||||
return new KeyPairEd25519(MemoryBlock.createPtr(MemoryBlock.fromHex(accountPublicKey)))
|
||||
|
||||
@ -45,7 +45,7 @@ export async function ResolveKeyPair(input: KeyPairIdentifierLogic): Promise<Key
|
||||
if (cache.getHomeCommunityTopicId() !== input.getCommunityTopicId()) {
|
||||
const role = input.isAccountKeyPair()
|
||||
? new RemoteAccountKeyPairRole(input.identifier)
|
||||
: new ForeignCommunityKeyPairRole(input.getCommunityTopicId())
|
||||
: new ForeignCommunityKeyPairRole(input.getCommunityId())
|
||||
return await role.retrieveKeyPair()
|
||||
}
|
||||
// Community
|
||||
|
||||
@ -27,7 +27,10 @@ export class CommunityRootTransactionRole extends AbstractTransactionRole {
|
||||
public async getGradidoTransactionBuilder(): Promise<GradidoTransactionBuilder> {
|
||||
const builder = new GradidoTransactionBuilder()
|
||||
const communityKeyPair = await ResolveKeyPair(
|
||||
new KeyPairIdentifierLogic({ communityTopicId: this.community.hieroTopicId }),
|
||||
new KeyPairIdentifierLogic({
|
||||
communityTopicId: this.community.hieroTopicId,
|
||||
communityId: this.community.uuid,
|
||||
}),
|
||||
)
|
||||
const gmwKeyPair = communityKeyPair.deriveChild(
|
||||
hardenDerivationIndex(GMW_ACCOUNT_DERIVATION_INDEX),
|
||||
|
||||
@ -52,6 +52,7 @@ export class CreationTransactionRole extends AbstractTransactionRole {
|
||||
const homeCommunityKeyPair = await ResolveKeyPair(
|
||||
new KeyPairIdentifierLogic({
|
||||
communityTopicId: this.homeCommunityTopicId,
|
||||
communityId: this.creationTransaction.user.communityId,
|
||||
}),
|
||||
)
|
||||
// Memo: encrypted, home community and recipient can decrypt it
|
||||
@ -65,7 +66,11 @@ export class CreationTransactionRole extends AbstractTransactionRole {
|
||||
),
|
||||
)
|
||||
.setTransactionCreation(
|
||||
new TransferAmount(recipientKeyPair.getPublicKey(), this.creationTransaction.amount),
|
||||
new TransferAmount(
|
||||
recipientKeyPair.getPublicKey(),
|
||||
this.creationTransaction.amount,
|
||||
this.creationTransaction.user.communityId,
|
||||
),
|
||||
this.creationTransaction.targetDate,
|
||||
)
|
||||
.sign(signerKeyPair)
|
||||
|
||||
@ -41,6 +41,7 @@ export class DeferredTransferTransactionRole extends AbstractTransactionRole {
|
||||
const recipientKeyPair = await ResolveKeyPair(
|
||||
new KeyPairIdentifierLogic({
|
||||
communityTopicId: this.deferredTransferTransaction.linkedUser.communityTopicId,
|
||||
communityId: this.deferredTransferTransaction.linkedUser.communityId,
|
||||
seed: this.seed,
|
||||
}),
|
||||
)
|
||||
@ -61,6 +62,7 @@ export class DeferredTransferTransactionRole extends AbstractTransactionRole {
|
||||
this.deferredTransferTransaction.amount.calculateCompoundInterest(
|
||||
this.deferredTransferTransaction.timeoutDuration.getSeconds(),
|
||||
),
|
||||
this.deferredTransferTransaction.user.communityId,
|
||||
),
|
||||
recipientKeyPair.getPublicKey(),
|
||||
),
|
||||
|
||||
@ -65,6 +65,7 @@ export class RedeemDeferredTransferTransactionRole extends AbstractTransactionRo
|
||||
new TransferAmount(
|
||||
senderKeyPair.getPublicKey(),
|
||||
this.redeemDeferredTransferTransaction.amount,
|
||||
this.redeemDeferredTransferTransaction.user.communityId,
|
||||
),
|
||||
recipientKeyPair.getPublicKey(),
|
||||
),
|
||||
|
||||
@ -35,7 +35,10 @@ export class RegisterAddressTransactionRole extends AbstractTransactionRole {
|
||||
public async getGradidoTransactionBuilder(): Promise<GradidoTransactionBuilder> {
|
||||
const builder = new GradidoTransactionBuilder()
|
||||
const communityTopicId = this.registerAddressTransaction.user.communityTopicId
|
||||
const communityKeyPair = await ResolveKeyPair(new KeyPairIdentifierLogic({ communityTopicId }))
|
||||
const communityKeyPair = await ResolveKeyPair(new KeyPairIdentifierLogic({
|
||||
communityTopicId,
|
||||
communityId: this.registerAddressTransaction.user.communityId,
|
||||
}))
|
||||
const keyPairIdentifier = this.registerAddressTransaction.user
|
||||
// when accountNr is 0 it is the user account
|
||||
keyPairIdentifier.account.accountNr = 0
|
||||
|
||||
@ -23,6 +23,8 @@ import {
|
||||
HieroTransactionIdString,
|
||||
hieroTransactionIdStringSchema,
|
||||
identifierSeedSchema,
|
||||
Uuidv4,
|
||||
uuidv4Schema,
|
||||
} from '../../schemas/typeGuard.schema'
|
||||
import { isTopicStillOpen } from '../../utils/hiero'
|
||||
import { LinkedTransactionKeyPairRole } from '../resolveKeyPair/LinkedTransactionKeyPair.role'
|
||||
@ -59,6 +61,7 @@ export async function SendToHieroContext(
|
||||
const outboundHieroTransactionIdString = await sendViaHiero(
|
||||
outboundTransaction,
|
||||
role.getSenderCommunityTopicId(),
|
||||
v.parse(uuidv4Schema, outboundTransaction.getCommunityId()),
|
||||
)
|
||||
|
||||
// attach Hiero transaction ID to the builder for the inbound transaction
|
||||
@ -69,7 +72,11 @@ export async function SendToHieroContext(
|
||||
validate(inboundTransaction)
|
||||
|
||||
// send inbound transaction to hiero
|
||||
await sendViaHiero(inboundTransaction, role.getRecipientCommunityTopicId())
|
||||
await sendViaHiero(
|
||||
inboundTransaction,
|
||||
role.getRecipientCommunityTopicId(),
|
||||
v.parse(uuidv4Schema, inboundTransaction.getCommunityId()),
|
||||
)
|
||||
return outboundHieroTransactionIdString
|
||||
} else {
|
||||
// build and validate local transaction
|
||||
@ -80,6 +87,7 @@ export async function SendToHieroContext(
|
||||
const hieroTransactionIdString = await sendViaHiero(
|
||||
transaction,
|
||||
role.getSenderCommunityTopicId(),
|
||||
v.parse(uuidv4Schema, transaction.getCommunityId()),
|
||||
)
|
||||
return hieroTransactionIdString
|
||||
}
|
||||
@ -95,9 +103,10 @@ function validate(transaction: GradidoTransaction): void {
|
||||
async function sendViaHiero(
|
||||
gradidoTransaction: GradidoTransaction,
|
||||
topic: HieroId,
|
||||
communityId: Uuidv4
|
||||
): Promise<HieroTransactionIdString> {
|
||||
const client = HieroClient.getInstance()
|
||||
const transactionId = await client.sendMessage(topic, gradidoTransaction)
|
||||
const transactionId = await client.sendMessage(topic, communityId, gradidoTransaction)
|
||||
if (!transactionId) {
|
||||
throw new Error('missing transaction id from hiero')
|
||||
}
|
||||
@ -153,7 +162,7 @@ async function chooseCorrectRole(
|
||||
throw new Error("redeem deferred transfer: couldn't generate seed public key")
|
||||
}
|
||||
const transactions = await GradidoNodeClient.getInstance().getTransactionsForAccount(
|
||||
{ maxResultCount: 2, topic: transaction.user.communityTopicId },
|
||||
{ maxResultCount: 2, communityId: transaction.user.communityId },
|
||||
seedPublicKey.convertToHex(),
|
||||
)
|
||||
if (!transactions || transactions.length !== 1) {
|
||||
|
||||
@ -51,7 +51,11 @@ export class TransferTransactionRole extends AbstractTransactionRole {
|
||||
),
|
||||
)
|
||||
.setTransactionTransfer(
|
||||
new TransferAmount(senderKeyPair.getPublicKey(), this.transferTransaction.amount),
|
||||
new TransferAmount(
|
||||
senderKeyPair.getPublicKey(),
|
||||
this.transferTransaction.amount,
|
||||
this.transferTransaction.user.communityId,
|
||||
),
|
||||
recipientKeyPair.getPublicKey(),
|
||||
)
|
||||
const senderCommunity = this.transferTransaction.user.communityTopicId
|
||||
|
||||
@ -30,7 +30,7 @@ export function generateKeyPairCommunity(
|
||||
if (!keyPair) {
|
||||
throw new Error(`Couldn't create key pair for community ${community.communityUuid}`)
|
||||
}
|
||||
const communityKeyPairKey = new KeyPairIdentifierLogic({ communityTopicId: topicId }).getKey()
|
||||
const communityKeyPairKey = new KeyPairIdentifierLogic({ communityTopicId: topicId, communityId: community.communityUuid }).getKey()
|
||||
cache.addKeyPair(communityKeyPairKey, keyPair)
|
||||
logger.info(`Community Key Pair added with key: ${communityKeyPairKey}`)
|
||||
}
|
||||
@ -44,6 +44,7 @@ export async function generateKeyPairUserAccount(
|
||||
const userKeyPairRole = new UserKeyPairRole(user.gradidoId, communityKeyPair)
|
||||
const userKeyPairKey = new KeyPairIdentifierLogic({
|
||||
communityTopicId: communityTopicId,
|
||||
communityId: user.communityUuid,
|
||||
account: {
|
||||
userUuid: user.gradidoId,
|
||||
accountNr: 0,
|
||||
@ -56,6 +57,7 @@ export async function generateKeyPairUserAccount(
|
||||
const accountKeyPairRole = new AccountKeyPairRole(1, userKeyPair)
|
||||
const accountKeyPairKey = new KeyPairIdentifierLogic({
|
||||
communityTopicId: communityTopicId,
|
||||
communityId: user.communityUuid,
|
||||
account: {
|
||||
userUuid: user.gradidoId,
|
||||
accountNr: 1,
|
||||
|
||||
@ -11,6 +11,7 @@ export type IdentifierCommunityAccount = v.InferOutput<typeof identifierCommunit
|
||||
|
||||
export const identifierKeyPairSchema = v.object({
|
||||
communityTopicId: hieroIdSchema,
|
||||
communityId: uuidv4Schema,
|
||||
account: v.optional(identifierCommunityAccountSchema),
|
||||
seed: v.optional(identifierSeedSchema),
|
||||
})
|
||||
|
||||
@ -34,8 +34,12 @@ const transactionLinkCode = (date: Date): string => {
|
||||
}
|
||||
let topic: HieroId
|
||||
const topicString = '0.0.261'
|
||||
let communityUuid: Uuidv4
|
||||
const communityUuidString = '123e4567-e89b-12d3-a456-426614174000'
|
||||
|
||||
beforeAll(() => {
|
||||
topic = v.parse(hieroIdSchema, topicString)
|
||||
communityUuid = v.parse(uuidv4Schema, communityUuidString)
|
||||
})
|
||||
|
||||
describe('transaction schemas', () => {
|
||||
@ -55,6 +59,7 @@ describe('transaction schemas', () => {
|
||||
registerAddress = {
|
||||
user: {
|
||||
communityTopicId: topicString,
|
||||
communityId: communityUuidString,
|
||||
account: { userUuid: userUuidString },
|
||||
},
|
||||
type: InputTransactionType.REGISTER_ADDRESS,
|
||||
@ -66,6 +71,7 @@ describe('transaction schemas', () => {
|
||||
expect(v.parse(transactionSchema, registerAddress)).toEqual({
|
||||
user: {
|
||||
communityTopicId: topic,
|
||||
communityId: communityUuid,
|
||||
account: {
|
||||
userUuid,
|
||||
accountNr: 0,
|
||||
@ -80,6 +86,7 @@ describe('transaction schemas', () => {
|
||||
expect(v.parse(registerAddressTransactionSchema, registerAddress)).toEqual({
|
||||
user: {
|
||||
communityTopicId: topic,
|
||||
communityId: communityUuid,
|
||||
account: {
|
||||
userUuid,
|
||||
accountNr: 0,
|
||||
@ -101,10 +108,12 @@ describe('transaction schemas', () => {
|
||||
const gradidoTransfer: TransactionInput = {
|
||||
user: {
|
||||
communityTopicId: topicString,
|
||||
communityId: communityUuidString,
|
||||
account: { userUuid: userUuidString },
|
||||
},
|
||||
linkedUser: {
|
||||
communityTopicId: topicString,
|
||||
communityId: communityUuidString,
|
||||
account: { userUuid: userUuidString },
|
||||
},
|
||||
amount: '100',
|
||||
@ -115,6 +124,7 @@ describe('transaction schemas', () => {
|
||||
expect(v.parse(transactionSchema, gradidoTransfer)).toEqual({
|
||||
user: {
|
||||
communityTopicId: topic,
|
||||
communityId: communityUuid,
|
||||
account: {
|
||||
userUuid,
|
||||
accountNr: 0,
|
||||
@ -122,6 +132,7 @@ describe('transaction schemas', () => {
|
||||
},
|
||||
linkedUser: {
|
||||
communityTopicId: topic,
|
||||
communityId: communityUuid,
|
||||
account: {
|
||||
userUuid,
|
||||
accountNr: 0,
|
||||
@ -138,10 +149,12 @@ describe('transaction schemas', () => {
|
||||
const gradidoCreation: TransactionInput = {
|
||||
user: {
|
||||
communityTopicId: topicString,
|
||||
communityId: communityUuidString,
|
||||
account: { userUuid: userUuidString },
|
||||
},
|
||||
linkedUser: {
|
||||
communityTopicId: topicString,
|
||||
communityId: communityUuidString,
|
||||
account: { userUuid: userUuidString },
|
||||
},
|
||||
amount: '1000',
|
||||
@ -153,10 +166,12 @@ describe('transaction schemas', () => {
|
||||
expect(v.parse(transactionSchema, gradidoCreation)).toEqual({
|
||||
user: {
|
||||
communityTopicId: topic,
|
||||
communityId: communityUuid,
|
||||
account: { userUuid, accountNr: 0 },
|
||||
},
|
||||
linkedUser: {
|
||||
communityTopicId: topic,
|
||||
communityId: communityUuid,
|
||||
account: { userUuid, accountNr: 0 },
|
||||
},
|
||||
amount: v.parse(gradidoAmountSchema, gradidoCreation.amount!),
|
||||
@ -172,12 +187,14 @@ describe('transaction schemas', () => {
|
||||
const gradidoTransactionLink: TransactionInput = {
|
||||
user: {
|
||||
communityTopicId: topicString,
|
||||
communityId: communityUuidString,
|
||||
account: {
|
||||
userUuid: userUuidString,
|
||||
},
|
||||
},
|
||||
linkedUser: {
|
||||
communityTopicId: topicString,
|
||||
communityId: communityUuidString,
|
||||
seed,
|
||||
},
|
||||
amount: '100',
|
||||
@ -189,6 +206,7 @@ describe('transaction schemas', () => {
|
||||
expect(v.parse(transactionSchema, gradidoTransactionLink)).toEqual({
|
||||
user: {
|
||||
communityTopicId: topic,
|
||||
communityId: communityUuid,
|
||||
account: {
|
||||
userUuid,
|
||||
accountNr: 0,
|
||||
@ -196,6 +214,7 @@ describe('transaction schemas', () => {
|
||||
},
|
||||
linkedUser: {
|
||||
communityTopicId: topic,
|
||||
communityId: communityUuid,
|
||||
seed: seedParsed,
|
||||
},
|
||||
amount: v.parse(gradidoAmountSchema, gradidoTransactionLink.amount!),
|
||||
|
||||
@ -43,12 +43,14 @@ export type Transaction = v.InferOutput<typeof transactionSchema>
|
||||
// if the account is identified by seed
|
||||
export const seedAccountSchema = v.object({
|
||||
communityTopicId: hieroIdSchema,
|
||||
communityId: uuidv4Schema,
|
||||
seed: identifierSeedSchema,
|
||||
})
|
||||
|
||||
// if the account is identified by userUuid and accountNr
|
||||
export const userAccountSchema = v.object({
|
||||
communityTopicId: hieroIdSchema,
|
||||
communityId: uuidv4Schema,
|
||||
account: identifierCommunityAccountSchema,
|
||||
})
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import {
|
||||
toAccountType,
|
||||
toAddressType,
|
||||
} from '../utils/typeConverter'
|
||||
import { Uuidv4, uuidv4Schema } from './typeGuard.schema'
|
||||
|
||||
/**
|
||||
* dateSchema for creating a date from string or Date object
|
||||
@ -72,17 +73,23 @@ export const accountTypeSchema = v.pipe(
|
||||
export const confirmedTransactionSchema = v.pipe(
|
||||
v.union([
|
||||
v.instance(ConfirmedTransaction, 'expect ConfirmedTransaction'),
|
||||
v.pipe(
|
||||
v.string('expect confirmed Transaction base64 as string type'),
|
||||
v.base64('expect to be valid base64'),
|
||||
),
|
||||
v.object({
|
||||
base64: v.pipe(
|
||||
v.string('expect confirmed Transaction base64 as string type'),
|
||||
v.base64('expect to be valid base64'),
|
||||
),
|
||||
communityId: uuidv4Schema,
|
||||
}),
|
||||
]),
|
||||
v.transform<string | ConfirmedTransaction, ConfirmedTransaction>(
|
||||
(data: string | ConfirmedTransaction) => {
|
||||
v.transform<ConfirmedTransaction | { base64: string; communityId: Uuidv4 }, ConfirmedTransaction>(
|
||||
(data: string | ConfirmedTransaction | { base64: string; communityId: Uuidv4 }) => {
|
||||
if (data instanceof ConfirmedTransaction) {
|
||||
return data
|
||||
}
|
||||
return confirmedTransactionFromBase64(data)
|
||||
if (typeof data === 'object' && 'base64' in data && 'communityId' in data) {
|
||||
return confirmedTransactionFromBase64(data.base64, data.communityId)
|
||||
}
|
||||
throw new Error('invalid data, community id missing, couldn\'t deserialize')
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
@ -69,9 +69,10 @@ export const appRoutes = new Elysia()
|
||||
// check if account exists by user, call example:
|
||||
// GET /isAccountExist/by-user/0.0.21732/408780b2-59b3-402a-94be-56a4f4f4e8ec/0
|
||||
.get(
|
||||
'/isAccountExist/by-user/:communityTopicId/:userUuid/:accountNr',
|
||||
async ({ params: { communityTopicId, userUuid, accountNr } }) => ({
|
||||
'/isAccountExist/by-user/:communityId/:communityTopicId/:userUuid/:accountNr',
|
||||
async ({ params: { communityId, communityTopicId, userUuid, accountNr } }) => ({
|
||||
exists: await isAccountExist({
|
||||
communityId,
|
||||
communityTopicId,
|
||||
account: { userUuid, accountNr },
|
||||
}),
|
||||
@ -84,9 +85,10 @@ export const appRoutes = new Elysia()
|
||||
// check if account exists by seed, call example:
|
||||
// GET /isAccountExist/by-seed/0.0.21732/0c4676adfd96519a0551596c
|
||||
.get(
|
||||
'/isAccountExist/by-seed/:communityTopicId/:seed',
|
||||
async ({ params: { communityTopicId, seed } }) => ({
|
||||
'/isAccountExist/by-seed/:communityId/:communityTopicId/:seed',
|
||||
async ({ params: { communityId, communityTopicId, seed } }) => ({
|
||||
exists: await isAccountExist({
|
||||
communityId,
|
||||
communityTopicId,
|
||||
seed,
|
||||
}),
|
||||
@ -145,7 +147,7 @@ async function isAccountExist(identifierAccount: IdentifierAccountInput): Promis
|
||||
// ask gradido node server for account type, if type !== NONE account exist
|
||||
const addressType = await GradidoNodeClient.getInstance().getAddressType(
|
||||
publicKey.convertToHex(),
|
||||
identifierAccountParsed.communityTopicId,
|
||||
identifierAccountParsed.communityId,
|
||||
)
|
||||
const exists = addressType !== AddressType_NONE
|
||||
const endTime = Date.now()
|
||||
|
||||
@ -3,6 +3,7 @@ import { t } from 'elysia'
|
||||
import { hieroIdSchema, uuidv4Schema } from '../schemas/typeGuard.schema'
|
||||
|
||||
export const accountIdentifierUserTypeBoxSchema = t.Object({
|
||||
communityId: TypeBoxFromValibot(uuidv4Schema),
|
||||
communityTopicId: TypeBoxFromValibot(hieroIdSchema),
|
||||
userUuid: TypeBoxFromValibot(uuidv4Schema),
|
||||
accountNr: t.Number({ min: 0 }),
|
||||
@ -10,6 +11,7 @@ export const accountIdentifierUserTypeBoxSchema = t.Object({
|
||||
|
||||
// identifier for a gradido account created by transaction link / deferred transfer
|
||||
export const accountIdentifierSeedTypeBoxSchema = t.Object({
|
||||
communityId: TypeBoxFromValibot(uuidv4Schema),
|
||||
communityTopicId: TypeBoxFromValibot(hieroIdSchema),
|
||||
seed: TypeBoxFromValibot(uuidv4Schema),
|
||||
})
|
||||
|
||||
@ -9,7 +9,7 @@ export function checkFileExist(filePath: string): boolean {
|
||||
fs.accessSync(filePath, fs.constants.R_OK | fs.constants.W_OK)
|
||||
return true
|
||||
} catch (_err) {
|
||||
// logger.debug(`file ${filePath} does not exist: ${_err}`)
|
||||
logger.debug(`file ${filePath} does not exist: ${_err}`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,14 +6,15 @@ import {
|
||||
} from 'gradido-blockchain-js'
|
||||
import { AccountType } from '../data/AccountType.enum'
|
||||
import { AddressType } from '../data/AddressType.enum'
|
||||
import { Uuidv4 } from '../schemas/typeGuard.schema'
|
||||
|
||||
export const confirmedTransactionFromBase64 = (base64: string): ConfirmedTransaction => {
|
||||
export const confirmedTransactionFromBase64 = (base64: string, communityId: Uuidv4): ConfirmedTransaction => {
|
||||
const confirmedTransactionBinaryPtr = MemoryBlock.createPtr(MemoryBlock.fromBase64(base64))
|
||||
const deserializer = new InteractionDeserialize(
|
||||
confirmedTransactionBinaryPtr,
|
||||
DeserializeType_CONFIRMED_TRANSACTION,
|
||||
)
|
||||
deserializer.run()
|
||||
deserializer.run(communityId)
|
||||
const confirmedTransaction = deserializer.getConfirmedTransaction()
|
||||
if (!confirmedTransaction) {
|
||||
throw new Error("invalid data, couldn't deserialize")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user