movement-sdk
Version:
Movement SDK
139 lines (127 loc) • 5.69 kB
JavaScript
const { createConsola } = require("consola");
const logger = createConsola();
const Movement = require("../dist");
const HexString = Movement.HexString;
exports.logger = logger;
exports.sleep = (s) => new Promise((resolve) => setTimeout(resolve, s * 1000));
const { ethers, toBigInt, toBeHex, keccak256 } = require("ethers");
exports.contractFileName = "ERC20";
exports.contractName = "ERC20Mock";
exports.code = "ERC20Mock";
exports.pkName = "demo";
const codeName = "evm";
exports.codeName = codeName;
const contractInterface = new ethers.Interface([
"function mint(address to, uint256 amount)",
"function balanceOf(address owner) view returns (uint256)",
"function approve(address spender, uint value) external returns (bool)",
"function transfer(address to, uint256 amount ) external",
"function createPair(address tokenA, address tokenB) external returns (address pair)",
"function getPair(address tokenA, address tokenB) external view returns (address pair)",
"function allPairs(uint) external view returns (address pair)",
"function allPairsLength() external view returns (uint)",
"function balanceOf(address account) public view returns (uint256)",
"function swapExactTokensForTokens(uint amountIn,uint amountOutMin,address[] calldata path,address to,uint deadline) external returns (uint[] memory amounts)",
"function addLiquidity(address tokenA,address tokenB,uint amountADesired,uint amountBDesired,uint amountAMin,uint amountBMin,address to,uint deadline) external returns (uint amountA, uint amountB, uint liquidity)",
]);
exports.contractInterface = contractInterface;
let NODE_URL = "https://fullnode.devnet.aptoslabs.com";
let FAUCET_URL = "https://faucet.devnet.aptoslabs.com";
const client = new Movement.AptosClient(NODE_URL);
exports.client = client;
const faucetClient = new Movement.FaucetClient(NODE_URL, FAUCET_URL);
const aptosCoin = "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>";
const payerAccount = {
address: "0xc05c4bafbbb769d269d9964b0e581c2c5d095e5e3130e9f5f6fc59c55fa9f250",
publicKeyHex: "0xe5d60844a659f320f6802a825bed12c1ce57ecf1c33186f344c1a5fcd9fe6cb0",
privateKeyHex: "0x92e9aad8942e4ed4cd9dcea6620672b9175cbecdad52eb09eadb4304085f9798",
};
exports.payerAccount = payerAccount;
const ETH_SENDER = "0x1000000000000000000000000000000000000000";
exports.ETH_SENDER = ETH_SENDER;
const toClientAccount = function (pk) {
return Movement.AptosAccount.fromAptosAccountObject({
privateKeyHex: pk,
});
};
exports.toClientAccount = toClientAccount;
exports.faucet = async function faucet(addr) {
await faucetClient.fundAccount(addr, 100_000_000_000);
let resources = await client.getAccountResources(addr);
let accountResource = resources.find((r) => r.type === aptosCoin);
logger.success(`movement: faucet %s token: ${accountResource.data.coin.value}`, addr);
};
exports.checkTxResult = async function checkTxResult(tx) {
const res = await client.getTransactionByHash(tx);
logger.info("movement: transaction %s on chain result is %s", tx, res.success);
if (!res["success"]) {
logger.error("movement: transaction %s on chain result is %s", tx, res);
throw "tx error ";
}
};
exports.sendTx = async function sendTx(payload) {
const signer = toClientAccount(payerAccount.privateKeyHex);
const txnRequest = await client.generateTransaction(signer.address().hexString, payload, {
max_gas_amount: 2 * 1e6,
});
const signedTxn = await client.signTransaction(signer, txnRequest);
const transactionRes = await client.submitTransaction(signedTxn);
await client.waitForTransaction(transactionRes.hash);
return transactionRes.hash;
};
function toEthAddress(addr) {
return "0x" + addr.slice(-40);
}
exports.toEthAddress = toEthAddress;
function toBuffer(hex) {
return new HexString(hex).toUint8Array();
}
exports.toBuffer = toBuffer;
function formatEthAddress(addr) {
addr = addr.toLowerCase();
return "0x" + addr.slice(2).padStart(64, "0");
}
exports.formatEthAddress = formatEthAddress;
exports.view = async function view(contract, calldata) {
const payer = payerAccount.address;
let sender = formatEthAddress(ETH_SENDER);
let payload = {
function: payer + `::${codeName}::view`,
type_arguments: [],
arguments: [sender, contract, calldata],
};
let result = await client.view(payload);
return result[0];
};
async function getCurrNonce(sender) {
const payer = payerAccount.address;
let resources = await client.getAccountResources(payer);
const newStr = payer.slice(2).replace(/^0+/, "");
let k = `0x${newStr}`;
let type = `${k}::evm::S`;
let defaultNonce = 1;
let nonceResource = resources.find((r) => r.type === type);
if (!nonceResource) return defaultNonce;
let item = nonceResource.data.nonce.data.find((it) => it.key === sender);
return item.value;
}
exports.getCurrNonce = getCurrNonce;
function toU256Hex(a, includePrefixe = true) {
let it = toBeHex(a).slice(2).padStart(64, "0");
if (includePrefixe) return "0x" + it;
return it;
}
exports.toU256Hex = toU256Hex;
function hex2number(h) {
return ethers.toBigInt(h).toString();
}
exports.hex2number = hex2number;
exports.toEthAddress = toEthAddress;
async function calculateContractAddress(sender) {
let nonce = await getCurrNonce(sender);
logger.info("movement: get %s nonce:%s ", sender, nonce);
let hexNonce = toU256Hex(parseInt(nonce), false);
let h = sender + hexNonce;
return formatEthAddress("0x" + keccak256(toBuffer(h)).slice(-40));
}
exports.calculateContractAddress = calculateContractAddress;