Skip to content

Commit

Permalink
refactor: wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
yongenaelf committed Jul 25, 2024
1 parent 7e0b8e7 commit b4dce74
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 127 deletions.
30 changes: 14 additions & 16 deletions components/workspace/cli.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,15 @@

import { build } from "@/data/build";
import { db } from "@/data/db";
import {
getProposalInfo,
useDeploy,
useLogs,
useTransactionResult,
} from "@/data/wallet";
import { useWallet } from "@/data/wallet";
import { useTheme } from "next-themes";
import { useParams } from "next/navigation";
import { ReactTerminal } from "react-terminal";
import { z } from "zod";

export default function Cli() {
const { id } = useParams();
const deploy = useDeploy();
const getResult = useTransactionResult();
const getLogs = useLogs();
const wallet = useWallet();
const commands = {
help: () => (
<div>
Expand Down Expand Up @@ -54,25 +47,30 @@ export default function Cli() {
if (typeof id !== "string") return "Workspace id not found.";
const { dll } = (await db.workspaces.get(id)) || {};
if (!dll) return "Contract not built. Please build first.";
const { TransactionId } = await deploy(dll);
if (!wallet) return "Wallet not ready.";
try {
const result: { TransactionId: string; Status: string } =
await getResult(TransactionId);
await wallet.faucet();
} catch (err) {}
const { TransactionId } = await wallet.deploy(dll);
try {
const result = await wallet.getTxResult(TransactionId);
return `TransactionId: ${TransactionId}, Status: ${result.Status}`;
} catch (err) {
return JSON.stringify(err, undefined, 2);
}
},
check: async (id: string) => {
if (!id) return `Please enter the Transaction ID.`;
if (!wallet) return "Wallet not ready.";
try {
const result = await getResult(id);
const logs = await getLogs(id);
const result = await wallet.getTxResult(id);
const logs = await wallet.getLogs(id);
const { data } = z.object({ proposalId: z.string() }).safeParse(logs);
const proposalInfo = await getProposalInfo(data?.proposalId);
if (!data?.proposalId) return "Missing proposalId.";
const proposalInfo = await wallet.getProposalInfo(data?.proposalId);
const releasedTxId = proposalInfo?.data.proposal.releasedTxId;
const releasedTxLogs = releasedTxId
? await getLogs(releasedTxId)
? await wallet.getLogs(releasedTxId)
: undefined;
const { data: contractAddressData } = z
.object({ address: z.string() })
Expand Down
190 changes: 79 additions & 111 deletions data/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,142 +32,110 @@ export function useWallet() {

if (!privateKey) return;

const wallet = AElf.wallet.getWalletByPrivateKey(privateKey);

return wallet;
return new Wallet(privateKey);
}

function useChainStatus() {
const { data } = useSWR("chainstatus", async () => {
return await aelf.chain.getChainStatus();
});
class Wallet {
privateKey;
wallet;
cached: Record<string, any> = {};

return data as { GenesisContractAddress: string };
}
constructor(privateKey: string) {
this.privateKey = privateKey;
this.wallet = AElf.wallet.getWalletByPrivateKey(privateKey);
}

function useContract(address: string) {
const wallet = useWallet();
const { data } = useSWR(
wallet && address ? `contract-${address}` : null,
async () => {
return await aelf.chain.contractAt(address, wallet);
}
);
async faucet() {
const res = await fetch(
`https://faucet.aelf.dev/api/claim?walletAddress=${this.wallet.address}`,
{ method: "POST" }
);

return data;
}
const data = await res.json();
console.log(data);
}

function useContractAddressByName(name: string) {
const chainStatus = useChainStatus();
const genesisContract = useContract(chainStatus.GenesisContractAddress);
private async getChainStatus() {
return await aelf.chain.getChainStatus();
}

const { data } = useSWR(
genesisContract ? `${name}-address` : null,
async () => {
return await genesisContract.GetContractAddressByName.call(
AElf.utils.sha256(name)
);
}
);
private getContract(address: string) {
return aelf.chain.contractAt(address, this.wallet);
}

return data;
}
private async getGenesisContract() {
const chainStatus = await this.getChainStatus();
return await this.getContract(chainStatus.GenesisContractAddress);
}

function useTokenContractAddress() {
return useContractAddressByName(`AElf.ContractNames.Token`);
}
private async getContractAddressByName(name: string) {
const genesisContract = await this.getGenesisContract();
return await genesisContract.GetContractAddressByName.call(
AElf.utils.sha256(name)
);
}

export function useTokenContract() {
const tokenContractAddress = useTokenContractAddress();
return useContract(tokenContractAddress);
}
private async getTokenContractAddress() {
return await this.getContractAddressByName(`AElf.ContractNames.Token`);
}

function useBalance() {
const tokenContract = useTokenContract();
const wallet = useWallet();
const { data } = useSWR(
tokenContract && wallet ? `balance` : null,
async () => {
return await tokenContract.GetBalance.call({
symbol: "ELF",
owner: wallet.address,
});
}
);
private async getTokenContract() {
const tokenContractAddress = await this.getTokenContractAddress();

return data as {
symbol: string;
owner: string;
balance: string;
};
}
return this.getContract(tokenContractAddress);
}

export function useBalanceInELF() {
const balance = useBalance();
return new BigNumber(balance.balance).dividedBy(10 ** 8).toFixed(5);
}
async getBalance() {
const tokenContract = await this.getTokenContract();
const res = await tokenContract.GetBalance.call({
symbol: "ELF",
owner: this.wallet.address,
});

function useGenesisContract() {
const chainstatus = useChainStatus();
return useContract(chainstatus?.GenesisContractAddress);
}
return new BigNumber(res.balance).dividedBy(10 ** 8).toFixed(5);
}

export function useDeploy() {
const genesisContract = useGenesisContract();
async deploy(code: string): Promise<{ TransactionId: string }> {
const genesisContract = await this.getGenesisContract();

const deploy = async (code: string) => {
return (await genesisContract.DeployUserSmartContract({
return await genesisContract.DeployUserSmartContract({
category: 0,
code,
})) as { TransactionId: string };
};

return deploy;
}
});
}

export function useTransactionResult() {
return async (id: string) => {
async getTxResult(
id: string
): Promise<{ TransactionId: string; Status: string }> {
return await aelf.chain.getTxResult(id);
};
}
}

let cached: Record<string, any> = {};
private async getProto(address: string) {
const key = aelf.currentProvider.host + "_" + address;
if (!this.cached[key])
this.cached[key] = await aelf.chain.getContractFileDescriptorSet(address);
return AElf.pbjs.Root.fromDescriptor(this.cached[key]);
}

async function getProto(address: string) {
const key = aelf.currentProvider.host + "_" + address;
if (!cached[key])
cached[key] = await aelf.chain.getContractFileDescriptorSet(address);
return AElf.pbjs.Root.fromDescriptor(cached[key]);
}
async getLogs(txId: string) {
const txResult = await aelf.chain.getTxResult(txId);

export function useLogs() {
return async (txId: string) => {
try {
const txResult = await aelf.chain.getTxResult(txId);
const services = await Promise.all(
txResult.Logs.map(
async ({ Address }: { Address: string }) => await this.getProto(Address)
)
);

const deserializeLogs = async () => {
const services = await Promise.all(
txResult.Logs.map(
async ({ Address }: { Address: string }) => await getProto(Address)
)
);
const deserializedLogs: Array<{ proposalId: string }> =
await deserializeLog(txResult.Logs, services);

const deserializedLogs: Array<{ proposalId: string }> =
await deserializeLog(txResult.Logs, services);
return deserializedLogs.reduce((acc, cur) => ({ ...acc, ...cur }), {});
}

return deserializedLogs.reduce((acc, cur) => ({ ...acc, ...cur }), {});
};
async getProposalInfo(proposalId: string) {
const res = await fetch(`/api/get-proposal-info?id=${proposalId}`);
const data: ProposalInfo = await res.json();

return await deserializeLogs();
} catch (err: unknown) {
return err;
}
};
return data;
}
}

export async function getProposalInfo(proposalId?: string) {
const res = await fetch(`/api/get-proposal-info?id=${proposalId}`);
const data: ProposalInfo = await res.json();

return data;
}

0 comments on commit b4dce74

Please sign in to comment.