Skip to content

Commit

Permalink
feat: add handlers for incrementing and decrementing balances
Browse files Browse the repository at this point in the history
  • Loading branch information
rabi-siddique committed Apr 30, 2024
1 parent 5147932 commit a05865e
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 42 deletions.
21 changes: 21 additions & 0 deletions project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,27 @@ const project: CosmosProject = {
type: "transfer",
},
},
{
handler: "handleBalanceDecrementEvent",
kind: CosmosHandlerKind.Event,
filter: {
type: "transfer",
},
},
{
handler: "handleBalanceIncrementEvent",
kind: CosmosHandlerKind.Event,
filter: {
type: "coin_received",
},
},
{
handler: "handleBalanceDecrementEvent",
kind: CosmosHandlerKind.Event,
filter: {
type: "coin_spent",
},
},
],
},
},
Expand Down
17 changes: 12 additions & 5 deletions src/mappings/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,18 @@ export const VAULT_STATES = {
LIQUIDATED: "liquidated"
}

export const TRANSACTION_FIELDS = {
RECIPIENT: 'recipient',
SENDER: 'sender',
AMOUNT: 'amount'
}
export const BALANCE_FIELDS = {
coinbase: 'minter',
commission: 'validator',
proposer_reward: 'validator',
message: 'sender',
rewards: 'validator',
coin_received: 'receiver',
coin_spent: 'spender',
transfer_recipient: 'recipient',
transfer_sender: 'sender',
amount: 'amount',
};

export const VALUE_KEY = b64encode("value");
export const STORE_KEY = b64encode("store");
Expand Down
68 changes: 42 additions & 26 deletions src/mappings/events/balances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ export const balancesEventKit = () => {
return decodedData;
}

