Skip to content

Latest commit

 

History

History
129 lines (115 loc) · 3.77 KB

CREATE_AND_USE_A_BATCH_SESSION.md

File metadata and controls

129 lines (115 loc) · 3.77 KB

Create and Use a Batch Session

Key Description
sessionConfigs svm criteria
createERC20SessionDatum helper that returns erc20 svm data (not recommended)
createABISessionDatum helper that returns abi svm data (recommended)
import {
  createSmartAccountClient,
  createSession,
  createSessionSmartAccountClient,
  Rule,
  PaymasterMode,
  Policy,
} from "@biconomy/account";
import { createWalletClient, http, createPublicClient } from "viem";
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
import { mainnet as chain } from "viem/chains";

const withSponsorship = {
  paymasterServiceData: { mode: PaymasterMode.SPONSORED },
};

const account = privateKeyToAccount(generatePrivateKey());
const signer = createWalletClient({ account, chain, transport: http() });
const smartAccount = await createSmartAccountClient({
  signer,
  bundlerUrl,
  paymasterUrl,
});

// Retrieve bundler and pymaster urls from dashboard
const smartAccountAddress = await smartAccount.getAccountAddress();

// creates a store for the session, and saves the keys to it to be later retrieved
const { sessionKeyAddress, sessionStorageClient } = await createSessionKeyEOA(
  smartAccount,
  chain
);

const leaves: CreateSessionParams[] = [
  createERC20SessionDatum({
    interval: {
      validUntil: 0,
      validAfter: 0,
    },
    sessionKeyAddress,
    sessionKeyData: encodeAbiParameters(
      [
        { type: "address" },
        { type: "address" },
        { type: "address" },
        { type: "uint256" },
      ],
      [sessionKeyAddress, token, recipient, amount]
    ),
  }),
  createABISessionDatum({
    interval: {
      validUntil: 0,
      validAfter: 0,
    },
    sessionKeyAddress,
    contractAddress: nftAddress,
    functionSelector: "safeMint(address)",
    rules: [
      {
        offset: 0,
        condition: 0,
        referenceValue: smartAccountAddress,
      },
    ],
    valueLimit: 0n,
  }),
];

const { wait, session } = await createBatchSession(
  smartAccount,
  sessionStorageClient,
  leaves,
  withSponsorship
);

const {
  receipt: { transactionHash },
  success,
} = await wait();

const smartAccountWithSession = await createSessionSmartAccountClient(
  {
    accountAddress: smartAccountAddress, // Set the account address on behalf of the user
    bundlerUrl,
    paymasterUrl,
    chainId,
  },
  "DEFAULT_STORE", // Storage client, full Session or smartAccount address if using default storage
  "BATCHED"
);

const transferTx: Transaction = {
  to: token,
  data: encodeFunctionData({
    abi: parseAbi(["function transfer(address _to, uint256 _value)"]),
    functionName: "transfer",
    args: [recipient, amount],
  }),
};
const nftMintTx: Transaction = {
  to: nftAddress,
  data: encodeFunctionData({
    abi: parseAbi(["function safeMint(address _to)"]),
    functionName: "safeMint",
    args: [smartAccountAddress],
  }),
};

const txs = [nftMintTx, transferTx];
const leafIndexes = [1, 0]; // The order of the txs from the sessionBatch

const { wait: sessionWait } = await smartAccountWithSession.sendTransaction(
  txs,
  withSponsorship,
  { leafIndex: leafIndexes },
);

const { success } = await sessionWait();