Evelyn needs a generic way to burn SPL tokens owned by a Solana wallet. The first consumer will be the future EvelynBurnerService, which must burn EVE tokens after other assets have been swapped to EVE.
EVE uses Token-2022, but the implementation should be generic and support both the original SPL Token Program and Token-2022.
The responsibility should follow the existing separation used by sendSPLToken():
SolanaBlockChain builds the unsigned low-level transaction.
SolanaWallet resolves the required blockchain state, validates the requested amount, signs the transaction and submits it.
The wallet method receives the amount in the token’s human-readable decimal unit.
No new DeTag value types are required.
SolanaBlockChain implementation
Implement buildSPLTokenBurnTransaction() in SolanaBlockChainImpl.
The method must:
Build an unsigned transaction containing one checked SPL-token burn instruction (BurnChecked).
Use the supplied SolanaSPLTokenProgram, allowing both:
the original SPL Token Program
Token-2022
Use owner as:
transaction fee payer
token-account authority
required signer
Burn from the supplied token account and mint.
Fetch and use a recent blockhash in the same manner as the existing transaction builders.
Validate that rawAmount:
is a valid integer
is greater than zero
fits in an unsigned 64-bit integer
Validate that decimals fits in an unsigned byte.
Reject null, blank or otherwise invalid required arguments consistently with the existing transaction builders.
Return the unsigned serialized transaction without signing or submitting it.
SolanaWallet implementation
Implement burnSPLToken() in SolanaWalletImpl.
The method must:
Validate that the mint address is present and non-blank.
Validate that the requested amount is greater than zero.
Fetch the mint account and fail if it does not exist.
Detect the token program from the mint account’s owner.
Reject mints that are not owned by a supported SPL token program.
Fetch the mint supply to obtain its decimals.
Find the wallet’s token holding for the mint under the detected token program.
Fail if the wallet does not have a token account for the mint.
Verify that the token-account decimals match the mint decimals.
Convert the human-readable amount exactly into raw token units.
Reject amounts containing more decimal places than supported by the mint.
Reject amounts larger than the wallet’s token balance.
Allow burning the complete token balance.
Build the transaction through buildSPLTokenBurnTransaction().
Sign and submit it using the wallet’s existing signing and submission flow.
Return the transaction signature received from Solana RPC.
The method must return immediately after submission. It must not call awaitTransaction() automatically.
Use the existing exception conventions:
IllegalArgumentException for invalid input or invalid amount precision.
IllegalStateException for missing or inconsistent blockchain state and insufficient balance.
IOException for blockchain, signing or submission failures.
InterruptedException when the calling thread is interrupted.
CachedSolanaBlockChain
Add the new interface method to CachedSolanaBlockChain.
It must delegate directly to the underlying SolanaBlockChain. Transaction construction must not be cached.
Out of scope
The following are explicitly outside the scope of this issue:
Burning native SOL.
Burning wrapped SOL through Solana’s native mint.
A separate burnAllSPLToken() convenience method.
Automatically waiting for confirmation or finalization.
Automatic transaction retry.
Closing the token account after its complete balance has been burned.
Recovering the token account’s rent.
Multisignature authorities.
Approved delegates or Token-2022 permanent delegates.
Changes to EvelynBurnerService.
Discord notifications.
A token account must remain open after its complete token balance has been burned.
Testing constraint
Do not add, generate or modify unit tests as part of this issue.
Existing production and test sources may be compiled to verify that the API changes do not break the existing codebase, but no new unit-test implementation is requested.
Acceptance criteria
SolanaWallet exposes the generic burnSPLToken() operation.
SolanaBlockChain can build a checked SPL-token burn transaction.
Both the original SPL Token Program and Token-2022 are supported.
Human-readable token amounts are converted exactly to raw units.
Invalid amounts, unsupported mints, missing holdings and insufficient balances fail before transaction submission.
Burning the wallet’s complete token balance is supported without closing its token account.
The wallet signs and submits the transaction and returns its signature without waiting for confirmation.
CachedSolanaBlockChain delegates the new operation without caching.
No new DeTag value types are introduced.
No unit tests are added or modified.
The project compiles successfully.
## Background
Evelyn needs a generic way to burn SPL tokens owned by a Solana wallet. The first consumer will be the future `EvelynBurnerService`, which must burn EVE tokens after other assets have been swapped to EVE.
EVE uses Token-2022, but the implementation should be generic and support both the original SPL Token Program and Token-2022.
The responsibility should follow the existing separation used by `sendSPLToken()`:
* `SolanaBlockChain` builds the unsigned low-level transaction.
* `SolanaWallet` resolves the required blockchain state, validates the requested amount, signs the transaction and submits it.
## Public API
Add the following operation to `SolanaBlockChain`:
```java
SolanaUnsignedTransaction buildSPLTokenBurnTransaction(
ΩSolanaAddressΩ owner,
ΩSPLTokenAccountΩ tokenAccount,
ΩSPLMintAddressΩ mintAddress,
ΩRawAmountΩ rawAmount,
ΩamountDecimalsΩ decimals,
SolanaSPLTokenProgram splProgram
) throws IOException, InterruptedException;
```
Add the following operation to `SolanaWallet`:
```java
ΩSolanaTransactionSignatureΩ burnSPLToken(
ΩSPLMintAddressΩ mintAddress,
ΩAmountΩ amount
) throws IOException, InterruptedException;
```
The wallet method receives the amount in the token’s human-readable decimal unit.
No new DeTag value types are required.
## SolanaBlockChain implementation
Implement `buildSPLTokenBurnTransaction()` in `SolanaBlockChainImpl`.
The method must:
* Build an unsigned transaction containing one checked SPL-token burn instruction (`BurnChecked`).
* Use the supplied `SolanaSPLTokenProgram`, allowing both:
* the original SPL Token Program
* Token-2022
* Use `owner` as:
* transaction fee payer
* token-account authority
* required signer
* Burn from the supplied token account and mint.
* Fetch and use a recent blockhash in the same manner as the existing transaction builders.
* Validate that `rawAmount`:
* is a valid integer
* is greater than zero
* fits in an unsigned 64-bit integer
* Validate that `decimals` fits in an unsigned byte.
* Reject null, blank or otherwise invalid required arguments consistently with the existing transaction builders.
* Return the unsigned serialized transaction without signing or submitting it.
## SolanaWallet implementation
Implement `burnSPLToken()` in `SolanaWalletImpl`.
The method must:
1. Validate that the mint address is present and non-blank.
2. Validate that the requested amount is greater than zero.
3. Fetch the mint account and fail if it does not exist.
4. Detect the token program from the mint account’s owner.
5. Reject mints that are not owned by a supported SPL token program.
6. Fetch the mint supply to obtain its decimals.
7. Find the wallet’s token holding for the mint under the detected token program.
8. Fail if the wallet does not have a token account for the mint.
9. Verify that the token-account decimals match the mint decimals.
10. Convert the human-readable amount exactly into raw token units.
11. Reject amounts containing more decimal places than supported by the mint.
12. Reject amounts larger than the wallet’s token balance.
13. Allow burning the complete token balance.
14. Build the transaction through `buildSPLTokenBurnTransaction()`.
15. Sign and submit it using the wallet’s existing signing and submission flow.
16. Return the transaction signature received from Solana RPC.
The method must return immediately after submission. It must not call `awaitTransaction()` automatically.
Use the existing exception conventions:
* `IllegalArgumentException` for invalid input or invalid amount precision.
* `IllegalStateException` for missing or inconsistent blockchain state and insufficient balance.
* `IOException` for blockchain, signing or submission failures.
* `InterruptedException` when the calling thread is interrupted.
## CachedSolanaBlockChain
Add the new interface method to `CachedSolanaBlockChain`.
It must delegate directly to the underlying `SolanaBlockChain`. Transaction construction must not be cached.
## Out of scope
The following are explicitly outside the scope of this issue:
* Burning native SOL.
* Burning wrapped SOL through Solana’s native mint.
* A separate `burnAllSPLToken()` convenience method.
* Automatically waiting for confirmation or finalization.
* Automatic transaction retry.
* Closing the token account after its complete balance has been burned.
* Recovering the token account’s rent.
* Multisignature authorities.
* Approved delegates or Token-2022 permanent delegates.
* Changes to `EvelynBurnerService`.
* Discord notifications.
A token account must remain open after its complete token balance has been burned.
## Testing constraint
Do not add, generate or modify unit tests as part of this issue.
Existing production and test sources may be compiled to verify that the API changes do not break the existing codebase, but no new unit-test implementation is requested.
## Acceptance criteria
* `SolanaWallet` exposes the generic `burnSPLToken()` operation.
* `SolanaBlockChain` can build a checked SPL-token burn transaction.
* Both the original SPL Token Program and Token-2022 are supported.
* Human-readable token amounts are converted exactly to raw units.
* Invalid amounts, unsupported mints, missing holdings and insufficient balances fail before transaction submission.
* Burning the wallet’s complete token balance is supported without closing its token account.
* The wallet signs and submits the transaction and returns its signature without waiting for confirmation.
* `CachedSolanaBlockChain` delegates the new operation without caching.
* No new DeTag value types are introduced.
* No unit tests are added or modified.
* The project compiles successfully.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Background
Evelyn needs a generic way to burn SPL tokens owned by a Solana wallet. The first consumer will be the future
EvelynBurnerService, which must burn EVE tokens after other assets have been swapped to EVE.EVE uses Token-2022, but the implementation should be generic and support both the original SPL Token Program and Token-2022.
The responsibility should follow the existing separation used by
sendSPLToken():SolanaBlockChainbuilds the unsigned low-level transaction.SolanaWalletresolves the required blockchain state, validates the requested amount, signs the transaction and submits it.Public API
Add the following operation to
SolanaBlockChain:Add the following operation to
SolanaWallet:The wallet method receives the amount in the token’s human-readable decimal unit.
No new DeTag value types are required.
SolanaBlockChain implementation
Implement
buildSPLTokenBurnTransaction()inSolanaBlockChainImpl.The method must:
Build an unsigned transaction containing one checked SPL-token burn instruction (
BurnChecked).Use the supplied
SolanaSPLTokenProgram, allowing both:Use
owneras:Burn from the supplied token account and mint.
Fetch and use a recent blockhash in the same manner as the existing transaction builders.
Validate that
rawAmount:Validate that
decimalsfits in an unsigned byte.Reject null, blank or otherwise invalid required arguments consistently with the existing transaction builders.
Return the unsigned serialized transaction without signing or submitting it.
SolanaWallet implementation
Implement
burnSPLToken()inSolanaWalletImpl.The method must:
buildSPLTokenBurnTransaction().The method must return immediately after submission. It must not call
awaitTransaction()automatically.Use the existing exception conventions:
IllegalArgumentExceptionfor invalid input or invalid amount precision.IllegalStateExceptionfor missing or inconsistent blockchain state and insufficient balance.IOExceptionfor blockchain, signing or submission failures.InterruptedExceptionwhen the calling thread is interrupted.CachedSolanaBlockChain
Add the new interface method to
CachedSolanaBlockChain.It must delegate directly to the underlying
SolanaBlockChain. Transaction construction must not be cached.Out of scope
The following are explicitly outside the scope of this issue:
burnAllSPLToken()convenience method.EvelynBurnerService.A token account must remain open after its complete token balance has been burned.
Testing constraint
Do not add, generate or modify unit tests as part of this issue.
Existing production and test sources may be compiled to verify that the API changes do not break the existing codebase, but no new unit-test implementation is requested.
Acceptance criteria
SolanaWalletexposes the genericburnSPLToken()operation.SolanaBlockChaincan build a checked SPL-token burn transaction.CachedSolanaBlockChaindelegates the new operation without caching.