Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.velumx.xyz/llms.txt

Use this file to discover all available pages before exploring further.

Testing on Testnet

Test the full gasless flow end-to-end before deploying to mainnet.

1. Fund Your Testnet Relayer

Your VELUMX_API_KEY works on both mainnet and testnet — the relayer routes based on the network field in each request. You still need STX in your relayer’s testnet balance.
  1. Log in to the VelumX Dashboard and copy your Relayer Address.
  2. Go to the Stacks Testnet Faucet and request STX for your relayer address.
  3. Repeat for your test wallet address — you’ll need testnet STX to hold tokens for USER_PAYS testing.

2. Switch the SDK to Testnet

import { VelumXClient } from '@velumx/sdk';

const velumx = new VelumXClient({
  paymasterUrl: '/api/velumx',
  network: 'testnet',  // <-- switch here
});
Also pass network: 'testnet' to buildSponsoredContractCall:
const unsignedTx = await buildSponsoredContractCall({
  contractAddress: 'ST...',
  contractName: 'my-contract',
  functionName: 'my-function',
  functionArgs: [...],
  publicKey: userPublicKey,
  network: 'testnet',  // <-- and here
});

3. Use Testnet Contract Addresses

Testnet deployer addresses start with ST. The Bitflow testnet deployer is ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM. If you’re testing against your own paymaster contract, deploy it to testnet first using Clarinet or the Hiro Platform.

4. Run a Full DEVELOPER_SPONSORS Test

import { VelumXClient, buildSponsoredContractCall, RelayerError } from '@velumx/sdk';
import { uintCV, contractPrincipalCV } from '@stacks/transactions';
import { request } from '@stacks/connect';

const velumx = new VelumXClient({ paymasterUrl: '/api/velumx', network: 'testnet' });

// Get public key from connected testnet wallet
const addrResult = await request('stx_getAddresses') as {
  addresses: Array<{ address: string; publicKey: string }>;
};
const publicKey = addrResult.addresses[0].publicKey;

// Build a sponsored call against a testnet contract
const unsignedTx = await buildSponsoredContractCall({
  contractAddress: 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM',
  contractName: 'my-testnet-contract',
  functionName: 'my-function',
  functionArgs: [uintCV(1_000_000n)],
  publicKey,
  network: 'testnet',
});

const signResult = await request('stx_signTransaction', {
  transaction: unsignedTx instanceof Uint8Array
    ? Buffer.from(unsignedTx).toString('hex')
    : unsignedTx,
  broadcast: false,
});

try {
  const { txid } = await velumx.sponsor(signResult.transaction);
  console.log('Testnet txid:', txid);
  // Verify on: https://explorer.hiro.so/txid/<txid>?chain=testnet
} catch (err) {
  if (err instanceof RelayerError) {
    console.error('Relayer rejected:', err.reason);
  } else {
    throw err;
  }
}

5. Verify on the Testnet Explorer

Once you have a txid, check it on the Stacks Testnet Explorer:
https://explorer.hiro.so/txid/<txid>?chain=testnet
Look for:
  • Status: success — the sponsored transaction was accepted and executed.
  • Sponsored by: your relayer address — confirms VelumX co-signed correctly.
  • Fee payer: your relayer address — confirms the relayer paid STX gas, not the user.

6. Common Testnet Issues

IssueCauseFix
insufficient_relayer_balanceRelayer has no testnet STXFund via the faucet
invalid_sponsor_sigWrong network in buildSponsoredContractCallEnsure network: 'testnet' is set
contract_not_foundUsing a mainnet contract address on testnetDeploy your contract to testnet first
Wallet shows mainnetWallet not switched to testnetSwitch network in Leather/Xverse settings