Skip to content
Logo

Adapters

The @mure/sdk uses an adapter pattern to stay wallet-agnostic. An adapter implements the AdapterServiceApi contract, which tells the SDK how to send transactions, read the current account, and read the current chain.

The only adapter shipped today is built on viem, but you can write your own by satisfying the same interface.

AdapterService

AdapterService is an Effect Context.Service. It defines the boundary between the SDK and the blockchain.

Interface

MethodSignatureDescription
sendTransaction(tx: Transaction) => Effect<Hex, AdapterServiceError>Send a single transaction and return its hash.
sendTransactions(txs: Transaction[]) => Effect<Hex[], AdapterServiceError>Send a batch of transactions via sendCalls ( EIP-5792 ) and return the hashes.
accountEffect<CAIPAccountCompact>The active account address in CAIP-10 compact format.
chainEffect<CAIPChainCompact>The active chain identifier in CAIP-2 format.

AdapterServiceError

All adapter failures are surfaced as AdapterServiceError, a typed Effect error that carries the original cause.

import { AdapterServiceError } from "@mure/sdk";
 
// Error shape:
// {
//   _tag: "AdapterServiceError",
//   cause: Error  // the original viem or provider error
// }

ViemAdapter

ViemAdapter is the production adapter for any EVM chain. It wraps a viem WalletClient and implements the full AdapterServiceApi.

Factory: viem()

The viem() helper is the easiest way to create an adapter. It accepts either a ready-made WalletClient or a configuration object.

import { http } from "viem";
import { sepolia } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
import { createWalletClient } from "viem";
import { viem } from "@mure/sdk";
 
const walletClient = createWalletClient({
  chain: sepolia,
  transport: http(),
  account: privateKeyToAccount("0x..."), // replace with your private key
});
 
const adapter = viem(walletClient);

Batch transactions with sendTransactions

ViemAdapter supports EIP-5792 batch calls through the sendTransactions method. It calls viem's sendCalls with experimental_fallback: true, polls the call status until it is no longer pending, and returns the resulting transaction hashes. If the wallet does not support sendCalls, viem falls back to sending the transactions sequentially.

import { Effect } from "effect";
import { AdapterService } from "@mure/sdk";
 
const program = Effect.gen(function* () {
  const adapter = yield* AdapterService;
  const hashes = yield* adapter.sendTransactions([
    { to: "0x...", data: "0x...", value: 0n },
    { to: "0x...", data: "0x...", value: 0n },
  ]);
  return hashes;
});

Low-level: ViemAdapter

If you already have a WalletClient and want to skip the viem() factory, use ViemAdapter directly.

import { ViemAdapter } from "@mure/sdk";
 
const adapter = ViemAdapter(walletClient);

Usage

An adapter is required to create a Client. Pass it to createClient along with the API URL.

import { viem, createClient } from "@mure/sdk";
import { http } from "viem";
import { sepolia } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
 
const adapter = viem({
  chain: sepolia,
  transport: http(),
  account: privateKeyToAccount("0x..."), // replace with your private key
});
 
const client = createClient({ adapter });

For advanced Effect patterns, you can provide the adapter Layer to any program that requires AdapterService.

import { Effect } from "effect";
import { AdapterService } from "@mure/sdk";
 
const program = Effect.gen(function* () {
  const adapter = yield* AdapterService;
  const account = yield* adapter.account;
  console.log("Connected:", account);
});
 
const runnable = program.pipe(Effect.provide(adapter));