Skip to content

Commit

Permalink
add network config
Browse files Browse the repository at this point in the history
  • Loading branch information
frankcrypto committed Aug 20, 2024
1 parent c0b6d24 commit 8770d96
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 84 deletions.
1 change: 1 addition & 0 deletions packages/snap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"dependencies": {
"@account-abstraction/contracts": "^0.6.0",
"@account-abstraction/sdk": "^0.6.0",
"@metamask/key-tree": "^9.1.2",
"@metamask/snaps-sdk": "^4.0.0",
"@noble/hashes": "^1.4.0",
"@types/base-x": "^3.0.6",
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": "cUuESUJvxaTB3CM5yTCgZYfD6R1mZzWVl08DxsyWJyA=",
"shasum": "+az8ZJ3rsNhX5gaBVmiy73XaytFggSq8UnCSpRh74dE=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
48 changes: 48 additions & 0 deletions packages/snap/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { networks } from 'qitmeerts';
import type { NetworkConfig } from 'qitmeerts/dist/src/networks';

export type Config = {
entryPointAddress: string;
factoryAddress: string;
proxyUrl: string;
networkConf: NetworkConfig;
};

export const PrivateConfig: Config = {
entryPointAddress: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
factoryAddress: '0x9406cc6185a346906296840746125a0e44976454',
proxyUrl: 'http://127.0.0.1:8081',
networkConf: networks.privnet,
};

export const TestConfig: Config = {
entryPointAddress: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
factoryAddress: '0x9406cc6185a346906296840746125a0e44976454',
proxyUrl: 'http://146.196.54.208:2234',
networkConf: networks.testnet,
};
export const MixConfig: Config = {
entryPointAddress: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
factoryAddress: '0x9406cc6185a346906296840746125a0e44976454',
proxyUrl: 'http://127.0.0.1:8081',
networkConf: networks.mixnet,
};
export const MainConfig: Config = {
entryPointAddress: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
factoryAddress: '0x9406cc6185a346906296840746125a0e44976454',
proxyUrl: 'http://127.0.0.1:8081',
networkConf: networks.mainnet,
};

export const getConfig = (chainId: number): Config => {
switch (chainId) {
case 813:
return MainConfig;
case 8131:
return TestConfig;
case 8132:
return MixConfig;
default:
return PrivateConfig;
}
};
46 changes: 31 additions & 15 deletions packages/snap/src/getAbstractAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
// import type { BigNumberish} from 'ethers';
import { ethers } from 'ethers';

import { getConfig } from './config';
// entryPointAddress
// const paymasterUrl = ''; // Optional
// Extend the Ethereum Foundation's account-abstraction/sdk's basic paymaster
// class VerifyingPaymasterAPI extends PaymasterAPI {
Expand Down Expand Up @@ -86,36 +88,50 @@ import { ethers } from 'ethers';
// qng testnet deployed
// entryPoint Contract https://github.com/eth-infinitism/account-abstraction/blob/v0.6.0/contracts/core/EntryPoint.sol
// deployed by deterministic-deployment-proxy https://github.com/Arachnid/deterministic-deployment-proxy.git
const entryPointAddress = '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789';
// entryPointAddress
// const paymasterAPI = new VerifyingPaymasterAPI(paymasterUrl, entryPointAddress);
// account factory Contract https://github.com/eth-infinitism/account-abstraction/blob/v0.6.0/contracts/samples/SimpleAccountFactory.sol
// deployed by deterministic-deployment-proxy https://github.com/Arachnid/deterministic-deployment-proxy.git
const factoryAddress = '0x9406cc6185a346906296840746125a0e44976454';
// const paymasterUrl = ''; // Optional

// const { factoryAddress } = getConfig();
// ** 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`;
export const bundlerUrl = (chainId: number): string => {
const conf = getConfig(chainId);
return `${conf.proxyUrl}/bundler`;
};
export const qngUrl = (chainId: number): string => {
const conf = getConfig(chainId);
return `${conf.proxyUrl}/qng`;
};

// TODO crossQngUrl will be merged in bundlerUrl
export const crossQngUrl = `${proxyUrl}/export`;
export const getAbstractAccount = async (): Promise<SimpleAccountAPI> => {
export const crossQngUrl = (chainId: number): string => {
const conf = getConfig(chainId);
return `${conf.proxyUrl}/export`;
};
export const getAbstractAccount = async (
chainId: number,
): Promise<SimpleAccountAPI> => {
const conf = getConfig(chainId);
const provider = new ethers.providers.Web3Provider(ethereum as any);
await provider.send('eth_requestAccounts', []);
const owner = provider.getSigner();
const aa = new SimpleAccountAPI({
provider,
entryPointAddress,
entryPointAddress: conf.entryPointAddress,
owner,
factoryAddress,
factoryAddress: conf.factoryAddress,
// paymasterAPI,
});
return aa;
};

export const bundlerProvider = async (): Promise<HttpRpcClient> => {
const provider = new ethers.providers.Web3Provider(ethereum as any);
const net = await provider.getNetwork();
return new HttpRpcClient(bundlerUrl, entryPointAddress, net.chainId);
export const bundlerProvider = async (
chainId: number,
): Promise<HttpRpcClient> => {
const conf = getConfig(chainId);
return new HttpRpcClient(
bundlerUrl(chainId),
conf.entryPointAddress,
chainId,
);
};
46 changes: 28 additions & 18 deletions packages/snap/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,21 @@ import {
getOneUtxo,
} from './qng';
import { transfer } from './transfer';
// export const changeNetwork = async () => {
// await ethereum.request({
// method: 'wallet_switchEthereumChain',
// params: [{ chainId: '0x1fc3' }],
// });
// };

export const getChainId = async (): Promise<number> => {
const provider = new ethers.providers.Web3Provider(ethereum as any);
const network = await provider.getNetwork();
return network.chainId;
};
export const getEoaAddress = async (): Promise<string> => {
const provider = new ethers.providers.Web3Provider(ethereum as any);
const accounts = await provider.send('eth_requestAccounts', []);
return accounts[0];
};

export const getAddress = async (): Promise<string> => {
const aa = await getAbstractAccount();
export const getAddress = async (chainId: number): Promise<string> => {
return '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789';
const aa = await getAbstractAccount(chainId);
const address = await aa.getAccountAddress();
return address;
};
Expand All @@ -45,21 +46,20 @@ export const onRpcRequest: OnRpcRequestHandler = async ({
origin,
request,
}) => {
console.log(request);
// await changeNetwork();
const chainId = await getChainId();
switch (request.method) {
case 'connect_eoa':
return await getEoaAddress();
case 'connect_qng':
return await getQngAddress();
return await getQngAddress(chainId);
case 'balance_eoa':
return await getBalance(await getEoaAddress());
case 'balance_qng':
return await getQngBalance();
return await getQngBalance(chainId);
case 'connect':
return await getAddress();
return await getAddress(chainId);
case 'balance':
return await getBalance(await getAddress());
return await getBalance(await getAddress(chainId));
case 'transfer':
// eslint-disable-next-line no-case-declarations
const { target, ethValue } = request?.params as unknown as {
Expand All @@ -71,14 +71,24 @@ export const onRpcRequest: OnRpcRequestHandler = async ({
const { from, to, amount } = request?.params as unknown as {
[key: string]: string;
};
return await qngTransfer(from as string, to as string, amount as string);
return await qngTransfer(
from as string,
to as string,
amount as string,
chainId,
);
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);
return await ethSign(
txid as string,
idx as number,
fee as number,
chainId,
);
}
// eslint-disable-next-line no-case-declarations
const res = await snap.request({
Expand All @@ -96,13 +106,13 @@ export const onRpcRequest: OnRpcRequestHandler = async ({
if (!res) {
return '';
}
return walletSign(txid as string, idx as number, fee as number);
return walletSign(txid as string, idx as number, fee as number, chainId);
case 'getOneUtxo':
// eslint-disable-next-line no-case-declarations
const { utxoFrom } = request?.params as unknown as {
[key: string]: string;
};
return getOneUtxo(utxoFrom as string);
return getOneUtxo(utxoFrom as string, chainId);
case 'hello':
return snap.request({
method: 'snap_dialog',
Expand Down
43 changes: 31 additions & 12 deletions packages/snap/src/qng.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { SLIP10Node } from '@metamask/key-tree';
import { ethers } from 'ethers';
import { ec, hash, address, networks } from 'qitmeerts';
import { ec, hash, address } from 'qitmeerts';
import * as uint8arraytools from 'uint8array-tools';

import { getConfig } from './config';
import {
qngTransferUtxo,
qngGetUTXOBalance,
Expand All @@ -27,44 +28,47 @@ export const getQngAccount = async (): Promise<SLIP10Node> => {
},
});

// Next, create an instance of a SLIP-10 node for the Dogecoin node.
// Next, create an instance of a SLIP-10 node for the Qng node.
const qngSlip10Node = await SLIP10Node.fromJSON(qngNode);
// m/44'/813'/0
const accountKey0 = await qngSlip10Node.derive(['bip32:0']);
return accountKey0;
};

export const getQngAddress = async (): Promise<string> => {
export const getQngAddress = async (chainId: number): Promise<string> => {
const conf = getConfig(chainId);
const account = await getQngAccount();
const privKey = ec.fromPrivateKey(
uint8arraytools.fromHex(trimHexPrefix(account.privateKey as string)),
{},
);
const pub = privKey.publicKey;
const h16 = hash.hash160(pub);
const addr = address.toBase58Check(h16, networks.privnet.pubKeyHashAddrId);
const addr = address.toBase58Check(h16, conf.networkConf.pubKeyHashAddrId);
return addr;
};

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

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

export const walletSign = async (
txid: string,
idx: number,
fee: number,
chainId: number,
): Promise<string> => {
const account = await getQngAccount();
const privKey = ec.fromPrivateKey(
Expand All @@ -80,26 +84,41 @@ export const walletSign = async (
idx,
fee,
handleSignStr(signature),
chainId,
);
return txhash;
// get the eth address
return `${wallet.address}:${txhash}`;
};

export const qngTransfer = async (
_from: string,
_target: string,
_amount: string,
chainId: number,
): Promise<string> => {
const account = await getQngAccount();
const privKey = ec.fromPrivateKey(
uint8arraytools.fromHex(trimHexPrefix(account.privateKey as string)),
{},
);
// create a new tx-signer
const txid = qngTransferUtxo(_from, _target, Number(_amount), privKey);
const txid = qngTransferUtxo(
_from,
_target,
Number(_amount),
privKey,
chainId,
);
return txid;
};
export const getOneUtxo = async (from: string): Promise<string> => {
const last = await qngGetAvailableUtxos(from);
export const getOneUtxo = async (
from: string,
chainId: number,
): Promise<string> => {
const last = await qngGetAvailableUtxos(from, chainId);
if (!last) {
return '';
}
if (last.length < 1) {
return '';
}
Expand Down
Loading

0 comments on commit 8770d96

Please sign in to comment.