"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/index.ts
var src_exports = {};
__export(src_exports, {
  buildTransaction: () => buildTransaction,
  encodeDeployment: () => encodeDeployment,
  encodeFunction: () => encodeFunction,
  getAccountNonce: () => getAccountNonce,
  insertAccount: () => insertAccount,
  keyPair: () => keyPair,
  run: () => run,
  tsSol: () => tsSol
});
module.exports = __toCommonJS(src_exports);
var import_block = require("@ethereumjs/block");
var import_common = require("@ethereumjs/common");
var import_tx = require("@ethereumjs/tx");
var import_util = require("@ethereumjs/util");
var import_vm = require("@ethereumjs/vm");
var import_abi = require("@ethersproject/abi");
var keyPair = {
  secretKey: "0x3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511",
  publicKey: "0x0406cc661590d48ee972944b35ad13ff03c7876eae3fd191e8a2f77311b0a3c6613407b5005e63d7d8d76b89d5f900cde691497688bb281e07a5052ff61edebdc0"
};
var common = new import_common.Common({
  chain: import_common.Chain.Rinkeby,
  hardfork: import_common.Hardfork.Istanbul
});
var block = import_block.Block.fromBlockData(
  { header: { extraData: Buffer.alloc(97) } },
  { common }
);
var insertAccount = async (vm, address) => {
  const acctData = {
    nonce: 0,
    balance: BigInt(10) ** BigInt(18)
    // 1 eth
  };
  const account = import_util.Account.fromAccountData(acctData);
  await vm.stateManager.putAccount(address, account);
};
var getAccountNonce = async (vm, accountPrivateKey) => {
  const address = import_util.Address.fromPrivateKey(accountPrivateKey);
  const account = await vm.stateManager.getAccount(address);
  return account.nonce;
};
var encodeFunction = (method, params) => {
  const parameters = params?.types ?? [];
  const methodWithParameters = `function ${method}(${parameters.join(",")})`;
  const signatureHash = new import_abi.Interface([methodWithParameters]).getSighash(method);
  const encodedArgs = import_abi.defaultAbiCoder.encode(parameters, params?.values ?? []);
  return signatureHash + encodedArgs.slice(2);
};
var encodeDeployment = (bytecode, params) => {
  const deploymentData = "0x" + bytecode;
  if (params) {
    const argumentsEncoded = import_abi.defaultAbiCoder.encode(params.types, params.values);
    return deploymentData + argumentsEncoded.slice(2);
  }
  return deploymentData;
};
var buildTransaction = (data) => {
  const defaultData = {
    nonce: BigInt(0),
    gasLimit: 2e6,
    // We assume that 2M is enough,
    gasPrice: 1,
    value: 0,
    data: "0x"
  };
  return {
    ...defaultData,
    ...data
  };
};
var tsSol = (strings, ...literals) => {
  console.log({ literals });
  return strings.join("");
};
async function deployContract(vm, senderPrivateKey, deploymentBytecode) {
  const data = encodeDeployment(deploymentBytecode.toString("hex"));
  const txData = {
    data,
    nonce: await getAccountNonce(vm, senderPrivateKey)
  };
  const tx = import_tx.Transaction.fromTxData(buildTransaction(txData), { common }).sign(
    senderPrivateKey
  );
  const deploymentResult = await vm.runTx({ tx, block });
  if (deploymentResult.execResult.exceptionError) {
    throw deploymentResult.execResult.exceptionError;
  }
  return deploymentResult.createdAddress;
}
var run = async (script) => {
  console.log("parsing the abi and byptecode");
  const { abi, bytecode } = script;
  console.log("creating a new common chain");
  const common2 = new import_common.Common({
    chain: import_common.Chain.Goerli,
    hardfork: import_common.Hardfork.Istanbul
  });
  console.log("creating a new vm instance");
  const vm = await import_vm.VM.create({ common: common2 });
  console.log("creating a new account");
  const accountPk = Buffer.from(
    "e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109",
    "hex"
  );
  const accountAddress = import_util.Address.fromPrivateKey(accountPk);
  console.log("Account: ", accountAddress.toString());
  console.log("sending account eth...", accountAddress.toString());
  await insertAccount(vm, accountAddress);
  console.log("deploying contract");
  debugger;
  const contractAddress = await deployContract(
    vm,
    accountPk,
    Buffer.from(bytecode.object)
  );
  console.log("Contract address:", contractAddress.toString());
  console.log("Creating sig hash");
  const sigHash = new import_abi.Interface(abi).getSighash("run");
  const result = await vm.evm.runCall({
    to: contractAddress,
    caller: accountAddress,
    origin: accountAddress,
    data: Buffer.from(sigHash.slice(2), "hex"),
    block
  });
  return result.execResult.returnValue.toString();
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  buildTransaction,
  encodeDeployment,
  encodeFunction,
  getAccountNonce,
  insertAccount,
  keyPair,
  run,
  tsSol
});
//# sourceMappingURL=index.cjs.map