From 6e5fb223d655d22bd9bedaa41518ee002f17ed76 Mon Sep 17 00:00:00 2001
From: clauspeterhuebner
Date: Wed, 20 Aug 2025 16:26:02 +0200
Subject: [PATCH] safe current work
---
.../apis/dltConnector/DltConnectorClient.ts | 2 +-
.../src/federation/authenticateCommunities.ts | 2 +-
.../client/1_0/DisbursementClient.ts | 48 ++++
.../federation/client/1_0/FederationClient.ts | 2 +-
.../processDisburseJwtOnSenderCommunity.ts | 7 +
.../client/1_1/DisbursementClient.ts | 3 +
.../federation/client/1_1/SendCoinsClient.ts | 3 -
.../client/AuthenticationClientFactory.ts | 2 +-
.../client/DisbursementClientFactory.ts | 58 +++++
.../client/FederationClientFactory.ts | 4 +-
backend/src/federation/validateCommunities.ts | 2 +-
backend/src/graphql/model/Transaction.ts | 2 +-
.../graphql/resolver/ContributionResolver.ts | 4 +-
.../resolver/TransactionLinkResolver.ts | 205 +++++++++---------
.../resolver/TransactionResolver.test.ts | 6 +-
.../graphql/resolver/TransactionResolver.ts | 18 +-
.../sendTransactionsToDltConnector.test.ts | 2 +-
.../graphql/resolver/util/storeForeignUser.ts | 2 +-
backend/src/util/virtualTransactions.ts | 2 +-
bun.lock | 1 +
core/package.json | 1 +
.../federation/client/1_0/SendCoinsClient.ts | 9 +-
.../1_0/logging/SendCoinsArgsLogging.view.ts | 2 +-
.../logging/SendCoinsResultLogging.view.ts | 2 +-
.../client/1_0/model/SendCoinsArgs.ts | 0
.../client/1_0/model/SendCoinsResult.ts | 0
.../client/1_0/query/revertSendCoins.ts | 0
.../1_0/query/revertSettledSendCoins.ts | 0
.../client/1_0/query/settleSendCoins.ts | 0
.../client/1_0/query/voteForSendCoins.ts | 0
.../federation/client/1_1/SendCoinsClient.ts | 3 +
.../client/SendCoinsClientFactory.ts | 7 +-
.../src/federation/enum/apiVersionType.ts | 0
.../src/graphql/enum/TransactionTypeId.ts | 0
.../graphql/logic}/processXComSendCoins.ts | 25 +--
core/src/index.ts | 16 +-
{backend => core}/src/util/utilities.test.ts | 0
{backend => core}/src/util/utilities.ts | 0
core/tsconfig.json | 11 +-
.../src/client/AuthenticationClientFactory.ts | 2 +-
federation/src/client/enum/ApiVersionType.ts | 4 -
.../api/1_0/resolver/DisbursementResolver.ts | 33 +++
42 files changed, 322 insertions(+), 168 deletions(-)
create mode 100644 backend/src/federation/client/1_0/DisbursementClient.ts
create mode 100644 backend/src/federation/client/1_0/query/processDisburseJwtOnSenderCommunity.ts
create mode 100644 backend/src/federation/client/1_1/DisbursementClient.ts
delete mode 100644 backend/src/federation/client/1_1/SendCoinsClient.ts
create mode 100644 backend/src/federation/client/DisbursementClientFactory.ts
rename {backend => core}/src/federation/client/1_0/SendCoinsClient.ts (92%)
rename {backend => core}/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts (89%)
rename {backend => core}/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts (85%)
rename {backend => core}/src/federation/client/1_0/model/SendCoinsArgs.ts (100%)
rename {backend => core}/src/federation/client/1_0/model/SendCoinsResult.ts (100%)
rename {backend => core}/src/federation/client/1_0/query/revertSendCoins.ts (100%)
rename {backend => core}/src/federation/client/1_0/query/revertSettledSendCoins.ts (100%)
rename {backend => core}/src/federation/client/1_0/query/settleSendCoins.ts (100%)
rename {backend => core}/src/federation/client/1_0/query/voteForSendCoins.ts (100%)
create mode 100644 core/src/federation/client/1_1/SendCoinsClient.ts
rename {backend => core}/src/federation/client/SendCoinsClientFactory.ts (85%)
rename {backend => core}/src/federation/enum/apiVersionType.ts (100%)
rename {backend => core}/src/graphql/enum/TransactionTypeId.ts (100%)
rename {backend/src/graphql/resolver/util => core/src/graphql/logic}/processXComSendCoins.ts (93%)
rename {backend => core}/src/util/utilities.test.ts (100%)
rename {backend => core}/src/util/utilities.ts (100%)
delete mode 100644 federation/src/client/enum/ApiVersionType.ts
create mode 100644 federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts
diff --git a/backend/src/apis/dltConnector/DltConnectorClient.ts b/backend/src/apis/dltConnector/DltConnectorClient.ts
index 6f5b437de..bec2990d0 100644
--- a/backend/src/apis/dltConnector/DltConnectorClient.ts
+++ b/backend/src/apis/dltConnector/DltConnectorClient.ts
@@ -3,7 +3,7 @@ import { GraphQLClient, gql } from 'graphql-request'
import { CONFIG } from '@/config'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
-import { TransactionTypeId } from '@/graphql/enum/TransactionTypeId'
+import { TransactionTypeId } from 'core/src/graphql/enum/TransactionTypeId'
import { LogError } from '@/server/LogError'
import { getLogger } from 'log4js'
diff --git a/backend/src/federation/authenticateCommunities.ts b/backend/src/federation/authenticateCommunities.ts
index d8946eb47..179c7e996 100644
--- a/backend/src/federation/authenticateCommunities.ts
+++ b/backend/src/federation/authenticateCommunities.ts
@@ -4,7 +4,7 @@ import { randombytes_random } from 'sodium-native'
import { CONFIG } from '@/config'
import { AuthenticationClient as V1_0_AuthenticationClient } from '@/federation/client/1_0/AuthenticationClient'
-import { ensureUrlEndsWithSlash } from '@/util/utilities'
+import { ensureUrlEndsWithSlash } from 'core'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { encryptAndSign, OpenConnectionJwtPayloadType } from 'shared'
diff --git a/backend/src/federation/client/1_0/DisbursementClient.ts b/backend/src/federation/client/1_0/DisbursementClient.ts
new file mode 100644
index 000000000..bf466feef
--- /dev/null
+++ b/backend/src/federation/client/1_0/DisbursementClient.ts
@@ -0,0 +1,48 @@
+import { FederatedCommunity as DbFederatedCommunity } from 'database'
+import { GraphQLClient } from 'graphql-request'
+
+import { LogError } from '@/server/LogError'
+import { ensureUrlEndsWithSlash } from 'core/src/util/utilities'
+import { getLogger } from 'log4js'
+
+import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
+import { EncryptedTransferArgs } from 'core'
+import { processDisburseJwtOnSenderCommunity as processDisburseJwtOnSenderCommunityQuery } from './query/processDisburseJwtOnSenderCommunity'
+
+const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.client.1_0.DisbursementClient`)
+
+export class DisbursementClient {
+ dbCom: DbFederatedCommunity
+ endpoint: string
+ client: GraphQLClient
+
+ constructor(dbCom: DbFederatedCommunity) {
+ this.dbCom = dbCom
+ this.endpoint = ensureUrlEndsWithSlash(dbCom.endPoint).concat(dbCom.apiVersion).concat('/')
+ this.client = new GraphQLClient(this.endpoint, {
+ method: 'POST',
+ jsonSerializer: {
+ parse: JSON.parse,
+ stringify: JSON.stringify,
+ },
+ })
+ }
+
+ async sendDisburseJwtToSenderCommunity(args: EncryptedTransferArgs): Promise {
+ logger.debug('sendDisburseJwtToSenderCommunity against endpoint=', this.endpoint)
+ try {
+ const { data } = await this.client.rawRequest<{ processDisburseJwtOnSenderCommunity: string }>(processDisburseJwtOnSenderCommunityQuery, { args })
+ const responseJwt = data?.processDisburseJwtOnSenderCommunity
+ if (responseJwt) {
+ logger.debug('received response jwt', responseJwt)
+ return responseJwt
+ }
+ } catch (err) {
+ const errmsg = `sendDisburseJwtToSenderCommunity failed for endpoint=${this.endpoint}, err=${err}`
+ logger.error(errmsg)
+ throw new Error(errmsg)
+ }
+ return null
+ }
+
+}
diff --git a/backend/src/federation/client/1_0/FederationClient.ts b/backend/src/federation/client/1_0/FederationClient.ts
index df1140f9c..525765803 100644
--- a/backend/src/federation/client/1_0/FederationClient.ts
+++ b/backend/src/federation/client/1_0/FederationClient.ts
@@ -4,7 +4,7 @@ import { GraphQLClient } from 'graphql-request'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { getPublicCommunityInfo } from '@/federation/client/1_0/query/getPublicCommunityInfo'
import { getPublicKey } from '@/federation/client/1_0/query/getPublicKey'
-import { ensureUrlEndsWithSlash } from '@/util/utilities'
+import { ensureUrlEndsWithSlash } from 'core/src/util/utilities'
import { getLogger } from 'log4js'
import { PublicCommunityInfoLoggingView } from './logging/PublicCommunityInfoLogging.view'
diff --git a/backend/src/federation/client/1_0/query/processDisburseJwtOnSenderCommunity.ts b/backend/src/federation/client/1_0/query/processDisburseJwtOnSenderCommunity.ts
new file mode 100644
index 000000000..e2d0f49d9
--- /dev/null
+++ b/backend/src/federation/client/1_0/query/processDisburseJwtOnSenderCommunity.ts
@@ -0,0 +1,7 @@
+import { gql } from 'graphql-request'
+
+export const processDisburseJwtOnSenderCommunity = gql`
+ mutation ($args: EncryptedTransferArgs!) {
+ processDisburseJwtOnSenderCommunity(data: $args)
+ }
+`
diff --git a/backend/src/federation/client/1_1/DisbursementClient.ts b/backend/src/federation/client/1_1/DisbursementClient.ts
new file mode 100644
index 000000000..411befe19
--- /dev/null
+++ b/backend/src/federation/client/1_1/DisbursementClient.ts
@@ -0,0 +1,3 @@
+import { DisbursementClient as V1_0_DisbursementClient } from '@/federation/client/1_0/DisbursementClient'
+
+export class DisbursementClient extends V1_0_DisbursementClient {}
diff --git a/backend/src/federation/client/1_1/SendCoinsClient.ts b/backend/src/federation/client/1_1/SendCoinsClient.ts
deleted file mode 100644
index cc804d0dc..000000000
--- a/backend/src/federation/client/1_1/SendCoinsClient.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { SendCoinsClient as V1_0_SendCoinsClient } from '@/federation/client/1_0/SendCoinsClient'
-
-export class SendCoinsClient extends V1_0_SendCoinsClient {}
diff --git a/backend/src/federation/client/AuthenticationClientFactory.ts b/backend/src/federation/client/AuthenticationClientFactory.ts
index 0ae0cd1b8..344753a48 100644
--- a/backend/src/federation/client/AuthenticationClientFactory.ts
+++ b/backend/src/federation/client/AuthenticationClientFactory.ts
@@ -3,7 +3,7 @@ import { FederatedCommunity as DbFederatedCommunity } from 'database'
import { AuthenticationClient as V1_0_AuthenticationClient } from '@/federation/client/1_0/AuthenticationClient'
import { AuthenticationClient as V1_1_AuthenticationClient } from '@/federation/client/1_1/AuthenticationClient'
-import { ApiVersionType } from '@/federation/enum/apiVersionType'
+import { ApiVersionType } from 'core'
type AuthenticationClient = V1_0_AuthenticationClient | V1_1_AuthenticationClient
diff --git a/backend/src/federation/client/DisbursementClientFactory.ts b/backend/src/federation/client/DisbursementClientFactory.ts
new file mode 100644
index 000000000..01c911e92
--- /dev/null
+++ b/backend/src/federation/client/DisbursementClientFactory.ts
@@ -0,0 +1,58 @@
+import { FederatedCommunity as DbFederatedCommunity } from 'database'
+
+import { DisbursementClient as V1_0_DisbursementClient } from '@/federation/client/1_0/DisbursementClient'
+import { DisbursementClient as V1_1_DisbursementClient } from '@/federation/client/1_1/DisbursementClient'
+import { ApiVersionType } from 'core'
+
+type DisbursementClient = V1_0_DisbursementClient | V1_1_DisbursementClient
+
+interface DisbursementClientInstance {
+ id: number
+
+ client: DisbursementClient
+}
+
+export class DisbursementClientFactory {
+ private static instanceArray: DisbursementClientInstance[] = []
+
+ /**
+ * The Singleton's constructor should always be private to prevent direct
+ * construction calls with the `new` operator.
+ */
+
+ private constructor() {}
+
+ private static createDisbursementClient = (dbCom: DbFederatedCommunity) => {
+ switch (dbCom.apiVersion) {
+ case ApiVersionType.V1_0:
+ return new V1_0_DisbursementClient(dbCom)
+ case ApiVersionType.V1_1:
+ return new V1_1_DisbursementClient(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): DisbursementClient | null {
+ const instance = DisbursementClientFactory.instanceArray.find(
+ (instance) => instance.id === dbCom.id,
+ )
+ if (instance) {
+ return instance.client
+ }
+ const client = DisbursementClientFactory.createDisbursementClient(dbCom)
+ if (client) {
+ DisbursementClientFactory.instanceArray.push({
+ id: dbCom.id,
+ client,
+ } as DisbursementClientInstance)
+ }
+ return client
+ }
+}
diff --git a/backend/src/federation/client/FederationClientFactory.ts b/backend/src/federation/client/FederationClientFactory.ts
index 3660934f4..926c3c180 100644
--- a/backend/src/federation/client/FederationClientFactory.ts
+++ b/backend/src/federation/client/FederationClientFactory.ts
@@ -1,10 +1,8 @@
import { FederatedCommunity as DbFederatedCommunity } from 'database'
import { FederationClient as V1_0_FederationClient } from '@/federation/client/1_0/FederationClient'
-
import { FederationClient as V1_1_FederationClient } from '@/federation/client/1_1/FederationClient'
-import { ApiVersionType } from '@/federation/enum/apiVersionType'
-import { ensureUrlEndsWithSlash } from '@/util/utilities'
+import { ApiVersionType, ensureUrlEndsWithSlash } from 'core'
type FederationClient = V1_0_FederationClient | V1_1_FederationClient
diff --git a/backend/src/federation/validateCommunities.ts b/backend/src/federation/validateCommunities.ts
index 478261386..36c9985c9 100644
--- a/backend/src/federation/validateCommunities.ts
+++ b/backend/src/federation/validateCommunities.ts
@@ -15,7 +15,7 @@ import { createKeyPair } from 'shared'
import { getLogger } from 'log4js'
import { startCommunityAuthentication } from './authenticateCommunities'
import { PublicCommunityInfoLoggingView } from './client/1_0/logging/PublicCommunityInfoLogging.view'
-import { ApiVersionType } from './enum/apiVersionType'
+import { ApiVersionType } from 'core'
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.validateCommunities`)
diff --git a/backend/src/graphql/model/Transaction.ts b/backend/src/graphql/model/Transaction.ts
index dc0849a53..ee7250271 100644
--- a/backend/src/graphql/model/Transaction.ts
+++ b/backend/src/graphql/model/Transaction.ts
@@ -2,7 +2,7 @@ import { Transaction as dbTransaction } from 'database'
import { Decimal } from 'decimal.js-light'
import { Field, Int, ObjectType } from 'type-graphql'
-import { TransactionTypeId } from '@enum/TransactionTypeId'
+import { TransactionTypeId } from 'core/src/graphql/enum/TransactionTypeId'
import { Decay } from './Decay'
import { User } from './User'
diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts
index c6f7b33c1..6e2a302ba 100644
--- a/backend/src/graphql/resolver/ContributionResolver.ts
+++ b/backend/src/graphql/resolver/ContributionResolver.ts
@@ -16,11 +16,11 @@ import { Paginated } from '@arg/Paginated'
import { SearchContributionsFilterArgs } from '@arg/SearchContributionsFilterArgs'
import { ContributionStatus } from '@enum/ContributionStatus'
import { ContributionType } from '@enum/ContributionType'
-import { TransactionTypeId } from '@enum/TransactionTypeId'
import { AdminUpdateContribution } from '@model/AdminUpdateContribution'
import { Contribution, ContributionListResult } from '@model/Contribution'
import { OpenCreation } from '@model/OpenCreation'
import { UnconfirmedContribution } from '@model/UnconfirmedContribution'
+import { TransactionTypeId } from 'core'
import { RIGHTS } from '@/auth/RIGHTS'
import {
@@ -43,8 +43,8 @@ import { UpdateUnconfirmedContributionContext } from '@/interactions/updateUncon
import { LogError } from '@/server/LogError'
import { Context, getClientTimezoneOffset, getUser } from '@/server/context'
import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
+import { fullName } from 'core'
import { calculateDecay, Decay } from 'shared'
-import { fullName } from '@/util/utilities'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { ContributionMessageType } from '@enum/ContributionMessageType'
diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts
index 65c2d5df6..546d11124 100644
--- a/backend/src/graphql/resolver/TransactionLinkResolver.ts
+++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts
@@ -6,22 +6,19 @@ import { TransactionLinkFilters } from '@arg/TransactionLinkFilters'
import { ContributionCycleType } from '@enum/ContributionCycleType'
import { ContributionStatus } from '@enum/ContributionStatus'
import { ContributionType } from '@enum/ContributionType'
-import { TransactionTypeId } from '@enum/TransactionTypeId'
-import { Community } from '@model/Community'
import { ContributionLink } from '@model/ContributionLink'
import { Decay } from '@model/Decay'
import { RedeemJwtLink } from '@model/RedeemJwtLink'
import { TransactionLink, TransactionLinkResult } from '@model/TransactionLink'
import { User } from '@model/User'
import { QueryLinkResult } from '@union/QueryLinkResult'
+import { TransactionTypeId } from 'core'
import {
- AppDatabase,
- Contribution as DbContribution,
- ContributionLink as DbContributionLink,
- Transaction as DbTransaction,
+ AppDatabase, Community as DbCommunity, Contribution as DbContribution,
+ ContributionLink as DbContributionLink, FederatedCommunity as DbFederatedCommunity, Transaction as DbTransaction,
TransactionLink as DbTransactionLink,
User as DbUser,
- getHomeCommunity,
+ getHomeCommunity
} from 'database'
import { Decimal } from 'decimal.js-light'
import { Arg, Args, Authorized, Ctx, Int, Mutation, Query, Resolver } from 'type-graphql'
@@ -37,12 +34,16 @@ import { LogError } from '@/server/LogError'
import { Context, getClientTimezoneOffset, getUser } from '@/server/context'
import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
import { TRANSACTION_LINK_LOCK } from '@/util/TRANSACTION_LINK_LOCK'
-import { fullName } from '@/util/utilities'
import { calculateBalance } from '@/util/validate'
+import { fullName } from 'core'
import { calculateDecay, decode, DisburseJwtPayloadType, encode, encryptAndSign, RedeemJwtPayloadType, verify } from 'shared'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
+import { DisbursementClient as V1_0_DisbursementClient } from '@/federation/client/1_0/DisbursementClient'
+import { DisbursementClientFactory } from '@/federation/client/DisbursementClientFactory'
+import { EncryptedTransferArgs } from 'core'
import { getLogger, Logger } from 'log4js'
+import { randombytes_random } from 'sodium-native'
import { executeTransaction } from './TransactionResolver'
import {
getAuthenticatedCommunities,
@@ -53,7 +54,7 @@ import { getLastTransaction } from './util/getLastTransaction'
import { sendTransactionsToDltConnector } from './util/sendTransactionsToDltConnector'
import { transactionLinkList } from './util/transactionLinkList'
-const createLogger = () => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.TransactionLinkResolver`)
+const createLogger = (method: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.resolver.TransactionLinkResolver.${method}`)
// TODO: do not export, test it inside the resolver
export const transactionLinkCode = (date: Date): string => {
@@ -148,9 +149,9 @@ export class TransactionLinkResolver {
@Authorized([RIGHTS.QUERY_TRANSACTION_LINK])
@Query(() => QueryLinkResult)
async queryTransactionLink(@Arg('code') code: string): Promise {
- const logger = createLogger()
- logger.addContext('code', code.substring(0, 6))
- logger.debug('TransactionLinkResolver.queryTransactionLink...')
+ const methodLogger = createLogger('queryTransactionLink')
+ methodLogger.addContext('code', code.substring(0, 6))
+ methodLogger.debug('queryTransactionLink...')
if (code.match(/^CL-/)) {
const contributionLink = await DbContributionLink.findOneOrFail({
where: { code: code.replace('CL-', '') },
@@ -171,7 +172,7 @@ export class TransactionLinkResolver {
}
// normal redeem code
if (txLinkFound) {
- logger.debug(
+ methodLogger.debug(
'TransactionLinkResolver.queryTransactionLink... normal redeem code found=',
txLinkFound,
)
@@ -186,7 +187,7 @@ export class TransactionLinkResolver {
return new TransactionLink(dbTransactionLink, new User(user), redeemedBy, communities)
} else {
// redeem jwt-token
- return await this.queryRedeemJwtLink(code, logger)
+ return await this.queryRedeemJwtLink(code, methodLogger)
}
}
}
@@ -197,8 +198,8 @@ export class TransactionLinkResolver {
@Arg('code', () => String) code: string,
@Ctx() context: Context,
): Promise {
- const logger = createLogger()
- logger.addContext('code', code.substring(0, 6))
+ const methodLogger = createLogger('redeemTransactionLink')
+ methodLogger.addContext('code', code.substring(0, 6))
const clientTimezoneOffset = getClientTimezoneOffset(context)
// const homeCom = await DbCommunity.findOneOrFail({ where: { foreign: false } })
const user = getUser(context)
@@ -206,7 +207,7 @@ export class TransactionLinkResolver {
// acquire lock
const releaseLock = await TRANSACTIONS_LOCK.acquire()
try {
- logger.info('redeem contribution link...')
+ methodLogger.info('redeem contribution link...')
const now = new Date()
const queryRunner = db.getDataSource().createQueryRunner()
await queryRunner.connect()
@@ -221,7 +222,7 @@ export class TransactionLinkResolver {
if (!contributionLink) {
throw new LogError('No contribution link found to given code', code)
}
- logger.info('...contribution link found with id', contributionLink.id)
+ methodLogger.info('...contribution link found with id', contributionLink.id)
if (new Date(contributionLink.validFrom).getTime() > now.getTime()) {
throw new LogError('Contribution link is not valid yet', contributionLink.validFrom)
}
@@ -278,7 +279,7 @@ export class TransactionLinkResolver {
}
const creations = await getUserCreation(user.id, clientTimezoneOffset)
- logger.info('open creations', creations)
+ methodLogger.info('open creations', creations)
validateContribution(creations, contributionLink.amount, now, clientTimezoneOffset)
const contribution = new DbContribution()
contribution.userId = user.id
@@ -383,7 +384,7 @@ export class TransactionLinkResolver {
transactionLink.memo,
linkedUser,
user,
- logger,
+ methodLogger,
transactionLink,
)
await EVENT_TRANSACTION_LINK_REDEEM(
@@ -413,9 +414,9 @@ export class TransactionLinkResolver {
@Arg('alias', { nullable: true }) alias?: string,
@Arg('validUntil', { nullable: true }) validUntil?: string,
): Promise {
- const logger = createLogger()
- logger.addContext('code', code.substring(0, 6))
- logger.debug('TransactionLinkResolver.queryRedeemJwt... args=', {
+ const methodLogger = createLogger('createRedeemJwt')
+ methodLogger.addContext('code', code.substring(0, 6))
+ methodLogger.debug('args=', {
gradidoId,
senderCommunityUuid,
senderCommunityName,
@@ -466,40 +467,80 @@ export class TransactionLinkResolver {
@Arg('validUntil', { nullable: true }) validUntil?: string,
@Arg('recipientAlias', { nullable: true }) recipientAlias?: string,
): Promise {
- const logger = createLogger()
- logger.addContext('code', code.substring(0, 6))
- logger.debug('TransactionLinkResolver.disburseTransactionLink... args=', {
- senderGradidoId,
- senderCommunityUuid,
- recipientCommunityUuid,
- recipientCommunityName,
- recipientGradidoId,
- recipientFirstName,
- code,
- amount,
- memo,
- validUntil,
+ const handshakeID = randombytes_random().toString()
+ const methodLogger = createLogger(`disburseTransactionLink`)
+ methodLogger.addContext('handshakeID', handshakeID)
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug('args=', {
+ senderGradidoId,
+ senderCommunityUuid,
+ recipientCommunityUuid,
+ recipientCommunityName,
+ recipientGradidoId,
+ recipientFirstName,
+ code,
+ amount,
+ memo,
+ validUntil,
recipientAlias,
- })
- const disburseJwt = await this.createDisburseJwt(
- senderCommunityUuid,
- senderGradidoId,
- recipientCommunityUuid,
- recipientCommunityName,
- recipientGradidoId,
- recipientFirstName,
- code,
- amount,
- memo,
- validUntil ?? '',
- recipientAlias ?? '',
- )
- try {
- logger.debug('TransactionLinkResolver.disburseTransactionLink... disburseJwt=', disburseJwt)
- // now send the disburseJwt to the sender community to invoke a x-community-tx to disbures the redeemLink
- // await sendDisburseJwtToSenderCommunity(context, disburseJwt)
- } catch (e) {
- throw new LogError('Disburse JWT was not sent successfully', e)
+ })
+ }
+ const senderCom = await DbCommunity.findOneBy({ communityUuid: senderCommunityUuid })
+ if (!senderCom) {
+ const errmsg = `Sender community not found with uuid=${senderCommunityUuid}`
+ methodLogger.error(errmsg)
+ throw new LogError(errmsg)
+ }
+ const senderFedCom = await DbFederatedCommunity.findOneBy({ publicKey: senderCom.publicKey })
+ if (!senderFedCom) {
+ const errmsg = `Sender federated community not found with publicKey=${senderCom.publicKey}`
+ methodLogger.error(errmsg)
+ throw new LogError(errmsg)
+ }
+ const recipientCom = await DbCommunity.findOneBy({ communityUuid: recipientCommunityUuid })
+ if (!recipientCom) {
+ const errmsg = `Recipient community not found with uuid=${recipientCommunityUuid}`
+ methodLogger.error(errmsg)
+ throw new LogError(errmsg)
+ }
+ const client = DisbursementClientFactory.getInstance(senderFedCom)
+ if (client instanceof V1_0_DisbursementClient) {
+ const disburseJwtPayload = new DisburseJwtPayloadType(
+ handshakeID,
+ senderCommunityUuid,
+ senderGradidoId,
+ recipientCommunityUuid,
+ recipientCommunityName,
+ recipientGradidoId,
+ recipientFirstName,
+ code,
+ amount,
+ memo,
+ validUntil!,
+ recipientAlias!,
+ )
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug('disburseJwtPayload=', disburseJwtPayload)
+ }
+ const jws = await encryptAndSign(disburseJwtPayload, recipientCom.privateJwtKey!, senderCom.publicJwtKey!)
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug('jws=', jws)
+ }
+ const args = new EncryptedTransferArgs()
+ args.publicKey = senderCom.publicKey.toString('hex')
+ args.jwt = jws
+ args.handshakeID = handshakeID
+ try {
+ // now send the disburseJwt to the sender community to invoke a x-community-tx to disbures the redeemLink
+ const result = await client.sendDisburseJwtToSenderCommunity(args)
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug('Disburse JWT was sent successfully with result=', result)
+ }
+ } catch (e) {
+ const errmsg = `Disburse JWT was not sent successfully with error=${e}`
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
+ }
}
return true
}
@@ -653,56 +694,4 @@ export class TransactionLinkResolver {
)
}
}
-
- async createDisburseJwt(
- handshakeId: string,
- senderCommunityUuid: string,
- senderGradidoId: string,
- recipientCommunityUuid: string,
- recipientCommunityName: string,
- recipientGradidoId: string,
- recipientFirstName: string,
- code: string,
- amount: string,
- memo: string,
- validUntil: string,
- recipientAlias: string,
- ): Promise {
- const logger = createLogger()
- logger.addContext('code', code.substring(0, 6))
- logger.debug('TransactionLinkResolver.createDisburseJwt... args=', {
- handshakeId,
- senderCommunityUuid,
- senderGradidoId,
- recipientCommunityUuid,
- recipientCommunityName,
- recipientGradidoId,
- recipientFirstName,
- code,
- amount,
- memo,
- validUntil,
- recipientAlias,
- })
-
- const disburseJwtPayload = new DisburseJwtPayloadType(
- handshakeId,
- senderCommunityUuid,
- senderGradidoId,
- recipientCommunityUuid,
- recipientCommunityName,
- recipientGradidoId,
- recipientFirstName,
- code,
- amount,
- memo,
- validUntil,
- recipientAlias,
- )
- const disburseJwt = await encryptAndSign(disburseJwtPayload, homeComB.privateJwtKey!, authCom.publicJwtKey!)
- // TODO:encode/sign the jwt normally with the private key of the recipient community, but interims with uuid
- logger.debug('TransactionLinkResolver.createDisburseJwt... disburseJwt=', disburseJwt)
- // TODO: encrypt the payload with the public key of the target/sender community
- return disburseJwt
- }
}
diff --git a/backend/src/graphql/resolver/TransactionResolver.test.ts b/backend/src/graphql/resolver/TransactionResolver.test.ts
index 275ae77fd..e39fcefc4 100644
--- a/backend/src/graphql/resolver/TransactionResolver.test.ts
+++ b/backend/src/graphql/resolver/TransactionResolver.test.ts
@@ -16,9 +16,9 @@ import { cleanDB, testEnvironment } from '@test/helpers'
import { CONFIG } from '@/config'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { EventType } from '@/event/Events'
-import { SendCoinsClient } from '@/federation/client/1_0/SendCoinsClient'
-import { SendCoinsArgs } from '@/federation/client/1_0/model/SendCoinsArgs'
-import { SendCoinsResult } from '@/federation/client/1_0/model/SendCoinsResult'
+import { SendCoinsClient } from 'core/src/federation/client/1_0/SendCoinsClient'
+import { SendCoinsArgs } from 'core/src/federation/client/1_0/model/SendCoinsArgs'
+import { SendCoinsResult } from 'core/src/federation/client/1_0/model/SendCoinsResult'
import { userFactory } from '@/seeds/factory/user'
import {
confirmContribution,
diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts
index 06ddf6bbf..5ceef0836 100644
--- a/backend/src/graphql/resolver/TransactionResolver.ts
+++ b/backend/src/graphql/resolver/TransactionResolver.ts
@@ -2,7 +2,6 @@ import {
AppDatabase,
countOpenPendingTransactions,
Community as DbCommunity,
- PendingTransaction as DbPendingTransaction,
Transaction as dbTransaction,
TransactionLink as dbTransactionLink,
User as dbUser,
@@ -15,11 +14,11 @@ import { In, IsNull } from 'typeorm'
import { Paginated } from '@arg/Paginated'
import { TransactionSendArgs } from '@arg/TransactionSendArgs'
import { Order } from '@enum/Order'
-import { PendingTransactionState, SendCoinsResponseJwtPayloadType } from 'shared'
-import { TransactionTypeId } from '@enum/TransactionTypeId'
import { Transaction } from '@model/Transaction'
import { TransactionList } from '@model/TransactionList'
import { User } from '@model/User'
+import { TransactionTypeId } from 'core/src/graphql/enum/TransactionTypeId'
+import { SendCoinsResponseJwtPayloadType } from 'shared'
import { RIGHTS } from '@/auth/RIGHTS'
import { CONFIG } from '@/config'
@@ -28,26 +27,25 @@ import {
sendTransactionReceivedEmail,
} from '@/emails/sendEmailVariants'
import { EVENT_TRANSACTION_RECEIVE, EVENT_TRANSACTION_SEND } from '@/event/Events'
-import { SendCoinsResult } from '@/federation/client/1_0/model/SendCoinsResult'
import { LogError } from '@/server/LogError'
import { Context, getUser } from '@/server/context'
import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
import { communityUser } from '@/util/communityUser'
-import { fullName } from '@/util/utilities'
import { calculateBalance } from '@/util/validate'
import { virtualDecayTransaction, virtualLinkTransaction } from '@/util/virtualTransactions'
+import { fullName, SendCoinsResult } from 'core'
-import { Logger, getLogger } from 'log4js'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
+import {
+ processXComCommittingSendCoins,
+ processXComPendingSendCoins,
+} from 'core'
+import { getLogger, Logger } from 'log4js'
import { BalanceResolver } from './BalanceResolver'
import { GdtResolver } from './GdtResolver'
import { getCommunityByIdentifier, getCommunityName, isHomeCommunity } from './util/communities'
import { getLastTransaction } from './util/getLastTransaction'
import { getTransactionList } from './util/getTransactionList'
-import {
- processXComCommittingSendCoins,
- processXComPendingSendCoins,
-} from './util/processXComSendCoins'
import { sendTransactionsToDltConnector } from './util/sendTransactionsToDltConnector'
import { storeForeignUser } from './util/storeForeignUser'
import { transactionLinkSummary } from './util/transactionLinkSummary'
diff --git a/backend/src/graphql/resolver/util/sendTransactionsToDltConnector.test.ts b/backend/src/graphql/resolver/util/sendTransactionsToDltConnector.test.ts
index b5ec0a08a..769730544 100644
--- a/backend/src/graphql/resolver/util/sendTransactionsToDltConnector.test.ts
+++ b/backend/src/graphql/resolver/util/sendTransactionsToDltConnector.test.ts
@@ -12,7 +12,7 @@ import { cleanDB, testEnvironment } from '@test/helpers'
import { i18n as localization } from '@test/testSetup'
import { CONFIG } from '@/config'
-import { TransactionTypeId } from '@/graphql/enum/TransactionTypeId'
+import { TransactionTypeId } from 'core'
import { creations } from '@/seeds/creation'
import { creationFactory } from '@/seeds/factory/creation'
import { userFactory } from '@/seeds/factory/user'
diff --git a/backend/src/graphql/resolver/util/storeForeignUser.ts b/backend/src/graphql/resolver/util/storeForeignUser.ts
index adceb155e..8c33c8923 100644
--- a/backend/src/graphql/resolver/util/storeForeignUser.ts
+++ b/backend/src/graphql/resolver/util/storeForeignUser.ts
@@ -1,6 +1,6 @@
import { Community as DbCommunity, User as DbUser } from 'database'
-import { SendCoinsResult } from '@/federation/client/1_0/model/SendCoinsResult'
+import { SendCoinsResult } from 'core/src/federation/client/1_0/model/SendCoinsResult'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { getLogger } from 'log4js'
diff --git a/backend/src/util/virtualTransactions.ts b/backend/src/util/virtualTransactions.ts
index dabaee264..0811eaf1b 100644
--- a/backend/src/util/virtualTransactions.ts
+++ b/backend/src/util/virtualTransactions.ts
@@ -2,7 +2,7 @@ import { Transaction as dbTransaction } from 'database'
import { Decimal } from 'decimal.js-light'
import { RemoveOptions, SaveOptions } from 'typeorm'
-import { TransactionTypeId } from '@enum/TransactionTypeId'
+import { TransactionTypeId } from 'core/src/graphql/enum/TransactionTypeId'
import { Transaction } from '@model/Transaction'
import { User } from '@model/User'
diff --git a/bun.lock b/bun.lock
index b49609f5c..30a87f9af 100644
--- a/bun.lock
+++ b/bun.lock
@@ -192,6 +192,7 @@
"devDependencies": {
"@biomejs/biome": "2.0.0",
"@types/node": "^17.0.21",
+ "jest": "27.2.4",
"type-graphql": "^1.1.1",
"typescript": "^4.9.5",
},
diff --git a/core/package.json b/core/package.json
index a1f7a5603..0044d263f 100644
--- a/core/package.json
+++ b/core/package.json
@@ -27,6 +27,7 @@
"devDependencies": {
"@biomejs/biome": "2.0.0",
"@types/node": "^17.0.21",
+ "jest": "27.2.4",
"type-graphql": "^1.1.1",
"typescript": "^4.9.5"
},
diff --git a/backend/src/federation/client/1_0/SendCoinsClient.ts b/core/src/federation/client/1_0/SendCoinsClient.ts
similarity index 92%
rename from backend/src/federation/client/1_0/SendCoinsClient.ts
rename to core/src/federation/client/1_0/SendCoinsClient.ts
index 13c2b8697..f4b6d49d8 100644
--- a/backend/src/federation/client/1_0/SendCoinsClient.ts
+++ b/core/src/federation/client/1_0/SendCoinsClient.ts
@@ -1,7 +1,6 @@
import { FederatedCommunity as DbFederatedCommunity } from 'database'
import { GraphQLClient } from 'graphql-request'
-import { LogError } from '@/server/LogError'
import { ensureUrlEndsWithSlash } from '@/util/utilities'
import { getLogger } from 'log4js'
@@ -83,7 +82,9 @@ export class SendCoinsClient {
logger.debug(`settleSendCoins successful from endpoint=${this.endpoint}`)
return true
} catch (err) {
- throw new LogError(`settleSendCoins failed for endpoint=${this.endpoint}`, err)
+ const errmsg = `settleSendCoins failed for endpoint=${this.endpoint}, err=${err}`
+ logger.error(errmsg)
+ throw new Error(errmsg)
}
}
@@ -103,7 +104,9 @@ export class SendCoinsClient {
logger.debug(`revertSettledSendCoins successful from endpoint=${this.endpoint}`)
return true
} catch (err) {
- throw new LogError(`revertSettledSendCoins failed for endpoint=${this.endpoint}`, err)
+ const errmsg = `revertSettledSendCoins failed for endpoint=${this.endpoint}, err=${err}`
+ logger.error(errmsg)
+ throw new Error(errmsg)
}
}
}
diff --git a/backend/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts b/core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
similarity index 89%
rename from backend/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
rename to core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
index 9bd8fee69..4057a2971 100644
--- a/backend/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
+++ b/core/src/federation/client/1_0/logging/SendCoinsArgsLogging.view.ts
@@ -1,6 +1,6 @@
import { AbstractLoggingView } from 'database'
-import { SendCoinsArgs } from '@/federation/client/1_0/model/SendCoinsArgs'
+import { SendCoinsArgs } from 'core/src/federation/client/1_0/model/SendCoinsArgs'
export class SendCoinsArgsLoggingView extends AbstractLoggingView {
public constructor(private self: SendCoinsArgs) {
diff --git a/backend/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts b/core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
similarity index 85%
rename from backend/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
rename to core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
index 2f2ec355e..a83e211e8 100644
--- a/backend/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
+++ b/core/src/federation/client/1_0/logging/SendCoinsResultLogging.view.ts
@@ -1,6 +1,6 @@
import { AbstractLoggingView } from 'database'
-import { SendCoinsResult } from '@/federation/client/1_0/model/SendCoinsResult'
+import { SendCoinsResult } from 'core/src/federation/client/1_0/model/SendCoinsResult'
export class SendCoinsResultLoggingView extends AbstractLoggingView {
public constructor(private self: SendCoinsResult) {
diff --git a/backend/src/federation/client/1_0/model/SendCoinsArgs.ts b/core/src/federation/client/1_0/model/SendCoinsArgs.ts
similarity index 100%
rename from backend/src/federation/client/1_0/model/SendCoinsArgs.ts
rename to core/src/federation/client/1_0/model/SendCoinsArgs.ts
diff --git a/backend/src/federation/client/1_0/model/SendCoinsResult.ts b/core/src/federation/client/1_0/model/SendCoinsResult.ts
similarity index 100%
rename from backend/src/federation/client/1_0/model/SendCoinsResult.ts
rename to core/src/federation/client/1_0/model/SendCoinsResult.ts
diff --git a/backend/src/federation/client/1_0/query/revertSendCoins.ts b/core/src/federation/client/1_0/query/revertSendCoins.ts
similarity index 100%
rename from backend/src/federation/client/1_0/query/revertSendCoins.ts
rename to core/src/federation/client/1_0/query/revertSendCoins.ts
diff --git a/backend/src/federation/client/1_0/query/revertSettledSendCoins.ts b/core/src/federation/client/1_0/query/revertSettledSendCoins.ts
similarity index 100%
rename from backend/src/federation/client/1_0/query/revertSettledSendCoins.ts
rename to core/src/federation/client/1_0/query/revertSettledSendCoins.ts
diff --git a/backend/src/federation/client/1_0/query/settleSendCoins.ts b/core/src/federation/client/1_0/query/settleSendCoins.ts
similarity index 100%
rename from backend/src/federation/client/1_0/query/settleSendCoins.ts
rename to core/src/federation/client/1_0/query/settleSendCoins.ts
diff --git a/backend/src/federation/client/1_0/query/voteForSendCoins.ts b/core/src/federation/client/1_0/query/voteForSendCoins.ts
similarity index 100%
rename from backend/src/federation/client/1_0/query/voteForSendCoins.ts
rename to core/src/federation/client/1_0/query/voteForSendCoins.ts
diff --git a/core/src/federation/client/1_1/SendCoinsClient.ts b/core/src/federation/client/1_1/SendCoinsClient.ts
new file mode 100644
index 000000000..b37f08b29
--- /dev/null
+++ b/core/src/federation/client/1_1/SendCoinsClient.ts
@@ -0,0 +1,3 @@
+import { SendCoinsClient as V1_0_SendCoinsClient } from 'core/src/federation/client/1_0/SendCoinsClient'
+
+export class SendCoinsClient extends V1_0_SendCoinsClient {}
diff --git a/backend/src/federation/client/SendCoinsClientFactory.ts b/core/src/federation/client/SendCoinsClientFactory.ts
similarity index 85%
rename from backend/src/federation/client/SendCoinsClientFactory.ts
rename to core/src/federation/client/SendCoinsClientFactory.ts
index 2fd15f739..8251da3cb 100644
--- a/backend/src/federation/client/SendCoinsClientFactory.ts
+++ b/core/src/federation/client/SendCoinsClientFactory.ts
@@ -1,9 +1,8 @@
import { FederatedCommunity as DbFederatedCommunity } from 'database'
-import { SendCoinsClient as V1_0_SendCoinsClient } from '@/federation/client/1_0/SendCoinsClient'
-
-import { SendCoinsClient as V1_1_SendCoinsClient } from '@/federation/client/1_1/SendCoinsClient'
-import { ApiVersionType } from '@/federation/enum/apiVersionType'
+import { SendCoinsClient as V1_0_SendCoinsClient } from '@federation/client/1_0/SendCoinsClient'
+import { SendCoinsClient as V1_1_SendCoinsClient } from '@federation/client/1_1/SendCoinsClient'
+import { ApiVersionType } from '@federation/enum/apiVersionType'
type SendCoinsClient = V1_0_SendCoinsClient | V1_1_SendCoinsClient
diff --git a/backend/src/federation/enum/apiVersionType.ts b/core/src/federation/enum/apiVersionType.ts
similarity index 100%
rename from backend/src/federation/enum/apiVersionType.ts
rename to core/src/federation/enum/apiVersionType.ts
diff --git a/backend/src/graphql/enum/TransactionTypeId.ts b/core/src/graphql/enum/TransactionTypeId.ts
similarity index 100%
rename from backend/src/graphql/enum/TransactionTypeId.ts
rename to core/src/graphql/enum/TransactionTypeId.ts
diff --git a/backend/src/graphql/resolver/util/processXComSendCoins.ts b/core/src/graphql/logic/processXComSendCoins.ts
similarity index 93%
rename from backend/src/graphql/resolver/util/processXComSendCoins.ts
rename to core/src/graphql/logic/processXComSendCoins.ts
index 91eb61a1e..3b17939d5 100644
--- a/backend/src/graphql/resolver/util/processXComSendCoins.ts
+++ b/core/src/graphql/logic/processXComSendCoins.ts
@@ -10,23 +10,22 @@ import {
} from 'database'
import { Decimal } from 'decimal.js-light'
-import { CONFIG } from '@/config'
+import { LOG4JS_BASE_CATEGORY_NAME } from '@config/const'
-import { SendCoinsClient as V1_0_SendCoinsClient } from '@/federation/client/1_0/SendCoinsClient'
-import { SendCoinsArgs } from '@/federation/client/1_0/model/SendCoinsArgs'
-import { SendCoinsResult } from '@/federation/client/1_0/model/SendCoinsResult'
-import { SendCoinsClientFactory } from '@/federation/client/SendCoinsClientFactory'
+import { SendCoinsClient as V1_0_SendCoinsClient } from '@federation/client/1_0/SendCoinsClient'
+import { SendCoinsArgs } from '@federation/client/1_0/model/SendCoinsArgs'
+import { SendCoinsResult } from '@federation/client/1_0/model/SendCoinsResult'
+import { SendCoinsClientFactory } from '@federation/client/SendCoinsClientFactory'
import { encryptAndSign, PendingTransactionState, SendCoinsJwtPayloadType, SendCoinsResponseJwtPayloadType, verifyAndDecrypt } from 'shared'
-import { TransactionTypeId } from '@/graphql/enum/TransactionTypeId'
-import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
-import { LogError } from '@/server/LogError'
-import { calculateSenderBalance } from '@/util/calculateSenderBalance'
-import { fullName } from '@/util/utilities'
+import { TransactionTypeId } from '@graphql/enum/TransactionTypeId'
+import { LogError } from '@server/LogError'
+import { calculateSenderBalance } from '@util/calculateSenderBalance'
+import { fullName } from '@util/utilities'
import { getLogger } from 'log4js'
-import { settlePendingSenderTransaction } from './settlePendingSenderTransaction'
-import { SendCoinsArgsLoggingView } from '@/federation/client/1_0/logging/SendCoinsArgsLogging.view'
-import { SendCoinsResultLoggingView } from '@/federation/client/1_0/logging/SendCoinsResultLogging.view'
+import { settlePendingSenderTransaction } from '@graphql/resolver/util/settlePendingSenderTransaction'
+import { SendCoinsArgsLoggingView } from '@federation/client/1_0/logging/SendCoinsArgsLogging.view'
+import { SendCoinsResultLoggingView } from '@federation/client/1_0/logging/SendCoinsResultLogging.view'
import { EncryptedTransferArgs } from 'core'
import { randombytes_random } from 'sodium-native'
diff --git a/core/src/index.ts b/core/src/index.ts
index 28aae758a..3aa4a63d8 100644
--- a/core/src/index.ts
+++ b/core/src/index.ts
@@ -1,3 +1,17 @@
-export * from './validation/user'
+export * from './federation/client/1_0/logging/SendCoinsArgsLogging.view'
+export * from './federation/client/1_0/logging/SendCoinsResultLogging.view'
+export * from './federation/client/1_0/model/SendCoinsArgs'
+export * from './federation/client/1_0/model/SendCoinsResult'
+export * from './federation/client/1_0/query/revertSendCoins'
+export * from './federation/client/1_0/query/revertSettledSendCoins'
+export * from './federation/client/1_0/query/settleSendCoins'
+export * from './federation/client/1_0/query/voteForSendCoins'
+export * from './federation/client/SendCoinsClientFactory'
+export * from './federation/enum/apiVersionType'
+export * from './graphql/enum/TransactionTypeId'
export * from './graphql/logic/interpretEncryptedTransferArgs'
+export * from './graphql/logic/processXComSendCoins'
export * from './graphql/model/EncryptedTransferArgs'
+export * from './util/utilities'
+export * from './validation/user'
+
diff --git a/backend/src/util/utilities.test.ts b/core/src/util/utilities.test.ts
similarity index 100%
rename from backend/src/util/utilities.test.ts
rename to core/src/util/utilities.test.ts
diff --git a/backend/src/util/utilities.ts b/core/src/util/utilities.ts
similarity index 100%
rename from backend/src/util/utilities.ts
rename to core/src/util/utilities.ts
diff --git a/core/tsconfig.json b/core/tsconfig.json
index 75b686340..660381127 100644
--- a/core/tsconfig.json
+++ b/core/tsconfig.json
@@ -44,8 +44,15 @@
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
- // "baseUrl": ".", /* Base directory to resolve non-absolute module names. */
- // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
+ "baseUrl": ".", /* Base directory to resolve non-absolute module names. */
+ "paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
+ "@/*": ["src/*"],
+ "@config/*": ["src/config/*"],
+ "@federation/*": ["src/federation/*"],
+ "@graphql/*": ["src/graphql/*"],
+ "@util/*": ["src/util/*"],
+ "@validation/*": ["src/validation/*"],
+ },
// "rootDirs": [".", "../database"], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": ["bun-types"], /* Type declaration files to be included in compilation. */
diff --git a/federation/src/client/AuthenticationClientFactory.ts b/federation/src/client/AuthenticationClientFactory.ts
index 29e55279d..94a74581a 100644
--- a/federation/src/client/AuthenticationClientFactory.ts
+++ b/federation/src/client/AuthenticationClientFactory.ts
@@ -3,7 +3,7 @@ import { FederatedCommunity as DbFederatedCommunity } from 'database'
import { AuthenticationClient as V1_0_AuthenticationClient } from './1_0/AuthenticationClient'
import { AuthenticationClient as V1_1_AuthenticationClient } from './1_1/AuthenticationClient'
-import { ApiVersionType } from './enum/ApiVersionType'
+import { ApiVersionType } from 'core'
type AuthenticationClient = V1_0_AuthenticationClient | V1_1_AuthenticationClient
diff --git a/federation/src/client/enum/ApiVersionType.ts b/federation/src/client/enum/ApiVersionType.ts
deleted file mode 100644
index 60da9de57..000000000
--- a/federation/src/client/enum/ApiVersionType.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export enum ApiVersionType {
- V1_0 = '1_0',
- V1_1 = '1_1',
-}
diff --git a/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts b/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts
new file mode 100644
index 000000000..629da9e54
--- /dev/null
+++ b/federation/src/graphql/api/1_0/resolver/DisbursementResolver.ts
@@ -0,0 +1,33 @@
+import { getLogger } from "log4js"
+import { Arg, Mutation, Resolver } from "type-graphql"
+
+import { LOG4JS_BASE_CATEGORY_NAME } from "@/config/const"
+import { interpretEncryptedTransferArgs } from "core"
+import { EncryptedTransferArgs } from "core"
+import { DisburseJwtPayloadType } from "shared"
+
+const createLogger = (method: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.graphql.api.1_0.resolver.DisbursementResolver.${method}`)
+
+@Resolver()
+export class DisbursementResolver {
+ @Mutation(() => String)
+ async processDisburseJwtOnSenderCommunity(
+ @Arg('data')
+ args: EncryptedTransferArgs,
+ ): Promise {
+ const methodLogger = createLogger(`processDisburseJwtOnSenderCommunity`)
+ methodLogger.addContext('handshakeID', args.handshakeID)
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug(`processDisburseJwtOnSenderCommunity() via apiVersion=1_0 ...`, args)
+ }
+ const authArgs = await interpretEncryptedTransferArgs(args) as DisburseJwtPayloadType
+ if (!authArgs) {
+ const errmsg = `invalid disbursement payload of requesting community with publicKey` + args.publicKey
+ methodLogger.error(errmsg)
+ throw new Error(errmsg)
+ }
+ if(methodLogger.isDebugEnabled()) {
+ methodLogger.debug(`processDisburseJwtOnSenderCommunity() via apiVersion=1_0 ...`, authArgs)
+ }
+ }
+}
\ No newline at end of file