Skip to main content

Methods

The SDK provides the following API methods for a smart account.

createSmartAccountClient

This method is used to create an instance of the AbstraXn Smart Account. This method requires a smart account configuration object to be passed and returns the smart account instance.

This method creates the smart account based on the config object. To configure a smart account on another chain, you need to instantiate another smart account instance with configuration of that chain.

Usage

let provider = new ethers.JsonRpcProvider("rpcUrl");
let signer = new ethers.Wallet("private key", provider);

const abstraxnSmartAccount = await AbstraxnSmartAccount.create({
chainId: ChainId.SEPOLIA, // you can use multiple chains available in chainId object
activeValidationModule: ownerShipModule,
defaultValidationModule: ownerShipModule,
bundler: bundler, // <-- Read about this at https://dashboard.abstraxn.com/
paymaster: paymaster, // <-- Read about this at https://dashboard.abstraxn.com/auth/paymaster
index: 1 // any index of your choice
signer
});

Parameters

required params are explicitly mentioned

  • config (object, required): AbstraxnSmartAccountConfig object containing configuration options for creating the smart account.
    • signer(Signer, required) : signer is required to pass in order to create a smart account for that specific user.
    • bundlerUrl (string, required) OR bundler (IBundler, required) : bundler url which will be internally used to create bundler instance. Bundler instance can also be used if one wants to customise the bundler. Refer to bundler integration for more details on bundler. // Need to add bundler integration page url
    • chainId (ChainId enum): The identifier for the blockchain network. (e.g., ChainId.SEPOLIA).
    • paymaster (IPaymaster): need to pass Paymaster instance in order to use the paymaster.
    • entryPointAddress (string): DEFAULT_ENTRY_POINT_ADDRESS will be used if not passed, otherwise the passed address will be used.
    • activeValidationModule (BaseValidationModule, required): The run-time validation module (must be one of enabled validation modules) to sign and validate next userOp.
    • defaultValidationModule (BaseValidationModule, required): One either needs to pass the signer instance or the default validation module which gets used to detect address of the smart account. If not passed explictly, ECDSA module gets used as default.
    • rpcUrl (string): Recommended for signers that are not using any type of wallet or implementing it in backend. It's advised to use your own RPC url beacuse of high traffic on public rpc url which can often silently fail. If rpcUrl is not provided then a default public rpc will be used.
    • index (number): index to create multiple smart accounts for an EOA. First account gets created with 0 index.

Returns

  • smartAccount (AbstraxnSmartAccount): An instance of the Abstraxn Smart Account.

createBundler

This method creates a custom bundler instance.

Usage

const bundler: IBundler = new Bundler({
bundlerUrl: "",
chainId: ChainId.SEPOLIA, // you can use multiple chains available in chainId object
entryPointAddress: DEFAULT_ENTRYPOINT_ADDRESS,
});

Params

  • config(BundlerConfig): configs to be passed to bundler
export type Bundlerconfig = {
bundlerUrl: string;
entryPointAddress?: string;
chainId?: number;
userOpReceiptIntervals?: {
[key in number]?: number; // The polling interval per chain for the tx receipt in milliseconds. Default value is 5 seconds.
};
userOpWaitForTxHashIntervals?: {
[key in number]?: number; // The polling interval per chain for the tx result in milliseconds. Default value is 0.5 seconds.
};
userOpReceiptMaxDurationIntervals?: {
[key in number]?: number; // The maximum duration in milliseconds per chain to wait for the tx receipt. Default value is 30 seconds.
};
userOpWaitForTxHashMaxDurationIntervals?: {
[key in number]?: number; // The maximum duration in milliseconds per chain to wait for the tx hash. Default value is 20 seconds.
};
};

Returns

  • bundler(Promise<Bundler>): bundler instance

Smart Account Get Methods

getAccountAddress( )

This method retrieves the counterfactual address of the abstraxnSmartAccount instance.

Usage

const address = await abstraxnSmartAccount.getAccountAddress();

Returns

  • address (Promise<string>): Returns he account address associated with the abstraxnSmartAccount instance.

getNonce( )

This method is used to retrieve the nonce associated with the abstraxnSmartAccount instance.

Usage

const nonce = await abstraxnSmartAccount.getNonce();
console.log(nonce.toNumber());

const nonceKey = 10;
const nonce = await abstraxnSmartAccount.getNonce(nonceKey);

Parameters

  • nonceKey(number): one can also pass the optional parameter nonceKey.

Returns

  • address (Promise<BigNumber>): Return the current nonce of the abstraxnSmartAccount.

index

This is used to retrieve the index of the current active abstraxnSmartAccount.

Usage ////Need to include this in sdk

const index = smartAccount.index;

Returns

  • index (number): A number indicating the index of current active abstraxnSmartAccount.

getInitCode( )

This method is used to retrieve the initCode associated with the abstraxnSmartAccount instance.

Usage

const initCode = await abstraxnSmartAccount.getInitCode();

Returns

  • bytes (Promise<Bytes>): Return the initcode of the abstraxnSmartAccount.

