diff --git a/backend/package.json b/backend/package.json index ba45225a2..beb460fee 100644 --- a/backend/package.json +++ b/backend/package.json @@ -61,6 +61,7 @@ "@types/jest": "^27.0.2", "@types/lodash.clonedeep": "^4.5.6", "@types/node": "^16.10.3", + "@types/node-fetch": "^2.6.11", "@types/nodemailer": "^6.4.4", "@types/sodium-native": "^2.3.5", "@types/uuid": "^8.3.4", diff --git a/backend/src/apis/dltConnector/DltConnectorClient.ts b/backend/src/apis/dltConnector/DltConnectorClient.ts index 75e9b2544..3402e0844 100644 --- a/backend/src/apis/dltConnector/DltConnectorClient.ts +++ b/backend/src/apis/dltConnector/DltConnectorClient.ts @@ -1,16 +1,17 @@ import { Transaction as DbTransaction } from '@entity/Transaction' import { User } from '@entity/User' import { gql, GraphQLClient } from 'graphql-request' +// eslint-disable-next-line import/named, n/no-extraneous-import +import { FetchError } from 'node-fetch' import { CONFIG } from '@/config' import { TransactionTypeId } from '@/graphql/enum/TransactionTypeId' import { LogError } from '@/server/LogError' import { backendLogger as logger } from '@/server/logger' -import { AccountType } from './enum/AccountType' +import { TransactionDraft } from './model/TransactionDraft' import { TransactionResult } from './model/TransactionResult' import { UserAccountDraft } from './model/UserAccountDraft' -import { UserIdentifier } from './model/UserIdentifier' const sendTransaction = gql` mutation ($input: TransactionDraft!) { @@ -46,17 +47,6 @@ const registerAddress = gql` } ` -// from ChatGPT -function getTransactionTypeString(id: TransactionTypeId): string { - const key = Object.keys(TransactionTypeId).find( - (key) => TransactionTypeId[key as keyof typeof TransactionTypeId] === id, - ) - if (key === undefined) { - throw new LogError('invalid transaction type id: ' + id.toString()) - } - return key -} - // Source: https://refactoring.guru/design-patterns/singleton/typescript/example // and ../federation/client/FederationClientFactory.ts /** @@ -109,92 +99,74 @@ export class DltConnectorClient { return DltConnectorClient.instance } + private getTransactionParams(input: DbTransaction | User): TransactionDraft | UserAccountDraft { + if (input instanceof DbTransaction) { + return new TransactionDraft(input) + } else if (input instanceof User) { + return new UserAccountDraft(input) + } + throw new LogError('transaction should be either Transaction or User Entity') + } + + private handleTransactionResult(result: TransactionResult) { + if (result.error) { + throw new Error(result.error.message) + } + return result + } + + private async sendTransaction(input: TransactionDraft) { + const { + data: { sendTransaction: result }, + } = await this.client.rawRequest<{ sendTransaction: TransactionResult }>(sendTransaction, { + input, + }) + return this.handleTransactionResult(result) + } + + private async registerAddress(input: UserAccountDraft) { + const { + data: { registerAddress: result }, + } = await this.client.rawRequest<{ registerAddress: TransactionResult }>(registerAddress, { + input, + }) + return this.handleTransactionResult(result) + } + /** * transmit transaction via dlt-connector to iota * and update dltTransactionId of transaction in db with iota message id */ public async transmitTransaction( - transaction: DbTransaction, + transaction: DbTransaction | User, ): Promise { // we don't need the receive transactions, there contain basically the same data as the send transactions - if ((transaction.typeId as TransactionTypeId) === TransactionTypeId.RECEIVE) { + if ( + transaction instanceof DbTransaction && + (transaction.typeId as TransactionTypeId) === TransactionTypeId.RECEIVE + ) { return } - const typeString = getTransactionTypeString(transaction.typeId) - // no negative values in dlt connector, gradido concept don't use negative values so the code don't use it too - const amountString = transaction.amount.abs().toString() - const params = { - input: { - user: { - uuid: transaction.userGradidoID, - communityUuid: transaction.userCommunityUuid, - } as UserIdentifier, - linkedUser: { - uuid: transaction.linkedUserGradidoID, - communityUuid: transaction.linkedUserCommunityUuid, - } as UserIdentifier, - amount: amountString, - type: typeString, - createdAt: transaction.balanceDate.toISOString(), - targetDate: transaction.creationDate?.toISOString(), - }, - } + + const input = this.getTransactionParams(transaction) try { - // TODO: add account nr for user after they have also more than one account in backend - logger.debug('transmit transaction to dlt connector', params) - const { - data: { sendTransaction: result }, - } = await this.client.rawRequest<{ sendTransaction: TransactionResult }>( - sendTransaction, - params, - ) - if (result.error) { - throw new Error(result.error.message) + logger.debug('transmit transaction or user to dlt connector', input) + if (input instanceof TransactionDraft) { + return await this.sendTransaction(input) + } else if (input instanceof UserAccountDraft) { + return await this.registerAddress(input) + } else { + throw new LogError('unhandled branch reached') } - console.log(result) - return result } catch (e) { - if (e instanceof Error) { + logger.error(e) + if (e instanceof FetchError) { + throw e + } else if (e instanceof Error) { throw new LogError(`from dlt-connector: ${e.message}`) } else { throw new LogError('Exception sending transfer transaction to dlt-connector', e) } } } - - public async registerAddress(dbUser: User): Promise { - const params = { - input: { - user: { - uuid: dbUser.gradidoID, - communityUuid: dbUser.communityUuid, - accountNr: 1, - } as UserIdentifier, - createdAt: dbUser.createdAt.toISOString(), - accountType: AccountType.COMMUNITY_HUMAN, - } as UserAccountDraft, - } - try { - const { - data: { registerAddress: result }, - } = await this.client.rawRequest<{ registerAddress: TransactionResult }>( - registerAddress, - params, - ) - logger.info('send register address transaction to dlt-connector', { - params, - result, - }) - if (result.error) { - throw new Error(result.error.message) - } - return result - } catch (e) { - if (e instanceof Error) { - throw new LogError(`from dlt-connector: ${e.message}`) - } else { - throw new LogError('Exception sending register address transaction to dlt-connector', e) - } - } - } } diff --git a/backend/src/apis/dltConnector/model/TransactionDraft.ts b/backend/src/apis/dltConnector/model/TransactionDraft.ts new file mode 100755 index 000000000..e6b8f8d6d --- /dev/null +++ b/backend/src/apis/dltConnector/model/TransactionDraft.ts @@ -0,0 +1,38 @@ +// https://www.npmjs.com/package/@apollo/protobufjs +import { Transaction } from '@entity/Transaction' + +import { TransactionTypeId } from '@/graphql/enum/TransactionTypeId' +import { LogError } from '@/server/LogError' + +import { UserIdentifier } from './UserIdentifier' + +export class TransactionDraft { + user: UserIdentifier + linkedUser: UserIdentifier + amount: string + type: string + createdAt: string + // only for creation transactions + targetDate?: string + + constructor(transaction: Transaction) { + if ( + !transaction.linkedUserGradidoID || + !transaction.linkedUserCommunityUuid || + !transaction.userCommunityUuid + ) { + throw new LogError( + `missing necessary field in transaction: ${transaction.id}, need linkedUserGradidoID, linkedUserCommunityUuid and userCommunityUuid`, + ) + } + this.user = new UserIdentifier(transaction.userGradidoID, transaction.userCommunityUuid) + this.linkedUser = new UserIdentifier( + transaction.linkedUserGradidoID, + transaction.linkedUserCommunityUuid, + ) + this.amount = transaction.amount.abs().toString() + this.type = TransactionTypeId[transaction.typeId] + this.createdAt = transaction.balanceDate.toISOString() + this.targetDate = transaction.creationDate?.toISOString() + } +} diff --git a/backend/src/apis/dltConnector/model/UserAccountDraft.ts b/backend/src/apis/dltConnector/model/UserAccountDraft.ts index f4aff4cb4..dc52065d1 100644 --- a/backend/src/apis/dltConnector/model/UserAccountDraft.ts +++ b/backend/src/apis/dltConnector/model/UserAccountDraft.ts @@ -1,9 +1,17 @@ +import { User } from '@entity/User' + import { AccountType } from '@/apis/dltConnector/enum/AccountType' import { UserIdentifier } from './UserIdentifier' -export interface UserAccountDraft { +export class UserAccountDraft { user: UserIdentifier createdAt: string accountType: AccountType + + constructor(user: User) { + this.user = new UserIdentifier(user.gradidoID, user.communityUuid) + this.createdAt = user.createdAt.toISOString() + this.accountType = AccountType.COMMUNITY_HUMAN + } } diff --git a/backend/src/apis/dltConnector/model/UserIdentifier.ts b/backend/src/apis/dltConnector/model/UserIdentifier.ts index e265593be..1824d17f3 100644 --- a/backend/src/apis/dltConnector/model/UserIdentifier.ts +++ b/backend/src/apis/dltConnector/model/UserIdentifier.ts @@ -1,5 +1,11 @@ -export interface UserIdentifier { +export class UserIdentifier { uuid: string communityUuid: string accountNr?: number + + constructor(uuid: string, communityUuid: string, accountNr?: number) { + this.uuid = uuid + this.communityUuid = communityUuid + this.accountNr = accountNr + } } diff --git a/backend/src/tasks/sendTransactionsToDltConnector.test.ts b/backend/src/apis/dltConnector/sendTransactionsToDltConnector.test.ts similarity index 100% rename from backend/src/tasks/sendTransactionsToDltConnector.test.ts rename to backend/src/apis/dltConnector/sendTransactionsToDltConnector.test.ts diff --git a/backend/src/apis/dltConnector/sendTransactionsToDltConnector.ts b/backend/src/apis/dltConnector/sendTransactionsToDltConnector.ts new file mode 100644 index 000000000..36974b5cf --- /dev/null +++ b/backend/src/apis/dltConnector/sendTransactionsToDltConnector.ts @@ -0,0 +1,142 @@ +import { DltTransaction } from '@entity/DltTransaction' +import { DltUser } from '@entity/DltUser' +import { Transaction } from '@entity/Transaction' +import { User } from '@entity/User' +// eslint-disable-next-line import/named, n/no-extraneous-import +import { FetchError } from 'node-fetch' + +import { DltConnectorClient } from '@dltConnector/DltConnectorClient' + +import { TransactionResult } from '@/apis/dltConnector/model/TransactionResult' +import { backendLogger as logger } from '@/server/logger' +import { + InterruptiveSleepManager, + TRANSMIT_TO_IOTA_INTERRUPTIVE_SLEEP_KEY, +} from '@/util/InterruptiveSleepManager' + +let isLoopRunning = true + +export const stopSendTransactionsToDltConnector = (): void => { + isLoopRunning = false +} + +function logTransactionResult( + type: 'dltUser' | 'dltTransaction', + data: { id: number; messageId: string; error: string | null }, +): void { + if (data.error) { + logger.error(`Store ${type} with error: id=${data.id}, error=${data.error}`) + } else { + logger.info(`Store ${type}: messageId=${data.messageId}, id=${data.id}`) + } +} + +async function saveTransactionResult( + pendingTransaction: User | Transaction, + messageId: string, + error: string | null, +): Promise { + if (pendingTransaction instanceof User) { + const dltUser = DltUser.create() + dltUser.userId = pendingTransaction.id + dltUser.messageId = messageId + dltUser.error = error + await DltUser.save(dltUser) + logTransactionResult('dltUser', dltUser) + } else if (pendingTransaction instanceof Transaction) { + const dltTransaction = DltTransaction.create() + dltTransaction.transactionId = pendingTransaction.id + dltTransaction.messageId = messageId + dltTransaction.error = error + await DltTransaction.save(dltTransaction) + logTransactionResult('dltTransaction', dltTransaction) + } +} + +async function findNextPendingTransaction(): Promise { + const lastTransactionPromise: Promise = Transaction.createQueryBuilder() + .leftJoin(DltTransaction, 'dltTransaction', 'Transaction.id = dltTransaction.transactionId') + .where('dltTransaction.transaction_id IS NULL') + // eslint-disable-next-line camelcase + .orderBy({ balance_date: 'ASC', Transaction_id: 'ASC' }) + .limit(1) + .getOne() + + const lastUserPromise: Promise = User.createQueryBuilder() + .leftJoin(DltUser, 'dltUser', 'User.id = dltUser.userId') + .where('dltUser.user_id IS NULL') + // eslint-disable-next-line camelcase + .orderBy({ User_created_at: 'ASC', User_id: 'ASC' }) + .limit(1) + .getOne() + + const results = await Promise.all([lastTransactionPromise, lastUserPromise]) + if (results[0] && results[1]) { + return results[0].balanceDate < results[1].createdAt ? results[0] : results[1] + } else if (results[0]) { + return results[0] + } else if (results[1]) { + return results[1] + } + return null +} + +async function processPendingTransactions(dltConnector: DltConnectorClient): Promise { + let pendingTransaction: Transaction | User | null = null + while ((pendingTransaction = await findNextPendingTransaction())) { + let result: TransactionResult | undefined + let messageId = '' + let error: string | null = null + + try { + result = await dltConnector.transmitTransaction(pendingTransaction) + if (result?.succeed && result.recipe) { + messageId = result.recipe.messageIdHex + } else { + error = 'skipped' + } + } catch (e) { + if (e instanceof FetchError) { + throw e + } + error = e instanceof Error ? e.message : String(e) + } + + await saveTransactionResult(pendingTransaction, messageId, error) + } +} + +export async function sendTransactionsToDltConnector(): Promise { + const dltConnector = DltConnectorClient.getInstance() + + if (!dltConnector) { + logger.info('Sending to DltConnector currently not configured...') + isLoopRunning = false + return + } + + logger.info('Starting sendTransactionsToDltConnector task') + + // eslint-disable-next-line no-unmodified-loop-condition + while (isLoopRunning) { + try { + // return after no pending transactions are left + await processPendingTransactions(dltConnector) + await InterruptiveSleepManager.getInstance().sleep( + TRANSMIT_TO_IOTA_INTERRUPTIVE_SLEEP_KEY, + 1000, + ) + } catch (e) { + // couldn't connect to dlt-connector? We wait + if (e instanceof FetchError) { + logger.error(`error connecting dlt-connector, wait 5 seconds before retry: ${String(e)}`) + await InterruptiveSleepManager.getInstance().sleep( + TRANSMIT_TO_IOTA_INTERRUPTIVE_SLEEP_KEY, + 5000, + ) + } else { + logger.error(`Error while sending to DLT-connector or writing messageId`, e) + } + } + } +} diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index 0ef7f0586..8a5c92cf4 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -38,7 +38,7 @@ import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK' import { fullName } from '@/util/utilities' import { calculateBalance } from '@/util/validate' -import { sendTransactionsToDltConnector } from '../../tasks/sendTransactionsToDltConnector' +import { sendTransactionsToDltConnector } from '../../apis/dltConnector/sendTransactionsToDltConnector' import { executeTransaction } from './TransactionResolver' import { getUserCreation, validateContribution } from './util/creations' diff --git a/backend/src/index.ts b/backend/src/index.ts index 5cb3574e4..dd166d3d5 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,7 +1,7 @@ import { CONFIG } from './config' import { startValidateCommunities } from './federation/validateCommunities' import { createServer } from './server/createServer' -import { sendTransactionsToDltConnector } from './tasks/sendTransactionsToDltConnector' +import { sendTransactionsToDltConnector } from './apis/dltConnector/sendTransactionsToDltConnector' async function main() { const { app } = await createServer() diff --git a/backend/src/tasks/sendTransactionsToDltConnector.ts b/backend/src/tasks/sendTransactionsToDltConnector.ts deleted file mode 100644 index 62c7c5ad7..000000000 --- a/backend/src/tasks/sendTransactionsToDltConnector.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { DltTransaction } from '@entity/DltTransaction' -import { DltUser } from '@entity/DltUser' -import { Transaction } from '@entity/Transaction' -import { User } from '@entity/User' - -import { DltConnectorClient } from '@dltConnector/DltConnectorClient' - -import { backendLogger as logger } from '@/server/logger' -import { - InterruptiveSleepManager, - TRANSMIT_TO_IOTA_INTERRUPTIVE_SLEEP_KEY, -} from '@/util/InterruptiveSleepManager' - -let running = true - -export const stopSendTransactionsToDltConnector = (): void => { - running = false -} - -export async function sendTransactionsToDltConnector(): Promise { - const dltConnector = DltConnectorClient.getInstance() - if (!dltConnector) { - logger.info('sending to DltConnector currently not configured...') - running = false - return - } - logger.info('start sendTransactionsToDltConnector task') - - // eslint-disable-next-line no-unmodified-loop-condition - while (running) { - try { - // loop while work could be found - while (true) { - const pendingTransaction = await findNextPendingTransaction() - if (pendingTransaction instanceof User) { - const dltUser = DltUser.create() - dltUser.userId = pendingTransaction.id - try { - const result = await dltConnector.registerAddress(pendingTransaction) - if (result?.succeed && result.recipe) { - dltUser.messageId = result.recipe.messageIdHex - } - } catch (e) { - if (e instanceof Error) { - dltUser.error = e.message - } else if (typeof e === 'string') { - dltUser.error = e - } - } - // wait until saved, necessary before next call to findNextPendingTransaction - await DltUser.save(dltUser) - if (dltUser.messageId) { - logger.info('store dltUser: messageId=%s, id=%d', dltUser.messageId, dltUser.id) - } else { - logger.error('store dltUser with error: id=%d, error=%s', dltUser.id, dltUser.error) - } - } else if (pendingTransaction instanceof Transaction) { - const dltTransaction = DltTransaction.create() - dltTransaction.transactionId = pendingTransaction.id - try { - const result = await dltConnector.transmitTransaction(pendingTransaction) - if (result?.succeed && result.recipe) { - dltTransaction.messageId = result.recipe.messageIdHex - } else { - dltTransaction.error = 'skipped' - } - } catch (e) { - if (e instanceof Error) { - dltTransaction.error = e.message - } else if (typeof e === 'string') { - dltTransaction.error = e - } - } - // wait until saved, necessary before next call to findNextPendingTransaction - await DltTransaction.save(dltTransaction) - if (dltTransaction.messageId) { - logger.info( - 'store dltTransaction: messageId=%s, id=%d', - dltTransaction.messageId, - dltTransaction.id, - ) - } else { - logger.error( - 'store dltTransaction with error: id=%d, error=%s', - dltTransaction.id, - dltTransaction.error, - ) - } - } else { - break - } - } - await InterruptiveSleepManager.getInstance().sleep( - TRANSMIT_TO_IOTA_INTERRUPTIVE_SLEEP_KEY, - 1000, - ) - } catch (e) { - logger.error(`error while sending to dlt-connector or writing messageId`, e) - } - } -} - -async function findNextPendingTransaction(): Promise { - const lastTransactionPromise: Promise = Transaction.createQueryBuilder() - .leftJoin(DltTransaction, 'dltTransaction', 'Transaction.id = dltTransaction.transactionId') - .where('dltTransaction.transaction_id IS NULL') - // eslint-disable-next-line camelcase - .orderBy({ balance_date: 'ASC', Transaction_id: 'ASC' }) - .limit(1) - .getOne() - - const lastUserPromise: Promise = User.createQueryBuilder() - .leftJoin(DltUser, 'dltUser', 'User.id = dltUser.userId') - .where('dltUser.user_id IS NULL') - // eslint-disable-next-line camelcase - .orderBy({ User_created_at: 'ASC', User_id: 'ASC' }) - .limit(1) - .getOne() - - const results = await Promise.all([lastTransactionPromise, lastUserPromise]) - if (results[0] && results[1]) { - return results[0].balanceDate < results[1].createdAt ? results[0] : results[1] - } else if (results[0]) { - return results[0] - } else if (results[1]) { - return results[1] - } - return null -} diff --git a/backend/yarn.lock b/backend/yarn.lock index 5c33b1ce8..9e32b7d8c 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -1126,6 +1126,14 @@ dependencies: "@types/node" "*" +"@types/node-fetch@^2.6.11": + version "2.6.11" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" + integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== + dependencies: + "@types/node" "*" + form-data "^4.0.0" + "@types/node@*", "@types/node@^16.10.3": version "16.10.3" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.3.tgz#7a8f2838603ea314d1d22bb3171d899e15c57bd5" @@ -3417,6 +3425,15 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48" + integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" diff --git a/dlt-connector/src/graphql/input/TransactionDraft.ts b/dlt-connector/src/graphql/input/TransactionDraft.ts index d1fa48c3c..3f1f57a85 100755 --- a/dlt-connector/src/graphql/input/TransactionDraft.ts +++ b/dlt-connector/src/graphql/input/TransactionDraft.ts @@ -1,9 +1,10 @@ // https://www.npmjs.com/package/@apollo/protobufjs -import { InputTransactionType } from '@enum/InputTransactionType' -import { isValidDateString, isValidNumberString } from '@validator/DateString' import { IsEnum, IsObject, ValidateNested } from 'class-validator' import { InputType, Field } from 'type-graphql' +import { InputTransactionType } from '@enum/InputTransactionType' +import { isValidDateString, isValidNumberString } from '@validator/DateString' + import { UserIdentifier } from './UserIdentifier' @InputType() diff --git a/dlt-connector/src/graphql/input/UserAccountDraft.ts b/dlt-connector/src/graphql/input/UserAccountDraft.ts index e10be9574..9ae544e32 100644 --- a/dlt-connector/src/graphql/input/UserAccountDraft.ts +++ b/dlt-connector/src/graphql/input/UserAccountDraft.ts @@ -1,9 +1,10 @@ // https://www.npmjs.com/package/@apollo/protobufjs -import { isValidDateString } from '@validator/DateString' import { IsEnum, IsObject, ValidateNested } from 'class-validator' import { InputType, Field } from 'type-graphql' +import { isValidDateString } from '@validator/DateString' + import { AccountType } from '@/graphql/enum/AccountType' import { UserIdentifier } from './UserIdentifier' diff --git a/dlt-connector/src/graphql/model/TransactionResult.ts b/dlt-connector/src/graphql/model/TransactionResult.ts index 370c9827d..346920310 100644 --- a/dlt-connector/src/graphql/model/TransactionResult.ts +++ b/dlt-connector/src/graphql/model/TransactionResult.ts @@ -19,7 +19,7 @@ export class TransactionResult { @Field(() => TransactionError, { nullable: true }) error?: TransactionError - // if no error happend, the message id of the iota transaction + // if no error happened, the message id of the iota transaction @Field(() => TransactionRecipe, { nullable: true }) recipe?: TransactionRecipe diff --git a/dlt-connector/src/graphql/resolver/TransactionsResolver.ts b/dlt-connector/src/graphql/resolver/TransactionsResolver.ts index 50636dee3..e5e537ad9 100755 --- a/dlt-connector/src/graphql/resolver/TransactionsResolver.ts +++ b/dlt-connector/src/graphql/resolver/TransactionsResolver.ts @@ -1,6 +1,7 @@ -import { TransactionDraft } from '@input/TransactionDraft' import { Resolver, Arg, Mutation } from 'type-graphql' +import { TransactionDraft } from '@input/TransactionDraft' + import { SendToIotaContext } from '@/interactions/sendToIota/SendToIota.context' import { TransactionError } from '../model/TransactionError' diff --git a/dlt-connector/src/graphql/validator/DateString.ts b/dlt-connector/src/graphql/validator/DateString.ts index 2be057194..0445c1bbe 100644 --- a/dlt-connector/src/graphql/validator/DateString.ts +++ b/dlt-connector/src/graphql/validator/DateString.ts @@ -38,4 +38,4 @@ export function isValidNumberString(validationOptions?: ValidationOptions) { }, }) } -} \ No newline at end of file +} diff --git a/dlt-connector/src/interactions/keyPairCalculation/KeyPairCalculation.context.ts b/dlt-connector/src/interactions/keyPairCalculation/KeyPairCalculation.context.ts index 8e6466df5..012168bb0 100644 --- a/dlt-connector/src/interactions/keyPairCalculation/KeyPairCalculation.context.ts +++ b/dlt-connector/src/interactions/keyPairCalculation/KeyPairCalculation.context.ts @@ -12,7 +12,7 @@ import { UserKeyPairRole } from './UserKeyPair.role' /** * @DCI-Context - * Context for calculating key pair for signing transactions + * Context for calculating key pair for signing transactions */ export async function KeyPairCalculation(input: UserIdentifier | string): Promise { const cache = KeyPairCacheManager.getInstance() diff --git a/dlt-connector/yarn.lock b/dlt-connector/yarn.lock index c4f244816..1f60d65f2 100644 --- a/dlt-connector/yarn.lock +++ b/dlt-connector/yarn.lock @@ -1082,7 +1082,7 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== -"@types/node-fetch@^2.6.1": +"@types/node-fetch@^2.6.1", "@types/node-fetch@^2.6.11": version "2.6.11" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== @@ -2112,6 +2112,11 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" +data-uri-to-buffer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" + integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== + data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -2931,6 +2936,14 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fetch-blob@^3.1.2, fetch-blob@^3.1.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" + integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== + dependencies: + node-domexception "^1.0.0" + web-streams-polyfill "^3.0.3" + figures@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" @@ -3050,6 +3063,13 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +formdata-polyfill@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + dependencies: + fetch-blob "^3.1.2" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -4670,6 +4690,11 @@ node-api-headers@^1.1.0: resolved "https://registry.yarnpkg.com/node-api-headers/-/node-api-headers-1.3.0.tgz#bb32c6b3e33fb0004bd93c66787bf00998c834ea" integrity sha512-8Bviwtw4jNhv0B2qDjj4M5e6GyAuGtxsmZTrFJu3S3Z0+oHwIgSUdIKkKJmZd+EbMo7g3v4PLBbrjxwmZOqMBg== +node-domexception@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + node-fetch@^2.6.12, node-fetch@^2.6.7: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -4677,6 +4702,15 @@ node-fetch@^2.6.12, node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" +node-fetch@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b" + integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.4" + formdata-polyfill "^4.0.10" + node-gyp-build@^4.8.1: version "4.8.2" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.2.tgz#4f802b71c1ab2ca16af830e6c1ea7dd1ad9496fa" @@ -6265,6 +6299,11 @@ walker@^1.0.7: dependencies: makeerror "1.0.12" +web-streams-polyfill@^3.0.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz#2073b91a2fdb1fbfbd401e7de0ac9f8214cecb4b" + integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"