Merge backend querie, mutation and database in frontend send coins.

This commit is contained in:
elweyn 2022-03-09 17:53:16 +01:00
commit c38c5c3243
5 changed files with 46 additions and 16 deletions

View File

@ -9,6 +9,7 @@ export class TransactionLink {
this.id = transactionLink.id
this.user = user
this.amount = transactionLink.amount
this.holdAvailableAmount = transactionLink.holdAvailableAmount
this.memo = transactionLink.memo
this.code = transactionLink.code
this.createdAt = transactionLink.createdAt
@ -27,6 +28,9 @@ export class TransactionLink {
@Field(() => Decimal)
amount: Decimal
@Field(() => Decimal)
holdAvailableAmount: Decimal
@Field(() => String)
memo: string

View File

@ -3,8 +3,8 @@ import { transactionLinkCode } from './TransactionLinkResolver'
describe('transactionLinkCode', () => {
const date = new Date()
it('returns a string of length 96', () => {
expect(transactionLinkCode(date)).toHaveLength(96)
it('returns a string of length 24', () => {
expect(transactionLinkCode(date)).toHaveLength(24)
})
it('returns a string that ends with the hex value of date', () => {

View File

@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Resolver, Args, Authorized, Ctx, Mutation, Query, Arg } from 'type-graphql'
import { getCustomRepository } from '@dbTools/typeorm'
import { getCustomRepository, MoreThan } from '@dbTools/typeorm'
import { TransactionLink } from '@model/TransactionLink'
import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink'
import TransactionLinkArgs from '@arg/TransactionLinkArgs'
@ -11,20 +11,22 @@ import { calculateBalance } from '@/util/validate'
import { RIGHTS } from '@/auth/RIGHTS'
import { randomBytes } from 'crypto'
import { User } from '@model/User'
import { calculateDecay } from '@/util/decay'
// TODO: do not export, test it inside the resolver
export const transactionLinkCode = (date: Date): string => {
const time = date.getTime().toString(16)
return (
randomBytes(48)
randomBytes(12)
.toString('hex')
.substring(0, 96 - time.length) + time
.substring(0, 24 - time.length) + time
)
}
const transactionLinkExpireDate = (date: Date): Date => {
const validUntil = new Date(date)
// valid for 14 days
return new Date(date.setDate(date.getDate() + 14))
return new Date(validUntil.setDate(date.getDate() + 14))
}
@Resolver()
@ -38,23 +40,39 @@ export class TransactionLinkResolver {
const userRepository = getCustomRepository(UserRepository)
const user = await userRepository.findByPubkeyHex(context.pubKey)
const createdDate = new Date()
const validUntil = transactionLinkExpireDate(createdDate)
const holdAvailableAmount = amount.add(
calculateDecay(amount, createdDate, validUntil).decay.mul(-1),
)
const openTransactionLinks = await dbTransactionLink.find({
select: ['holdAvailableAmount'],
where: { userId: user.id, redeemedAt: null, validUntil: MoreThan(createdDate) },
})
const holdAvailable = openTransactionLinks.reduce(
(previousValue, currentValue) =>
previousValue.add(currentValue.holdAvailableAmount.toString()),
holdAvailableAmount,
)
// validate amount
// TODO taken from transaction resolver, duplicate code
const createdDate = new Date()
const sendBalance = await calculateBalance(user.id, amount.mul(-1), createdDate)
const sendBalance = await calculateBalance(user.id, holdAvailable.mul(-1), createdDate)
if (!sendBalance) {
throw new Error("user hasn't enough GDD or amount is < 0")
}
// TODO!!!! Test balance for pending transaction links
const transactionLink = dbTransactionLink.create()
transactionLink.userId = user.id
transactionLink.amount = amount
transactionLink.memo = memo
transactionLink.holdAvailableAmount = holdAvailableAmount
transactionLink.code = transactionLinkCode(createdDate)
transactionLink.createdAt = createdDate
transactionLink.validUntil = transactionLinkExpireDate(createdDate)
transactionLink.validUntil = validUntil
transactionLink.showEmail = showEmail
await dbTransactionLink.save(transactionLink).catch((error) => {
throw error

View File

@ -19,22 +19,30 @@ export class TransactionLink extends BaseEntity {
})
amount: Decimal
@Column({
type: 'decimal',
name: 'hold_available_amount',
precision: 40,
scale: 20,
nullable: false,
transformer: DecimalTransformer,
})
holdAvailableAmount: Decimal
@Column({ length: 255, nullable: false, collation: 'utf8mb4_unicode_ci' })
memo: string
@Column({ length: 96, nullable: false, collation: 'utf8mb4_unicode_ci' })
@Column({ length: 24, nullable: false, collation: 'utf8mb4_unicode_ci' })
code: string
@Column({
type: 'datetime',
default: () => 'CURRENT_TIMESTAMP',
nullable: false,
})
createdAt: Date
@Column({
type: 'datetime',
default: () => 'CURRENT_TIMESTAMP',
nullable: false,
})
validUntil: Date
@ -48,7 +56,6 @@ export class TransactionLink extends BaseEntity {
@Column({
type: 'datetime',
default: () => 'CURRENT_TIMESTAMP',
nullable: true,
})
redeemedAt?: Date | null

View File

@ -9,8 +9,9 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
\`id\` int UNSIGNED NOT NULL AUTO_INCREMENT,
\`userId\` int UNSIGNED NOT NULL,
\`amount\` DECIMAL(40,20) NOT NULL,
\`hold_available_amount\` DECIMAL(40,20) NOT NULL,
\`memo\` varchar(255) NOT NULL,
\`code\` varchar(96) NOT NULL,
\`code\` varchar(24) NOT NULL,
\`createdAt\` datetime NOT NULL,
\`validUntil\` datetime NOT NULL,
\`showEmail\` boolean NOT NULL DEFAULT false,