first draft of graphql client SendCoins

This commit is contained in:
Claus-Peter Huebner 2023-08-23 00:58:31 +02:00
parent a33dba3a77
commit ec9c78dbef
6 changed files with 212 additions and 0 deletions

View File

@ -0,0 +1,69 @@
import { FederatedCommunity as DbFederatedCommunity } from '@entity/FederatedCommunity'
import { GraphQLClient } from 'graphql-request'
import { LogError } from '@/server/LogError'
import { backendLogger as logger } from '@/server/logger'
import { SendCoinsArgs } from './model/SendCoinsArgs'
import { revertSendCoins } from './query/revertSendCoins'
import { voteForSendCoins } from './query/voteForSendCoins'
// eslint-disable-next-line camelcase
export class SendCoinsClient {
dbCom: DbFederatedCommunity
endpoint: string
client: GraphQLClient
constructor(dbCom: DbFederatedCommunity) {
this.dbCom = dbCom
this.endpoint = `${dbCom.endPoint.endsWith('/') ? dbCom.endPoint : dbCom.endPoint + '/'}${
dbCom.apiVersion
}/`
this.client = new GraphQLClient(this.endpoint, {
method: 'GET',
jsonSerializer: {
parse: JSON.parse,
stringify: JSON.stringify,
},
})
}
voteForSendCoins = async (args: SendCoinsArgs): Promise<boolean> => {
logger.debug('X-Com: voteForSendCoins against endpoint', this.endpoint)
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { data } = await this.client.rawRequest(voteForSendCoins, { args })
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (!data?.voteForSendCoins?.vote) {
logger.warn('X-Com: voteForSendCoins without response data from endpoint', this.endpoint)
return false
}
logger.debug(
'X-Com: voteForSendCoins successful from endpoint',
this.endpoint,
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
data.voteForSendCoins.vote,
)
return true
} catch (err) {
throw new LogError(`X-Com: voteForSendCoins failed for endpoint=${this.endpoint}:`, err)
}
}
revertSendCoins = async (args: SendCoinsArgs): Promise<boolean> => {
logger.debug(`X-Com: revertSendCoins against endpoint='${this.endpoint}'...`)
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { data } = await this.client.rawRequest(revertSendCoins, { args })
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (!data?.revertSendCoins?.acknowledged) {
logger.warn('X-Com: revertSendCoins without response data from endpoint', this.endpoint)
return false
}
logger.debug(`X-Com: revertSendCoins successful from endpoint=${this.endpoint}`)
return true
} catch (err) {
throw new LogError(`X-Com: revertSendCoins failed for endpoint=${this.endpoint}`, err)
}
}
}

View File

@ -0,0 +1,26 @@
import { Decimal } from 'decimal.js-light'
import { ArgsType, Field, Int } from 'type-graphql'
@ArgsType()
export class SendCoinsArgs {
@Field(() => String)
communityReceiverIdentifier: string
@Field(() => String)
userReceiverIdentifier: string
@Field(() => Decimal)
amount: Decimal
@Field(() => String)
memo: string
@Field(() => String)
communitySenderIdentifier: string
@Field(() => String)
userSenderIdentifier: string
@Field(() => String)
userSenderName: string
}

View File

@ -0,0 +1,25 @@
import { gql } from 'graphql-request'
export const revertSendCoins = gql`
mutation (
$communityReceiverIdentifier: String!
$userReceiverIdentifier: String!
$amount: Decimal!
$memo: String!
$communitySenderIdentifier: String!
$userSenderIdentifier: String!
$userSenderName: String!
) {
revertSendCoins(
communityReceiverIdentifier: $communityReceiverIdentifier
userReceiverIdentifier: $userReceiverIdentifier
amount: $amount
memo: $memo
communitySenderIdentifier: $communitySenderIdentifier
userSenderIdentifier: $userSenderIdentifier
userSenderName: $userSenderName
) {
acknowledged
}
}
`

View File

@ -0,0 +1,25 @@
import { gql } from 'graphql-request'
export const voteForSendCoins = gql`
mutation (
$communityReceiverIdentifier: String!
$userReceiverIdentifier: String!
$amount: Decimal!
$memo: String!
$communitySenderIdentifier: String!
$userSenderIdentifier: String!
$userSenderName: String!
) {
voteForSendCoins(
communityReceiverIdentifier: $communityReceiverIdentifier
userReceiverIdentifier: $userReceiverIdentifier
amount: $amount
memo: $memo
communitySenderIdentifier: $communitySenderIdentifier
userSenderIdentifier: $userSenderIdentifier
userSenderName: $userSenderName
) {
vote
}
}
`

View File

@ -0,0 +1,5 @@
// eslint-disable-next-line camelcase
import { SendCoinsClient as V1_0_SendCoinsClient } from '@/federation/client/1_0/SendCoinsClient'
// eslint-disable-next-line camelcase
export class SendCoinsClient extends V1_0_SendCoinsClient {}

View File

@ -0,0 +1,62 @@
import { FederatedCommunity as DbFederatedCommunity } from '@entity/FederatedCommunity'
// eslint-disable-next-line camelcase
import { SendCoinsClient as V1_0_SendCoinsClient } from '@/federation/client/1_0/SendCoinsClient'
// eslint-disable-next-line camelcase
import { SendCoinsClient as V1_1_SendCoinsClient } from '@/federation/client/1_1/SendCoinsClient'
import { ApiVersionType } from '@/federation/enum/apiVersionType'
// eslint-disable-next-line camelcase
type SendCoinsClient = V1_0_SendCoinsClient | V1_1_SendCoinsClient
interface SendCoinsClientInstance {
id: number
// eslint-disable-next-line no-use-before-define
client: SendCoinsClient
}
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class SendCoinsClientFactory {
private static instanceArray: SendCoinsClientInstance[] = []
/**
* The Singleton's constructor should always be private to prevent direct
* construction calls with the `new` operator.
*/
// eslint-disable-next-line no-useless-constructor, @typescript-eslint/no-empty-function
private constructor() {}
private static createSendCoinsClient = (dbCom: DbFederatedCommunity) => {
switch (dbCom.apiVersion) {
case ApiVersionType.V1_0:
return new V1_0_SendCoinsClient(dbCom)
case ApiVersionType.V1_1:
return new V1_1_SendCoinsClient(dbCom)
default:
return null
}
}
/**
* The static method that controls the access to the singleton instance.
*
* This implementation let you subclass the Singleton class while keeping
* just one instance of each subclass around.
*/
public static getInstance(dbCom: DbFederatedCommunity): SendCoinsClient | null {
const instance = SendCoinsClientFactory.instanceArray.find(
(instance) => instance.id === dbCom.id,
)
if (instance) {
return instance.client
}
const client = SendCoinsClientFactory.createSendCoinsClient(dbCom)
if (client) {
SendCoinsClientFactory.instanceArray.push({
id: dbCom.id,
client,
} as SendCoinsClientInstance)
}
return client
}
}