Monetize your API with x402
Recipes
Stake ETH From Fireblocks
Creates new validator keys and returns a staking transaction to deposit ETH to those validators. Then the staking transaction gets signed w Fireblocks API.
In this Recipe
- Provision validators
- Submit for Fireblocks signature
- Wait for Fireblocks signature
async function createValidators() {
const url = '<https://api.figment.io/ethereum/validators>';
const data = {
network: 'hoodi',
validators_count: 1,
withdrawal_address: '0x8C025F5EdaBE788A7f14Db861420aaE12CDf979f',
funding_address: '0x8C025F5EdaBE788A7f14Db861420aaE12CDf979f',
fee_recipient_address: '0x8C025F5EdaBE788A7f14Db861420aaE12CDf979f',
region: 'ca-central-1'
};
try {
const response = await axios.post(url, data, {
headers: {
'accept': 'application/json',
'content-type': 'application/json',
'x-api-key': process.env.FIGMENT_API_KEY
}
});
if (response.data && response.data.meta && response.data.meta.staking_transaction && response.data.meta.staking_transaction.contract_call_data) {
return response.data.meta.staking_transaction.contract_call_data;
} else {
console.log('Contract Call Data not found in the response.');
return null;
}
} catch (error) {
console.error('Error:', error.response ? error.response.data : error);
return null;
}
}
async function signWithFireblocks(contractAddress, contractCallData) {
console.log("Contract Call Data:", contractCallData);
return fireblocksApiClient.createTransaction({
operation: TransactionOperation.CONTRACT_CALL,
assetId: process.env.FIREBLOCKS_ASSET_ID,
source: {
type: PeerType.VAULT_ACCOUNT,
id: "1"
},
destination: {
type: PeerType.ONE_TIME_ADDRESS,
oneTimeAddress: {
address: contractAddress
}
},
note: "Contract Call Transaction",
amount: "32",
extraParameters: {
contractCallData
}
}).then(res => {
console.log(`✔ Submitted to Fireblocks for approval & signature. ID: ${res.id}`);
return res;
}).catch(e => {
console.error(`Fireblocks API Error: ${e.message}`);
});
}
async function waitForTxCompletion(fbTx) {
let tx = fbTx;
while (tx.status !== TransactionStatus.COMPLETED) {
if ([TransactionStatus.BLOCKED, TransactionStatus.FAILED, TransactionStatus.REJECTED, TransactionStatus.CANCELLED].includes(tx.status)) {
throw new Error(`Exiting the operation due to error. Transaction status: ${tx.status}`);
}
console.log("Transaction's status:", (await fireblocksApiClient.getTransactionById(fbTx.id)).status);
await new Promise(resolve => setTimeout(resolve, 4000));
tx = await fireblocksApiClient.getTransactionById(fbTx.id);
}
return (await fireblocksApiClient.getTransactionById(fbTx.id));
}
async function processValidators() {
const contractCallData = await createValidators();
if (contractCallData) {
const fbTx = await signWithFireblocks('0xA627f94a8F94E4713d38F52aC3a6377B0a111d47', contractCallData); // Use the actual contract address
if (fbTx) {
const fbRes = await waitForTxCompletion(fbTx);
console.log(fbRes);
}
}
}
// Execute the combined function
processValidators();
Monetize your API with x402
Use Figment's x402 Facilitator to charge per API call
Sample Code
import 'dotenv/config';
import express from 'express';
import { paymentMiddleware, x402ResourceServer } from '@x402/express';
import { ExactSvmScheme } from '@x402/svm/exact/server';
import { HTTPFacilitatorClient } from '@x402/core/server';
const svmAddress = process.env.SVM_ADDRESS;
const facilitatorUrl = process.env.FACILITATOR_URL || 'http://localhost:4022';
const facilitatorApiKey = process.env.FACILITATOR_API_KEY;
const facilitatorOrgId = process.env.FACILITATOR_ORG_ID;
const network = process.env.SVM_NETWORK || 'solana-devnet';
const port = Number(process.env.PORT || 4021);
if (!svmAddress) {
console.error('Set SVM_ADDRESS to the Solana wallet that should receive USDC payments.');
process.exit(1);
}
if (!facilitatorApiKey || !facilitatorOrgId) {
console.error('Set FACILITATOR_API_KEY (Kong bearer token) and FACILITATOR_ORG_ID (X-Figment-Org-Id) to authenticate against staking-accounts.');
process.exit(1);
}
const authHeaders = {
'x-api-key': facilitatorApiKey
};
const facilitatorClient = new HTTPFacilitatorClient({
url: facilitatorUrl,
createAuthHeaders: async () => ({
verify: authHeaders,
settle: authHeaders,
supported: authHeaders,
}),
});
const app = express();
app.use(
paymentMiddleware(
{
'GET /data': {
accepts: [
{
scheme: 'exact',
price: '$0.001',
network,
payTo: svmAddress,
},
],
description: 'Sample paid data endpoint',
mimeType: 'application/json',
},
},
new x402ResourceServer(facilitatorClient).register(network, new ExactSvmScheme()),
),
);
app.get('/data', (_req, res) => {
res.json({
secret: 'gm — you paid 0.001 devnet USDC for this',
timestamp: new Date().toISOString(),
});
});
app.listen(port, () => {
console.log(`sample data provider on http://localhost:${port}`);
console.log(` facilitator: ${facilitatorUrl}`);
console.log(` payTo: ${svmAddress}`);
console.log(` network: ${network}`);
});