diff --git a/dlt-connector/src/data/Transaction.builder.ts b/dlt-connector/src/data/Transaction.builder.ts index 115391e91..f46f02a29 100644 --- a/dlt-connector/src/data/Transaction.builder.ts +++ b/dlt-connector/src/data/Transaction.builder.ts @@ -59,6 +59,10 @@ export class TransactionBuilder { return this.transaction.community } + public getOtherCommunity(): Community | undefined { + return this.transaction.otherCommunity + } + public setSigningAccount(signingAccount: Account): TransactionBuilder { this.transaction.signingAccount = signingAccount return this @@ -103,22 +107,18 @@ export class TransactionBuilder { return this } - public async setSenderCommunityFromSenderUser( - senderUser: UserIdentifier, - ): Promise { + public async setCommunityFromUser(user: UserIdentifier): Promise { // get sender community - const community = await CommunityRepository.getCommunityForUserIdentifier(senderUser) + const community = await CommunityRepository.getCommunityForUserIdentifier(user) if (!community) { throw new LogError("couldn't find community for transaction") } return this.setCommunity(community) } - public async setOtherCommunityFromRecipientUser( - recipientUser: UserIdentifier, - ): Promise { + public async setOtherCommunityFromUser(user: UserIdentifier): Promise { // get recipient community - const otherCommunity = await CommunityRepository.getCommunityForUserIdentifier(recipientUser) + const otherCommunity = await CommunityRepository.getCommunityForUserIdentifier(user) return this.setOtherCommunity(otherCommunity) } diff --git a/dlt-connector/src/data/Transaction.logic.test.ts b/dlt-connector/src/data/Transaction.logic.test.ts index fe9c2c085..b5ef73de2 100644 --- a/dlt-connector/src/data/Transaction.logic.test.ts +++ b/dlt-connector/src/data/Transaction.logic.test.ts @@ -44,8 +44,8 @@ describe('data/transaction.logic', () => { b = new Transaction() b.community = new Community() - b.communityId = 1 - b.otherCommunityId = 2 + b.communityId = 2 + b.otherCommunityId = 1 b.id = 2 b.signingAccountId = 1 b.recipientAccountId = 2 diff --git a/dlt-connector/src/data/Transaction.logic.ts b/dlt-connector/src/data/Transaction.logic.ts index f237e9b3b..f61c9a6e9 100644 --- a/dlt-connector/src/data/Transaction.logic.ts +++ b/dlt-connector/src/data/Transaction.logic.ts @@ -81,8 +81,8 @@ export class TransactionLogic { if ( this.self.signingAccountId !== otherTransaction.signingAccountId || this.self.recipientAccountId !== otherTransaction.recipientAccountId || - this.self.communityId !== otherTransaction.communityId || - this.self.otherCommunityId !== otherTransaction.otherCommunityId || + this.self.communityId !== otherTransaction.otherCommunityId || + this.self.otherCommunityId !== otherTransaction.communityId || this.self.createdAt.getTime() !== otherTransaction.createdAt.getTime() ) { logger.info('transaction a and b are not pairs', { diff --git a/dlt-connector/src/graphql/input/TransactionDraft.ts b/dlt-connector/src/graphql/input/TransactionDraft.ts index 541797565..c69a7dea3 100755 --- a/dlt-connector/src/graphql/input/TransactionDraft.ts +++ b/dlt-connector/src/graphql/input/TransactionDraft.ts @@ -1,11 +1,10 @@ // https://www.npmjs.com/package/@apollo/protobufjs -import { IsEnum, IsObject, IsPositive, ValidateNested } from 'class-validator' -import { Decimal } from 'decimal.js-light' -import { InputType, Field, Int } from 'type-graphql' - import { InputTransactionType } from '@enum/InputTransactionType' import { isValidDateString } from '@validator/DateString' import { IsPositiveDecimal } from '@validator/Decimal' +import { IsEnum, IsObject, IsPositive, ValidateNested } from 'class-validator' +import { Decimal } from 'decimal.js-light' +import { InputType, Field, Int } from 'type-graphql' import { UserIdentifier } from './UserIdentifier' diff --git a/dlt-connector/src/graphql/input/UserIdentifier.ts b/dlt-connector/src/graphql/input/UserIdentifier.ts index 12f2e5889..7d9035b93 100644 --- a/dlt-connector/src/graphql/input/UserIdentifier.ts +++ b/dlt-connector/src/graphql/input/UserIdentifier.ts @@ -9,9 +9,9 @@ export class UserIdentifier { @IsUUID('4') uuid: string - @Field(() => String, { nullable: true }) + @Field(() => String) @IsUUID('4') - communityUuid?: string + communityUuid: string @Field(() => Int, { defaultValue: 1, nullable: true }) @IsPositive() diff --git a/dlt-connector/src/interactions/backendToDb/transaction/AbstractTransaction.role.ts b/dlt-connector/src/interactions/backendToDb/transaction/AbstractTransaction.role.ts index 62fcf90de..b23d381cd 100644 --- a/dlt-connector/src/interactions/backendToDb/transaction/AbstractTransaction.role.ts +++ b/dlt-connector/src/interactions/backendToDb/transaction/AbstractTransaction.role.ts @@ -1,8 +1,11 @@ +import { Community } from '@entity/Community' + import { CrossGroupType } from '@/data/proto/3_3/enum/CrossGroupType' import { TransactionErrorType } from '@/graphql/enum/TransactionErrorType' import { TransactionDraft } from '@/graphql/input/TransactionDraft' import { UserIdentifier } from '@/graphql/input/UserIdentifier' import { TransactionError } from '@/graphql/model/TransactionError' +import { iotaTopicFromCommunityUUID } from '@/utils/typeConverter' export abstract class AbstractTransactionRole { // eslint-disable-next-line no-useless-constructor @@ -26,7 +29,7 @@ export abstract class AbstractTransactionRole { * OUTBOUND: stored on 'gdd1', otherGroup: 'gdd2' * INBOUND: goes to receiver, stored on receiver community blockchain * INBOUND: stored on 'gdd2', otherGroup: 'gdd1' - * @returns + * @returns iota topic */ public getOtherGroup(): string { let user: UserIdentifier @@ -42,7 +45,7 @@ export abstract class AbstractTransactionRole { 'missing sender/signing user community id for cross group transaction', ) } - return user.communityUuid + return iotaTopicFromCommunityUUID(user.communityUuid) case CrossGroupType.OUTBOUND: user = this.getRecipientUser() if (!user.communityUuid) { @@ -51,7 +54,7 @@ export abstract class AbstractTransactionRole { 'missing recipient user community id for cross group transaction', ) } - return user.communityUuid + return iotaTopicFromCommunityUUID(user.communityUuid) default: throw new TransactionError( TransactionErrorType.NOT_IMPLEMENTED_YET, diff --git a/dlt-connector/src/interactions/backendToDb/transaction/CreateTransactionRecipe.context.test.ts b/dlt-connector/src/interactions/backendToDb/transaction/CreateTransactionRecipe.context.test.ts index 0382632b3..e5535f3f7 100644 --- a/dlt-connector/src/interactions/backendToDb/transaction/CreateTransactionRecipe.context.test.ts +++ b/dlt-connector/src/interactions/backendToDb/transaction/CreateTransactionRecipe.context.test.ts @@ -272,6 +272,7 @@ describe('interactions/backendToDb/transaction/Create Transaction Recipe Context ) expect(body).toMatchObject({ type: CrossGroupType.OUTBOUND, + otherGroup: foreignTopic, transfer: { sender: { amount: '100', @@ -296,15 +297,15 @@ describe('interactions/backendToDb/transaction/Create Transaction Recipe Context type: TransactionType.GRADIDO_TRANSFER, protocolVersion: '3.3', community: { - rootPubkey: keyPair.publicKey, - foreign: 0, - iotaTopic: topic, - }, - otherCommunity: { rootPubkey: foreignKeyPair.publicKey, foreign: 1, iotaTopic: foreignTopic, }, + otherCommunity: { + rootPubkey: keyPair.publicKey, + foreign: 0, + iotaTopic: topic, + }, signingAccount: { derive2Pubkey: firstUser.account.derive2Pubkey, }, @@ -328,6 +329,7 @@ describe('interactions/backendToDb/transaction/Create Transaction Recipe Context ) expect(body).toMatchObject({ type: CrossGroupType.INBOUND, + otherGroup: topic, transfer: { sender: { amount: '100', diff --git a/dlt-connector/src/interactions/backendToDb/transaction/CreationTransaction.role.ts b/dlt-connector/src/interactions/backendToDb/transaction/CreationTransaction.role.ts index 7b82f8805..f11518d02 100644 --- a/dlt-connector/src/interactions/backendToDb/transaction/CreationTransaction.role.ts +++ b/dlt-connector/src/interactions/backendToDb/transaction/CreationTransaction.role.ts @@ -1,5 +1,12 @@ +import { Community } from '@entity/Community' + +import { CommunityRepository } from '@/data/Community.repository' import { CrossGroupType } from '@/data/proto/3_3/enum/CrossGroupType' +import { TransactionErrorType } from '@/graphql/enum/TransactionErrorType' import { UserIdentifier } from '@/graphql/input/UserIdentifier' +import { TransactionError } from '@/graphql/model/TransactionError' +import { logger } from '@/logging/logger' +import { UserIdentifierLoggingView } from '@/logging/UserIdentifierLogging.view' import { AbstractTransactionRole } from './AbstractTransaction.role' @@ -15,4 +22,26 @@ export class CreationTransactionRole extends AbstractTransactionRole { public getCrossGroupType(): CrossGroupType { return CrossGroupType.LOCAL } + + public async getCommunity(): Promise { + if (this.self.user.communityUuid !== this.self.linkedUser.communityUuid) { + throw new TransactionError( + TransactionErrorType.LOGIC_ERROR, + 'mismatch community uuids on creation transaction', + ) + } + const community = await CommunityRepository.getCommunityForUserIdentifier(this.self.user) + if (!community) { + logger.error( + 'missing community for user identifier', + new UserIdentifierLoggingView(this.self.user), + ) + throw new TransactionError(TransactionErrorType.NOT_FOUND, "couldn't find community for user") + } + return community + } + + public async getOtherCommunity(): Promise { + return null + } } diff --git a/dlt-connector/src/interactions/backendToDb/transaction/TransactionRecipe.role.ts b/dlt-connector/src/interactions/backendToDb/transaction/TransactionRecipe.role.ts index 7c6d3015d..f1be50c75 100644 --- a/dlt-connector/src/interactions/backendToDb/transaction/TransactionRecipe.role.ts +++ b/dlt-connector/src/interactions/backendToDb/transaction/TransactionRecipe.role.ts @@ -1,7 +1,9 @@ +import { Community } from '@entity/Community' import { Transaction } from '@entity/Transaction' import { AccountLogic } from '@/data/Account.logic' import { KeyPair } from '@/data/KeyPair' +import { CrossGroupType } from '@/data/proto/3_3/enum/CrossGroupType' import { TransactionBodyBuilder } from '@/data/proto/TransactionBody.builder' import { TransactionBuilder } from '@/data/Transaction.builder' import { UserRepository } from '@/data/User.repository' @@ -53,12 +55,15 @@ export class TransactionRecipeRole { this.transactionBuilder .fromTransactionBodyBuilder(transactionBodyBuilder) .addBackendTransaction(transactionDraft) - await this.transactionBuilder.setSenderCommunityFromSenderUser(signingUser) + + await this.transactionBuilder.setCommunityFromUser(transactionDraft.user) if (recipientUser.communityUuid !== signingUser.communityUuid) { - await this.transactionBuilder.setOtherCommunityFromRecipientUser(recipientUser) + await this.transactionBuilder.setOtherCommunityFromUser(transactionDraft.linkedUser) } const transaction = this.transactionBuilder.getTransaction() - const communityKeyPair = new KeyPair(this.transactionBuilder.getCommunity()) + const communityKeyPair = new KeyPair( + this.getSigningCommunity(transactionTypeRole.getCrossGroupType()), + ) const accountLogic = new AccountLogic(signingAccount) // sign this.transactionBuilder.setSignature( @@ -67,6 +72,17 @@ export class TransactionRecipeRole { return this } + public getSigningCommunity(crossGroupType: CrossGroupType): Community { + if (crossGroupType === CrossGroupType.INBOUND) { + const otherCommunity = this.transactionBuilder.getOtherCommunity() + if (!otherCommunity) { + throw new TransactionError(TransactionErrorType.NOT_FOUND, 'missing other community') + } + return otherCommunity + } + return this.transactionBuilder.getCommunity() + } + public getTransaction(): Transaction { return this.transactionBuilder.getTransaction() } diff --git a/dlt-connector/tsconfig.json b/dlt-connector/tsconfig.json index e37b2a7a0..32525c013 100644 --- a/dlt-connector/tsconfig.json +++ b/dlt-connector/tsconfig.json @@ -63,7 +63,7 @@ "@entity/*": ["../dlt-database/entity/*", "../../dlt-database/build/entity/*"] }, // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - "typeRoots": ["node_modules/@types"], /* List of folders to include type definitions from. */ + "typeRoots": ["node_modules/@types", "@types"], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */