Skip to content

Ownable (Multisig) Module

The Ownable module provides multi-signature functionality for smart contract accounts, allowing multiple owners to control an account with configurable signature thresholds.

Actions

addOwner

Adds a new owner to the smart contract account.

Usage

import { nexusClient } from "./nexusClient"
import { toOwnableValidator, ownableActions } from "@biconomy/sdk"
 
const ownableModule = toOwnableValidator({
  account: nexusClient.account,
  signer: eoaAccount
});
 
const ownableNexusClient = nexusClient.extend(ownableActions(ownableModule));
 
const hash = await ownableNexusClient.addOwner({
  owner: "0x..."
});

Parameters

ParameterTypeDescriptionRequired
accountModularSmartAccountThe smart account to add the owner to. Uses client's account if not providedNo
ownerHexAddress of the new ownerYes
maxFeePerGasbigintMaximum fee per gas unitNo
maxPriorityFeePerGasbigintMaximum priority fee per gas unitNo
noncebigintTransaction nonce. Auto-determined if not providedNo

Response

Returns a promise that resolves to the transaction hash (Hex).

removeOwner

Removes an existing owner from the smart contract account.

Usage

const hash = await ownableNexusClient.removeOwner({
  owner: "0x..."
});

Parameters

ParameterTypeDescriptionRequired
accountModularSmartAccountThe smart account to remove the owner from. Uses client's account if not providedNo
ownerHexAddress of the owner to removeYes
maxFeePerGasbigintMaximum fee per gas unitNo
maxPriorityFeePerGasbigintMaximum priority fee per gas unitNo
noncebigintTransaction nonce. Auto-determined if not providedNo

getThreshold

Retrieves the current signature threshold for the account.

Usage

const threshold = await ownableNexusClient.getThreshold();

Parameters

ParameterTypeDescriptionRequired
accountModularSmartAccountThe smart account to query. Uses client's account if not providedNo

Response

Returns a promise that resolves to the current threshold value (number).

setThreshold

Updates the signature threshold for the account.

Usage

const hash = await ownableNexusClient.setThreshold({
  threshold: 2n
});

Parameters

ParameterTypeDescriptionRequired
accountModularSmartAccountThe smart account to update. Uses client's account if not providedNo
thresholdbigintNew threshold valueYes
maxFeePerGasbigintMaximum fee per gas unitNo
maxPriorityFeePerGasbigintMaximum priority fee per gas unitNo
noncebigintTransaction nonce. Auto-determined if not providedNo

prepareSignatures

Combines multiple signatures for a multi-sig transaction.

Usage

const combinedSignature = await ownableNexusClient.prepareSignatures({
  signatures: ["0x...", "0x..."]
});

Parameters

ParameterTypeDescriptionRequired
accountModularSmartAccountThe smart account context. Uses client's account if not providedNo
signaturesHex[]Array of signatures to combineYes

Response

Returns a promise that resolves to the combined signature (Hex).

Complete Example

Here's a complete example showing how to set up and use a multi-signature configuration:

import { nexusClient } from "./nexusClient"
import { toOwnableValidator, ownableActions } from "@biconomy/sdk"
 
// 1. Create and configure the ownable module
const ownableModule = toOwnableValidator({
  account: nexusClient.account,
  signer: eoaAccount,
  moduleInitArgs: {
    threshold: 2n,
    owners: [owner1.address, owner2.address]
  }
});
 
// 2. Install the module
const installHash = await nexusClient.installModule({
  module: ownableModule.moduleInitData
});
await nexusClient.waitForUserOperationReceipt({ hash: installHash });
 
// 3. Extend the client with ownable actions
const ownableNexusClient = nexusClient.extend(ownableActions(ownableModule));
 
// 4. Prepare a multi-sig transaction
const userOp = await ownableNexusClient.prepareUserOperation({
  calls: [{
    to: recipient,
    value: amount
  }]
});
 
// 5. Collect required signatures
const userOpHash = await nexusClient.account.getUserOpHash(userOp);
const signatures = await Promise.all([
  owner1.signMessage({ message: { raw: userOpHash } }),
  owner2.signMessage({ message: { raw: userOpHash } })
]);
 
// 6. Combine signatures and execute
userOp.signature = await ownableNexusClient.prepareSignatures({ signatures });
const uoHash = await nexusClient.sendUserOperation(userOp);