Update all to useUSer composabe. Still some bugs to resolve.

This commit is contained in:
Filipe Soccol
2025-04-01 12:04:24 -03:00
parent e93cac6086
commit 9fa2b34a5d
26 changed files with 495 additions and 454 deletions

View File

@@ -8,7 +8,7 @@ import {
import { setActivePinia, createPinia } from "pinia";
import { NetworkEnum, TokenEnum } from "@/model/NetworkEnum";
import { useViemStore } from "@/store/viem";
import { useUser } from "@/composables/useUser";
describe("addresses.ts types", () => {
it("My addresses.ts types work properly", () => {
@@ -25,16 +25,16 @@ describe("addresses.ts functions", () => {
});
it("getTokenAddress Ethereum", () => {
const etherStore = useViemStore();
etherStore.setNetworkId(NetworkEnum.sepolia);
const user = useUser();
user.setNetworkId(NetworkEnum.sepolia);
expect(getTokenAddress(TokenEnum.BRZ)).toBe(
"0x4A2886EAEc931e04297ed336Cc55c4eb7C75BA00"
);
});
it("getTokenAddress Rootstock", () => {
const etherStore = useViemStore();
etherStore.setNetworkId(NetworkEnum.rootstock);
const user = useUser();
user.setNetworkId(NetworkEnum.rootstock);
expect(getTokenAddress(TokenEnum.BRZ)).toBe(
"0xfE841c74250e57640390f46d914C88d22C51e82e"
);
@@ -47,16 +47,16 @@ describe("addresses.ts functions", () => {
});
it("getP2PixAddress Ethereum", () => {
const etherStore = useViemStore();
etherStore.setNetworkId(NetworkEnum.sepolia);
const user = useUser();
user.setNetworkId(NetworkEnum.sepolia);
expect(getP2PixAddress()).toBe(
"0x2414817FF64A114d91eCFA16a834d3fCf69103d4"
);
});
it("getP2PixAddress Rootstock", () => {
const etherStore = useViemStore();
etherStore.setNetworkId(NetworkEnum.rootstock);
const user = useUser();
user.setNetworkId(NetworkEnum.rootstock);
expect(getP2PixAddress()).toBe(
"0x98ba35eb14b38D6Aa709338283af3e922476dE34"
);
@@ -69,14 +69,14 @@ describe("addresses.ts functions", () => {
});
it("getProviderUrl Ethereum", () => {
const etherStore = useViemStore();
etherStore.setNetworkId(NetworkEnum.sepolia);
const user = useUser();
user.setNetworkId(NetworkEnum.sepolia);
expect(getProviderUrl()).toBe(import.meta.env.VITE_GOERLI_API_URL);
});
it("getProviderUrl Rootstock", () => {
const etherStore = useViemStore();
etherStore.setNetworkId(NetworkEnum.rootstock);
const user = useUser();
user.setNetworkId(NetworkEnum.rootstock);
expect(getProviderUrl()).toBe(import.meta.env.VITE_ROOTSTOCK_API_URL);
});
@@ -85,8 +85,8 @@ describe("addresses.ts functions", () => {
});
it("isPossibleNetwork Returns", () => {
const etherStore = useViemStore();
etherStore.setNetworkId(NetworkEnum.sepolia);
const user = useUser();
user.setNetworkId(NetworkEnum.sepolia);
expect(isPossibleNetwork(0x5 as NetworkEnum)).toBe(true);
expect(isPossibleNetwork(5 as NetworkEnum)).toBe(true);
expect(isPossibleNetwork(0x13881 as NetworkEnum)).toBe(true);

View File

@@ -1,4 +1,4 @@
import { useViemStore } from "@/store/viem";
import { useUser } from "@/composables/useUser";
import { NetworkEnum, TokenEnum } from "@/model/NetworkEnum";
import { createPublicClient, http } from "viem";
import { sepolia, rootstock } from "viem/chains";
@@ -15,8 +15,8 @@ const Tokens: { [key in NetworkEnum]: { [key in TokenEnum]: string } } = {
};
export const getTokenByAddress = (address: string) => {
const viemStore = useViemStore();
const networksTokens = Tokens[viemStore.networkName];
const user = useUser();
const networksTokens = Tokens[user.networkName.value];
for (const [token, tokenAddress] of Object.entries(networksTokens)) {
if (tokenAddress.toLowerCase() === address.toLowerCase()) {
return token;
@@ -29,28 +29,28 @@ export const getTokenAddress = (
token: TokenEnum,
network?: NetworkEnum
): string => {
const viemStore = useViemStore();
return Tokens[network ? network : viemStore.networkName][token];
const user = useUser();
return Tokens[network ? network : user.networkName.value][token];
};
export const getP2PixAddress = (network?: NetworkEnum): string => {
const viemStore = useViemStore();
const user = useUser();
const possibleP2PixAddresses: { [key in NetworkEnum]: string } = {
[NetworkEnum.sepolia]: "0x2414817FF64A114d91eCFA16a834d3fCf69103d4",
[NetworkEnum.rootstock]: "0x98ba35eb14b38D6Aa709338283af3e922476dE34",
};
return possibleP2PixAddresses[network ? network : viemStore.networkName];
return possibleP2PixAddresses[network ? network : user.networkName.value];
};
export const getProviderUrl = (network?: NetworkEnum): string => {
const viemStore = useViemStore();
const user = useUser();
const possibleProvidersUrls: { [key in NetworkEnum]: string } = {
[NetworkEnum.sepolia]: import.meta.env.VITE_SEPOLIA_API_URL,
[NetworkEnum.rootstock]: import.meta.env.VITE_RSK_API_URL,
};
return possibleProvidersUrls[network || viemStore.networkName];
return possibleProvidersUrls[network || user.networkName.value];
};
export const getProviderByNetwork = (network: NetworkEnum) => {

View File

@@ -1,141 +1,61 @@
import { getContract, getWalletClient } from "./provider";
import { getContract } from "./provider";
import { getTokenAddress } from "./addresses";
import { parseEther, stringToHex, toHex } from "viem";
import { parseEther } from "viem";
import type { TokenEnum } from "@/model/NetworkEnum";
import { createSolicitation } from "../utils/bbPay";
import type { Offer } from "../utils/bbPay";
const addLock = async (
sellerId: string,
token: string,
export const addLock = async (
sellerAddress: string,
tokenAddress: string,
amount: number
): Promise<string> => {
const { address, abi, client } = await getContract();
const walletClient = getWalletClient();
if (!walletClient) {
throw new Error("Wallet client not initialized");
}
const [account] = await walletClient.getAddresses();
const hash = await walletClient.writeContract({
const parsedAmount = parseEther(amount.toString());
const { request } = await client.simulateContract({
address,
abi,
functionName: 'lock',
args: [
sellerId,
token,
parseEther(String(amount)),
[],
[]
],
account
functionName: "addLock",
args: [sellerAddress, tokenAddress, parsedAmount],
});
const hash = await client.writeContract(request);
const receipt = await client.waitForTransactionReceipt({ hash });
const logs = receipt.logs;
// Extract the lockID from transaction logs
// This is a simplified approach - in production you'll want more robust log parsing
const lockId = logs[0].topics[2]; // Simplified - adjust based on actual event structure
const offer: Offer = {
amount,
lockId: String(lockId),
sellerId: sellerId,
};
await createSolicitation(offer);
return String(lockId);
return receipt.status ? receipt.logs[0].topics[2] : "";
};
const releaseLock = async (
pixKey: string,
amount: number,
e2eId: string,
lockId: string
): Promise<any> => {
const { address, abi, client } = await getContract();
const walletClient = getWalletClient();
if (!walletClient) {
throw new Error("Wallet client not initialized");
}
const [account] = await walletClient.getAddresses();
// In a real implementation, you would get this signature from your backend
// This is just a placeholder for the mock implementation
const signature = "0x1234567890";
const hash = await walletClient.writeContract({
address,
abi,
functionName: 'release',
args: [
BigInt(lockId),
toHex(e2eId, { size: 32 }),
signature
],
account
});
const receipt = await client.waitForTransactionReceipt({ hash });
return receipt;
};
const cancelDeposit = async (depositId: bigint): Promise<any> => {
const { address, abi, client } = await getContract();
const walletClient = getWalletClient();
if (!walletClient) {
throw new Error("Wallet client not initialized");
}
const [account] = await walletClient.getAddresses();
const hash = await walletClient.writeContract({
address,
abi,
functionName: 'cancelDeposit',
args: [depositId],
account
});
const receipt = await client.waitForTransactionReceipt({ hash });
return receipt;
};
const withdrawDeposit = async (
export const withdrawDeposit = async (
amount: string,
token: TokenEnum
): Promise<any> => {
): Promise<boolean> => {
const { address, abi, client } = await getContract();
const walletClient = getWalletClient();
if (!walletClient) {
throw new Error("Wallet client not initialized");
}
const [account] = await walletClient.getAddresses();
const hash = await walletClient.writeContract({
const tokenAddress = getTokenAddress(token);
const { request } = await client.simulateContract({
address,
abi,
functionName: 'withdraw',
args: [
getTokenAddress(token),
parseEther(String(amount)),
[]
],
account
functionName: "withdrawDeposit",
args: [tokenAddress, parseEther(amount)],
});
const hash = await client.writeContract(request);
const receipt = await client.waitForTransactionReceipt({ hash });
return receipt;
return receipt.status;
};
export { cancelDeposit, withdrawDeposit, addLock, releaseLock };
export const releaseLock = async (solicitation: any): Promise<any> => {
const { address, abi, client } = await getContract();
const { request } = await client.simulateContract({
address,
abi,
functionName: "releaseLock",
args: [solicitation.lockId, solicitation.e2eId],
});
const hash = await client.writeContract(request);
return client.waitForTransactionReceipt({ hash });
};

View File

@@ -1,4 +1,4 @@
import { useViemStore } from "@/store/viem";
import { useUser } from "@/composables/useUser";
import { formatEther, decodeEventLog, parseAbi, toHex, type PublicClient, type Address } from "viem";
import p2pix from "@/utils/smart_contract_files/P2PIX.json";
@@ -14,8 +14,8 @@ import type { UnreleasedLock } from "@/model/UnreleasedLock";
import type { Pix } from "@/model/Pix";
const getNetworksLiquidity = async (): Promise<void> => {
const viemStore = useViemStore();
viemStore.setLoadingNetworkLiquidity(true);
const user = useUser();
user.setLoadingNetworkLiquidity(true);
const depositLists: ValidDeposit[][] = [];
@@ -23,22 +23,16 @@ const getNetworksLiquidity = async (): Promise<void> => {
(v) => !isNaN(Number(v))
)) {
console.log("getNetworksLiquidity", network);
// Get public client for this network
const client = getProviderByNetwork(network as NetworkEnum);
const address = getP2PixAddress(network as NetworkEnum);
depositLists.push(
await getValidDeposits(
getTokenAddress(viemStore.selectedToken, network as NetworkEnum),
network as NetworkEnum,
{ client, address }
)
const deposits = await getValidDeposits(
getTokenAddress(user.selectedToken.value),
Number(network)
);
if (deposits) depositLists.push(deposits);
}
viemStore.setDepositsValidList(depositLists.flat());
viemStore.setLoadingNetworkLiquidity(false);
const allDeposits = depositLists.flat();
user.setDepositsValidList(allDeposits);
user.setLoadingNetworkLiquidity(false);
};
const getPixKey = async (seller: string, token: string): Promise<string> => {

View File

@@ -3,17 +3,17 @@ import { updateWalletStatus } from "./wallet";
import { getProviderUrl, getP2PixAddress } from "./addresses";
import { createPublicClient, createWalletClient, custom, http } from "viem";
import { sepolia, rootstock } from "viem/chains";
import { useViemStore } from "@/store/viem";
import { useUser } from "@/composables/useUser";
let publicClient = null;
let walletClient = null;
const getPublicClient = (onlyRpcProvider = false) => {
if (onlyRpcProvider) {
const viemStore = useViemStore();
const user = useUser();
const rpcUrl = getProviderUrl();
return createPublicClient({
chain: viemStore.networkName === sepolia.id ? sepolia : rootstock,
chain: Number(user.networkName.value) === sepolia.id ? sepolia : rootstock,
transport: http(rpcUrl)
});
}
@@ -28,24 +28,25 @@ const getContract = async (onlyRpcProvider = false) => {
const client = getPublicClient(onlyRpcProvider);
const address = getP2PixAddress();
const abi = p2pix.abi;
return { address, abi, client };
};
const connectProvider = async (p: any): Promise<void> => {
const viemStore = useViemStore();
const chain = viemStore.networkName === sepolia.id ? sepolia : rootstock;
console.log("Connecting to provider...");
const user = useUser();
const chain = Number(user.networkName.value) === sepolia.id ? sepolia : rootstock;
publicClient = createPublicClient({
chain,
transport: custom(p)
});
walletClient = createWalletClient({
chain,
transport: custom(p)
});
await updateWalletStatus();
};

View File

@@ -3,25 +3,25 @@ import { getTokenAddress, getP2PixAddress } from "./addresses";
import { parseEther, toHex } from "viem";
import mockToken from "../utils/smart_contract_files/MockToken.json";
import { useViemStore } from "@/store/viem";
import { useUser } from "@/composables/useUser";
import { createParticipant } from "@/utils/bbPay";
import type { Participant } from "@/utils/bbPay";
const approveTokens = async (participant: Participant): Promise<any> => {
const viemStore = useViemStore();
const user = useUser();
const publicClient = getPublicClient();
const walletClient = getWalletClient();
if (!publicClient || !walletClient) {
throw new Error("Clients not initialized");
}
viemStore.setSeller(participant);
user.setSeller(participant);
const [account] = await walletClient.getAddresses();
// Get token address
const tokenAddress = getTokenAddress(viemStore.selectedToken);
const tokenAddress = getTokenAddress(user.selectedToken.value);
// Check if the token is already approved
const allowance = await publicClient.readContract({
address: tokenAddress,
@@ -29,17 +29,17 @@ const approveTokens = async (participant: Participant): Promise<any> => {
functionName: 'allowance',
args: [account, getP2PixAddress()]
});
if (allowance < parseEther(participant.offer)) {
if (allowance < parseEther(participant.offer.toString())) {
// Approve tokens
const hash = await walletClient.writeContract({
address: tokenAddress,
abi: mockToken.abi,
functionName: 'approve',
args: [getP2PixAddress(), parseEther(participant.offer)],
args: [getP2PixAddress(), parseEther(participant.offer.toString())],
account
});
await publicClient.waitForTransactionReceipt({ hash });
return true;
}
@@ -49,17 +49,17 @@ const approveTokens = async (participant: Participant): Promise<any> => {
const addDeposit = async (): Promise<any> => {
const { address, abi, client } = await getContract();
const walletClient = getWalletClient();
const viemStore = useViemStore();
const user = useUser();
if (!walletClient) {
throw new Error("Wallet client not initialized");
}
const [account] = await walletClient.getAddresses();
const sellerId = await createParticipant(viemStore.seller);
viemStore.setSellerId(sellerId.id);
const sellerId = await createParticipant(user.seller.value);
user.setSellerId(sellerId.id);
const hash = await walletClient.writeContract({
address,
abi,
@@ -67,13 +67,13 @@ const addDeposit = async (): Promise<any> => {
args: [
sellerId.id,
toHex("", { size: 32 }),
getTokenAddress(viemStore.selectedToken),
parseEther(viemStore.seller.offer),
getTokenAddress(user.selectedToken.value),
parseEther(user.seller.value.offer),
true
],
account
});
const receipt = await client.waitForTransactionReceipt({ hash });
return receipt;
};

View File

@@ -5,7 +5,7 @@ import {
type Log,
parseAbi,
} from "viem";
import { useViemStore } from "@/store/viem";
import { useUser } from "@/composables/useUser";
import { getPublicClient, getWalletClient, getContract } from "./provider";
import { getTokenAddress, isPossibleNetwork } from "./addresses";
@@ -21,46 +21,31 @@ import type { UnreleasedLock } from "@/model/UnreleasedLock";
import type { Pix } from "@/model/Pix";
export const updateWalletStatus = async (): Promise<void> => {
const viemStore = useViemStore();
const user = useUser();
const publicClient = getPublicClient();
const walletClient = getWalletClient();
if (!publicClient || !walletClient) {
console.error("Client not initialized");
return;
}
const chainId = await publicClient.getChainId();
if (!isPossibleNetwork(Number(chainId))) {
window.alert("Invalid chain!:" + chainId);
return;
}
viemStore.setNetworkId(Number(chainId));
// Get account address
const [address] = await walletClient.getAddresses();
// Get token balance
const tokenAddress = getTokenAddress(viemStore.selectedToken);
const balanceResult = await publicClient.readContract({
address: tokenAddress,
abi: mockToken.abi,
functionName: 'balanceOf',
args: [address]
});
// Get balance
const [account] = await walletClient.getAddresses();
const balance = await publicClient.getBalance({ address: account });
viemStore.setBalance(formatEther(balanceResult));
viemStore.setWalletAddress(getAddress(address));
user.setWalletAddress(account);
user.setBalance(formatEther(balance));
};
export const listValidDepositTransactionsByWalletAddress = async (
walletAddress: string
): Promise<ValidDeposit[]> => {
const viemStore = useViemStore();
const user = useUser();
const walletDeposits = await getValidDeposits(
getTokenAddress(viemStore.selectedToken),
viemStore.networkName
getTokenAddress(user.selectedToken.value),
user.networkName.value
);
if (walletDeposits) {
return walletDeposits
@@ -96,12 +81,12 @@ const filterLockStatus = async (
data: transaction.data,
topics: transaction.topics,
});
if (!decoded || !decoded.args) continue;
// Type assertion to handle the args safely
const args = decoded.args as Record<string, any>;
const tx: WalletTransaction = {
token: args.token ? String(args.token) : "",
blockNumber: Number(transaction.blockNumber),
@@ -244,7 +229,7 @@ const listLockTransactionByWalletAddress = async (
});
return lockLogs
.sort((a:Log, b:Log) => {
.sort((a: Log, b: Log) => {
return Number(b.blockNumber) - Number(a.blockNumber);
})
.map((log: Log) => {
@@ -259,7 +244,7 @@ const listLockTransactionByWalletAddress = async (
return null;
}
})
.filter((decoded:any) => decoded !== null);
.filter((decoded: any) => decoded !== null);
};
const listLockTransactionBySellerAddress = async (
@@ -267,7 +252,7 @@ const listLockTransactionBySellerAddress = async (
) => {
const { address, abi, client } = await getContract(true);
console.log("Will get locks as seller", sellerAddress);
const lockLogs = await client.getLogs({
address,
event: parseAbi(['event LockAdded(address indexed buyer, uint256 indexed lockID, address seller, address token, uint256 amount)'])[0],
@@ -290,8 +275,8 @@ const listLockTransactionBySellerAddress = async (
})
.filter((decoded: any) => decoded !== null)
.filter(
(decoded:any) => decoded.args && decoded.args.seller &&
decoded.args.seller.toLowerCase() === sellerAddress.toLowerCase()
(decoded: any) => decoded.args && decoded.args.seller &&
decoded.args.seller.toLowerCase() === sellerAddress.toLowerCase()
);
};
@@ -304,25 +289,25 @@ export const checkUnreleasedLock = async (
};
const addedLocks = await listLockTransactionByWalletAddress(walletAddress);
if (!addedLocks.length) return undefined;
const lockIds = addedLocks.map((lock: any) => lock.args.lockID);
const lockStatus = await client.readContract({
address,
abi,
functionName: 'getLocksStatus',
args: [lockIds]
});
const unreleasedLockId = lockStatus[1].findIndex(
(status: number) => status == 1
);
if (unreleasedLockId !== -1) {
const lockID = lockStatus[0][unreleasedLockId];
const lock = await client.readContract({
address,
abi,
@@ -351,7 +336,7 @@ export const getActiveLockAmount = async (
if (!lockSeller.length) return 0;
const lockIds = lockSeller.map((lock: any) => lock.args.lockID);
const lockStatus = await client.readContract({
address,
abi,