Skip to content

Commit

Permalink
[MilkmApp] Update ponder for new chains and add token info (#535)
Browse files Browse the repository at this point in the history
* refactor: update gql for new entities

* chore: fetch token info for pending transactions

* chore: run lint
  • Loading branch information
yvesfracari authored Dec 15, 2023
1 parent 435bd65 commit 8afd633
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export function CancelButton({
({
type: TRANSACTION_TYPES.MILKMAN_CANCEL,
contractAddress: order.orderEvent.orderContract,
tokenAddressToSell: order.orderEvent.tokenIn?.id,
tokenAddressToBuy: order.orderEvent.tokenOut?.id,
tokenAddressToSell: order.orderEvent.tokenIn?.address,
tokenAddressToBuy: order.orderEvent.tokenOut?.address,
toAddress: order.orderEvent.to,
amount: BigInt(order.orderEvent.tokenAmountIn),
priceChecker: order.orderEvent.priceChecker,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export function TableRowOrder({
order.tokenIn?.decimals ||
cowTokenList.find(
(token) =>
token.address == order.tokenIn?.id && token.chainId == order.chainId,
token.address == order.tokenIn?.address &&
token.chainId == order.chainId,
)?.decimals ||
1;
const tokenInAmount = formatUnits(order.tokenAmountIn, tokenInDecimals);
Expand All @@ -53,15 +54,15 @@ export function TableRowOrder({
<Table.BodyCell />
<Table.BodyCell>
<TokenInfo
id={order.tokenIn?.id}
id={order.tokenIn?.address}
symbol={order.tokenIn?.symbol}
chainId={order.chainId}
amount={tokenInAmount}
/>
</Table.BodyCell>
<Table.BodyCell>
<TokenInfo
id={order.tokenOut?.id}
id={order.tokenOut?.address}
symbol={order.tokenOut?.symbol}
chainId={order.chainId}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,21 +104,21 @@ export function TableRowTransaction({

const equalTokensIn = transaction.orders.every(
(order) =>
order.orderEvent.tokenIn?.id ==
transaction.orders[0].orderEvent.tokenIn?.id,
order.orderEvent.tokenIn?.address ==
transaction.orders[0].orderEvent.tokenIn?.address,
);

const equalTokensOut = transaction.orders.every(
(order) =>
order.orderEvent.tokenOut?.id ==
transaction.orders[0].orderEvent.tokenOut?.id,
order.orderEvent.tokenOut?.address ==
transaction.orders[0].orderEvent.tokenOut?.address,
);

const decimalsTokenIn =
transaction.orders[0].orderEvent.tokenIn?.decimals ||
cowTokenList.find(
(token) =>
token.address == transaction.orders[0].orderEvent.tokenIn?.id &&
token.address == transaction.orders[0].orderEvent.tokenIn?.address &&
token.chainId == transaction.orders[0].orderEvent.chainId,
)?.decimals ||
1;
Expand Down Expand Up @@ -151,7 +151,7 @@ export function TableRowTransaction({
</Table.BodyCell>
<Table.BodyCell>
<TokenInfo
id={transaction.orders[0].orderEvent.tokenIn?.id}
id={transaction.orders[0].orderEvent.tokenIn?.address}
symbol={
equalTokensIn
? transaction.orders[0].orderEvent.tokenIn?.symbol
Expand All @@ -163,7 +163,7 @@ export function TableRowTransaction({
</Table.BodyCell>
<Table.BodyCell>
<TokenInfo
id={transaction.orders[0].orderEvent.tokenOut?.id}
id={transaction.orders[0].orderEvent.tokenOut?.address}
symbol={
equalTokensOut
? transaction.orders[0].orderEvent.tokenOut?.symbol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ export function TokenInfo({
</div>
</div>
</div>
{symbol ?? truncateAddress(id)}{" "}
{amount && `(${formatNumber(amount, 2, "decimal", "compact", 0.001)})`}
{symbol ? symbol : truncateAddress(id)}{" "}
{amount && `(${formatNumber(amount, 4, "decimal", "compact", 0.001)})`}
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ export function TransactionInfo({
<div className="text-white">
<div className="font-semibold text-2xl flex justify-between">
Price Checker Data -{" "}
{order.tokenIn?.symbol || truncateAddress(order.tokenIn?.id)} for{" "}
{order.tokenOut?.symbol || truncateAddress(order.tokenOut?.id)}
{order.tokenIn?.symbol || truncateAddress(order.tokenIn?.address)} for{" "}
{order.tokenOut?.symbol || truncateAddress(order.tokenOut?.address)}
</div>
<hr className="mb-2" />
<div className="flex flex-col">
Expand Down
129 changes: 92 additions & 37 deletions apps/cow-tools/src/hooks/useUserMilkmanTransactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import {
getTransactionDetails,
getTransactionQueue,
Transaction,
TransactionDetails,
} from "@safe-global/safe-gateway-typescript-sdk";
import { erc20ABI } from "@wagmi/core";
import { gql } from "graphql-tag";
import { useEffect, useState } from "react";
import { PublicClient } from "viem";

import { fetchTokenInfo } from "#/lib/fetchTokenInfo";
import { AllTransactionFromUserQuery } from "#/lib/gql/generated";
import { milkmanSubgraph } from "#/lib/gql/sdk";
import { MILKMAN_ADDRESS } from "#/lib/transactionFactory";
Expand All @@ -29,20 +31,19 @@ gql(`
swaps {
id
chainId
transactionHash
tokenAmountIn
priceChecker
orderContract
priceCheckerData
to
tokenIn {
id
address
name
symbol
decimals
}
tokenOut {
id
address
name
symbol
decimals
Expand Down Expand Up @@ -114,7 +115,7 @@ async function getProcessedMilkmanTransactions({
const publicClient = publicClientsFromIds[chainId as ChainId];

const { users } = await milkmanSubgraph.AllTransactionFromUser({
user: address,
user: `${address}-${chainId}`,
});

const swapsLenByTransaction = users[0]?.transactions.map(
Expand All @@ -130,7 +131,7 @@ async function getProcessedMilkmanTransactions({
);

const tokenAddressesByTransactions = users[0]?.transactions.map(
(transaction) => transaction.swaps.map((swap) => swap.tokenIn?.id),
(transaction) => transaction.swaps.map((swap) => swap.tokenIn?.address),
) as (Address | undefined)[][];

const tokenAddressesBySwap = ([] as (Address | undefined)[]).concat(
Expand Down Expand Up @@ -185,6 +186,31 @@ async function getProcessedMilkmanTransactions({
);
}

async function fetchToken(tokenAddress: Address, chainId: ChainId) {
const [symbol, name, decimals] = await Promise.all([
fetchTokenInfo<string>(tokenAddress, chainId, "symbol").catch(() => ""),
fetchTokenInfo<string>(tokenAddress, chainId, "name").catch(() => ""),
fetchTokenInfo<number>(tokenAddress, chainId, "decimals").catch(() => 1),
]);

return {
address: tokenAddress,
symbol,
name,
decimals,
};
}

function getMilkmanTransactionsFromTransactionsDetails(
transactionDetails: TransactionDetails,
) {
return (
transactionDetails.txData?.dataDecoded?.parameters?.[0].valueDecoded?.filter(
(value) => value.to?.toLowerCase() == MILKMAN_ADDRESS.toLowerCase(),
) || []
);
}

async function getQueuedMilkmanTransactions({
chainId,
address,
Expand All @@ -209,39 +235,68 @@ async function getQueuedMilkmanTransactions({
),
);

return queuedMilkmanTransactionQueueDetails.map((transactionDetails) => {
const milkmanTransactions =
transactionDetails.txData?.dataDecoded?.parameters?.[0].valueDecoded?.filter(
(value) => value.to?.toLowerCase() == MILKMAN_ADDRESS.toLowerCase(),
);
const [tokensIn, tokensOut] = await Promise.all(
[1, 2].map((index) =>
Promise.all(
queuedMilkmanTransactionQueueDetails.map((transactionDetails) =>
Promise.all(
getMilkmanTransactionsFromTransactionsDetails(
transactionDetails,
).map((milkmanTransaction) =>
fetchToken(
milkmanTransaction.dataDecoded?.parameters?.[index]
.value as Address,
Number(chainId) as ChainId,
),
),
),
),
),
),
);

return {
id: transactionDetails.txId,
blockTimestamp: 0,
processed: false,
orders: milkmanTransactions?.map((milkmanTransaction) => ({
cowOrders: [],
hasToken: false,
orderEvent: {
chainId: Number(chainId),
tokenAmountIn: milkmanTransaction.dataDecoded?.parameters?.[0].value,
tokenIn: {
id: milkmanTransaction.dataDecoded?.parameters?.[1].value,
},
tokenOut: {
id: milkmanTransaction.dataDecoded?.parameters?.[2].value,
},
to: milkmanTransaction.dataDecoded?.parameters?.[3].value,
priceChecker: milkmanTransaction.dataDecoded?.parameters?.[4].value,
priceCheckerData:
milkmanTransaction.dataDecoded?.parameters?.[5].value,
id: "",
transactionHash: "",
orderContract: "",
},
})) as IMilkmanOrder[],
};
});
return queuedMilkmanTransactionQueueDetails.map(
(transactionDetails, transactionIndex) => {
const milkmanTransactions =
getMilkmanTransactionsFromTransactionsDetails(transactionDetails);

return {
id: transactionDetails.txId,
blockTimestamp: 0,
processed: false,
orders: milkmanTransactions?.map((milkmanTransaction, milkmanIndex) => {
// const [tokenIn, tokenOut] = await Promise.all([
// fetchToken(
// milkmanTransaction.dataDecoded?.parameters?.[1].value as Address,
// Number(chainId) as ChainId
// ),
// fetchToken(
// milkmanTransaction.dataDecoded?.parameters?.[2].value as Address,
// Number(chainId) as ChainId
// ),
// ]);
return {
cowOrders: [],
hasToken: false,
orderEvent: {
chainId: Number(chainId),
tokenAmountIn:
milkmanTransaction.dataDecoded?.parameters?.[0].value,
tokenIn: tokensIn[transactionIndex][milkmanIndex],
tokenOut: tokensOut[transactionIndex][milkmanIndex],
to: milkmanTransaction.dataDecoded?.parameters?.[3].value,
priceChecker:
milkmanTransaction.dataDecoded?.parameters?.[4].value,
priceCheckerData:
milkmanTransaction.dataDecoded?.parameters?.[5].value,
id: "",
orderContract: "",
},
};
}) as IMilkmanOrder[],
};
},
);
}

export function useUserMilkmanTransactions() {
Expand Down
24 changes: 24 additions & 0 deletions apps/cow-tools/src/lib/fetchTokenInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Address } from "@bleu-fi/utils";

import { ChainId, publicClientsFromIds } from "#/utils/chainsPublicClients";
import { erc20ABI } from "#/wagmi";

export function fetchTokenInfo<T>(
tokenAddress: Address,
chainId: ChainId,
info:
| "symbol"
| "name"
| "decimals"
| "allowance"
| "balanceOf"
| "totalSupply",
) {
const publicClient = publicClientsFromIds[chainId as ChainId];

return publicClient.readContract({
address: tokenAddress,
abi: erc20ABI,
functionName: info,
}) as Promise<T>;
}
Loading

0 comments on commit 8afd633

Please sign in to comment.