mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
refactor, add feature for register address
This commit is contained in:
parent
a3cc076e47
commit
b9e138939b
@ -1,5 +1,6 @@
|
||||
import { Account } from '@entity/Account'
|
||||
import { User } from '@entity/User'
|
||||
import { FindOptionsRelations } from 'typeorm'
|
||||
|
||||
import { UserIdentifier } from '@/graphql/input/UserIdentifier'
|
||||
import { getDataSource } from '@/typeorm/DataSource'
|
||||
@ -21,4 +22,11 @@ export const UserRepository = getDataSource()
|
||||
return account
|
||||
}
|
||||
},
|
||||
|
||||
findByGradidoId(
|
||||
{ uuid }: UserIdentifier,
|
||||
relations?: FindOptionsRelations<User>,
|
||||
): Promise<User | null> {
|
||||
return User.findOne({ where: { gradidoID: uuid }, relations })
|
||||
},
|
||||
})
|
||||
|
||||
@ -1,15 +1,35 @@
|
||||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import { Account } from '@entity/Account'
|
||||
import { Transaction } from '@entity/Transaction'
|
||||
import { User } from '@entity/User'
|
||||
import { Field, Message } from 'protobufjs'
|
||||
|
||||
import { AddressType } from '@/data/proto/3_3/enum/AddressType'
|
||||
import { AccountType } from '@/graphql/enum/AccountType'
|
||||
import { UserAccountDraft } from '@/graphql/input/UserAccountDraft'
|
||||
import { accountTypeToAddressType } from '@/utils/typeConverter'
|
||||
|
||||
import { AbstractTransaction } from '../AbstractTransaction'
|
||||
|
||||
// https://www.npmjs.com/package/@apollo/protobufjs
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
export class RegisterAddress extends Message<RegisterAddress> implements AbstractTransaction {
|
||||
constructor(transaction?: UserAccountDraft, account?: Account) {
|
||||
if (transaction) {
|
||||
super({ addressType: accountTypeToAddressType(transaction.accountType) })
|
||||
if (account) {
|
||||
this.derivationIndex = account.derivationIndex
|
||||
this.accountPubkey = account.derive2Pubkey
|
||||
if (account.user) {
|
||||
this.userPubkey = account.user.derive1Pubkey
|
||||
}
|
||||
}
|
||||
} else {
|
||||
super()
|
||||
}
|
||||
}
|
||||
|
||||
@Field.d(1, 'bytes')
|
||||
public userPubkey: Buffer
|
||||
|
||||
|
||||
@ -4,12 +4,14 @@ import { Field, Message, OneOf } from 'protobufjs'
|
||||
import { TransactionErrorType } from '@/graphql/enum/TransactionErrorType'
|
||||
import { CommunityDraft } from '@/graphql/input/CommunityDraft'
|
||||
import { TransactionDraft } from '@/graphql/input/TransactionDraft'
|
||||
import { UserAccountDraft } from '@/graphql/input/UserAccountDraft'
|
||||
import { TransactionError } from '@/graphql/model/TransactionError'
|
||||
import { logger } from '@/logging/logger'
|
||||
import { LogError } from '@/server/LogError'
|
||||
import { timestampToDate } from '@/utils/typeConverter'
|
||||
|
||||
import { AbstractTransaction } from '../AbstractTransaction'
|
||||
import { determineCrossGroupType, determineOtherGroup } from '../transactionBody.logic'
|
||||
|
||||
import { CommunityRoot } from './CommunityRoot'
|
||||
import { PROTO_TRANSACTION_BODY_VERSION_NUMBER } from './const'
|
||||
@ -25,14 +27,21 @@ import { Timestamp } from './Timestamp'
|
||||
// https://www.npmjs.com/package/@apollo/protobufjs
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
export class TransactionBody extends Message<TransactionBody> {
|
||||
public constructor(transaction?: TransactionDraft | CommunityDraft) {
|
||||
public constructor(transaction?: TransactionDraft | CommunityDraft | UserAccountDraft) {
|
||||
if (transaction) {
|
||||
let type = CrossGroupType.LOCAL
|
||||
let otherGroup = ''
|
||||
if (transaction instanceof TransactionDraft) {
|
||||
type = determineCrossGroupType(transaction)
|
||||
otherGroup = determineOtherGroup(type, transaction)
|
||||
}
|
||||
|
||||
super({
|
||||
memo: 'Not implemented yet',
|
||||
createdAt: new Timestamp(new Date(transaction.createdAt)),
|
||||
versionNumber: PROTO_TRANSACTION_BODY_VERSION_NUMBER,
|
||||
type: CrossGroupType.LOCAL,
|
||||
otherGroup: '',
|
||||
type,
|
||||
otherGroup,
|
||||
})
|
||||
} else {
|
||||
super()
|
||||
|
||||
@ -4,12 +4,14 @@ import { Community } from '@entity/Community'
|
||||
import { InputTransactionType } from '@/graphql/enum/InputTransactionType'
|
||||
import { CommunityDraft } from '@/graphql/input/CommunityDraft'
|
||||
import { TransactionDraft } from '@/graphql/input/TransactionDraft'
|
||||
import { UserAccountDraft } from '@/graphql/input/UserAccountDraft'
|
||||
import { LogError } from '@/server/LogError'
|
||||
|
||||
import { CommunityRoot } from './3_3/CommunityRoot'
|
||||
import { CrossGroupType } from './3_3/enum/CrossGroupType'
|
||||
import { GradidoCreation } from './3_3/GradidoCreation'
|
||||
import { GradidoTransfer } from './3_3/GradidoTransfer'
|
||||
import { RegisterAddress } from './3_3/RegisterAddress'
|
||||
import { TransactionBody } from './3_3/TransactionBody'
|
||||
|
||||
export class TransactionBodyBuilder {
|
||||
@ -99,9 +101,16 @@ export class TransactionBodyBuilder {
|
||||
return this
|
||||
}
|
||||
|
||||
public fromUserAccountDraft(userAccountDraft: UserAccountDraft, account: Account): this {
|
||||
this.body = new TransactionBody(userAccountDraft)
|
||||
this.body.registerAddress = new RegisterAddress(userAccountDraft, account)
|
||||
this.body.data = 'registerAddress'
|
||||
return this
|
||||
}
|
||||
|
||||
public fromTransactionDraft(transactionDraft: TransactionDraft): TransactionBodyBuilder {
|
||||
this.body = new TransactionBody(transactionDraft)
|
||||
// TODO: load pubkeys for sender and recipient user from db
|
||||
// TODO: load public keys for sender and recipient user from db
|
||||
switch (transactionDraft.type) {
|
||||
case InputTransactionType.CREATION:
|
||||
if (!this.recipientAccount) {
|
||||
|
||||
59
dlt-connector/src/data/proto/transactionBody.logic.ts
Normal file
59
dlt-connector/src/data/proto/transactionBody.logic.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import { InputTransactionType } from '@/graphql/enum/InputTransactionType'
|
||||
import { TransactionErrorType } from '@/graphql/enum/TransactionErrorType'
|
||||
import { TransactionDraft } from '@/graphql/input/TransactionDraft'
|
||||
import { TransactionError } from '@/graphql/model/TransactionError'
|
||||
|
||||
import { CrossGroupType } from './3_3/enum/CrossGroupType'
|
||||
|
||||
export const determineCrossGroupType = ({
|
||||
user,
|
||||
linkedUser,
|
||||
type,
|
||||
}: TransactionDraft): CrossGroupType => {
|
||||
if (
|
||||
!linkedUser.communityUuid ||
|
||||
!user.communityUuid ||
|
||||
linkedUser.communityUuid === '' ||
|
||||
user.communityUuid === '' ||
|
||||
user.communityUuid === linkedUser.communityUuid ||
|
||||
type === InputTransactionType.CREATION
|
||||
) {
|
||||
return CrossGroupType.LOCAL
|
||||
} else if (type === InputTransactionType.SEND) {
|
||||
return CrossGroupType.INBOUND
|
||||
} else if (type === InputTransactionType.RECEIVE) {
|
||||
return CrossGroupType.OUTBOUND
|
||||
}
|
||||
throw new TransactionError(
|
||||
TransactionErrorType.NOT_IMPLEMENTED_YET,
|
||||
'cannot determine CrossGroupType',
|
||||
)
|
||||
}
|
||||
|
||||
export const determineOtherGroup = (
|
||||
type: CrossGroupType,
|
||||
{ user, linkedUser }: TransactionDraft,
|
||||
): string => {
|
||||
switch (type) {
|
||||
case CrossGroupType.LOCAL:
|
||||
return ''
|
||||
case CrossGroupType.INBOUND:
|
||||
if (!linkedUser.communityUuid || linkedUser.communityUuid === '') {
|
||||
throw new TransactionError(
|
||||
TransactionErrorType.MISSING_PARAMETER,
|
||||
'missing linkedUser community id for cross group transaction',
|
||||
)
|
||||
}
|
||||
return linkedUser.communityUuid
|
||||
case CrossGroupType.OUTBOUND:
|
||||
if (!user.communityUuid || user.communityUuid === '') {
|
||||
throw new TransactionError(
|
||||
TransactionErrorType.MISSING_PARAMETER,
|
||||
'missing user community id for cross group transaction',
|
||||
)
|
||||
}
|
||||
return user.communityUuid
|
||||
case CrossGroupType.CROSS:
|
||||
throw new TransactionError(TransactionErrorType.NOT_IMPLEMENTED_YET, 'not implemented yet')
|
||||
}
|
||||
}
|
||||
60
dlt-connector/src/graphql/resolver/AccountsResolver.ts
Normal file
60
dlt-connector/src/graphql/resolver/AccountsResolver.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import { Arg, Mutation, Query, Resolver } from 'type-graphql'
|
||||
import { QueryFailedError } from 'typeorm'
|
||||
|
||||
import { TransactionRecipe } from '@model/TransactionRecipe'
|
||||
|
||||
import { TRANSMIT_TO_IOTA_INTERRUPTIVE_SLEEP_KEY } from '@/data/const'
|
||||
import { UserRepository } from '@/data/User.repository'
|
||||
import { RegisterAddressContext } from '@/interactions/backendToDb/account/RegisterAddress.context'
|
||||
import { logger } from '@/logging/logger'
|
||||
import { TransactionLoggingView } from '@/logging/TransactionLogging.view'
|
||||
import { InterruptiveSleepManager } from '@/manager/InterruptiveSleepManager'
|
||||
import { getDataSource } from '@/typeorm/DataSource'
|
||||
|
||||
import { TransactionErrorType } from '../enum/TransactionErrorType'
|
||||
import { UserAccountDraft } from '../input/UserAccountDraft'
|
||||
import { UserIdentifier } from '../input/UserIdentifier'
|
||||
import { TransactionError } from '../model/TransactionError'
|
||||
import { TransactionResult } from '../model/TransactionResult'
|
||||
|
||||
@Resolver()
|
||||
export class AccountResolver {
|
||||
@Query(() => Boolean)
|
||||
async isAccountExist(@Arg('data') userIdentifier: UserIdentifier): Promise<boolean> {
|
||||
logger.info('isAccountExist', userIdentifier)
|
||||
return !!(await UserRepository.findAccountByUserIdentifier(userIdentifier))
|
||||
}
|
||||
|
||||
@Mutation(() => TransactionResult)
|
||||
async registerAddress(
|
||||
@Arg('data')
|
||||
userAccountDraft: UserAccountDraft,
|
||||
): Promise<TransactionResult> {
|
||||
const registerAddressContext = new RegisterAddressContext(userAccountDraft)
|
||||
try {
|
||||
const { transaction, account } = await registerAddressContext.run()
|
||||
await getDataSource().transaction(async (transactionalEntityManager) => {
|
||||
await transactionalEntityManager.save(account)
|
||||
await transactionalEntityManager.save(transaction)
|
||||
logger.debug('store register address transaction', new TransactionLoggingView(transaction))
|
||||
})
|
||||
InterruptiveSleepManager.getInstance().interrupt(TRANSMIT_TO_IOTA_INTERRUPTIVE_SLEEP_KEY)
|
||||
return new TransactionResult(new TransactionRecipe(transaction))
|
||||
} catch (err) {
|
||||
if (err instanceof QueryFailedError) {
|
||||
logger.error('error saving user or new account or transaction into db: %s', err)
|
||||
return new TransactionResult(
|
||||
new TransactionError(
|
||||
TransactionErrorType.DB_ERROR,
|
||||
'error saving user or new account or transaction into db',
|
||||
),
|
||||
)
|
||||
} else if (err instanceof TransactionError) {
|
||||
return new TransactionResult(err)
|
||||
} else {
|
||||
logger.error('error in register address: ', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,7 @@ import { TransactionDraft } from '@input/TransactionDraft'
|
||||
|
||||
import { TRANSMIT_TO_IOTA_INTERRUPTIVE_SLEEP_KEY } from '@/data/const'
|
||||
import { TransactionRepository } from '@/data/Transaction.repository'
|
||||
import { CreateTransactionRecipeContext } from '@/interactions/backendToDb/transaction/CreateTransationRecipe.context'
|
||||
import { CreateTransactionRecipeContext } from '@/interactions/backendToDb/transaction/CreateTransactionRecipe.context'
|
||||
import { BackendTransactionLoggingView } from '@/logging/BackendTransactionLogging.view'
|
||||
import { logger } from '@/logging/logger'
|
||||
import { TransactionLoggingView } from '@/logging/TransactionLogging.view'
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
import { Account } from '@entity/Account'
|
||||
import { Transaction } from '@entity/Transaction'
|
||||
import { User } from '@entity/User'
|
||||
|
||||
import { AccountFactory } from '@/data/Account.factory'
|
||||
import { CommunityRepository } from '@/data/Community.repository'
|
||||
import { KeyPair } from '@/data/KeyPair'
|
||||
import { UserFactory } from '@/data/User.factory'
|
||||
import { UserLogic } from '@/data/User.logic'
|
||||
import { UserRepository } from '@/data/User.repository'
|
||||
import { TransactionErrorType } from '@/graphql/enum/TransactionErrorType'
|
||||
import { UserAccountDraft } from '@/graphql/input/UserAccountDraft'
|
||||
import { TransactionError } from '@/graphql/model/TransactionError'
|
||||
import { logger } from '@/logging/logger'
|
||||
|
||||
import { CreateTransactionRecipeContext } from '../transaction/CreateTransactionRecipe.context'
|
||||
|
||||
export interface TransactionWithAccount {
|
||||
transaction: Transaction
|
||||
account: Account
|
||||
}
|
||||
|
||||
export class RegisterAddressContext {
|
||||
// eslint-disable-next-line no-useless-constructor
|
||||
public constructor(private userAccountDraft: UserAccountDraft) {}
|
||||
|
||||
public async run(): Promise<TransactionWithAccount> {
|
||||
const communityKeyPair = await CommunityRepository.loadHomeCommunityKeyPair()
|
||||
const user = await this.loadOrCreateUser(communityKeyPair)
|
||||
if (this.isAccountAlreadyExistOnUser(user)) {
|
||||
throw new TransactionError(
|
||||
TransactionErrorType.ALREADY_EXIST,
|
||||
'account for this user already exist!',
|
||||
)
|
||||
}
|
||||
logger.info('add user and account', this.userAccountDraft)
|
||||
const account = this.createAccount(new UserLogic(user).calculateKeyPair(communityKeyPair))
|
||||
account.user = user
|
||||
const createTransactionContext = new CreateTransactionRecipeContext(this.userAccountDraft, {
|
||||
account,
|
||||
})
|
||||
await createTransactionContext.run()
|
||||
return { transaction: createTransactionContext.getTransactionRecipe(), account }
|
||||
}
|
||||
|
||||
public isAccountAlreadyExistOnUser(user: User): boolean {
|
||||
return !!user.accounts?.find(
|
||||
(value) => value.derivationIndex === this.userAccountDraft.user.accountNr,
|
||||
)
|
||||
}
|
||||
|
||||
public async loadOrCreateUser(communityKeyPair: KeyPair): Promise<User> {
|
||||
let user = await UserRepository.findByGradidoId(this.userAccountDraft.user, { accounts: true })
|
||||
if (!user) {
|
||||
user = UserFactory.create(this.userAccountDraft, communityKeyPair)
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
public createAccount(userKeyPair: KeyPair): Account {
|
||||
return AccountFactory.createAccountFromUserAccountDraft(this.userAccountDraft, userKeyPair)
|
||||
}
|
||||
}
|
||||
@ -15,7 +15,7 @@ import { InterruptiveSleepManager } from '@/manager/InterruptiveSleepManager'
|
||||
import { LogError } from '@/server/LogError'
|
||||
import { getDataSource } from '@/typeorm/DataSource'
|
||||
|
||||
import { CreateTransactionRecipeContext } from '../transaction/CreateTransationRecipe.context'
|
||||
import { CreateTransactionRecipeContext } from '../transaction/CreateTransactionRecipe.context'
|
||||
|
||||
import { CommunityRole } from './Community.role'
|
||||
|
||||
@ -44,7 +44,9 @@ export class HomeCommunityRole extends CommunityRole {
|
||||
this.self.aufAccount = AccountFactory.createAufAccount(keyPair, this.self.createdAt)
|
||||
this.self.gmwAccount = AccountFactory.createGmwAccount(keyPair, this.self.createdAt)
|
||||
|
||||
const transactionRecipeContext = new CreateTransactionRecipeContext(communityDraft, this.self)
|
||||
const transactionRecipeContext = new CreateTransactionRecipeContext(communityDraft, {
|
||||
community: this.self,
|
||||
})
|
||||
await transactionRecipeContext.run()
|
||||
this.transactionRecipe = transactionRecipeContext.getTransactionRecipe()
|
||||
}
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
import { Transaction } from '@entity/Transaction'
|
||||
|
||||
import { TransactionBuilder } from '@/data/Transaction.builder'
|
||||
|
||||
export class AbstractTransactionRecipeRole {
|
||||
protected transactionBuilder: TransactionBuilder
|
||||
|
||||
public constructor() {
|
||||
this.transactionBuilder = new TransactionBuilder()
|
||||
}
|
||||
|
||||
public getTransaction(): Transaction {
|
||||
return this.transactionBuilder.getTransaction()
|
||||
}
|
||||
}
|
||||
@ -1,29 +1,22 @@
|
||||
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'
|
||||
import { TransactionErrorType } from '@/graphql/enum/TransactionErrorType'
|
||||
import { TransactionDraft } from '@/graphql/input/TransactionDraft'
|
||||
import { TransactionError } from '@/graphql/model/TransactionError'
|
||||
|
||||
import { AbstractTransactionRole } from './AbstractTransaction.role'
|
||||
import { AbstractTransactionRecipeRole } from './AbstractTransactionRecipeRole'
|
||||
|
||||
export class TransactionRecipeRole {
|
||||
protected transactionBuilder: TransactionBuilder
|
||||
|
||||
public constructor() {
|
||||
this.transactionBuilder = new TransactionBuilder()
|
||||
}
|
||||
|
||||
export class BalanceChangingTransactionRecipeRole extends AbstractTransactionRecipeRole {
|
||||
public async create(
|
||||
transactionDraft: TransactionDraft,
|
||||
transactionTypeRole: AbstractTransactionRole,
|
||||
): Promise<TransactionRecipeRole> {
|
||||
): Promise<BalanceChangingTransactionRecipeRole> {
|
||||
const signingUser = transactionTypeRole.getSigningUser()
|
||||
const recipientUser = transactionTypeRole.getRecipientUser()
|
||||
|
||||
@ -82,8 +75,4 @@ export class TransactionRecipeRole {
|
||||
}
|
||||
return this.transactionBuilder.getCommunity()
|
||||
}
|
||||
|
||||
public getTransaction(): Transaction {
|
||||
return this.transactionBuilder.getTransaction()
|
||||
}
|
||||
}
|
||||
@ -4,13 +4,13 @@ import { KeyPair } from '@/data/KeyPair'
|
||||
import { TransactionBodyBuilder } from '@/data/proto/TransactionBody.builder'
|
||||
import { CommunityDraft } from '@/graphql/input/CommunityDraft'
|
||||
|
||||
import { TransactionRecipeRole } from './TransactionRecipe.role'
|
||||
import { AbstractTransactionRecipeRole } from './AbstractTransactionRecipeRole'
|
||||
|
||||
export class CommunityRootTransactionRole extends TransactionRecipeRole {
|
||||
public createFromCommunityRoot(
|
||||
export class CommunityRootTransactionRole extends AbstractTransactionRecipeRole {
|
||||
public create(
|
||||
communityDraft: CommunityDraft,
|
||||
community: Community,
|
||||
): CommunityRootTransactionRole {
|
||||
): AbstractTransactionRecipeRole {
|
||||
// create proto transaction body
|
||||
const transactionBody = new TransactionBodyBuilder()
|
||||
.fromCommunityDraft(communityDraft, community)
|
||||
|
||||
@ -15,7 +15,7 @@ import { InputTransactionType } from '@/graphql/enum/InputTransactionType'
|
||||
import { TransactionDraft } from '@/graphql/input/TransactionDraft'
|
||||
import { iotaTopicFromCommunityUUID } from '@/utils/typeConverter'
|
||||
|
||||
import { CreateTransactionRecipeContext } from './CreateTransationRecipe.context'
|
||||
import { CreateTransactionRecipeContext } from './CreateTransactionRecipe.context'
|
||||
|
||||
// eslint-disable-next-line import/order
|
||||
import { communitySeed } from '@test/seeding/Community.seed'
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { Account } from '@entity/Account'
|
||||
import { Community } from '@entity/Community'
|
||||
import { Transaction } from '@entity/Transaction'
|
||||
|
||||
@ -5,30 +6,38 @@ import { InputTransactionType } from '@/graphql/enum/InputTransactionType'
|
||||
import { TransactionErrorType } from '@/graphql/enum/TransactionErrorType'
|
||||
import { CommunityDraft } from '@/graphql/input/CommunityDraft'
|
||||
import { TransactionDraft } from '@/graphql/input/TransactionDraft'
|
||||
import { UserAccountDraft } from '@/graphql/input/UserAccountDraft'
|
||||
import { TransactionError } from '@/graphql/model/TransactionError'
|
||||
|
||||
import { AbstractTransactionRole } from './AbstractTransaction.role'
|
||||
import { AbstractTransactionRecipeRole } from './AbstractTransactionRecipeRole'
|
||||
import { BalanceChangingTransactionRecipeRole } from './BalanceChangingTransactionRecipeRole'
|
||||
import { CommunityRootTransactionRole } from './CommunityRootTransaction.role'
|
||||
import { CreationTransactionRole } from './CreationTransaction.role'
|
||||
import { ReceiveTransactionRole } from './ReceiveTransaction.role'
|
||||
import { RegisterAddressTransactionRole } from './RegisterAddressTransaction.role'
|
||||
import { SendTransactionRole } from './SendTransaction.role'
|
||||
import { TransactionRecipeRole } from './TransactionRecipe.role'
|
||||
|
||||
/**
|
||||
* @DCI-Context
|
||||
* Context for create and add Transaction Recipe to DB
|
||||
*/
|
||||
|
||||
export interface AdditionalData {
|
||||
community?: Community
|
||||
account?: Account
|
||||
}
|
||||
|
||||
export class CreateTransactionRecipeContext {
|
||||
private transactionRecipeRole: TransactionRecipeRole
|
||||
private transactionRecipe: AbstractTransactionRecipeRole
|
||||
// eslint-disable-next-line no-useless-constructor
|
||||
public constructor(
|
||||
private draft: CommunityDraft | TransactionDraft,
|
||||
private community?: Community,
|
||||
private draft: CommunityDraft | TransactionDraft | UserAccountDraft,
|
||||
private data?: AdditionalData,
|
||||
) {}
|
||||
|
||||
public getTransactionRecipe(): Transaction {
|
||||
return this.transactionRecipeRole.getTransaction()
|
||||
return this.transactionRecipe.getTransaction()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -36,7 +45,7 @@ export class CreateTransactionRecipeContext {
|
||||
*/
|
||||
public async run(): Promise<boolean> {
|
||||
if (this.draft instanceof TransactionDraft) {
|
||||
this.transactionRecipeRole = new TransactionRecipeRole()
|
||||
const transactionRecipeRole = new BalanceChangingTransactionRecipeRole()
|
||||
// contain logic for translation from backend to dlt-connector format
|
||||
let transactionTypeRole: AbstractTransactionRole
|
||||
switch (this.draft.type) {
|
||||
@ -50,15 +59,24 @@ export class CreateTransactionRecipeContext {
|
||||
transactionTypeRole = new ReceiveTransactionRole(this.draft)
|
||||
break
|
||||
}
|
||||
await this.transactionRecipeRole.create(this.draft, transactionTypeRole)
|
||||
await transactionRecipeRole.create(this.draft, transactionTypeRole)
|
||||
return true
|
||||
} else if (this.draft instanceof CommunityDraft) {
|
||||
if (!this.community) {
|
||||
if (!this.data?.community) {
|
||||
throw new TransactionError(TransactionErrorType.MISSING_PARAMETER, 'community was not set')
|
||||
}
|
||||
this.transactionRecipeRole = new CommunityRootTransactionRole().createFromCommunityRoot(
|
||||
this.transactionRecipe = new CommunityRootTransactionRole().create(
|
||||
this.draft,
|
||||
this.community,
|
||||
this.data.community,
|
||||
)
|
||||
return true
|
||||
} else if (this.draft instanceof UserAccountDraft) {
|
||||
if (!this.data?.account) {
|
||||
throw new TransactionError(TransactionErrorType.MISSING_PARAMETER, 'account was not set')
|
||||
}
|
||||
this.transactionRecipe = await new RegisterAddressTransactionRole().create(
|
||||
this.draft,
|
||||
this.data.account,
|
||||
)
|
||||
return true
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
import { Account } from '@entity/Account'
|
||||
|
||||
import { AccountLogic } from '@/data/Account.logic'
|
||||
import { CommunityRepository } from '@/data/Community.repository'
|
||||
import { TransactionBodyBuilder } from '@/data/proto/TransactionBody.builder'
|
||||
import { TransactionErrorType } from '@/graphql/enum/TransactionErrorType'
|
||||
import { UserAccountDraft } from '@/graphql/input/UserAccountDraft'
|
||||
import { TransactionError } from '@/graphql/model/TransactionError'
|
||||
|
||||
import { AbstractTransactionRecipeRole } from './AbstractTransactionRecipeRole'
|
||||
|
||||
export class RegisterAddressTransactionRole extends AbstractTransactionRecipeRole {
|
||||
async create(
|
||||
userAccountDraft: UserAccountDraft,
|
||||
account: Account,
|
||||
): Promise<AbstractTransactionRecipeRole> {
|
||||
const bodyBuilder = new TransactionBodyBuilder()
|
||||
const communityKeyPair = await CommunityRepository.loadHomeCommunityKeyPair()
|
||||
const signingKeyPair = new AccountLogic(account).calculateKeyPair(communityKeyPair)
|
||||
if (!signingKeyPair) {
|
||||
throw new TransactionError(TransactionErrorType.NOT_FOUND, "couldn't found signing key pair")
|
||||
}
|
||||
this.transactionBuilder
|
||||
.fromTransactionBodyBuilder(bodyBuilder.fromUserAccountDraft(userAccountDraft, account))
|
||||
.setSignature(signingKeyPair.sign(this.transactionBuilder.getTransaction().bodyBytes))
|
||||
.setSigningAccount(account)
|
||||
return this
|
||||
}
|
||||
}
|
||||
@ -14,7 +14,7 @@ import { InputTransactionType } from '@/graphql/enum/InputTransactionType'
|
||||
import { TransactionDraft } from '@/graphql/input/TransactionDraft'
|
||||
import { logger } from '@/logging/logger'
|
||||
|
||||
import { CreateTransactionRecipeContext } from '../backendToDb/transaction/CreateTransationRecipe.context'
|
||||
import { CreateTransactionRecipeContext } from '../backendToDb/transaction/CreateTransactionRecipe.context'
|
||||
|
||||
import { TransmitToIotaContext } from './TransmitToIota.context'
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user