NERO
Wallets

Signing Transactions

Sign and send blockchain transactions using DKLS (EOA) or Pedersen (ERC-4337 UserOperations)

Signing Transactions

Transaction signing in the Nero MPC SDK is protocol-dependent. DKLS signs raw transaction hashes for EOA transactions, while Pedersen creates ERC-4337 UserOperations for smart account execution.

Protocol-Specific Transaction Paths

ProtocolBehavior
dklsSigns raw transaction hashes using ethers.Transaction to compute the unsigned hash
pedersenBuilds an ERC-4337 UserOperation, signs it via MPC, and submits to a bundler

Pedersen Transaction Pipeline

ComponentResponsibility
SmartWallet.buildUserOperation()Constructs UserOp with callData, gas estimates, nonce
SigningClientCoordinates threshold signature of the UserOp hash
SmartWallet.sendUserOperation()Submits signed UserOp to bundler

Direct Transaction Signing

const tx = {
  to: "0xRecipientAddress",
  value: "0x16345785D8A0000", // 0.1 ETH in hex
  gasLimit: "0x5208", // 21000
};

const signedTx = await sdk.signTransaction(tx);

Using the EIP-1193 Provider

The eth_sendTransaction method triggers protocol-specific workflows automatically. Pedersen builds ERC-4337 UserOperations, while DKLS generates signatures for raw transactions.

const provider = sdk.getProvider();

const txHash = await provider.request({
  method: "eth_sendTransaction",
  params: [{
    to: "0xRecipientAddress",
    value: "0x16345785D8A0000",
  }],
});

Provider RPC Handlers

MethodBehavior
eth_accounts / eth_requestAccountsReturns active wallet address (DKLS returns _dklsWalletAddress, Pedersen returns EOA from SmartWallet)
personal_signConverts hex or UTF-8 messages to bytes before calling signMessageInternal
eth_signTypedData_v4Parses JSON typed data and forwards to signTypedDataInternal
eth_sendTransactionRoutes to protocol-specific transaction workflow

With ethers.js

import { BrowserProvider } from "ethers";

const provider = new BrowserProvider(sdk.getProvider());
const signer = await provider.getSigner();

const tx = await signer.sendTransaction({
  to: "0xRecipientAddress",
  value: ethers.parseEther("0.1"),
});

await tx.wait();
console.log("Transaction confirmed:", tx.hash);

Provider Events

The EIP-1193 provider emits standard events:

EventTriggerData
connectProvider becomes activeProviderConnectInfo (hex chainId)
disconnectProvider deactivatedProviderRpcError
chainChangedChain switchstring (hex chainId)
accountsChangedWallet generated/clearedstring[]

Connection Lifecycle

The SDK manages provider connectivity through a state machine with four states:

StateDescription
disconnectedInitial state with no active provider
connectingSDK initializing the provider
connectedNeroProvider ready for requests
erroredInitialization failure occurred
const provider = sdk.getProvider();
await sdk.connect();

console.log(sdk.status); // "connected"
console.log(sdk.connected); // true

Provider Error Codes

CodeNameDescription
4001USER_REJECTEDUser rejected request
4100UNAUTHORIZEDProvider lacks authorization
4200UNSUPPORTED_METHODRPC method not implemented
4900DISCONNECTEDProvider disconnected from chain
4902CHAIN_NOT_ADDEDRequested chain not added

Signing Error Codes

Error CodeScenarioThrown By
NO_WALLETSigning attempted before wallet creationSDK signing method guards
INVALID_NONCE_COMMITMENTBackend provided malformed nonceSigningClient validation
INVALID_PARTIAL_SIGNATUREBackend partial signature verification failedSigningClient verification logic

On this page