Quickstart
Onboard a provider and send their first USDC payout. No code required for the first one.
Add NVDA Protocol with a coding agent
The fastest way to add NVDA Protocol to a platform you already run. Your checkout and your existing payout methods stay exactly where they are; NVDA becomes one more option in the payout picker.
Do it by hand
Start by creating an account and opening the dashboard. Everything below works in test mode without funding anything.
- Open ProvidersIn the dashboard sidebar, open
Providers. This is the list of connected accounts your platform pays. - Create an accountClick
+ Create. Add the provider's email and country. Leave the wallet blank; they add it themselves. - Share the onboarding linkCopy the hosted onboarding link and send it to the provider. They confirm their details and connect a USDC wallet. You get an
account.updatedwebhook when they finish. - Fund the platform walletOpen
Balancesand top up with USDC from any exchange or wallet. In test mode this button mints play money. - Send a transferOpen
Payouts, click+ New payout, pick the provider and an amount. It lands in seconds and costs about $0.002.
How it works
Your platform holds a USDC balance in a wallet you control. Each provider onboards once, proves who they are if you ask them to, and connects a wallet of their own.
A transfer is a signed USDC movement from your wallet to theirs on a low-cost network. There are no correspondent banks, no FX desk and no monthly account fee; the only cost is the network fee, which is a fraction of a cent.
Everything else is the part you already know: accounts, transfers, balances, events and webhooks with the same names and shapes as Stripe Connect, so your existing code paths keep working.
On-chain ledger
Every payout settles on Robinhood Chain (chain id 4663) through NVDAPayouts, a single ledger contract. A platform holds a USDC or USDG balance in it, connects provider accounts, and pays them; each payout is a real token transfer from the platform's balance to the provider's wallet. There is no protocol fee, so the only cost is gas.
The ledger is not a token. It holds no supply and there is nothing to buy in it; it is the payouts contract. You can inspect it on Blockscout (deployed at block 58,214,572). $PRO is a separate community token on the ponsfamily launchpad; it is not issued by the ledger and holding it grants no claim on any platform balance.
Source: contracts/src/NVDAPayouts.sol, published with the repository soon (Apache 2.0, 34 unit tests + mainnet fork tests). Try it with a wallet: demo dashboard → Switch to mainnet.
Functions
| Call | Who | What |
|---|---|---|
createPlatform(string name) | anyone | Registers a platform; the caller becomes its operator |
createAccount(uint256 platformId, address wallet, bytes32 ref) | operator | Connects a provider; ref is your own id for them |
setRestricted(uint256 accountId, bool) | operator | The KYC hold: payouts to that account revert while true |
deposit(uint256 platformId, address token, uint256 amount) | anyone | Funds a platform (after an ERC-20 approve) |
withdraw(uint256 platformId, address token, uint256 amount, address to) | operator | Takes funds back out |
transfer(uint256 platformId, uint256 accountId, address token, uint256 amount, bytes32 memo) | operator | Pays one provider from the platform's balance |
transferBatch(...) | operator | Up to 200 payouts in one transaction, all or nothing |
stats() · getPlatform · getAccount · platformsOf · accountsOf · balanceOf | view | Everything the dashboard and this site read |
Events
PlatformCreated, AccountCreated, AccountUpdated, Deposited, Withdrawn, TransferCreated, PayoutPaid — named after their Stripe Connect counterparts so an integration that already listens for account.updated or payout.paid maps one to one.
Units and tokens
Amounts are the token's base units. USDC (0x80e0…6cA8) and USDG (0x5fc5…d168) both use 6 decimals, so $250.00 is 250000000. Only allow-listed tokens can be deposited; this chain carries many impostor "USDC" tokens with 18 decimals, and the allowlist is what keeps a platform from funding itself with one.
Authentication
Every request carries a secret key. Test keys start with sk_nvda_test_, live keys with sk_nvda_live_. Keep them on the server.
curl https://api.example.com/v1/accounts \
-H "Authorization: Bearer sk_nvda_test_..."
Migrate from Stripe
Swap the import and the constructor. The rest of your integration stays as it is.
// before
import Stripe from 'stripe';
const client = new Stripe('sk_live_...');
// after
import { NVDA } from '@nvda/node';
const client = new NVDA('sk_nvda_live_...', 'api.example.com');
const provider = await client.accounts.create({
type: 'express',
country: 'JP',
email: 'kenji@rackspot.example',
});
await client.transfers.create({
amount: 324000, // in cents
currency: 'usdc',
destination: provider.id,
description: '412 GPU-hours · H100 SXM',
});
| Stripe Connect | NVDA Protocol |
|---|---|
accounts.create | Same |
accountLinks.create | Same, returns a hosted onboarding link |
transfers.create | Same, currency: 'usdc' |
payouts.create | Same, settles in seconds |
webhookEndpoints.create | Same events, same signatures |
Connected accounts
A connected account is one provider. It carries their details, verification state, wallet and a balance. Restrict an account to pause its payouts without touching anything else.
Fund your platform wallet
Send USDC to the address shown under Balances. Funds are available the moment the transfer confirms. There is no minimum and no holding period.
Identity verification
Verification is optional and per account. Turn on rules such as "verify above $1,000 a month" or "verify when a wallet is shared between accounts". When a rule trips, the account is marked Restricted, payouts pause, and the provider is asked for a document from their dashboard.
Self-hosting
NVDA Protocol is a single service plus Postgres. The public repository opens soon; this is what starting it looks like.
git clone
cd nvda-protocol
cp .env.example .env # fill in the values below
docker compose up -d
Environment variables
| Variable | What it is |
|---|---|
NVDA_DATABASE_URL | Postgres connection string |
NVDA_RPC_URL | RPC endpoint for the settlement network |
NVDA_TREASURY_KEY | Signing key for the platform wallet. Use a KMS in production; never commit it. |
NVDA_WEBHOOK_SECRET | Signs outgoing webhooks |
NVDA_PUBLIC_URL | Where hosted onboarding pages are served |
Deployment
Any host that runs a container works. Put the service behind TLS, point NVDA_PUBLIC_URL at it, and rotate the treasury key through your secrets manager rather than the environment file.
API reference
| Resource | Endpoints |
|---|---|
| Accounts | POST /v1/accounts · GET /v1/accounts/:id · POST /v1/account_links |
| Transfers | POST /v1/transfers · GET /v1/transfers |
| Payouts | POST /v1/payouts · GET /v1/payouts/:id |
| Balance | GET /v1/balance · GET /v1/balance_transactions |
| Events | GET /v1/events |
Webhooks
Register an endpoint and you receive account.updated, transfer.created, payout.paid, payout.failed and balance.available, signed with NVDA_WEBHOOK_SECRET in the same header format Stripe uses.