getUserOpHash( )

This method is used to retrieve the userOphash of a userOp.

Usage

const userOpHash = await abstraxnSmartAccount.getUserOpHash();

Parameters

  • userOp(tuple): UserOperation.

Returns

  • bytes (Promise<Bytes>): Return the hash of the userOp.

Transaction Methods

sendUserOp( )

This method is used to send a transaction to a bundler for execution. It internally build and execute the UserOp.

Usage

const userOpResponse = await abstraxnSmartAccount.sendUserOp(userOp);

Parameters

  • manyOrOneTransactions (Transaction | Transaction[], required): An array of transactions to be batched which will be executed in the provided order. You can also pass a single transaction.

    Transaction: {
    to: string;
    } & ValueOrData
  • buildUseropDto (BuildUserOpOptions, optional): These options can be passed to customize how a userOp is built.

    type BuildUserOpOptions = {
    overrides: Overrides;
    skipBundlerGasEstimation?: boolean;
    params?: ModuleInfo;
    nonceOptions?: NonceOptions;
    forceEncodeForBatch?: boolean;
    paymasterServiceData?: SponsorUserOperationDto;
    };

    Let's look at each of these params:

    1. overrides (Overrides): These values overrides the default values used by the SDK.
    type Overrides = {
    callGasLimit?: BigNumberish;
    verificationGasLimit?: BigNumberish;
    preVerificationGas?: BigNumberish;
    maxFeePerGas?: BigNumberish;
    maxPriorityFeePerGas?: BigNumberish;
    paymasterData?: string;
    signature?: string;
    }
    const userOp = await abstraxnSmartAccount.buildUserOp([tx1, ...], {
    overrides: {callGasLimit:1000000}
    })
    1. skipBundlerGasEstimation(boolean): Boolean value to calculate or skip the gas estimation for userOp.

    2. params (ModuleInfo): This param can be used to pass session validation module parameters. Refer to the tutorial to learn more about the session keys.

    type ModuleInfo = {
    sessionID?: string;
    sessionSigner?: Signer;
    sessionValidationModule?: string;
    additionalSessionData?: string;
    batchSessionParams?: SessionParams[];
    };
    1. nonceOptions(NonceOptions) : This can be used to execute multiple user operations in parallel for the same smart account.
    type NonceOptions = {
    nonceKey?: number;
    nonceOverride?: number;
    };
    // nonceOptions usage
    let i = 0;
    const userOp = await smartAccount.buildUserOp([tx1], {
    nonceOptions: { nonceKey: i++ },
    });

    nonceKey can be initialised at any arbitrary number and incremented as one builds user operations to be sent in parallel. The nonceKey will create a batch or space in which the nonce can safely increment without colliding with other transactions. The nonceOverride will directly override the nonce and should only be used if you know the order in which you are sending the userOps.

    1. forceEncodeForBatch (boolean): When a transactions array is passed, by default the Abstraxn SDK encodes it for executeBatch() executor function and execute() function for single transaction. However, in some cases, there may be a preference to encode a single transaction for a batch, especially if the custom module only decodes for executeBatch. In such cases, set this flag to true; otherwise, it remains false by default.

    2. paymasterServiceData (PaymasterUserOperationDto): The paymasterServiceData includes details about the kind of sponsorship and payment token in case mode is ERC20. It contains information about the paymaster service, which is used to calculate the paymasterAndData field in the user operation. Note that this is only applicable if you're using Abstraxn paymaster.

    type SponsorUserOperationDto = {
    mode: PaymasterMode;
    calculateGasLimits?: boolean;
    expiryDuration?: number;
    webhookData?: {
    [key: string]: any;
    };
    feeTokenAddress?: string;
    };

Returns

  • userOpResponse (Promise<UserOpResponse>): The method returns an object of type UserOpResponse which has a userOpHash and two methods: wait() and waitForTxHash().
type UserOpResponse = {
userOpHash: string;
wait(_confirmations?: number): Promise<UserOpReceipt>;
waitForTxHash(): Promise<UserOpStatus>;
};

type UserOpReceipt = {
/* The request hash of the UserOperation. */
userOpHash: string;
/* The entry point address used for the UserOperation. */
entryPoint: string;
/* The paymaster used for this UserOperation (or empty). */
sender: string;
/* The sender who wants to send the transaction */
nonce: number;
/* Nonce of the account*/
paymaster: string;
/* The actual amount paid (by account or paymaster) for this UserOperation. */
actualGasCost: BigNumber;
/* The total gas used by this UserOperation (including preVerification, creation, validation, and execution). */
actualGasUsed: BigNumber;
/* Indicates whether the execution completed without reverting. */
success: "true" | "false";
/* In case of revert, this is the revert reason. */
reason: string;
/* The logs generated by this UserOperation (not including logs of other UserOperations in the same bundle). */
logs: Array<any>; // The logs generated by this UserOperation (not including logs of other UserOperations in the same bundle)
/* The TransactionReceipt object for the entire bundle, not only for this UserOperation. */
receipt: ethers.providers.TransactionReceipt;
};

