Skip to content

Guides

How to set up your agent wallet and call /settle

Wallet setup, funding, and end-to-end settlement — from oracle check through on-chain execution. No API key required.

Updated

DPX is sender-funded: when your agent calls /settle, DPX returns execution parameters and your agent runs approve() + router.settle() on-chain from its own wallet. DPX never holds or moves funds on your behalf.

This guide walks through every step from a blank wallet to a confirmed settlement.


  • An EVM wallet on Base (chainId 8453) with:
    • USDC equal to your settlement amount (goes to the recipient)
    • A small ETH buffer for gas (~$0.01 covers 5 settlements at Base rates)
    • A small USDC buffer for the x402 intelligence fee (0.5 bps of settlement amount, floor $0.001, cap $5.00)
  • Node 18+
Terminal window
npm install ethers x402-fetch

1. Create a self-custody EVM wallet

Any wallet that gives you the private key works: Coinbase Wallet, MetaMask, or generate one programmatically:

import { ethers } from 'ethers';
const wallet = ethers.Wallet.createRandom();
console.log(wallet.address); // your wallet address
console.log(wallet.privateKey); // store this securely — never commit it

2. Get USDC on Base

Buy USDC on an exchange and withdraw to your wallet on the Base network, or bridge from another chain. Your wallet must hold enough USDC to cover the gross settlement amount (after DPX fees).

3. Get ETH on Base for gas

Bridge a small amount of ETH to Base. Each settlement is two transactions: approve() + settle(). Gas on Base is typically under $0.01 total.

4. Configure your environment

Terminal window
export SETTLEMENT_WALLET_PRIVATE_KEY=0x... # your wallet private key
export RECIPIENT_ADDRESS=0x... # where settlement net lands

Every settlement runs through five stages:

oracle check (free) → fee quote (free) → POST /settle (x402 fee) → approve() → settle()

The first two are informational. The x402 fee is paid automatically by x402-fetch. The last two are on-chain transactions your wallet signs and broadcasts.


Check whether global conditions are safe before committing. Free, no auth.

const oracle = await fetch('https://stability.untitledfinancial.com/reliability')
.then(r => r.json());
// { status: "STABLE", score: 91, reasoning: "Yield curve normal, FX stress low." }
if (oracle.status === 'UNSTABLE') {
throw new Error('Oracle UNSTABLE — hold and retry');
}

Returns fees, net amount, and a quoteId valid for 300 seconds. Pass the quoteId to /settle to lock in the rate.

const { quote } = await fetch(
'https://agent.untitledfinancial.com/quote?amountUsd=10000&hasFx=false'
).then(r => r.json());
console.log(quote.fees.total.bps); // 85
console.log(quote.settlement.netUsd); // 9915
console.log(quote.quoteId); // "dpx_a1b2c3..."

Step 3 — POST /settle (x402 intelligence fee)

Section titled “Step 3 — POST /settle (x402 intelligence fee)”

/settle is gated by a small x402 payment that covers oracle signal + AI reasoning. x402-fetch handles the 402 → sign → retry cycle automatically — your code just calls fetch.

import { createSigner, wrapFetchWithPayment } from 'x402-fetch';
const signer = await createSigner('base', process.env.SETTLEMENT_WALLET_PRIVATE_KEY);
const fetchX402 = wrapFetchWithPayment(fetch, signer, BigInt(1 * 10 ** 6)); // $1 cap
const result = await fetchX402('https://agent.untitledfinancial.com/settle', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
amount: 10000,
sourceCurrency: 'USD',
destinationCurrency: 'USD',
recipientAddress: process.env.RECIPIENT_ADDRESS,
purpose: 'agent-payment',
referenceId: `ref-${Date.now()}`,
quoteId: quote.quoteId,
sandbox: false, // true to test without broadcasting
}),
}).then(r => r.json());
// result.status === 'authorized'
// result.execution has everything you need for the on-chain calls

A status of 'authorized' means DPX has verified the counterparty, checked compliance, and computed the execution params. Other statuses:

statusmeaning
authorizedReady to execute on-chain
sandboxDry run — no on-chain calls needed
heldOracle flagged the corridor — retry when conditions clear
reviewCompliance escalation — check complianceScreen in the response
failedSanctions block or hard validation failure

Authorize the DPX router to pull the settlement amount from your wallet. Nothing moves yet — this is a standard ERC-20 approval.

import { ethers } from 'ethers';
const { execution } = result;
const provider = new ethers.JsonRpcProvider('https://mainnet.base.org');
const wallet = new ethers.Wallet(process.env.SETTLEMENT_WALLET_PRIVATE_KEY, provider);
const erc20 = new ethers.Interface(['function approve(address,uint256) returns (bool)']);
const approveTx = await wallet.sendTransaction({
to: execution.tokenAddress,
data: erc20.encodeFunctionData('approve', [
execution.routerAddress,
execution.grossAmountRaw, // in USDC token decimals (6)
]),
});
await approveTx.wait();
console.log('approved:', approveTx.hash);

Pulls funds, runs final oracle checks, and nets the amount to the recipient. The router ABI is returned by /settle in execution.abi — you don’t need to hardcode it.

const router = new ethers.Interface(execution.abi);
const settleTx = await wallet.sendTransaction({
to: execution.routerAddress,
data: router.encodeFunctionData('settle', [
execution.recipient,
execution.grossAmountRaw,
execution.isCrossCurrency,
execution.quoteIdBytes32,
execution.tokenAddress,
]),
});
const receipt = await settleTx.wait();
console.log('settled:', settleTx.hash);
console.log('explorer: https://base.blockscout.com/tx/' + settleTx.hash);

A complete, runnable script is in the DPX protocol repo:

Terminal window
git clone https://github.com/untitledfinancial/dpx-protocol
cd dpx-protocol/examples
SETTLEMENT_WALLET_PRIVATE_KEY=0x... \
RECIPIENT_ADDRESS=0x... \
npx ts-node quickstart-settle.ts

To test the full flow without real funds:

Terminal window
SANDBOX=true \
SETTLEMENT_WALLET_PRIVATE_KEY=0x... \
RECIPIENT_ADDRESS=0x... \
npx ts-node quickstart-settle.ts

Oracle checks and compliance screening run live even in sandbox mode — only the on-chain transactions are skipped.


Before setting up a wallet at all, run the live oracle demo — no payment required:

GET https://agent.untitledfinancial.com/try?amount=10000&from=USD&to=USD

Returns the full oracle response your agent would get on a real /settle call.


If you’re building with Claude Desktop or Cursor, the MCP server wraps the full flow as tool calls:

{
"mcpServers": {
"dpx": {
"command": "npx",
"args": ["@untitledfinancial/dpx-mcp"]
}
}
}

Then in your session: settlement.quote → settlement.execute. The MCP layer handles oracle checks, x402 payment, and returns the execution params — on-chain signing still happens on your side.