Skip to content

Commit

Permalink
feat: updated method to get escrow addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
frazarshad committed May 4, 2024
1 parent f31cbd3 commit 63a185a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 104 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
"dependencies": {
"@subql/types-cosmos": "^3.2.3",
"@types/node": "^17.0.21",
"bech32": "^2.0.0",
"js-sha256": "^0.11.0",
"pino": "^7.8.0",
"ts-proto": "^1.112.1",
"tslib": "^2.3.1"
Expand Down
3 changes: 1 addition & 2 deletions src/mappings/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,4 @@ export const RECEPIENT_KEY = b64encode("recipient");
export const SENDER_KEY = b64encode("sender");
export const RECEIVER_KEY = b64encode("receiver");
export const AMOUNT_KEY = b64encode("amount");
export const TRANSFER_PORT_VALUE = 'transfer';

export const TRANSFER_PORT_VALUE = "transfer";
119 changes: 17 additions & 102 deletions src/mappings/mappingHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
extractBrand,
resolveBrandNamesAndValues,
dateToDayKey,
getEscrowAddress,
} from "./utils";

import {
Expand Down Expand Up @@ -65,8 +66,15 @@ BigInt.prototype.toJSON = function () {
return this.toString();
};

async function saveIbcChannel(channelName: string) {
const generatedEscrowAddress = getEscrowAddress(TRANSFER_PORT_VALUE, channelName);

const channelRecord = new IBCChannel(channelName, channelName, generatedEscrowAddress);
channelRecord.save();
}

export async function handleIbcSendPacketEvent(cosmosEvent: CosmosEvent): Promise<void> {
const { event, block } = cosmosEvent;
const { event, block, tx } = cosmosEvent;
if (event.type != EVENT_TYPES.SEND_PACKET) {
logger.warn("Not valid send_packet event.");
return;
Expand All @@ -89,48 +97,12 @@ export async function handleIbcSendPacketEvent(cosmosEvent: CosmosEvent): Promis
return;
}
const { amount, denom, receiver, sender } = JSON.parse(packetDataAttr.value);
const sourceChannel = packetSrcChannelAttr.value;

const txns = block.txs;
const ibcTransaction = txns.find(
(txn) =>
txn.events.find(
(event) =>
event.type === EVENT_TYPES.MESSAGE &&
event.attributes.find(
(attribute) => attribute.key === ACTION_KEY && attribute.value === IBC_MESSAGE_TRANSFER_VALUE,
),
) &&
txn.events.find(
(event) =>
event.type === EVENT_TYPES.IBC_TRANSFER &&
event.attributes.find((attribute) => attribute.key === SENDER_KEY)?.value === b64encode(sender) &&
event.attributes.find((attribute) => attribute.key === RECEIVER_KEY)?.value === b64encode(receiver),
),
);
const transferEvents = ibcTransaction?.events.filter((event) => event.type === EVENT_TYPES.TRANSFER);
const escrowTransaction = transferEvents
?.reverse()
.find(
(event) =>
event.attributes.find((attribute) => attribute.key === SENDER_KEY)?.value === b64encode(sender) &&
event.attributes.find((attribute) => attribute.key === AMOUNT_KEY)?.value === b64encode(amount + denom),
);
const encodedEscrowAddress = escrowTransaction?.attributes.find(
(attribute) => attribute.key === RECEPIENT_KEY,
)?.value;
const escrowAddress = encodedEscrowAddress ? b64decode(encodedEscrowAddress) : null;

if (!escrowAddress) {
logger.error(`No escrow address found for ${packetSrcChannelAttr.value} at block height ${block.header.height}`);
return;
}
const ibcChannel = await IBCChannel.get(packetSrcChannelAttr.value);
if (ibcChannel && ibcChannel.escrowAddress !== escrowAddress) {
throw new Error(`Escrow address does not match that of ${packetSrcChannelAttr.value}`);
}
saveIbcChannel(sourceChannel);

const transferRecord = new IBCTransfer(
`${block.block.id}-${packetSrcChannelAttr.value}`,
tx.hash,
block.header.time as any,
BigInt(block.header.height),
packetSrcChannelAttr.value,
Expand All @@ -141,19 +113,10 @@ export async function handleIbcSendPacketEvent(cosmosEvent: CosmosEvent): Promis
TransferType.SEND,
);
transferRecord.save();

if (!ibcChannel) {
const channelRecord = new IBCChannel(
packetSrcChannelAttr.value,
packetSrcChannelAttr.value,
escrowAddress,
);
channelRecord.save();
}
}

export async function handleIbcReceivePacketEvent(cosmosEvent: CosmosEvent): Promise<void> {
const { event, block } = cosmosEvent;
const { event, block, tx } = cosmosEvent;
if (event.type != EVENT_TYPES.RECEIVE_PACKET) {
logger.warn("Not valid recv_packet event.");
return;
Expand All @@ -177,72 +140,24 @@ export async function handleIbcReceivePacketEvent(cosmosEvent: CosmosEvent): Pro
return;
}
const { amount, denom, receiver, sender } = JSON.parse(packetDataAttr.value);
const destinationChannel = packetDstChannelAttr.value;

const txns = block.txs;
const ibcTransaction = txns.find(
(txn) =>
txn.events.find(
(event) =>
event.type === EVENT_TYPES.MESSAGE &&
event.attributes.find(
(attribute) => attribute.key === ACTION_KEY && attribute.value === IBC_MESSAGE_RECEIVE_PACKET_VALUE,
),
) &&
txn.events.find(
(event) =>
event.type === EVENT_TYPES.FUNGIBLE_TOKEN_PACKET &&
event.attributes.find((attribute) => attribute.key === SENDER_KEY)?.value === b64encode(sender) &&
event.attributes.find((attribute) => attribute.key === RECEIVER_KEY)?.value === b64encode(receiver),
),
);
const transferEvents = ibcTransaction?.events.filter((event) => event.type === EVENT_TYPES.TRANSFER);
const [, , denomUnit] = denom.split('/')
const escrowTransaction = transferEvents
?.reverse()
.find(
(event) =>
event.attributes.find((attribute) => attribute.key === RECEPIENT_KEY)?.value === b64encode(receiver) &&
event.attributes.find((attribute) => attribute.key === AMOUNT_KEY)?.value === b64encode(amount + denomUnit),
);
const encodedEscrowAddress = escrowTransaction?.attributes.find(
(attribute) => attribute.key === SENDER_KEY,
)?.value;
const escrowAddress = encodedEscrowAddress ? b64decode(encodedEscrowAddress) : null;

if (!escrowAddress) {
logger.error(`No escrow address found for ${packetDstChannelAttr.value} at block height ${block.header.height}`);
return;
}

const ibcChannel = await IBCChannel.get(packetDstChannelAttr.value);
if (ibcChannel && ibcChannel.escrowAddress !== escrowAddress) {
throw new Error(`Escrow address does not match that of ${packetDstChannelAttr.value}`);
}
saveIbcChannel(destinationChannel);

const transferRecord = new IBCTransfer(
`${block.block.id}-${packetDstChannelAttr.value}`,
tx.hash,
block.header.time as any,
BigInt(block.header.height),
packetDstChannelAttr.value,
destinationChannel,
sender,
receiver,
denom,
amount,
TransferType.RECEIVE,
);
transferRecord.save();

if (!ibcChannel) {
const channelRecord = new IBCChannel(
packetDstChannelAttr.value,
packetDstChannelAttr.value,
escrowAddress,
);
channelRecord.save();
}
}


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

Expand Down
13 changes: 13 additions & 0 deletions src/mappings/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { bech32 } from "bech32";
import sha256 from "js-sha256";

export function extractBrand(str: string): string {
return str.replace("Alleged: ", "").replace(" brand", "");
}
Expand Down Expand Up @@ -95,3 +98,13 @@ export function dateToDayKey(timestamp: any): number {
const day = date.getUTCDate().toString().padStart(2, "0");
return parseInt(`${year}${month}${day}`);
}

export const getEscrowAddress = (port: string, channel: string) => {
const version = "ics20-1";
const chainPrefix = "agoric";
const stringtoSha = Buffer.from([...Buffer.from(version), 0, ...Buffer.from(`${port}/${channel}`)]);
const shaHash = sha256.sha256.array(stringtoSha.toString());
const bechWords = bech32.toWords(shaHash.slice(0, 20));
const address = bech32.encode(chainPrefix, bechWords);
return address;
};

0 comments on commit 63a185a

Please sign in to comment.