Client
The @mure/sdk client wraps the lower-level @mure/api-v2 client and a blockchain adapter into one interface. It handles transaction creation, API communication, and on-chain submission in one call.
Installation
Creating a Client
Use createClient to instantiate the client. You must provide an Adapter — the SDK ships with a viem adapter out of the box.
import { createClient, viem } 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 });Transfer
The transfer method creates a transfer intent via the API and immediately submits the resulting transaction through the adapter.
import { eth } from "@mure/sdk/accounts/evm";
const hash = await client.transfer({
to: eth("0x8f664a25158021EFb4470f9036431664ce9f7895"), // recipient address
asset: "USDC",
amount: 10_000_000n, // 10 USDC (6 decimals)
});Parameters
| Field | Type | Required | Description |
|---|---|---|---|
from | Address | No | Source address and chain. Defaults to the adapter's connected account. |
to | Address | Yes | Destination address and chain (same chain as from). |
asset | string | { in: Address; out: Address } | Yes | Token symbol, CAIP-10 asset, or swap pair. See Swaps. |
amount | bigint | Yes | Amount to transfer as a bigint. |
deadline | string | No | Latest execution time (ISO 8601). Defaults to +1 hour. |
callData | string | No | Hex-encoded calldata forwarded to recipient. |
Explicit from
When from is omitted, the client uses the adapter's connected account. You can also provide it explicitly:
import { sepolia } from "@mure/sdk/accounts/evm";
const hash = await client.transfer({
from: sepolia("0x3165fd5B9D37Ac9619aC5895CA33F308aB02a053"), // sender address
to: sepolia("0x8f664a25158021EFb4470f9036431664ce9f7895"), // recipient address
asset: "USDC",
amount: 10_000_000n, // 10 USDC (6 decimals)
});Swaps
To swap one asset for another on the same chain, pass an { in, out } object instead of a single asset string.
Both fields accept the same address formats as from and to.
import { base, eth } from "@mure/sdk/accounts/evm";
const USDC = eth("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
const NATIVE_ETH = eth("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE");
const hash = await client.transfer({
to: eth("0x8f664a25158021EFb4470f9036431664ce9f7895"),
asset: { in: USDC, out: NATIVE_ETH },
amount: 10_000_000n,
});Cross-chain bridges
To move assets across chains, set to to an address on a different chain than from. The SDK submits a single transfer call and Mure selects a bridge route automatically.
import { base, eth } from "@mure/sdk/accounts/evm";
const USDC = eth("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
const hash = await client.transfer({
from: eth("0x3165fd5B9D37Ac9619aC5895CA33F308aB02a053"),
to: base("0x8f664a25158021EFb4470f9036431664ce9f7895"),
asset: { in: USDC, out: USDC },
amount: 10_000_000n,
});Send
For transactions you have already constructed, use client.send to broadcast them through the configured adapter. Pass a single transaction or an array for EIP-5792 batch submission.
const hashes = await client.send([
{ to: "0x...", data: "0x...", value: 0n },
{ to: "0x...", data: "0x...", value: 0n },
]);send is useful when you want to combine Mure-generated transactions with your own calls, or when you are using a wallet model such as account abstraction or EIP-7702 that is covered by Mure's Unified Entrypoint.
EVM account helpers
The SDK ships with small helpers that build CAIP-10 identifiers for common EVM chains. They are available from @mure/sdk/accounts/evm.
import {
eth,
sepolia,
base,
baseSepolia,
hyperliquid,
hyperliquidTestnet,
} from "@mure/sdk/accounts/evm";
const mainnetAccount = eth("0x8f664a25158021EFb4470f9036431664ce9f7895");
// => "eip155:1:0x8f664a25158021EFb4470f9036431664ce9f7895"Use these helpers to keep addresses chain-scoped and avoid hand-written CAIP-10 strings in examples.
Error Handling
All SDK errors are surfaced as ClientServiceError. Wrap calls in try/catch to handle failures.
import { ClientServiceError } from "@mure/sdk";
import { eth } from "@mure/sdk/accounts/evm";
try {
const hash = await client.transfer({
to: eth("0x..."), // recipient address
asset: "USDC",
amount: 10_000_000n, // 10 USDC (6 decimals)
});
} catch (error) {
if (error instanceof ClientServiceError) {
console.error("Transfer failed:", error.message);
}
}Effect-TS Integration
For advanced use cases, you can access the client inside an Effect program.
import { Effect } from "effect";
import { ClientService } from "@mure/sdk";
import { eth } from "@mure/sdk/accounts/evm";
const program = Effect.gen(function* () {
const client = yield* ClientService;
const hash = yield* client.transfer({
to: eth("0x..."), // recipient address
asset: "USDC",
amount: 10_000_000n, // 10 USDC (6 decimals)
});
return hash;
});The ClientService is a Context.Service. Provide it via ClientService.layer combined with an Adapter and ApiClient.layer.
import { ClientService } from "@mure/sdk";
import { ApiClient } from "@mure/api-v2/client";
import { Effect } from "effect";
const runnable = program.pipe(
Effect.provide(ClientService.layer),
Effect.provide(adapter),
Effect.provide(ApiClient.layer("https://api.mure.app/v2")),
);
Effect.runPromise(runnable).then(console.log).catch(console.error);