async function addressExists(address: string): Promise<boolean> {
async function isAddressInUse(address: string): Promise<boolean> {
const balance = await Balances.getByAddress(address);
if (balance?.length === 0) {

if (!balance || balance.length === 0) {
return false;
}
return true;
Expand All @@ -50,55 +51,70 @@ export const balancesEventKit = () => {
const newBalance = new Balances(address);
newBalance.address = address;
newBalance.balance = BigInt(0);
newBalance.denom = '';
newBalance.denom = 'ubld';

await newBalance.save();

logger.info(`Created new entry for address: ${address}`);
}

async function updateBalances(
senderAddress: string,
recipientAddress: string,
async function incrementBalance(
address: string,
amount: bigint
): Promise<void> {
const senderBalances = await Balances.getByAddress(senderAddress);
const recipientBalances = await Balances.getByAddress(recipientAddress);
const balances = await Balances.getByAddress(address);

if (!senderBalances || senderBalances.length === 0) {
logger.error(`Sender balance not found for address: ${senderAddress}`);
if (!balances || balances.length === 0) {
logger.error(`Balance not found for address: ${address}`);
return;
}

if (!recipientBalances || recipientBalances.length === 0) {
logger.error(
`Recipient balance not found for address: ${recipientAddress}`
);
const balance = balances[0];
const currentBalance = balance.balance ?? BigInt(0);
balance.balance = currentBalance + amount;

await balance.save();
logger.info(
`Incremented balance for ${address} by ${amount}. New balance: ${balance.balance}`
);
}

async function decrementBalance(
address: string,
amount: bigint
): Promise<void> {
const balances = await Balances.getByAddress(address);

if (!balances || balances.length === 0) {
logger.error(`Balance not found for address: ${address}`);
return;
}

const senderBalance = senderBalances[0];
const recipientBalance = recipientBalances[0];

const senderCurrentBalance = senderBalance.balance ?? BigInt(0);
const recipientCurrentBalance = recipientBalance.balance ?? BigInt(0);
const balance = balances[0];
const currentBalance = balance.balance ?? BigInt(0);
const newBalance = currentBalance - amount;

senderBalance.balance = senderCurrentBalance - amount;
recipientBalance.balance = recipientCurrentBalance + amount;
if (newBalance < 0) {
logger.error(
`Transaction failed: Attempt to decrement ${amount} would result in a negative balance. Current balance: ${currentBalance}.`
);
return;
}

await senderBalance.save();
await recipientBalance.save();
balance.balance = newBalance;
await balance.save();

logger.info(
`Updated balances: Sender ${senderAddress} balance: ${senderBalance.balance}, Recipient ${recipientAddress} balance: ${recipientBalance.balance}`
`Decremented balance for ${address} by ${amount}. New balance: ${balance.balance}`
);
}

return {
getAttributeValue,
decodeEvent,
addressExists,
isAddressInUse,
createBalancesEntry,
updateBalances,
incrementBalance,
decrementBalance,
};
};
120 changes: 109 additions & 11 deletions src/mappings/mappingHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
STORE_NAME_KEY,
SUBKEY_KEY,
UNPROVED_VALUE_KEY,
TRANSACTION_FIELDS
BALANCE_FIELDS
} from "./constants";
import { psmEventKit } from "./events/psm";
import { boardAuxEventKit } from "./events/boardAux";
Expand Down Expand Up @@ -169,27 +169,30 @@ export async function handleStateChangeEvent(cosmosEvent: CosmosEvent): Promise<
export async function handleTransferEvent(
cosmosEvent: CosmosEvent
): Promise<void> {
const { event, block } = cosmosEvent;
const { event } = cosmosEvent;

if (event.type != EVENT_TYPES.TRANSFER) {
logger.warn('Not valid transfer event.');
return;
}

logger.info('Captured a TRANSFER event');

const balancesKit = balancesEventKit();
const decodedData: DecodedEvent = balancesKit.decodeEvent(cosmosEvent);
logger.info(`Decoded transaction data ${JSON.stringify(decodedData)}`);

const recipientAddress = balancesKit.getAttributeValue(
decodedData,
TRANSACTION_FIELDS.RECIPIENT
BALANCE_FIELDS.transfer_recipient
);
const senderAddress = balancesKit.getAttributeValue(
decodedData,
TRANSACTION_FIELDS.SENDER
BALANCE_FIELDS.transfer_sender
);
const transactionAmount = balancesKit.getAttributeValue(
decodedData,
TRANSACTION_FIELDS.AMOUNT
BALANCE_FIELDS.amount
);

if (!recipientAddress) {
Expand All @@ -208,8 +211,8 @@ export async function handleTransferEvent(
}

const [recipientEntryExists, senderEntryExists] = await Promise.all([
balancesKit.addressExists(recipientAddress),
balancesKit.addressExists(senderAddress),
balancesKit.isAddressInUse(recipientAddress),
balancesKit.isAddressInUse(senderAddress),
]);

if (!recipientEntryExists) {
Expand All @@ -220,9 +223,104 @@ export async function handleTransferEvent(
await balancesKit.createBalancesEntry(senderAddress);
}

balancesKit.updateBalances(
senderAddress,
recipientAddress,
BigInt(transactionAmount.slice(0, -4))
await Promise.all([
balancesKit.decrementBalance(
senderAddress,
BigInt(transactionAmount.slice(0, -4))
),
balancesKit.incrementBalance(
recipientAddress,
BigInt(transactionAmount.slice(0, -4))
),
]);
}

export async function handleBalanceIncrementEvent(
cosmosEvent: CosmosEvent
): Promise<void> {
const { event } = cosmosEvent;

if (![EVENT_TYPES.COIN_RECEIVED].includes(event.type)) {
logger.warn(`${event.type} is not valid balance increment event.`);
return;
}

logger.info(`Captured ${event.type} event`);

const balancesKit = balancesEventKit();
const decodedData: DecodedEvent = balancesKit.decodeEvent(cosmosEvent);
logger.info(`Decoded transaction data ${JSON.stringify(decodedData)}`);

const address = balancesKit.getAttributeValue(
decodedData,
BALANCE_FIELDS[event.type as keyof typeof BALANCE_FIELDS]
);

const transactionAmount = balancesKit.getAttributeValue(
decodedData,
BALANCE_FIELDS.amount
);

if (!address) {
logger.error('Address is missing or invalid.');
return;
}

if (!transactionAmount) {
logger.error('Transaction amount is missing or invalid.');
return;
}

const entryExists = balancesKit.isAddressInUse(address);

if (!entryExists) {
await balancesKit.createBalancesEntry(address);
}

balancesKit.incrementBalance(address, BigInt(transactionAmount.slice(0, -4)));
}

export async function handleBalanceDecrementEvent(
cosmosEvent: CosmosEvent
): Promise<void> {
const { event } = cosmosEvent;

if (![EVENT_TYPES.COIN_SPENT].includes(event.type)) {
logger.warn(`${event.type} is not valid balance decrement event.`);
return;
}

logger.info(`Captured ${event.type} event`);

const balancesKit = balancesEventKit();
const decodedData: DecodedEvent = balancesKit.decodeEvent(cosmosEvent);
logger.info(`Decoded transaction data ${JSON.stringify(decodedData)}`);

const address = balancesKit.getAttributeValue(
decodedData,
BALANCE_FIELDS[event.type as keyof typeof BALANCE_FIELDS]
);

const transactionAmount = balancesKit.getAttributeValue(
decodedData,
BALANCE_FIELDS.amount
);

if (!address) {
logger.error('Address is missing or invalid.');
return;
}

if (!transactionAmount) {
logger.error('Transaction amount is missing or invalid.');
return;
}

const entryExists = balancesKit.isAddressInUse(address);

if (!entryExists) {
await balancesKit.createBalancesEntry(address);
}

balancesKit.decrementBalance(address, BigInt(transactionAmount.slice(0, -4)));
}

0 comments on commit a05865e

Please sign in to comment.