Ripardocs
Dashboard

Quickstart

By the end of this page you will have an HTTP endpoint that refuses unpaid requests with a USDC price attached, and publishes a manifest any agent can read.

What Ripar is, and is not

Ripar is an SDK, a CLI and an MCP server. There is no hosting platform: nothing here builds, deploys or runs your code for you, and there is no account to create. You run the process; see Deploy anywhere for where to put it.

What you need

Node 20+, git, and an Algorand address to receive funds (Pera, Defly or any wallet).

1 · Install the SDK

@ripar/sdk is not on npm yet — npm install @ripar/sdk returns a 404. Install it from the repository:

git clone https://github.com/nickthelegend/ripar-sdk && cd ripar-sdk
npm install && npm run build
npm link                    # puts the `ripar` command on your PATH

The ripar command ships inside the SDK package — there is no separate CLI package. Check it:

ripar --version
ripar --help

2 · Scaffold an agent

ripar init my-agent --template basic
cd my-agent
npm install
npm link @ripar/sdk         # while the package is unpublished

--template takes basic (one echo endpoint), llm (completion, priced per requested token budget) or oracle (price quotes signed with an Algorand key).

The scaffolded agent.ts is an ordinary HTTP handler — there is nothing blockchain-shaped about it, and that is the point:

agent.ts
import { defineAgent, defineEndpoint, serve } from "@ripar/sdk";
 
const echo = defineEndpoint({
  name: "echo",
  description: "Returns the text it was given, priced per call.",
  // What a caller pays, per request, in USDC.
  price: "$0.001",
  input: {
    type: "object",
    properties: { text: { type: "string", minLength: 1, maxLength: 5000 } },
    required: ["text"],
    additionalProperties: false,
  },
  handler: ({ body, log }) => {
    const { text } = body as { text: string };
    log("echoing", { chars: text.length });
    return { echoed: text, chars: text.length };
  },
});
 
await serve(
  defineAgent({
    name: "My Agent",
    handle: "my-agent",
    description: "An agent scaffolded with `ripar init`.",
    // Settlement lands here directly — no Ripar account holds it on the way.
    payTo: process.env.RIPAR_PAY_TO!,
    network: (process.env.RIPAR_NETWORK as "mainnet" | "testnet") ?? "testnet",
    endpoints: [echo],
  }),
  { port: Number(process.env.PORT ?? 4021) }
);

Every option on defineEndpoint and serve is in the SDK reference.

3 · Set where you get paid

payTo comes from the environment, not from a config command:

cp .env.example .env
# RIPAR_PAY_TO=YOUR_ALGORAND_ADDRESS
# RIPAR_NETWORK=testnet
Nothing here holds your balance

Payments settle directly from the caller to the address in RIPAR_PAY_TO. The server process holds no key at all — it never signs anything, which is why a compromised agent cannot move money.

Job escrow is the one place a contract does take custody, it is opt-in per job, and it is not this stack. See Custody model.

Check the environment before you advertise a URL:

ripar doctor --network testnet
output
ok    node         v22.14.0
ok    payTo        KBDRZK3B…KEISKQ
ok    facilitator  https://facilitator.goplausible.xyz
ok    network      algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=
ok    fees         sponsored by ZMFK2OI7…67RA22AA — callers need USDC but no ALGO
ok    asset        USDC 10458941 on testnet

4 · Run it

ripar dev
output
ripar dev · node agent.ts (PORT=4021)
ripar · my-agent on :4021 (testnet)
  POST /echo  $0.001
  GET /.well-known/ripar.json
  GET /metrics · GET /_ripar/runs · GET /health   (unpaid)

ripar dev runs TypeScript directly through Node's own type stripping — no build step and no bundler.

5 · Prove the gate works

An unpaid request must be refused with the price attached:

curl -i -X POST http://localhost:4021/echo \
  -H 'content-type: application/json' \
  -d '{"text":"hello"}'
HTTP/1.1 402 Payment Required
PAYMENT-REQUIRED: <base64 JSON: accepts[].amount, asset, network, payTo>

A 200 here means the middleware is not in front of your route and you are giving the work away.

The requirements travel base64-encoded in the PAYMENT-REQUIRED header, not as plain JSON in the body. Read them with the CLI, which decodes for you:

ripar quote http://localhost:4021/echo --body '{"text":"hello"}'
output
http://localhost:4021/echo
  price     $0.001
  network   algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=
  payTo     KBDRZK3BV2YFJJAVV3S5XQYDWU4RDDI6EDXXKMG3O4AEVPEDCETDKEISKQ
 
Quoting is free and needs no wallet. `ripar call` pays it.

6 · Pay it

ripar call does both legs — quote, sign, retry. The wallet comes from the environment; there is deliberately no --mnemonic flag, because it would land in your shell history and in ps.

export RIPAR_MNEMONIC="twenty five words …"
ripar call http://localhost:4021/echo \
  --body '{"text":"hello"}' \
  --max-price 0.01 \
  --network testnet

Or in code:

pay.ts
import { RiparClient } from "@ripar/sdk";
 
const ripar = new RiparClient({
  mnemonic: process.env.RIPAR_MNEMONIC,
  network: "testnet",
  maxPrice: "0.01", // this client refuses anything above it — see /security
});
 
const res = await ripar.call("http://localhost:4021/echo", { text: "hello" });
 
console.log(res.data);          // { echoed: "hello", chars: 5 }
console.log(res.payment?.txId); // 7A2F…9C1B

That transaction is on Algorand. The USDC lands in the payTo wallet, not in an account on Ripar waiting for a payout run.

What just happened

  1. serve() wrapped your handler in x402 middleware that refuses unpaid calls with a price.
  2. It also mounted a free manifest at /.well-known/ripar.json, so a caller can learn the price and input schema before paying anything.
  3. A caller quoted, signed a USDC transfer for exactly that amount, and retried.
  4. The facilitator verified it, your handler ran, and settlement went caller → payTo.
Nothing listed you anywhere

Running an agent does not publish it. Discovery is a separate, manual step — and the SDK declares Bazaar discovery on each listed route, and the facilitator catalogues it when a payment is verified — so an endpoint is listed by being paid for. See Discovery for what actually works today.