import { parseUnits, stringToHex, hexToString, parseEventLogs } from 'viem';
const TOKEN = '0xB20f...'; // the B20 token you accept
const MERCHANT = '0x...'; // where payments land
const ABI = [
{ type: 'function', name: 'decimals', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint8' }] },
{ type: 'function', name: 'transferWithMemo', stateMutability: 'nonpayable',
inputs: [{ name: 'to', type: 'address' }, { name: 'amount', type: 'uint256' }, { name: 'memo', type: 'bytes32' }],
outputs: [{ type: 'bool' }] },
{ type: 'event', name: 'Memo', inputs: [
{ name: 'caller', type: 'address', indexed: true },
{ name: 'memo', type: 'bytes32', indexed: true },
] },
];
// Read decimals because B20 tokens range from 6 to 18.
const decimals = await publicClient.readContract({ address: TOKEN, abi: ABI, functionName: 'decimals' });
// Pay 10 tokens, tagging the transfer with an order ID.
const hash = await walletClient.writeContract({
address: TOKEN, abi: ABI, functionName: 'transferWithMemo',
args: [MERCHANT, parseUnits('10', decimals), stringToHex('order-42', { size: 32 })],
});
// The Memo event carries the order ID back. Read it from the receipt.
const receipt = await publicClient.waitForTransactionReceipt({ hash });
const [memo] = parseEventLogs({ abi: ABI, logs: receipt.logs, eventName: 'Memo' });
console.log(hexToString(memo.args.memo, { size: 32 }).replace(/\0+$/, '')); // "order-42"