The wait() method resolves when the user operation is dispatched by the bundler on-chain and gets mined. The waitForTxHash() method returns a UserOpStatus object which includes the transaction hash and the receipt once added on-chain.

const { transactionHash } = await userOpResponse.waitForTxHash();
console.log("transaction Hash", transactionHash);

const userOpReceipt = await userOpResponse.wait();

if (userOpReceipt.success == "true") {
// indicates that the user operation was successful without any revert
console.log("UserOp receipt", userOpReceipt);
console.log("actual transaction receipt", userOpReceipt.receipt);
}

buildUserOp( )

This method is used for configuring and setting up properties of the partial userOp object. It converts an individual transaction or batch of transactions into a partial user operation populating fields such as initCode, sender, nonce, maxFeePerGas, maxPriorityFeePerGas, callGasLimit, verificationGasLimit and preVerificationGas (as this step also involves estimating gas for the userOp internally)

Usage

For example, in the context of creating a userOp for a mint transaction, an instance of the contract is created. A basic transaction object is then created that holds the necessary address and data from the transaction. Finally, a partial userOp is created using the Smart Account's buildUserOp method⁠. Now this can be signed and sent to the bundler.

const contractAddress = "contract address";
const provider = new ethers.JsonRpcProvider("rpc url");
const userAddress = "user address";

const tokenContract = new ethers.Contract(
contractAddress,
abi, // contract abi
provider
);

const mintTokens = await tokenContract.populateTransaction.mint(userAddress,"10000000");

const tx1 = {
to: contractAddress,
data: mintTokens.data,
};

const userOp = await smartAccount.buildUserOp([tx1]);

Parameters

  • transactions (Transaction[], required): The required argument is an array of transactions which will be executed in provided order. You can pass multiple transactions into a userOp if you would like to batch them together into one transaction.
  • buildUseropDto (BuildUserOpOptions): One can also pass these options to customize how a userOp is built.

Returns

  • partialUserOp (Promise<Partial<UserOperation>>): A Promise resolving to UserOperation which can be further signed and sent to the bundler.

senduserOp( )

This method is used to submit a User Operation object to the bundler mempool. It signs the UserOperation using the default module selected by the user and submits it to the bundler for on-chain processing.

Usage

const userOp = await abstraxnSmartAccount.buildUserOp([tx1, ...], {
overrides: {...}
});

const userOpResponse = await abstraxnSmartAccount.sendUserOp(userOp);

const { receipt } = await userOpResponse.wait(1);

Parameters

  • userOp (Partial<UserOperation>, required): The userOp object includes essential fields like sender, nonce, callData, callGasLimit and gas related properties.

  • params (SendUserOpParams, optional): This gets used when the active validation module is complex and requires additional information for signature generation. The SendUserOpParams object can contain fields such as simulationType. These parameters are used to customize the behavior of the sendUserOp method and are optional.

const userOpResponse = await moduleSmartAccount?.sendUserOp(userOp, {
simulationType:"validation_and_execution"
});

Similar to building a userOp we need to ensure that any modules used for additional validation or execution logic are specified in the sendUserOp method. Currently, this only applies for session key module requirements.

Returns

  • userOpsResponse (UserOpResponse): The method returns an object of type UserOpResponse which has a userOpHash and two methods: wait() and waitForTxHash().
type UserOpResponse = {
userOpHash: string;
wait(_confirmations?: number): Promise<UserOpReceipt>;
waitForTxHash(): Promise<UserOpStatus>;
};

type UserOpReceipt = {
userOpHash: string;
entryPoint: string;
sender: string;
nonce: number;
paymaster: string;
actualGasCost: BigNumber;
actualGasUsed: BigNumber;
success: boolean;
reason: string;
logs: Array<ethers.providers.Log>;
receipt: ethers.providers.TransactionReceipt;
};

The wait() method resolves when the user operation is dispatched by the bundler on-chain and gets mined. The waitForTxHash() method returns a UserOpStatus object which includes the transaction hash and the receipt once added on-chain.

sendSignedUserOp( )

This function is used to send signed userOp to the bundler. This function can be used to make multiple instances of smart account to reduce the wait time of the developer implementing it on its app, for example one backend instance to build userOp, while another instance to obtain the signed userOp on the frontend and subsequently dispatch the signed userOp using the backend instance.

Usage

const userOpResponse = await abstraxnSmartAccount.sendSignedUserOp(userOp);

Parameters

  • userOp (UserOperation, required): The userOp object includes essential fields like sender, nonce, callData, gas related properties, and signature.

  • params (SendUserOpParams): The SendUserOpParams object can contain fields such as simulationType. These parameters are used to customize the behavior of the sendUserOp method and are optional.

Returns

  • userOpsResponse (UserOpResponse): The method returns an object of type UserOpResponse which has a userOpHash and two methods: wait() and waitForTxHash(). The wait() method resolves when the user operation is dispatched by the bundler on-chain and gets mined. The waitForTxHash() method returns a UserOpStatus object which includes the transaction hash and the receipt once added on-chain.