Skip to main content

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

1

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.
2

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

ItemValue
Program IDRLAYHr9TRFcKB2ubYQhspcnXiaGpaVzNQvHytt47RZu
On-chain IDLSolana 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_v1donateV1 / getDonateV1Instruction, etc.).

SPL Token and Token-2022 (donate_v1, donate_pubkey_config_id_v1)

Instructionconfig_id in argsWhen to use
donate_v1[u8; 32]Matches EVM-style raw bytes from your backend.
donate_pubkey_config_id_v1pubkey (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)

Instructionconfig_id in argsWhen to use
donate_native_v1[u8; 32]Raw 32-byte config id (same as donate_v1).
donate_native_pubkey_config_id_v1pubkeySame 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).

Account metas (order)

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).
#AccountNotes
1epoch_tracker_v1PDA: seeds epoch_tracker_v1 · config_id (32 bytes) · mint.
2debouncer_v1PDA: seeds debouncer_v1 · config_id (32 bytes) · mint.
3debouncer_v1 vault ATAATA: authority = debouncer_v1, mint, correct token program.
4mintSPL or Token-2022 mint (must pass program mint policy).
5from_token_accountDonor’s ATA for mint (authority = from).
6fromDonor signer; also payer for init_if_needed.
7mint_whitelist_v1PDA: single seed mint_whitelist_v1 (global whitelist account).
8associated_token_programAssociated Token program: ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL.
9token_programSPL Token or Token-2022 program, matching mint and accounts.
10system_programSystem program.
11event_authorityPDA: seed __event_authority (Anchor event CPI).
12programDonation Relay program ID (self).
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.
#AccountNotes
1epoch_tracker_v1Same PDA seeds as SPL, with WSOL mint.
2debouncer_v1Same as SPL.
3debouncer_v1 vault ATADebouncer ATA for WSOL mint.
4mintCanonical WSOL mint for the chosen token_program (see above).
5donate_native_wsol_tmp_v1PDA: seeds donate_native_wsol_tmp_v1 · from · token_program; ephemeral vault for this donation.
6fromDonor signer; pays lamports for amount, rent for init / init_if_needed, and receives temp-account rent back on close.
7mint_whitelist_v1Same as SPL.
8associated_token_programSame as SPL.
9token_programAllowed native-donate programs only (legacy SPL Token or Token-2022, matching mint).
10system_programSystem program.
11event_authoritySame as SPL.
12programDonation 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).
AccountData lengthRent-exempt minimum (typical)
epoch_tracker_v190 bytes1,517,280 lamports (~0.00151728 SOL)
debouncer_v182 bytes1,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:
FieldTypeMeaning
daas_event_discriminatorenumEvent family discriminator.
config_id[u8; 32]Config the donation applied to.
mintpubkeyDonated mint.
epochu128Epoch when the donation was recorded.
gross_amountu64Total amount transferred in (base units).
tipu64Tip portion from tip_bps.
messagestringDonor message.
credited_topubkeyCredited 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