Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion platforms/ecurrency/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,3 @@
"typescript": "^5.3.3"
}
}

Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
{
"tableName": "currencies",
"schemaId": "550e8400-e29b-41d4-a716-446655440008",
"ownerEnamePath": "ename",
"ownerEnamePath": "groups(group.admins[].ename)||users(creator.ename)",
"ownedJunctionTables": [],
"localToUniversalMap": {
"name": "name",
"description": "description",
"ename": "ename",
"groupId": "groupId",
"allowNegative": "allowNegative",
"maxNegativeBalance": "maxNegativeBalance",
"allowNegativeGroupOnly": "allowNegativeGroupOnly",
"createdBy": "createdBy",
"createdAt": "createdAt",
"updatedAt": "updatedAt"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
{
"tableName": "ledger",
"tableName": "ledgers",
"schemaId": "550e8400-e29b-41d4-a716-446655440006",
"ownerEnamePath": "currency.ename",
"ownerEnamePath": "syncOwnerEname",
"ownedJunctionTables": [],
"localToUniversalMap": {
"currencyId": "currencyId",
"currencyId": "currencies(currencyId),currencyId",
"accountId": "accountId",
"accountType": "accountType",
"amount": "amount",
"type": "type",
"description": "description",
"senderAccountId": "senderAccountId",
"senderAccountType": "senderAccountType",
"receiverAccountId": "receiverAccountId",
"receiverAccountType": "receiverAccountType",
"balance": "balance",
"hash": "hash",
"prevHash": "prevHash",
"createdAt": "createdAt"
},
"readOnly": false
Expand Down
107 changes: 105 additions & 2 deletions platforms/ecurrency/api/src/web3adapter/watchers/subscriber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,36 @@ export class PostgresSubscriber implements EntitySubscriberInterface {

}

private async loadFullEntity(
entityId: string,
tableTarget: any
): Promise<any | null> {
try {
const repository = AppDataSource.getRepository(tableTarget);
const entityName = typeof tableTarget === "function"
? tableTarget.name
: tableTarget;
const relations = this.getRelationsForEntity(entityName);
return await repository.findOne({
where: { id: entityId },
relations,
});
} catch (error) {
console.error("Error loading full entity:", error);
return null;
}
}

async enrichEntity(entity: any, tableName: string, tableTarget: any) {
try {
const entityId = entity?.id;
if (entityId) {
const fullEntity = await this.loadFullEntity(entityId, tableTarget);
if (fullEntity) {
return this.entityToPlain(fullEntity);
}
}

const enrichedEntity = { ...entity };
return this.entityToPlain(enrichedEntity);
} catch (error) {
Expand Down Expand Up @@ -263,7 +291,12 @@ export class PostgresSubscriber implements EntitySubscriberInterface {
return;
}

const envelope = await this.adapter.handleChange({
if (tableName === "ledgers") {
await this.syncLedgerToAllParticipantEVaults(data);
return;
}

await this.adapter.handleChange({
data,
tableName: tableName.toLowerCase(),
});
Expand All @@ -273,6 +306,76 @@ export class PostgresSubscriber implements EntitySubscriberInterface {
}
}

private async resolveAccountEname(
accountId?: string,
accountType?: string | null
): Promise<string | null> {
if (!accountId || !accountType) {
return null;
}

try {
if (accountType === "user") {
const userRepository = AppDataSource.getRepository("User");
const user = await userRepository.findOne({ where: { id: accountId } });
return user?.ename || null;
}

if (accountType === "group") {
const groupRepository = AppDataSource.getRepository("Group");
const group = await groupRepository.findOne({ where: { id: accountId } });
return group?.ename || null;
}
} catch (error) {
console.error("Error resolving account eName:", error);
}

return null;
}

private async resolveLedgerParticipants(ledgerData: any): Promise<string[]> {
const participants = new Set<string>();

const senderEname = await this.resolveAccountEname(
ledgerData?.senderAccountId,
ledgerData?.senderAccountType
);
if (senderEname) {
participants.add(senderEname);
}

const receiverEname = await this.resolveAccountEname(
ledgerData?.receiverAccountId,
ledgerData?.receiverAccountType
);
if (receiverEname) {
participants.add(receiverEname);
}

return Array.from(participants);
}

private async syncLedgerToAllParticipantEVaults(data: any): Promise<void> {
const participantEnames = await this.resolveLedgerParticipants(data);
if (participantEnames.length === 0) {
console.warn(`No participant eNames resolved for ledger ${data.id}`);
return;
}

for (const participantEname of participantEnames) {
const scopedLedgerData = {
...data,
id: `${data.id}::${participantEname}`,
syncOwnerEname: participantEname,
};

await this.adapter.handleChange({
data: scopedLedgerData,
tableName: "ledgers",
});
}
}

/**
* Handle changes in junction tables by converting them to parent entity changes
*/
Expand Down Expand Up @@ -387,7 +490,7 @@ export class PostgresSubscriber implements EntitySubscriberInterface {
case "Message":
return ["sender", "group"];
case "Currency":
return ["group", "creator"];
return ["group", "group.admins", "creator"];
case "Ledger":
return ["currency"];
default:
Expand Down