Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

SDK

execute

Submit one or more calls from a wallet. client.execute accepts either an admin pair (wallet + signer) or a session, plus the calls to run.

Keystore impact

ScenarioTouches Keystore?
First admin execute on a fresh walletYes (admin key registered)
Subsequent admin execute callsNo
Any session executeNo (session was registered at grant time)

Admin path

The wallet's admin signs the intent. Use this for first-party operations.

import { createClient, BNB_TESTNET, signerFromPrivateKey } from "@functornetwork/agentic-wallet";
 
const client = createClient({ chains: [BNB_TESTNET] });
const signer = signerFromPrivateKey("0x...");
const wallet = await client.createWallet({ signer });
 
const result = await client.execute({
  wallet,
  signer,
  calls: { to: "0xRecipient...", value: 1_000_000_000_000_000n }, // 0.001 BNB on BNB testnet
});
 
console.log(result.status, result.transactionHash);

Session path

A session signs the intent. Use this for agent-driven operations.

// `client` and `session` from grantSession
const result = await client.execute({
  session,
  calls: [{ to: "0xUniswapRouter...", data: "0x...", value: 0n }],
});

Parameters

client.execute(opts: ClientExecuteOptions): Promise<ExecuteResult>;
 
type ClientExecuteOptions =
  | {
      wallet: Wallet;
      signer: Signer;
      calls: Call | readonly Call[];
      feeToken?: Address;  // default: native token
      noWait?: boolean;    // return as soon as submitted, don't wait for confirmation
      chainId?: number;    // defaults to the client's default chain
    }
  | {
      session: Session;
      calls: Call | readonly Call[];
      feeToken?: Address;
      noWait?: boolean;
      chainId?: number;
    };
 
type Call = {
  to: Address;
  data?: Hex;
  value?: bigint;
};

Returns

type ExecuteResult = {
  callsId: Hex;
  status: "CONFIRMED" | "FAILED" | "PENDING";
  transactionHash?: Hex;
};

Notes

  • First execute on a fresh wallet auto-registers the admin key in Keystore. initialRegisterKey is prepended transparently in the same userOp.
  • Empty calls is rejected. client.execute({ wallet, signer, calls: [] }) errors. Pass at least one call.
  • Session execute is byte-exact. The onchain validator matches the session's permissions + expiry + role + publicKey to the hash committed at grant. Persist the Session object verbatim.
  • chainId selects the chain. Omit it to use the client's default chain; pass one of the client's configured chains to target another.
  • With noWait: true, you get status: "PENDING" and a callsId to poll later.