Skip to content

Commit

Permalink
debug export balance from utxo to evm
Browse files Browse the repository at this point in the history
  • Loading branch information
frankcrypto committed Aug 20, 2024
1 parent 115e4a3 commit c0b6d24
Show file tree
Hide file tree
Showing 6 changed files with 413 additions and 86 deletions.
117 changes: 115 additions & 2 deletions packages/site/src/components/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,12 @@ export const AACard = () => {
const [address, setAddress] = useState('');
const [balance, setBalance] = useState('');
const [qngAddress, setQngAddress] = useState('');
const [qngBalance, setQngBalance] = useState('');
const [target, setTarget] = useState('');
const [txide, setTxid] = useState('');
const [idx, setIdx] = useState('');
const [fee, setFee] = useState('10000');
const [oneUtxo, setOneUtxo] = useState('');
const [ethAmount, setEthAmount] = useState('');

// const Hash160 = (pubHex: string): string => {
Expand All @@ -118,6 +123,13 @@ export const AACard = () => {
setAddress((await invokeSnap({ method: 'connect' })) as string);
setQngAddress((await invokeSnap({ method: 'connect_qng' })) as string);
setBalance((await invokeSnap({ method: 'balance' })) as string);
setQngBalance((await invokeSnap({ method: 'balance_qng' })) as string);
setOneUtxo(
(await invokeSnap({
method: 'getOneUtxo',
params: { utxoFrom: qngAddress },
})) as string,
);
} catch (er) {
console.error(er);
}
Expand All @@ -127,6 +139,13 @@ export const AACard = () => {
try {
setEOABalance((await invokeSnap({ method: 'balance_eoa' })) as string);
setBalance((await invokeSnap({ method: 'balance' })) as string);
setQngBalance((await invokeSnap({ method: 'balance_qng' })) as string);
setOneUtxo(
(await invokeSnap({
method: 'getOneUtxo',
params: { utxoFrom: qngAddress },
})) as string,
);
} catch (er) {
console.error(er);
}
Expand All @@ -140,6 +159,18 @@ export const AACard = () => {
setEthAmount(ev.currentTarget.value);
};

const handleTxidChange = (ev: React.FocusEvent<HTMLInputElement>) => {
setTxid(ev.currentTarget.value);
};

const handleIdxChange = (ev: React.FocusEvent<HTMLInputElement>) => {
setIdx(ev.currentTarget.value);
};

const handleFeeChange = (ev: React.FocusEvent<HTMLInputElement>) => {
setFee(ev.currentTarget.value);
};

const handleTransferFromAAClick = async () => {
if (!target || !ethAmount) {
// eslint-disable-next-line no-alert
Expand Down Expand Up @@ -173,7 +204,7 @@ export const AACard = () => {

try {
const ethValue = `${ethAmount}`;
const rawTx = (await invokeSnap({
const txid = (await invokeSnap({
method: 'utxoTransfer',
params: {
from: qngAddress,
Expand All @@ -183,12 +214,62 @@ export const AACard = () => {
})) as string;
// eslint-disable-next-line no-alert
alert(`tx sign succ`);
console.log(rawTx);
console.log(txid);
} catch (er) {
console.error(er);
}
};

const handleUtxoToEvmClick = async () => {
if (!txide || !idx) {
// eslint-disable-next-line no-alert
alert('enter txid and idx and fee.');
return;
}

const withWallet = false;
try {
const res = (await invokeSnap({
method: 'export',
params: {
txid: txide,
idx,
fee,
withWallet,
},
})) as string;
// eslint-disable-next-line no-alert
alert(`sign succ ${res}`);
console.log(res);
} catch (er) {
console.error(er);
}
};

const handleUtxoToEvmWithWalletClick = async () => {
if (!txide || !idx) {
// eslint-disable-next-line no-alert
alert('enter txid and idx and fee.');
return;
}
const withWallet = true;
try {
const res = (await invokeSnap({
method: 'export',
params: {
txid: txide,
idx,
fee,
withWallet,
},
})) as string;
// eslint-disable-next-line no-alert
alert(`sign succ ${res}`);
console.log(res);
} catch (er) {
console.error(er);
}
};
return (
<>
{!address && (
Expand All @@ -215,6 +296,7 @@ export const AACard = () => {
<CardWrapper fullWidth={true} disabled={false}>
<Title>Your Qng Account 🎉</Title>
<AAText>P2KH Address: {qngAddress}</AAText>
<AAText>Balance: {qngBalance}</AAText>
</CardWrapper>
<CardWrapper fullWidth={true} disabled={false}>
<Button onClick={handleReloadBalancesClick}>Reload Balances</Button>
Expand Down Expand Up @@ -258,6 +340,37 @@ export const AACard = () => {
Transfer from UTXO
</Button>
</CardWrapper>

<CardWrapper fullWidth={true} disabled={false}>
<Title>Transfer from Qng Account</Title>
<div>
<TargetInput
type="text"
placeholder="txid"
onChange={handleTxidChange}
/>
<AmountInput
type="number"
placeholder="idx"
onChange={handleIdxChange}
/>
<AmountInput
type="number"
placeholder="fee"
onChange={handleFeeChange}
/>
</div>
<Title>Available UTXO of the EoaAddress</Title>
<AAText> {oneUtxo} </AAText>
<Spacer />
<Button onClick={handleUtxoToEvmClick}>
Transfer from UTXO to EVM with {eoaAddress}
</Button>
<Spacer />
<Button onClick={handleUtxoToEvmWithWalletClick}>
Transfer from UTXO to EVM with {qngAddress}
</Button>
</CardWrapper>
</>
)}
</>
Expand Down
2 changes: 1 addition & 1 deletion packages/snap/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/template-snap-monorepo.git"
},
"source": {
"shasum": "X0E7Z4Xx8kFeadQjs1fMG9MNX51YoJSBtbUo+Ok+VJ8=",
"shasum": "cUuESUJvxaTB3CM5yTCgZYfD6R1mZzWVl08DxsyWJyA=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
9 changes: 8 additions & 1 deletion packages/snap/src/getAbstractAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,14 @@ const entryPointAddress = '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789';
// deployed by deterministic-deployment-proxy https://github.com/Arachnid/deterministic-deployment-proxy.git
const factoryAddress = '0x9406cc6185a346906296840746125a0e44976454';
// const paymasterUrl = ''; // Optional
const bundlerUrl = 'http://127.0.0.1:3000/rpc';

// ** server response header set "Access-Control-Allow-Origin": "null" **
export const proxyUrl = 'http://127.0.0.1:8081';
export const bundlerUrl = `${proxyUrl}/bundler`;
export const qngUrl = `${proxyUrl}/qng`;

// TODO crossQngUrl will be merged in bundlerUrl
export const crossQngUrl = `${proxyUrl}/export`;
export const getAbstractAccount = async (): Promise<SimpleAccountAPI> => {
const provider = new ethers.providers.Web3Provider(ethereum as any);
await provider.send('eth_requestAccounts', []);
Expand Down
42 changes: 41 additions & 1 deletion packages/snap/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ import { ethers } from 'ethers';

import { getAbstractAccount } from './getAbstractAccount';
import { getBalance } from './getBalance';
import { getQngAddress, qngTransfer } from './qng';
import {
getQngAddress,
qngTransfer,
getQngBalance,
ethSign,
walletSign,
getOneUtxo,
} from './qng';
import { transfer } from './transfer';
// export const changeNetwork = async () => {
// await ethereum.request({
Expand Down Expand Up @@ -47,6 +54,8 @@ export const onRpcRequest: OnRpcRequestHandler = async ({
return await getQngAddress();
case 'balance_eoa':
return await getBalance(await getEoaAddress());
case 'balance_qng':
return await getQngBalance();
case 'connect':
return await getAddress();
case 'balance':
Expand All @@ -63,6 +72,37 @@ export const onRpcRequest: OnRpcRequestHandler = async ({
[key: string]: string;
};
return await qngTransfer(from as string, to as string, amount as string);
case 'export':
// eslint-disable-next-line no-case-declarations
const { txid, idx, fee, withWallet } = request?.params as unknown as {
[key: string]: any;
};
if (!withWallet) {
return await ethSign(txid as string, idx as number, fee as number);
}
// eslint-disable-next-line no-case-declarations
const res = await snap.request({
method: 'snap_dialog',
params: {
type: 'confirmation',
content: panel([
text(`sign with 813 wallet`),
// eslint-disable-next-line no-template-curly-in-string, @typescript-eslint/restrict-template-expressions
text(`Sign Content\n txid:${txid} \nidx:${idx} \nfee:${fee}`),
text('Please Check the fee!'),
]),
},
});
if (!res) {
return '';
}
return walletSign(txid as string, idx as number, fee as number);
case 'getOneUtxo':
// eslint-disable-next-line no-case-declarations
const { utxoFrom } = request?.params as unknown as {
[key: string]: string;
};
return getOneUtxo(utxoFrom as string);
case 'hello':
return snap.request({
method: 'snap_dialog',
Expand Down
63 changes: 58 additions & 5 deletions packages/snap/src/qng.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { SLIP10Node } from '@metamask/key-tree';
import { ethers } from 'ethers';
import { ec, hash, address, networks } from 'qitmeerts';
import * as uint8arraytools from 'uint8array-tools';

import { qngTransferUtxo } from './qngweb3';

export const trimHexPrefix = (key: string) =>
key.startsWith('0x') ? key.substring(2) : key;
import {
qngTransferUtxo,
qngGetUTXOBalance,
transferUTXOToEvmWithEthSign,
getInputHash,
qngGetAvailableUtxos,
crossSendtoBunder,
handleSignStr,
trimHexPrefix,
} from './qngweb3';

export const CRYPTO_CURVE = 'secp256k1';

Expand Down Expand Up @@ -35,10 +42,48 @@ export const getQngAddress = async (): Promise<string> => {
);
const pub = privKey.publicKey;
const h16 = hash.hash160(pub);
const addr = address.toBase58Check(h16, networks.testnet.pubKeyHashAddrId);
const addr = address.toBase58Check(h16, networks.privnet.pubKeyHashAddrId);
return addr;
};

export const getQngBalance = async (): Promise<string> => {
const addr = await getQngAddress();
const ba = await qngGetUTXOBalance(addr);
return ba;
};

export const ethSign = async (
txid: string,
idx: number,
fee: number,
): Promise<string> => {
const signRes = await transferUTXOToEvmWithEthSign(txid, idx, fee);
return signRes;
};

export const walletSign = async (
txid: string,
idx: number,
fee: number,
): Promise<string> => {
const account = await getQngAccount();
const privKey = ec.fromPrivateKey(
uint8arraytools.fromHex(trimHexPrefix(account.privateKey as string)),
{},
);
const wallet = new ethers.Wallet(
uint8arraytools.toHex(privKey.privateKey as Uint8Array),
);
const signature = await wallet.signMessage(getInputHash(txid, idx, fee));
const txhash = await crossSendtoBunder(
txid,
idx,
fee,
handleSignStr(signature),
);
return txhash;
};

export const qngTransfer = async (
_from: string,
_target: string,
Expand All @@ -53,3 +98,11 @@ export const qngTransfer = async (
const txid = qngTransferUtxo(_from, _target, Number(_amount), privKey);
return txid;
};
export const getOneUtxo = async (from: string): Promise<string> => {
const last = await qngGetAvailableUtxos(from);
if (last.length < 1) {
return '';
}
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
return `${last[0]?.txid}:${last[0]?.idx}:${last[0]?.amount}`;
};
Loading

0 comments on commit c0b6d24

Please sign in to comment.