Skip to content

Wallet concierge

The Wallet Concierge acts as a personal financial assistant within your Agent. It handles the user financial needs without you needing to worry about the logic.

As seen in this tweet

Features

Balance

Simply ask the concierge to check your balance, and it will provide you with the current amount in your wallet. For example, you can say:

Hey, check my balance.

The concierge will respond with your current balance.

// Balance checking implementation
if (skill === "balance") {
  const { balance } = await walletService.checkBalance(sender.address);
  await context.send({
    message: `Your agent wallet has a balance of ${balance}`,
    originalMessage: context.message,
  });
}

Funding

You can request to add funds to your wallet. If you try to exceed the maximum limit, the concierge will notify you. For instance, you might say:

Can you add 5 USDC to my wallet?

The concierge will handle the transaction.

// Funding logic
async function fund(context: Context, amount: number) {
  if (Number(balance) === 10) {
    await context.send({
      message: "You have maxed out your funds. Max 10 USDC.",
      receivers: [context.message.sender.address],
      originalMessage: context.message,
    });
    return false;
  }
 
  let onRampURL = await walletService.onRampURL(
    amount,
    walletData.agent_address,
  );
  const url = baselinks.paymentLink(
    walletData.agent_address,
    amount,
    onRamp ? onRampURL : undefined,
  );
  await context.send({
    message: url,
    originalMessage: context.message,
  });
}

Transfers

You can instruct the concierge to transfer funds to another user. If your balance is insufficient, it will inform you. For example, you might say:

Please send 5 USDC to @username.

The concierge will execute the transfer.

// Transfer implementation
if (skill === "transfer") {
  const { balance } = await walletService.checkBalance(sender.address);
  if (balance === 0) {
    await context.send({
      message: "You have no funds to transfer.",
      originalMessage: context.message,
      typeId: "reply",
    });
    return;
  }
 
  await context.send({
    message: `Transferring ${amount} USDC to ${recipient?.preferredName}`,
    originalMessage: context.message,
  });
  const tx = await walletService.transfer(
    sender.address,
    recipient?.address as string,
    amount,
  );
}

Swaps

You can instruct the concierge to swap tokens from one type to another. For example, you might say:

Please swap 0.1 ETH to USDC.

The concierge will execute the swap.

// Swap implementation
if (skill === "swap") {
  await walletService.swap(sender.address, fromToken, toToken, amount);
  await context.send({
    message: "Swap completed",
    originalMessage: context.message,
  });
  return;
}

Notifications

After a transaction, the concierge will notify you with a receipt and update your balance. It will also inform the recipient if they are on XMTP. For example, after sending funds, you will receive a message confirming the transaction and your new balance.

// Smart notifications
await notifyUser(context, sender.address, recipient?.address, tx, amount);

Installation

Concierge is a Skill already included in Message Kit.

import { concierge, createAgent } from "@xmtp/message-kit";
import { degen } from "./vibes/degen.js";
 
export const agent = createAgent({
  name: "Human Agent",
  tag: "@bot",
  description: "An agent that performs payments and transfers in usdc. .",
  intro:
    "You are a helpful agent called {agent_name} that helps people with their agent wallets. You can help them fund their wallets, check their balance and making transfers. All in usdc.",
  vibe: degen,
  skills: [concierge],
  config: {
    walletService: true,
  },
}).run();
 

Wallet Service

Wallet Service is a plugin that manages the Concierge uses for performing gasless transactions on behalf of the user.

  • Gasless
  • Onramp
  • Offramp
  • Swaps
  • Transfers

Learn more about the Wallet Service.