Documentation Index
Fetch the complete documentation index at: https://docs.donate.gg/llms.txt
Use this file to discover all available pages before exploring further.
Donate.gg uses a config-driven donation pipeline. You interact with our on-chain program using metadata from Donation configs: the configId returned by the API is the on-chain routing key.
For EVM chains, see EVM.
How it works
Create a config via the API
Use the Configs endpoint to create a config that defines your
charity beneficiaries and weights. You receive an id object with hex and base58 fields —
both encode the same 32-byte identifier that routes donations to the correct destinations. Submit the Solana transaction
Call a public donate instruction on the Donation Relay program: SPL Token / Token-2022 use
donate_v1 or donate_pubkey_config_id_v1; native SOL uses donate_native_v1 or
donate_native_pubkey_config_id_v1 (see below for accounts and arguments).
The Donation Relay program routes donations into a per-config, per-mint debouncer_v1 PDA. For SPL Token and Token-2022, you transfer from the donor’s token account. For native SOL, dedicated instructions move lamports through an ephemeral wrapped-SOL vault (donate_native_wsol_tmp_v1) inside the program. Donations are accumulated per epoch; the relayer closes epochs and runs distribution (not callable by integrators).
Program ID and IDL
| Item | Value |
|---|
| Program ID | RLAYHr9TRFcKB2ubYQhspcnXiaGpaVzNQvHytt47RZu |
| On-chain IDL | Solana Explorer (IDL) |
The contract has been audited by Halborn and has gone through multiple rounds of review.
Mapping configId from the API
The API returns config IDs as { "hex": "0x...", "base58": "..." }. Both encode the same 32 bytes.
donate_v1 / donate_native_v1: use id.hex — strip the 0x prefix and decode the hex to [u8; 32] (left-to-right byte order).
donate_pubkey_config_id_v1 / donate_native_pubkey_config_id_v1: use id.base58 directly as a Pubkey (convenient when your stack already uses PublicKey types).
Instructions (integrators)
There are four public donate instructions, in two pairs. Within each pair the account layout and semantics are identical; only config_id encoding in the instruction data differs. On-chain names use snake_case (donate_native_v1, …). Generated TypeScript clients typically expose the native pair as donateNativeV1 and donateNativePubkeyConfigIdV1 (for example UMI) or getDonateNativeV1Instruction / getDonateNativePubkeyConfigIdV1Instruction (Codama-style kits); the SPL instructions follow the same pattern (donate_v1 → donateV1 / getDonateV1Instruction, etc.).
SPL Token and Token-2022 (donate_v1, donate_pubkey_config_id_v1)
| Instruction | config_id in args | When to use |
|---|
donate_v1 | [u8; 32] | Matches EVM-style raw bytes from your backend. |
donate_pubkey_config_id_v1 | pubkey (32 bytes) | Same logic, ergonomic for Solana PublicKey / Explorer-style tooling. |
Both transfer amount (base units of mint) from the donor’s token account into the debouncer_v1 vault ATA for (config_id, mint), with tip_bps, message (UTF-8; max 255 bytes), and credited_to.
Native SOL (donate_native_v1, donate_native_pubkey_config_id_v1)
| Instruction | config_id in args | When to use |
|---|
donate_native_v1 | [u8; 32] | Raw 32-byte config id (same as donate_v1). |
donate_native_pubkey_config_id_v1 | pubkey | Same as donate_pubkey_config_id_v1. |
These instructions donate lamports equal to amount: the program transfers lamports from the donor to an ephemeral donate_native_wsol_tmp_v1 PDA (wrapped-SOL token account), calls sync_native, runs the same donation core as SPL (transfer_checked into the debouncer_v1 vault), then close_account on the temp vault (rent returns to the donor). Arguments tip_bps, message, and credited_to match the SPL donate instructions. mint must be the canonical wrapped SOL mint for the token_program you pass: legacy SPL Token So11111111111111111111111111111111111111112, or Token-2022 9pan9bMn5HatX4EJdBwg9VgCa7Uz5HL8N1m5D3NdXejP.
All four instructions emit DonationMadeV1Event (see Events).
Pass accounts in this order (matches the IDL). Several PDAs use init_if_needed (or init for the native temp vault); the donor (from) pays rent when accounts are created.
PDAs are derived with the relay program ID as the program id. config_id in seeds is always the 32-byte config identifier (for *_pubkey_config_id_* instructions, the same bytes as the Pubkey argument).
donate_v1 and donate_pubkey_config_id_v1
| # | Account | Notes |
|---|
| 1 | epoch_tracker_v1 | PDA: seeds epoch_tracker_v1 · config_id (32 bytes) · mint. |
| 2 | debouncer_v1 | PDA: seeds debouncer_v1 · config_id (32 bytes) · mint. |
| 3 | debouncer_v1 vault ATA | ATA: authority = debouncer_v1, mint, correct token program. |
| 4 | mint | SPL or Token-2022 mint (must pass program mint policy). |
| 5 | from_token_account | Donor’s ATA for mint (authority = from). |
| 6 | from | Donor signer; also payer for init_if_needed. |
| 7 | mint_whitelist_v1 | PDA: single seed mint_whitelist_v1 (global whitelist account). |
| 8 | associated_token_program | Associated Token program: ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL. |
| 9 | token_program | SPL Token or Token-2022 program, matching mint and accounts. |
| 10 | system_program | System program. |
| 11 | event_authority | PDA: seed __event_authority (Anchor event CPI). |
| 12 | program | Donation Relay program ID (self). |
donate_native_v1 and donate_native_pubkey_config_id_v1
Same as SPL, except the donor’s source of funds is donate_native_wsol_tmp_v1 (program-owned PDA, init per instruction) instead of the donor’s ATA.
| # | Account | Notes |
|---|
| 1 | epoch_tracker_v1 | Same PDA seeds as SPL, with WSOL mint. |
| 2 | debouncer_v1 | Same as SPL. |
| 3 | debouncer_v1 vault ATA | Debouncer ATA for WSOL mint. |
| 4 | mint | Canonical WSOL mint for the chosen token_program (see above). |
| 5 | donate_native_wsol_tmp_v1 | PDA: seeds donate_native_wsol_tmp_v1 · from · token_program; ephemeral vault for this donation. |
| 6 | from | Donor signer; pays lamports for amount, rent for init / init_if_needed, and receives temp-account rent back on close. |
| 7 | mint_whitelist_v1 | Same as SPL. |
| 8 | associated_token_program | Same as SPL. |
| 9 | token_program | Allowed native-donate programs only (legacy SPL Token or Token-2022, matching mint). |
| 10 | system_program | System program. |
| 11 | event_authority | Same as SPL. |
| 12 | program | Donation Relay program ID (self). |
Minimum SOL and rent
The donate instructions use init_if_needed on epoch_tracker_v1, debouncer_v1, and the debouncer_v1 vault, with payer = from (the donor signer). Native donate also **init**s donate_native_wsol_tmp_v1 each time. Network transaction fees are additional (often paid by the same key as from, depending on your client).
Rent-exempt lamports come from the cluster Rent sysvar. The table below uses the standard mainnet-style formula (2-year exemption, 3480 lamports per byte-year, 128-byte account overhead). If your RPC or cluster parameters differ, use getMinimumBalanceForRentExemption(dataLength) with the on-chain data length (program account space, or token account size).
First donation for a given (config_id, mint)
These accounts are created once per config + mint pair (WSOL mint for native donate). Sizes match the on-chain program (EpochTrackerV1 / DebouncerV1 account space, standard SPL token account 165 bytes for the debouncer_v1 vault).
| Account | Data length | Rent-exempt minimum (typical) |
|---|
epoch_tracker_v1 | 90 bytes | 1,517,280 lamports (~0.00151728 SOL) |
debouncer_v1 | 82 bytes | 1,461,600 lamports (~0.0014616 SOL) |
debouncer_v1 vault (token account) | 165 bytes (standard SPL token account) | 2,039,280 lamports (~0.00203928 SOL) |
| Total (one-time, stays on-chain) | | 5,018,160 lamports (~0.00501816 SOL) |
Native SOL (donate_native_*) — temporary wrapped-SOL vault
donate_native_wsol_tmp_v1 is a 165-byte token account (same rent as above: ~0.00203928 SOL). It is **init**d at the start of the instruction and **close_account**d at the end, with rent returned to from in the same transaction. It is not an extra long-term cost, but the donor wallet must still have enough lamports at execution time to cover donation amount + this rent (plus any first-time rows above) until the close runs.
After the first donation (same config_id + mint)
No further rent is charged for epoch_tracker_v1, debouncer_v1, or the debouncer_v1 vault. For native donate, each transaction still briefly needs amount + ~0.00203928 SOL (donate_native_wsol_tmp_v1) plus fees. For SPL donate, the donor only needs SPL balance + SOL for fees (and an existing funded from_token_account).
Native SOL (overview)
Use donate_native_v1 / donate_native_pubkey_config_id_v1 when you want donors to spend native lamports without maintaining their own WSOL ATA balance; the program wraps through donate_native_wsol_tmp_v1 for you.
Alternatively, you can still pre-wrap SOL into the donor’s WSOL ATA and call donate_v1 / donate_pubkey_config_id_v1 with the WSOL mint, same as any other SPL mint.
Mint policy
Mints must either appear on the on-chain mint_whitelist_v1 PDA or satisfy strict safety checks (for example, no active mint/freeze authority; Token-2022 extensions such as transfer fee, transfer hook, and others are validated). Unsupported or unsafe mints fail with errors such as InvalidMint.
If you need a mint allowlisted, coordinate with Donate.gg; updating the whitelist is upsert_mint_whitelist_v1 (relayer-only).
Events
After a successful donation, observe DonationMadeV1Event:
| Field | Type | Meaning |
|---|
daas_event_discriminator | enum | Event family discriminator. |
config_id | [u8; 32] | Config the donation applied to. |
mint | pubkey | Donated mint. |
epoch | u128 | Epoch when the donation was recorded. |
gross_amount | u64 | Total amount transferred in (base units). |
tip | u64 | Tip portion from tip_bps. |
message | string | Donor message. |
credited_to | pubkey | Credited party. |
Relayer-only instructions (do not integrate)
These require the relayer signer and are not for end-user wallets:
close_donation_epoch_v1
distribute_non_swap_output_mint_v1
swap_then_distribute_v1
upsert_mint_whitelist_v1