Try it now in Val Town Interactive playground to test Helius API calls
Click “Remix” to fork the playground, add your PAYER_KEYPAIR as an environment secret, and run live API calls.
Setup
Using @faremeter/rides
Advanced Setup
Set up your payment handler in just 3 lines: import { payer } from "@faremeter/rides" ;
// Load keypair and add wallet (auto-detects Solana or EVM)
const { PAYER_KEYPAIR } = process . env ;
if ( ! PAYER_KEYPAIR ) throw new Error ( "PAYER_KEYPAIR must be set" );
await payer . addLocalWallet ( PAYER_KEYPAIR );
@faremeter/rides automatically detects your network, looks up USDC, and sets up payments using your existing wallet.
All examples below use payer.fetch() instead of fetchWithPayer().
Set up your payment handler with full control: import {
clusterApiUrl ,
Connection ,
Keypair ,
PublicKey ,
} from "@solana/web3.js" ;
import { createLocalWallet } from "@faremeter/wallet-solana" ;
import { lookupKnownSPLToken } from "@faremeter/info/solana" ;
import {
createPaymentHandler ,
} from "@faremeter/payment-solana/exact" ;
import { wrap as wrapFetch } from "@faremeter/fetch" ;
// Load keypair from environment
const { PAYER_KEYPAIR } = process . env ;
if ( ! PAYER_KEYPAIR ) throw new Error ( "PAYER_KEYPAIR must be set" );
const network = "mainnet-beta" ;
// Lookup USDC mint address automatically
const usdcInfo = lookupKnownSPLToken ( network , "USDC" );
if ( ! usdcInfo ) throw new Error ( "Could not find USDC mint" );
const keypair = Keypair . fromSecretKey (
Uint8Array . from ( JSON . parse ( PAYER_KEYPAIR )),
);
const connection = new Connection ( clusterApiUrl ( network ));
const mint = new PublicKey ( usdcInfo . address );
const wallet = await createLocalWallet ( network , keypair );
const fetchWithPayer = wrapFetch ( fetch , {
handlers: [ createPaymentHandler ( wallet , mint , connection )],
});
This approach is required for browser apps, custom wallets, or when you need fine-grained control.
Example 1: getBalance
Query account balance through the proxy:
Using @faremeter/rides
Advanced Setup
const url = "https://helius.api.corbits.dev" ;
const payload = {
jsonrpc: "2.0" ,
id: 1 ,
method: "getBalance" ,
params: [ "corzHctjX9Wtcrkfxz3Se8zdXqJYCaamWcQA7vwKF7Q" ]
};
const response = await payer . fetch ( url , {
method: "POST" ,
headers: {
Accept: "application/json" ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ( payload ),
});
if ( ! response . ok ) {
const text = await response . text (). catch (() => "" );
throw new Error ( `HTTP ${ response . status } ${ response . statusText } ${ text } ` );
}
const data = await response . json ();
console . log ( "Balance:" , data . result . value / 1e9 , "SOL" );
const url = "https://helius.api.corbits.dev" ;
const payload = {
jsonrpc: "2.0" ,
id: 1 ,
method: "getBalance" ,
params: [ "corzHctjX9Wtcrkfxz3Se8zdXqJYCaamWcQA7vwKF7Q" ]
};
const response = await fetchWithPayer ( url , {
method: "POST" ,
headers: {
Accept: "application/json" ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ( payload ),
});
if ( ! response . ok ) {
const text = await response . text (). catch (() => "" );
throw new Error ( `HTTP ${ response . status } ${ response . statusText } ${ text } ` );
}
const data = await response . json ();
console . log ( "Balance:" , data . result . value / 1e9 , "SOL" );
Response:
{
"jsonrpc" : "2.0" ,
"id" : 1 ,
"result" : {
"context" : {
"slot" : 370340879 ,
"apiVersion" : "2.2.7"
},
"value" : 10030024
}
}
Example 2: getBlockHeight
Get current block height:
Using @faremeter/rides
Advanced Setup
const url = "https://helius.api.corbits.dev" ;
const payload = {
jsonrpc: "2.0" ,
id: 1 ,
method: "getBlockHeight"
};
const response = await payer . fetch ( url , {
method: "POST" ,
headers: {
Accept: "application/json" ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ( payload ),
});
if ( ! response . ok ) {
const text = await response . text (). catch (() => "" );
throw new Error ( `HTTP ${ response . status } ${ response . statusText } ${ text } ` );
}
const data = await response . json ();
console . log ( "Latest Block Height:" , data . result );
const url = "https://helius.api.corbits.dev" ;
const payload = {
jsonrpc: "2.0" ,
id: 1 ,
method: "getBlockHeight"
};
const response = await fetchWithPayer ( url , {
method: "POST" ,
headers: {
Accept: "application/json" ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ( payload ),
});
if ( ! response . ok ) {
const text = await response . text (). catch (() => "" );
throw new Error ( `HTTP ${ response . status } ${ response . statusText } ${ text } ` );
}
const data = await response . json ();
console . log ( "Latest Block Height:" , data . result );
Response:
{
"jsonrpc" : "2.0" ,
"result" : 348510722 ,
"id" : 2
}
Using Solana Web3.js
You can also use the Solana Web3.js library directly with a custom fetch:
Using @faremeter/rides
Advanced Setup
import { Connection , PublicKey } from "@solana/web3.js" ;
const rpcConn = new Connection (
"https://helius.api.corbits.dev" ,
{
fetch: payer . fetch ,
},
);
// Now use standard Web3.js methods
const balance = await rpcConn . getBalance (
new PublicKey ( "corzHctjX9Wtcrkfxz3Se8zdXqJYCaamWcQA7vwKF7Q" )
);
console . log ( `Balance: ${ balance / 1e9 } SOL` );
const blockHeight = await rpcConn . getBlockHeight ();
console . log ( `Block height: ${ blockHeight } ` );
const rpcConn = new Connection (
"https://helius.api.corbits.dev" ,
{
fetch: fetchWithPayer ,
},
);
// Now use standard Web3.js methods
const balance = await rpcConn . getBalance (
new PublicKey ( "corzHctjX9Wtcrkfxz3Se8zdXqJYCaamWcQA7vwKF7Q" )
);
console . log ( `Balance: ${ balance / 1e9 } SOL` );
const blockHeight = await rpcConn . getBlockHeight ();
console . log ( `Block height: ${ blockHeight } ` );
Complete Example
Here’s a full working example:
Using @faremeter/rides
Advanced Setup
import { payer } from "@faremeter/rides" ;
const { PAYER_KEYPAIR } = process . env ;
if ( ! PAYER_KEYPAIR ) throw new Error ( "PAYER_KEYPAIR must be set" );
// Setup - add wallet once
await payer . addLocalWallet ( PAYER_KEYPAIR );
// Make API call
const url = "https://helius.api.corbits.dev" ;
const payload = {
jsonrpc: "2.0" ,
id: 1 ,
method: "getBlockHeight" ,
};
const response = await payer . fetch ( url , {
method: "POST" ,
headers: {
Accept: "application/json" ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ( payload ),
});
if ( ! response . ok ) {
const text = await response . text (). catch (() => "" );
throw new Error ( `HTTP ${ response . status } ${ response . statusText } ${ text } ` );
}
const data = await response . json ();
console . log ( "Latest Block Height:" , data . result );
import {
clusterApiUrl ,
Connection ,
Keypair ,
PublicKey ,
} from "@solana/web3.js" ;
import { createLocalWallet } from "@faremeter/wallet-solana" ;
import { lookupKnownSPLToken } from "@faremeter/info/solana" ;
import {
createPaymentHandler ,
} from "@faremeter/payment-solana/exact" ;
import { wrap as wrapFetch } from "@faremeter/fetch" ;
const { PAYER_KEYPAIR } = process . env ;
if ( ! PAYER_KEYPAIR ) throw new Error ( "PAYER_KEYPAIR must be set" );
const network = "mainnet-beta" ;
const usdcInfo = lookupKnownSPLToken ( network , "USDC" );
if ( ! usdcInfo ) throw new Error ( "Could not find USDC mint" );
const keypair = Keypair . fromSecretKey (
Uint8Array . from ( JSON . parse ( PAYER_KEYPAIR )),
);
const connection = new Connection ( clusterApiUrl ( network ));
const mint = new PublicKey ( usdcInfo . address );
const wallet = await createLocalWallet ( network , keypair );
const fetchWithPayer = wrapFetch ( fetch , {
handlers: [ createPaymentHandler ( wallet , mint , connection )],
});
const url = "https://helius.api.corbits.dev" ;
const payload = {
jsonrpc: "2.0" ,
id: 1 ,
method: "getBlockHeight" ,
};
const response = await fetchWithPayer ( url , {
method: "POST" ,
headers: {
Accept: "application/json" ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ( payload ),
});
if ( ! response . ok ) {
const text = await response . text (). catch (() => "" );
throw new Error ( `HTTP ${ response . status } ${ response . statusText } ${ text } ` );
}
const data = await response . json ();
console . log ( "Latest Block Height:" , data . result );
Payment Flow
When you make a request, the following happens automatically:
Initial Request : Client sends RPC request
402 Response : Proxy returns payment requirements
{
"accepts" : [{
"network" : "solana-mainnet-beta" ,
"maxAmountRequired" : 10000 ,
"asset" : "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" ,
"payTo" : "corzHctjX9Wtcrkfxz3Se8zdXqJYCaamWcQA7vwKF7Q"
}]
}
Payment : Payment handler processes USDC transfer (0.01 USDC)
Success : Proxy fulfills original request with 200 OK
All of this is handled automatically by fetchWithPayer!
External Resources