npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@shakesco/userop

v1.0.1

Published

Shakesco useroperation package

Downloads

7

Readme

@shakesco/userop

This repository makes it easy for developers to create userop that can be sent to bundlers for execution!

To install:

npm i @shakesco/userop

After installing:

const shakesco = require("@shakesco/userop");

To send a user operation or intents you need:

  1. Sender - This is the smart account
  2. Nonce - This is the smart accounts number of intent sent from deployment
  3. initCode - This is the code used to deploy the sender if not yet on-chain.
  4. callData - Data that you want the smart account to execute
  5. callGasLimit - Gas limit for the execution phase
  6. verificationGasLimit - Gas limit for the verification phase
  7. preVerificationGas - Gas to compensate the bundler for the overhead to submit the User Operation.
  8. maxFeePerGas - Similar to eip 1559
  9. maxPriorityFeePerGas - Similar to eip 1559
  10. paymasterAndData - The paymaster plus data used to sponsor transaction and verify legibility
  11. signature - The signature of from the owner of the smart wallet.

So let's start with nonce because sender is pretty straightforward. To get the nonce call the function below from your smart account:

const ACCOUNT = new ethers.Contract(sender, smartWalletABI, provider);
const nonce = await ACCOUNT.getNonce();

📓NOTE: This assumes you have deployed smart wallet. If not populate nonce with "0x0"

To get the initcode you need the factory contract. You can create the initcode by simply doing:

    const factory = new ethers.Interface(accountFactoryABI);
    const initCode = ethers.concat([
      accountFactoryAddress,
      factory.encodeFunctionData("deployWallet", [
        owner, //owner of the smart wallet
        "0", //salt.
      ]),
    ]);

The calldata is the function you want to execute. So you encode the function as below:

const accountABI = new ethers.Interface(smartWalletABI);

const calldata = accountABI.encodeFunctionData("execute", 
    [
        address,
        ethers.parseEther(value),
        "0x",
    ]);

The above calldata is a simple one requesting the smart wallet to send eth to address.

Now to the gas value:

Use our package to get the eip 1559 gas value as below:

  const provider = new ethers.JsonRpcProvider(
    process.env.RPC_URL
  );
  const { maxFeePerGas, maxPriorityFeePerGas } = await shakesco.getEIP1559(
    provider
  );
  console.log(maxFeePerGas); //0x1500000016
  console.log(maxPriorityFeePerGas); //0x1500000000

To get the other userop gas value:

  const { callGasLimit, preVerificationGas, verificationGasLimit } =
    await shakesco.useropGasValues(
      smartWallerAddress,
      provider,
      calldata,
      initCode
    );
  console.log(callGasLimit); //0x83074
  console.log(preVerificationGas); //0x01228e
  console.log(verificationGasLimit); //0x0186a0

📓NOTE: If smart wallet deployed pass initcode as empty string. If you also don't want to call any data from the smart wallet pass an empty string.

Finally we need to sign the userop so as to send the userop. We can do this by:

 const arraifiedHash = shakesco.useropHash(
    smartWallerAddress,
    nonce,
    initCode,
    calldata,
    callGasLimit,
    verificationGasLimit,
    preVerificationGas,
    maxFeePerGas,
    maxPriorityFeePerGas,
    paymasterAndDataNOSIG,
    chainId
  );
  console.log(arraifiedHash);

After getting the hash we can sign this by doing:

   const signer = new ethers.Wallet(process.env.PRIV_KEY, provider);
   const signature = await signer.signMessage(arraifiedHash);

📓NOTE: This assumes that you passed one owner while deploying wallet. If using multi-signature or Threshold signatures this will not work.

You now have all the value to send the userop. Pass them as required by your bundler provider.