Add native Solana balance and transfer support

- SolanaTransaction: hand-rolled compact-u16/legacy-Message/signed-tx
  wire-format primitives, cross-validated byte-for-byte against the
  solders Python library's own serialization of an identical System
  Program transfer message.
- SolanaApi: JSON-RPC client (getBalance/getLatestBlockhash/
  getFeeForMessage/sendTransaction) over a single POST endpoint, unlike
  Tron/Bitcoin's path-per-resource REST style.
- SolanaNativeAssetBalance: getBalance polling, same design as Bitcoin's
  mempool.space polling (no push/subscription mechanism available).
- RealSolanaTransactionService: builds a single-instruction transfer
  message, signs it raw via the existing Ed25519 signer dispatch
  (skipMessageHashing - Solana signs the message directly, no external
  hashing), broadcasts via sendTransaction. Fee is Solana's actual
  getFeeForMessage answer, not a client-side estimate.
- TransactionExecution.Solana(hash) variant; wired into AssetsModule via
  a new SolanaAssetsModule, following the Bitcoin/Tron precedent exactly.
This commit is contained in:
2026-07-16 18:49:29 -07:00
parent d35687f2ce
commit ecdb5ee44c
18 changed files with 1008 additions and 0 deletions
@@ -88,6 +88,18 @@ class TronFee(
override val asset: Chain.Asset
) : Fee
/**
* Fee for a Solana transaction, denominated in lamports, always paid in native SOL regardless of which asset is
* being sent (Solana has no separate "gas token" concept, same as Tron). [amount] is `getFeeForMessage`'s
* authoritative, exact answer for this specific compiled message (not an estimate the way Bitcoin's vsize-based
* fee is) - see `RealSolanaTransactionService`.
*/
class SolanaFee(
override val amount: BigInteger,
override val submissionOrigin: SubmissionOrigin,
override val asset: Chain.Asset
) : Fee
class SubstrateFeeBase(
override val amount: BigInteger,
override val asset: Chain.Asset