Skip to content

Setting Up an Advisor Account

An advisor manages trade proposals for one or more clients. Advisors don’t have a dedicated on-chain account — they are identified by their Solana wallet pubkey and tracked by the off-chain valuation service.

  • A Solana wallet with SOL for transaction fees
  • A client who has created an advisory account naming you as advisor

Give your wallet’s public key to clients who want to work with you. They will use it when creating their advisory account.

When a client creates an advisory account with your pubkey, it starts in Pending status. You must accept it to activate the relationship.

import { acceptAdvisoryAccount } from "./lib/program/client";
const txSig = await acceptAdvisoryAccount(
wallet,
connection,
advisoryAccountAddress, // the client's advisory account PDA
advisorFeeBps, // your fee in basis points (0-100)
sendTransaction,
);
  • advisor_fee_bps is your commission rate, charged on the input amount of each executed trade
  • Max: 100 bps (1.0%)
  • Example: at 25 bps, a 1000 USDC swap pays you 2.5 USDC
  • Fees are deducted from the swap input before the trade executes
  • A separate program fee (set by the protocol admin) is also deducted

On acceptance, the advisory account transitions from Pending to Active.

Once active, you can create encrypted trade proposals for the client:

import { createProposal } from "./lib/program/client";
import { encryptPayload } from "./lib/program/decrypt";
const payload = {
rationale: "SOL showing strength against USDC, recommend increasing SOL exposure",
amount: 1_000_000, // 1 USDC (6 decimals)
other_amount_threshold: 5_000_000, // min 0.005 SOL output (9 decimals)
amount_specified_is_input: true,
a_to_b: true,
pool: "pool_address_here",
token_mint_a: "USDC_mint_address",
token_mint_b: "SOL_mint_address",
pool_type: "cpmm",
};
// Encrypt with the client's on-chain x25519 public key
const encryptedData = encryptPayload(
payload,
ownerEncryptionKeyBytes, // from the advisory account's owner_encryption_key field
advisorX25519Keypair, // optional: pass for v2 envelope (both parties can decrypt)
);
const txSig = await createProposal(
wallet,
connection,
advisoryAccountAddress,
proposalCount, // current proposal_count from the advisory account
encryptedData,
sendTransaction,
);
VersionByte prefixWho can decryptUse case
v10x01Owner onlyDefault — ephemeral sender key
v20x02Owner + AdvisorPass your persistent x25519 keypair to encrypt

For v2, derive your x25519 keypair the same way the client does — sign the message beluga:x25519:v1 and hash the signature.

After the client approves a proposal, you have a window (60 seconds to 24 hours) to execute it. The executeProposal function handles all the Raydium CPI plumbing:

import { executeProposal } from "./lib/program/client";
const txSig = await executeProposal(
wallet,
connection,
sendTransaction,
{
address: proposalAddress,
advisoryAccount: advisoryAccountAddress,
owner: ownerPubkey,
pool: poolAddress,
tokenMintA,
tokenMintB,
aToB: true,
},
);

The function automatically:

  • Initializes missing vaults
  • Creates fee destination ATAs if needed
  • Routes to CP-Swap or CLMM based on the pool’s on-chain owner
  • Deducts program fee + advisor fee, then executes the swap

Advisor fees accumulate in your fee destination ATA (associated token account for the input token). You can also call withdrawFees to collect from the vault.

The off-chain valuation service automatically picks up your activity by polling on-chain data. No manual registration is needed — once you execute your first trade, the service creates an advisor record.

To set a display name:

Terminal window
curl -X POST https://valuation-production-2919.up.railway.app/api/v1/advisors/<your_pubkey>/name \
-H "Content-Type: application/json" \
-d '{"displayName": "Your Display Name"}'

Your performance metrics (win rate, Sharpe ratio, total P&L, valuation score) are computed automatically from executed trades and published via the leaderboard API.