Updated code to fetch available offers using subgraph and multicall.

This commit is contained in:
Filipe Soccol 2025-06-06 17:38:00 -03:00
parent 8a1dab4764
commit fa2def812c
6 changed files with 274 additions and 226 deletions

View File

@ -26,7 +26,7 @@
"ethers": "^6.13.4", "ethers": "^6.13.4",
"marked": "^4.2.12", "marked": "^4.2.12",
"qrcode": "^1.5.1", "qrcode": "^1.5.1",
"viem": "2.19.0", "viem": "^2.30.6",
"vite-svg-loader": "^5.1.0", "vite-svg-loader": "^5.1.0",
"vue": "^3.2.41", "vue": "^3.2.41",
"vue-markdown": "^2.2.4", "vue-markdown": "^2.2.4",

View File

@ -36,7 +36,7 @@ export const getTokenAddress = (
export const getP2PixAddress = (network?: NetworkEnum): string => { export const getP2PixAddress = (network?: NetworkEnum): string => {
const user = useUser(); const user = useUser();
const possibleP2PixAddresses: { [key in NetworkEnum]: string } = { const possibleP2PixAddresses: { [key in NetworkEnum]: string } = {
[NetworkEnum.sepolia]: "0x2414817FF64A114d91eCFA16a834d3fCf69103d4", [NetworkEnum.sepolia]: "0xb7cD135F5eFD9760981e02E2a898790b688939fe",
[NetworkEnum.rootstock]: "0x98ba35eb14b38D6Aa709338283af3e922476dE34", [NetworkEnum.rootstock]: "0x98ba35eb14b38D6Aa709338283af3e922476dE34",
}; };

View File

@ -1,16 +1,10 @@
import { useUser } from "@/composables/useUser"; import { useUser } from "@/composables/useUser";
import { import { formatEther, toHex, type PublicClient } from "viem";
formatEther,
decodeEventLog,
parseAbi,
toHex,
type PublicClient,
} from "viem";
import p2pix from "@/utils/smart_contract_files/P2PIX.json"; import p2pix from "@/utils/smart_contract_files/P2PIX.json";
import { getContract } from "./provider"; import { getContract } from "./provider";
import type { ValidDeposit } from "@/model/ValidDeposit"; import type { ValidDeposit } from "@/model/ValidDeposit";
import { getTokenAddress } from "./addresses"; import { getP2PixAddress, getTokenAddress } from "./addresses";
import { NetworkEnum } from "@/model/NetworkEnum"; import { NetworkEnum } from "@/model/NetworkEnum";
import type { UnreleasedLock } from "@/model/UnreleasedLock"; import type { UnreleasedLock } from "@/model/UnreleasedLock";
import type { Pix } from "@/model/Pix"; import type { Pix } from "@/model/Pix";
@ -76,58 +70,80 @@ const getValidDeposits = async (
({ address, abi, client } = await getContract(true)); ({ address, abi, client } = await getContract(true));
} }
const depositLogs = await client.getLogs({ if (network === NetworkEnum.rootstock) return [];
address,
event: parseAbi([ const body = {
"event DepositAdded(address indexed seller, address token, uint256 amount)", query: `
])[0], {
fromBlock: 0n, depositAddeds(where: { token: "${token}" }) {
toBlock: "latest", seller
}); amount
blockTimestamp
blockNumber
}
}
`,
};
const depositLogs = await fetch(
"https://subgraph.satsuma-prod.com/0c3d7b832269/gavins-team--383150/p2pix/version/v0.0.2/api",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}
);
// remove doubles from sellers list
const depositData = await depositLogs.json();
const depositAddeds = depositData.data.depositAddeds;
const uniqueSellers = depositAddeds.reduce(
(acc: Record<string, boolean>, deposit: any) => {
acc[deposit.seller] = true;
return acc;
},
{} as Record<string, boolean>
);
if (!contractInfo) { if (!contractInfo) {
// Get metamask provider contract // Get metamask provider contract
({ address, abi, client } = await getContract()); ({ abi, client } = await getContract(true));
} }
const depositList: { [key: string]: ValidDeposit } = {}; const depositList: { [key: string]: ValidDeposit } = {};
for (const log of depositLogs) { const sellersList = Object.keys(uniqueSellers);
try { // Use multicall to batch all getBalance requests
const decoded = decodeEventLog({ const balanceCalls = sellersList.map((seller) => ({
abi, address: getP2PixAddress(network),
data: log.data, abi,
topics: log.topics, functionName: "getBalance",
}); args: [seller, token],
}));
// Get liquidity only for the selected token const balanceResults = await client.multicall({
if (decoded?.args.token.toLowerCase() !== token.toLowerCase()) continue; contracts: balanceCalls as any,
});
const mappedBalance = await client.readContract({ // Process results into the depositList
address, sellersList.forEach((seller, index) => {
abi, const mappedBalance = balanceResults[index];
functionName: "getBalance",
args: [decoded.args.seller, token],
});
let validDeposit: ValidDeposit | null = null; if (!mappedBalance.error && mappedBalance.result) {
const validDeposit: ValidDeposit = {
token: token,
blockNumber: 0,
remaining: Number(formatEther(mappedBalance.result as bigint)),
seller: seller,
network,
pixKey: "",
};
if (mappedBalance) { depositList[seller + token] = validDeposit;
validDeposit = {
token: token,
blockNumber: Number(log.blockNumber),
remaining: Number(formatEther(mappedBalance)),
seller: decoded.args.seller,
network,
pixKey: "",
};
}
if (validDeposit) depositList[decoded.args.seller + token] = validDeposit;
} catch (error) {
console.error("Error decoding log", error);
} }
} });
return Object.values(depositList); return Object.values(depositList);
}; };

View File

@ -1,14 +1,20 @@
import p2pix from "@/utils/smart_contract_files/P2PIX.json"; import p2pix from "@/utils/smart_contract_files/P2PIX.json";
import { updateWalletStatus } from "./wallet"; import { updateWalletStatus } from "./wallet";
import { getProviderUrl, getP2PixAddress } from "./addresses"; import { getProviderUrl, getP2PixAddress } from "./addresses";
import { createPublicClient, createWalletClient, custom, http } from "viem"; import {
createPublicClient,
createWalletClient,
custom,
http,
PublicClient,
} from "viem";
import { sepolia, rootstock } from "viem/chains"; import { sepolia, rootstock } from "viem/chains";
import { useUser } from "@/composables/useUser"; import { useUser } from "@/composables/useUser";
let publicClient = null; let publicClient = null;
let walletClient = null; let walletClient = null;
const getPublicClient = (onlyRpcProvider = false) => { const getPublicClient: PublicClient = (onlyRpcProvider = false) => {
if (onlyRpcProvider) { if (onlyRpcProvider) {
const user = useUser(); const user = useUser();
const rpcUrl = getProviderUrl(); const rpcUrl = getProviderUrl();

View File

@ -39,6 +39,9 @@ export default defineConfig({
"viem/errors": fileURLToPath( "viem/errors": fileURLToPath(
new URL("./node_modules/viem/errors", import.meta.url) new URL("./node_modules/viem/errors", import.meta.url)
), ),
"../../errors/unit.js": fileURLToPath(
new URL("./node_modules/viem/errors/unit.js", import.meta.url)
),
}, },
}, },
}); });

371
yarn.lock

File diff suppressed because it is too large Load Diff