next try for x-com sendCoins

This commit is contained in:
Claus-Peter Huebner 2023-09-21 18:45:53 +02:00
parent 7561025c99
commit 31d47d7537
11 changed files with 119 additions and 88 deletions

View File

@ -121,6 +121,7 @@
{
"appenders":
[
"out",
"backend",
"errors"
],

View File

@ -34,21 +34,14 @@ export class SendCoinsClient {
voteForSendCoins = async (args: SendCoinsArgs): Promise<SendCoinsResult> => {
logger.debug('X-Com: voteForSendCoins against endpoint=', this.endpoint)
try {
logger.debug(`SendCoinsClient: voteForSendCoins with args=`, args)
logger.debug(`X-Com: SendCoinsClient: voteForSendCoins with args=`, args)
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { data } = await this.client.rawRequest(voteForSendCoins, { args })
logger.debug(`SendCoinsClient: after rawRequest...`, data)
const sendCoinsResult = data as SendCoinsResult
logger.debug(`X-Com: SendCoinsClient: after rawRequest...data:`, data)
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (!sendCoinsResult.vote) {
logger.warn(
'X-Com: voteForSendCoins failed with: ',
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
sendCoinsResult.recipGradidoID,
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
sendCoinsResult.recipName,
)
return sendCoinsResult
if (!data?.voteForSendCoins?.vote) {
logger.warn('X-Com: voteForSendCoins failed with: ', data)
return new SendCoinsResult()
}
const result = new SendCoinsResult()
result.vote = true
@ -66,17 +59,24 @@ export class SendCoinsClient {
revertSendCoins = async (args: SendCoinsArgs): Promise<boolean> => {
logger.debug('X-Com: revertSendCoins against endpoint=', this.endpoint)
try {
logger.debug(`X-Com: SendCoinsClient: revertSendCoins with args=`, args)
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { data } = await this.client.rawRequest(revertSendCoins, { args })
logger.debug(`X-Com: SendCoinsClient: after revertSendCoins: data=`, data)
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (!data?.revertSendCoins?.revertSendCoins) {
logger.warn('X-Com: revertSendCoins without response data from endpoint', this.endpoint)
return false
}
logger.debug(`X-Com: revertSendCoins successful from endpoint=${this.endpoint}`)
logger.debug(
`X-Com: SendCoinsClient: revertSendCoins successful from endpoint=${this.endpoint}`,
)
return true
} catch (err) {
logger.error(`X-Com: revertSendCoins failed for endpoint=${this.endpoint}`, err)
logger.error(
`X-Com: SendCoinsClient: revertSendCoins failed for endpoint=${this.endpoint}`,
err,
)
return false
}
}
@ -84,37 +84,54 @@ export class SendCoinsClient {
settleSendCoins = async (args: SendCoinsArgs): Promise<boolean> => {
logger.debug(`X-Com: settleSendCoins against endpoint='${this.endpoint}'...`)
try {
logger.debug(`X-Com: SendCoinsClient: settleSendCoins with args=`, args)
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { data } = await this.client.rawRequest(settleSendCoins, { args })
logger.debug(`X-Com: SendCoinsClient: after settleSendCoins: data=`, data)
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (!data?.settleSendCoins?.acknowledged) {
logger.warn('X-Com: settleSendCoins without response data from endpoint', this.endpoint)
logger.warn(
'X-Com: SendCoinsClient: settleSendCoins without response data from endpoint',
this.endpoint,
)
return false
}
logger.debug(`X-Com: settleSendCoins successful from endpoint=${this.endpoint}`)
logger.debug(
`X-Com: SendCoinsClient: settleSendCoins successful from endpoint=${this.endpoint}`,
)
return true
} catch (err) {
throw new LogError(`X-Com: settleSendCoins failed for endpoint=${this.endpoint}`, err)
throw new LogError(
`X-Com: SendCoinsClient: settleSendCoins failed for endpoint=${this.endpoint}`,
err,
)
}
}
revertSettledSendCoins = async (args: SendCoinsArgs): Promise<boolean> => {
logger.debug(`X-Com: revertSettledSendCoins against endpoint='${this.endpoint}'...`)
try {
logger.debug(`X-Com: SendCoinsClient: revertSettledSendCoins with args=`, args)
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { data } = await this.client.rawRequest(revertSettledSendCoins, { args })
logger.debug(`X-Com: SendCoinsClient: after revertSettledSendCoins: data=`, data)
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (!data?.revertSettledSendCoins?.acknowledged) {
logger.warn(
'X-Com: revertSettledSendCoins without response data from endpoint',
'X-Com: SendCoinsClient: revertSettledSendCoins without response data from endpoint',
this.endpoint,
)
return false
}
logger.debug(`X-Com: revertSettledSendCoins successful from endpoint=${this.endpoint}`)
logger.debug(
`X-Com: SendCoinsClient: revertSettledSendCoins successful from endpoint=${this.endpoint}`,
)
return true
} catch (err) {
throw new LogError(`X-Com: revertSettledSendCoins failed for endpoint=${this.endpoint}`, err)
throw new LogError(
`X-Com: SendCoinsClient: revertSettledSendCoins failed for endpoint=${this.endpoint}`,
err,
)
}
}
}

View File

@ -10,8 +10,8 @@ export class SendCoinsResult {
vote: boolean
@Field(() => String, { nullable: true })
recipGradidoID: string | null | undefined
recipGradidoID: string | null
@Field(() => String, { nullable: true })
recipName: string | null | undefined
recipName: string | null
}

View File

@ -1,6 +1,11 @@
import { gql } from 'graphql-request'
export const revertSendCoins = gql`
mutation ($args: SendCoinsArgs!) {
revertSendCoins(data: $args)
}
`
/*
mutation (
$recipientCommunityUuid: String!
$recipientUserIdentifier: String!
@ -22,4 +27,4 @@ export const revertSendCoins = gql`
senderUserName: $senderUserName
)
}
`
*/

View File

@ -1,6 +1,12 @@
import { gql } from 'graphql-request'
export const revertSettledSendCoins = gql`
mutation ($args: SendCoinsArgs!) {
revertSettledSendCoins(data: $args)
}
`
/*
mutation (
$recipientCommunityUuid: String!
$recipientUserIdentifier: String!
@ -22,4 +28,4 @@ export const revertSettledSendCoins = gql`
senderUserName: $senderUserName
)
}
`
*/

View File

@ -1,6 +1,11 @@
import { gql } from 'graphql-request'
export const settleSendCoins = gql`
mutation ($args: SendCoinsArgs!) {
settleSendCoins(data: $args)
}
`
/*
mutation (
$recipientCommunityUuid: String!
$recipientUserIdentifier: String!
@ -22,4 +27,4 @@ export const settleSendCoins = gql`
senderUserName: $senderUserName
)
}
`
*/

View File

@ -74,7 +74,9 @@ export const executeTransaction = async (
],
})
if (openSenderPendingTx > 0 || openReceiverPendingTx > 0) {
throw new LogError('There are still pending Transactions for Sender and/or Recipient')
throw new LogError(
`There exist still ongoing 'Pending-Transactions' for the involved users on sender-side!`,
)
}
if (sender.id === recipient.id) {
@ -529,7 +531,7 @@ export class TransactionResolver {
logger.info('successful executeTransaction', amount, memo, senderUser, recipientUser)
} else {
// processing a x-community sendCoins
logger.debug('processing a x-community transaction...')
logger.debug('X-Com: processing a x-community transaction...')
if (!CONFIG.FEDERATION_XCOM_SENDCOINS_ENABLED) {
throw new LogError('X-Community sendCoins disabled per configuration!')
}

View File

@ -1,14 +1,14 @@
import { Community as DbCommunity } from '@entity/Community'
export async function isHomeCommunity(communityIdentifier: string): Promise<boolean> {
const homeCommunity = await DbCommunity.findOneByOrFail({ foreign: false })
if (communityIdentifier === homeCommunity.id.toString()) {
return true
} else if (communityIdentifier === homeCommunity.name) {
return true
} else if (communityIdentifier === homeCommunity.communityUuid) {
return true
} else if (communityIdentifier === homeCommunity.url) {
const homeCommunity = await DbCommunity.findOne({
where: [
{ foreign: false, communityUuid: communityIdentifier },
{ foreign: false, name: communityIdentifier },
{ foreign: false, url: communityIdentifier },
],
})
if (homeCommunity) {
return true
} else {
return false
@ -16,11 +16,6 @@ export async function isHomeCommunity(communityIdentifier: string): Promise<bool
}
export async function getCommunityUrl(communityIdentifier: string): Promise<string> {
const community = await DbCommunity.findOneByOrFail({ name: communityIdentifier })
return community.url
}
export async function isCommunityAuthenticated(communityIdentifier: string): Promise<boolean> {
const community = await DbCommunity.findOneOrFail({
where: [
{ communityUuid: communityIdentifier },
@ -28,7 +23,18 @@ export async function isCommunityAuthenticated(communityIdentifier: string): Pro
{ url: communityIdentifier },
],
})
if (community.authenticatedAt) {
return community.url
}
export async function isCommunityAuthenticated(communityIdentifier: string): Promise<boolean> {
const community = await DbCommunity.findOne({
where: [
{ communityUuid: communityIdentifier },
{ name: communityIdentifier },
{ url: communityIdentifier },
],
})
if (community?.authenticatedAt) {
return true
} else {
return false

View File

@ -28,7 +28,7 @@ export async function processXComPendingSendCoins(
sender: dbUser,
recipientIdentifier: string,
): Promise<SendCoinsResult> {
let sendCoinsResult = new SendCoinsResult()
let voteResult: SendCoinsResult
try {
logger.debug(
`XCom: processXComPendingSendCoins...`,
@ -69,9 +69,10 @@ export async function processXComPendingSendCoins(
args.senderUserUuid = sender.gradidoID
args.senderUserName = fullName(sender.firstName, sender.lastName)
logger.debug(`X-Com: ready for voteForSendCoins with args=`, args)
sendCoinsResult = await client.voteForSendCoins(args)
logger.debug(`X-Com: returnd from voteForSendCoins:`, sendCoinsResult)
if (sendCoinsResult.vote) {
voteResult = await client.voteForSendCoins(args)
logger.debug(`X-Com: returnd from voteForSendCoins:`, voteResult)
if (voteResult.vote) {
logger.debug(`X-Com: prepare pendingTransaction for sender...`)
// writing the pending transaction on receiver-side was successfull, so now write the sender side
try {
const pendingTx = DbPendingTransaction.create()
@ -83,17 +84,18 @@ export async function processXComPendingSendCoins(
if (receiverCom.communityUuid) {
pendingTx.linkedUserCommunityUuid = receiverCom.communityUuid
}
if (sendCoinsResult.recipGradidoID) {
pendingTx.linkedUserGradidoID = sendCoinsResult.recipGradidoID
if (voteResult.recipGradidoID) {
pendingTx.linkedUserGradidoID = voteResult.recipGradidoID
}
if (sendCoinsResult.recipName) {
pendingTx.linkedUserName = sendCoinsResult.recipName
if (voteResult.recipName) {
pendingTx.linkedUserName = voteResult.recipName
}
pendingTx.memo = memo
pendingTx.previous = senderBalance ? senderBalance.lastTransactionId : null
pendingTx.state = PendingTransactionState.NEW
pendingTx.typeId = TransactionTypeId.SEND
if (senderCom.communityUuid) pendingTx.userCommunityUuid = senderCom.communityUuid
pendingTx.id = sender.id
pendingTx.userGradidoID = sender.gradidoID
pendingTx.userName = fullName(sender.firstName, sender.lastName)
logger.debug(`X-Com: initialized sender pendingTX=`, pendingTx)
@ -118,12 +120,17 @@ export async function processXComPendingSendCoins(
)
}
logger.debug(`voteForSendCoins()-1_0... successfull`)
} else {
logger.debug(
`X-Com: break with error on writing pendingTransaction for recipient...`,
voteResult,
)
}
}
} catch (err) {
throw new LogError(`Error:`, err)
}
return sendCoinsResult
return new SendCoinsResult()
}
export async function processXComCommittingSendCoins(

View File

@ -9,9 +9,9 @@ export class SendCoinsResult {
@Field(() => Boolean)
vote: boolean
@Field(() => String)
@Field(() => String, { nullable: true })
recipGradidoID: string | null
@Field(() => String)
@Field(() => String, { nullable: true })
recipName: string | null
}

View File

@ -57,6 +57,24 @@ export class SendCoinsResolver {
homeCom.name,
)
}
const openSenderPendingTx = await DbPendingTransaction.count({
where: [
{ userGradidoID: args.senderUserUuid, state: PendingTransactionState.NEW },
{ linkedUserGradidoID: args.senderUserUuid, state: PendingTransactionState.NEW },
],
})
const openReceiverPendingTx = await DbPendingTransaction.count({
where: [
{ userGradidoID: receiverUser.gradidoID, state: PendingTransactionState.NEW },
{ linkedUserGradidoID: receiverUser.gradidoID, state: PendingTransactionState.NEW },
],
})
if (openSenderPendingTx > 0 || openReceiverPendingTx > 0) {
throw new LogError(
`There exist still ongoing 'Pending-Transactions' for the involved users on receiver-side!`,
)
}
try {
const txDate = new Date(args.creationDate)
const receiveBalance = await calculateRecipientBalance(receiverUser.id, args.amount, txDate)
@ -94,18 +112,6 @@ export class SendCoinsResolver {
async revertSendCoins(
@Arg('data')
args: SendCoinsArgs,
/*
{
recipientCommunityUuid,
recipientUserIdentifier,
creationDate,
amount,
memo,
senderCommunityUuid,
senderUserUuid,
senderUserName,
}: SendCoinsArgs,
*/
): Promise<boolean> {
logger.debug(`revertSendCoins() via apiVersion=1_0 ...`)
// first check if receiver community is correct
@ -179,18 +185,6 @@ export class SendCoinsResolver {
async settleSendCoins(
@Arg('data')
args: SendCoinsArgs,
/*
{
recipientCommunityUuid,
recipientUserIdentifier,
creationDate,
amount,
memo,
senderCommunityUuid,
senderUserUuid,
senderUserName,
}: SendCoinsArgs,
*/
): Promise<boolean> {
logger.debug(
`settleSendCoins() via apiVersion=1_0 ...userCommunityUuid=${
@ -264,18 +258,6 @@ export class SendCoinsResolver {
async revertSettledSendCoins(
@Arg('data')
args: SendCoinsArgs,
/*
{
recipientCommunityUuid,
recipientUserIdentifier,
creationDate,
amount,
memo,
senderCommunityUuid,
senderUserUuid,
senderUserName,
}: SendCoinsArgs,
*/
): Promise<boolean> {
logger.debug(`revertSettledSendCoins() via apiVersion=1_0 ...`)
// first check if receiver community is correct