Move hubd API to Impl temporarily

This commit is contained in:
2026-06-09 21:27:56 +02:00
parent eed626e95d
commit b48d809360
42 changed files with 1142 additions and 1 deletions
@@ -0,0 +1,220 @@
package com.r35157.libs.raydium;
import com.r35157.libs.valuetypes.basic.MoneyAmount;
import com.r35157.libs.valuetypes.basic.Range;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Set;
public interface Raydium {
/**
* Fetches the current price for a Raydium liquidity pool.
*
* <p>The price is fetched from Raydium using the supplied pool id. The pool id may refer
* to any Raydium liquidity pool supported by the implementation.</p>
*
* @param poolId the Raydium liquidity pool id
* @return the current pool price expressed as a Solana amount
* @throws IOException if the price could not be fetched or the response could not be parsed
* @throws InterruptedException if the calling thread is interrupted while fetching the price
*/
ΩSolanaAmountΩ fetchPoolPrice(ΩRaydiumLiquidityPoolIdΩ poolId) throws IOException, InterruptedException;
/**
* Fetches the Raydium liquidity pool ids where the supplied Solana owner address has positions.
*
* <p>The returned set contains unique pool ids and does not guarantee iteration order.</p>
*
* <p>An implementation may discover pools through multiple Raydium position mechanisms,
* including standard liquidity pool token holdings and concentrated liquidity position NFTs.
* The returned ids are aggregated under the common {@code ΩRaydiumLiquidityPoolIdΩ} ValueTag.</p>
*
* @param ownerAddress the Solana owner address to inspect
* @return the unique Raydium liquidity pool ids where the owner has a position
* @throws IOException if liquidity pool ids could not be fetched or parsed
* @throws InterruptedException if the calling thread is interrupted while fetching liquidity pool ids
*/
Set<ΩRaydiumLiquidityPoolIdΩ> fetchLiquidityPoolIds(ΩSolanaAddressΩ ownerAddress) throws IOException, InterruptedException;
/**
* Fetches the Raydium concentrated liquidity position NFT ids owned by a Solana address.
*
* <p>The supplied owner address is inspected for token holdings that are candidates for
* Raydium concentrated liquidity position NFTs. The implementation verifies the candidates
* against Raydium's concentrated liquidity program before returning them.</p>
*
* <p>The returned set contains position NFT ids, not pool ids. Callers can use the returned
* NFT ids to fetch concentrated position state and then determine which pools the positions
* belong to.</p>
*
* @param ownerAddress the Solana owner address to inspect
* @return the Raydium concentrated liquidity position NFT ids owned by the address
* @throws IOException if the position NFT ids could not be fetched or verified
* @throws InterruptedException if the calling thread is interrupted while fetching position NFT ids
*/
Set<ΩRaydiumLiquidityPoolPositionNftIdΩ> fetchConcentratedPositionNftIds(
ΩSolanaAddressΩ ownerAddress
) throws IOException, InterruptedException;
/**
* Fetches the total token amounts held by a standard Raydium liquidity pool.
*
* <p>The returned amounts represent the pool-level token reserves for token A and
* token B. They do not describe a single liquidity provider's share of the pool.</p>
*
* @param poolId the Raydium standard liquidity pool id
* @return the total token amounts held by the standard liquidity pool
* @throws IOException if the pool information could not be fetched or parsed
* @throws InterruptedException if the calling thread is interrupted while fetching the pool information
*/
RaydiumLiquidityPoolTokenAmounts fetchStandardLiquidityPoolTokenAmounts(
ΩRaydiumLiquidityPoolStandardIdΩ poolId
) throws IOException, InterruptedException;
/**
* Fetches the token amounts represented by an owner's position in a standard Raydium liquidity pool.
*
* <p>The returned amounts describe the owner's calculated share of token A and token B in the
* standard liquidity pool. The calculation is based on the owner's liquidity pool token holdings,
* the LP mint supply and the pool-level token reserves returned by Raydium.</p>
*
* <p><strong>Important:</strong> The returned amounts should be treated as an estimated pool-share
* view, not as an exact withdraw preview. Raydium's UI may show lower amounts when removing
* liquidity. For example, for pool {@code 8os8bnXoy5voKv3uBPPuVGyqWZGJaa2RRri5RbLUwPCY},
* the pool-share calculation returned approximately {@code 2.1594651 EVE / 31.867153 USDT},
* while Raydium's 100% withdraw preview showed approximately {@code 2.1062559 EVE / 31.55046 USDT}.</p>
*
* <p>// TODO To match Raydium's withdraw preview more precisely, this method should eventually use
* on-chain pool state and vault balances, excluding protocol, fund and creator fee buckets.
* Raydium's CPMM pool state contains fee fields and a {@code vault_amount_without_fee(...)}
* calculation that appears relevant for this. Until that is implemented, this method represents
* an estimate based on Raydium REST pool amounts and Solana LP supply.</p>
*
* <p>This method is specific to standard liquidity pools. Concentrated liquidity positions are
* represented differently and should use concentrated-position-specific methods.</p>
*
* @param ownerAddress the Solana owner address whose standard pool position should be inspected
* @param poolId the Raydium standard liquidity pool id
* @return the estimated token amounts represented by the owner's standard pool position
* @throws IOException if the position information could not be fetched, calculated or parsed
* @throws InterruptedException if the calling thread is interrupted while fetching the position information
*/
RaydiumLiquidityPoolTokenAmounts fetchStandardLiquidityPoolPositionTokenAmounts(
ΩSolanaAddressΩ ownerAddress,
ΩRaydiumLiquidityPoolStandardIdΩ poolId
) throws IOException, InterruptedException;
/**
* Fetches the raw Raydium concentrated position state for a position NFT.
*
* <p>The supplied NFT id identifies a concentrated liquidity position on Raydium. The returned
* state is a low-level Raydium representation of that position, including the pool id, tick
* boundaries and liquidity value decoded from the position account.</p>
*
* <p>This method does not calculate token amounts, price ranges or higher-level strategy values.
* Higher-level modules may use the returned state together with pool state, current price and CLMM
* math to calculate those values.</p>
*
* @param positionNftId the Raydium concentrated liquidity position NFT id
* @return the raw Raydium concentrated position state for the supplied position NFT
* @throws IOException if the position state could not be fetched or decoded
* @throws InterruptedException if the calling thread is interrupted while fetching the position state
*/
RaydiumConcentratedPositionState fetchConcentratedPositionState(
ΩRaydiumLiquidityPoolPositionNftIdΩ positionNftId
) throws IOException, InterruptedException;
/**
* Fetches basic information about a Raydium concentrated liquidity pool.
*
* <p>The returned information contains the pool id, token mint addresses,
* token decimals and the current pool price as reported by Raydium. This is
* low-level pool information that can be combined with concentrated position
* state to interpret ticks, price ranges and liquidity values.</p>
*
* <p>This method does not fetch an owner's position and does not calculate token
* amounts for a position.</p>
*
* @param poolId the Raydium concentrated liquidity pool id
* @return basic information about the concentrated liquidity pool
* @throws IOException if the pool information could not be fetched or parsed
* @throws InterruptedException if the calling thread is interrupted while fetching the pool information
*/
RaydiumConcentratedPoolInfo fetchConcentratedPoolInfo(
ΩRaydiumLiquidityPoolConcentratedIdΩ poolId
) throws IOException, InterruptedException;
/**
* Fetches the raw on-chain state for a Raydium concentrated liquidity pool.
*
* <p>The returned state is decoded from the Raydium concentrated pool account on Solana.
* It contains low-level CLMM state such as active liquidity, the current square-root price
* in Q64.64 format and the current tick index.</p>
*
* <p>This method is different from {@link #fetchConcentratedPoolInfo(ΩRaydiumLiquidityPoolConcentratedIdΩ)},
* which fetches pool information from Raydium's REST API. This method is intended for calculations
* that need fresher or more precise on-chain CLMM state than the REST API price field can provide.</p>
*
* <p>This method does not fetch token metadata, token decimals or position state. Those values
* must be supplied separately when needed for higher-level calculations.</p>
*
* @param poolId the Raydium concentrated liquidity pool id
* @return the raw on-chain state for the concentrated liquidity pool
* @throws IOException if the pool state could not be fetched or decoded
* @throws InterruptedException if the calling thread is interrupted while fetching the pool state
*/
RaydiumConcentratedPoolState fetchConcentratedPoolState(
ΩRaydiumLiquidityPoolConcentratedIdΩ poolId
) throws IOException, InterruptedException;
/**
* Calculates the price range represented by a Raydium concentrated liquidity position.
*
* <p>The returned range is calculated from the position's lower and upper tick indexes,
* adjusted by the token decimals from the concentrated pool information.</p>
*
* <p>Raydium concentrated liquidity ranges are treated as lower-inclusive and
* upper-exclusive. This avoids overlapping ownership at shared boundaries between
* adjacent tick ranges.</p>
*
* @param positionState the concentrated position state containing the lower and upper tick indexes
* @param poolInfo the concentrated pool information containing token decimals and pool context
* @param decimalPlaces the number decimal places in the resulting price currency
* @return the price range represented by the concentrated liquidity position
*/
Range<ΩPriceΩ> calculateConcentratedPositionPriceRange(
RaydiumConcentratedPositionState positionState,
RaydiumConcentratedPoolInfo poolInfo,
int decimalPlaces
);
/**
* Calculates the token amounts represented by a Raydium concentrated liquidity position using
* raw on-chain pool state for the current square-root price.
*
* <p>The returned amounts are calculated from the position liquidity, the position tick range,
* token decimals from the concentrated pool information, and the current square-root price from
* the supplied on-chain pool state. This can be more precise than using the REST API price field
* from {@link RaydiumConcentratedPoolInfo}.</p>
*
* <p>If the current pool price is below the position range, the position is represented as
* token A. If the current pool price is above the position range, the position is represented
* as token B. If the current pool price is inside the position range, the position is
* represented as a mix of token A and token B.</p>
*
* <p>This method performs only the mathematical conversion from Raydium concentrated position
* state and pool state to token amounts. It does not fetch position state, pool information or
* pool state.</p>
*
* @param positionState the concentrated position state containing tick indexes and liquidity
* @param poolInfo the concentrated pool information containing token mints and decimals
* @param poolState the on-chain concentrated pool state containing current square-root price and tick
* @return the token amounts represented by the concentrated liquidity position
*/
RaydiumLiquidityPoolTokenAmounts calculateConcentratedPositionTokenAmounts(
RaydiumConcentratedPositionState positionState,
RaydiumConcentratedPoolInfo poolInfo,
RaydiumConcentratedPoolState poolState
);
}
@@ -0,0 +1,30 @@
package com.r35157.libs.raydium;
import java.math.BigDecimal;
/**
* Represents basic information about a Raydium concentrated liquidity pool.
*
* <p>This record contains the pool-level information needed to interpret
* concentrated position state. The mint addresses and decimals are required when
* converting Raydium tick indexes into human-readable prices.</p>
*
* <p>This record is intentionally a low-level Raydium model. It does not describe
* an owner's position and does not calculate token amounts for a position.</p>
*
* @param poolId the Raydium concentrated liquidity pool id
* @param mintA the SPL mint address of token A
* @param mintADecimals the number of decimals used by token A
* @param mintB the SPL mint address of token B
* @param mintBDecimals the number of decimals used by token B
* @param priceEstimate the pool price estimate as reported by Raydium
*/
public record RaydiumConcentratedPoolInfo(
ΩRaydiumLiquidityPoolConcentratedIdΩ poolId,
ΩSPLMintAddressΩ mintA,
ΩamountDecimalsΩ mintADecimals,
ΩSPLMintAddressΩ mintB,
ΩamountDecimalsΩ mintBDecimals,
ΩPriceΩ priceEstimate
) {
}
@@ -0,0 +1,32 @@
package com.r35157.libs.raydium;
import java.math.BigInteger;
/**
* Represents raw on-chain state for a Raydium concentrated liquidity pool.
*
* <p>This record contains low-level CLMM pool state decoded from the Raydium
* concentrated liquidity pool account on Solana. It is different from
* {@link RaydiumConcentratedPoolInfo}, which represents pool information fetched
* from Raydium's REST API.</p>
*
* <p>The {@code sqrtPriceX64} field represents the current square-root price in
* Raydium's fixed-point Q64.64 format. This value can be used for more precise
* concentrated liquidity calculations than using the REST API price field.</p>
*
* <p>This record does not contain token mint metadata, decimals or display prices.
* Those values belong in {@link RaydiumConcentratedPoolInfo} or in higher-level
* calculations that combine pool state with pool information.</p>
*
* @param poolId the Raydium concentrated liquidity pool id
* @param liquidity the currently active liquidity in the pool
* @param sqrtPriceX64 the current square-root price in Q64.64 fixed-point format
* @param tickCurrent the current Raydium liquidity tick index
*/
public record RaydiumConcentratedPoolState(
ΩRaydiumLiquidityPoolConcentratedIdΩ poolId,
ΩRaydiumLiquidityΩ liquidity,
ΩRaydiumSqrtPriceX64Ω sqrtPriceX64,
ΩraydiumLiquidityTickIndexΩ tickCurrent
) {
}
@@ -0,0 +1,12 @@
package com.r35157.libs.raydium;
import java.math.BigInteger;
public record RaydiumConcentratedPositionState(
ΩRaydiumLiquidityPoolPositionNftIdΩ nftId,
ΩRaydiumLiquidityPoolConcentratedIdΩ poolId,
ΩraydiumLiquidityTickIndexΩ tickLowerIndex,
ΩraydiumLiquidityTickIndexΩ tickUpperIndex,
ΩRaydiumLiquidityΩ liquidity
) {
}
@@ -0,0 +1,29 @@
package com.r35157.libs.raydium;
import java.math.BigDecimal;
/**
* Represents a standard Raydium liquidity pool position.
*
* <p>A standard liquidity position is represented by ownership of liquidity pool
* tokens. The liquidity pool token mint identifies the LP token, while the SPL
* token account identifies where the owner holds the LP token balance.</p>
*
* <p>This record describes both the account holding the LP tokens and the amount
* of LP tokens held in that account. It does not represent a concentrated
* liquidity NFT position.</p>
*
* @param positionId the Raydium liquidity pool position id
* @param lpMintId the SPL mint address of the Raydium liquidity pool token
* @param lpAccount the Raydium liquidity pool account associated with the position
* @param lpTokenAccount the SPL token account holding the liquidity pool tokens
* @param lpTokenAmount the amount of liquidity pool tokens held in the SPL token account
*/
public record RaydiumLiquidityPoolPositionStandard(
ΩRaydiumLiquidityPoolPositionIdΩ positionId,
ΩRaydiumLiquidityPoolPositionMintIdΩ lpMintId,
ΩRaydiumLiquidityPoolAccountΩ lpAccount,
ΩSPLTokenAccountΩ lpTokenAccount,
ΩAmountΩ lpTokenAmount
) {
}
@@ -0,0 +1,18 @@
package com.r35157.libs.raydium;
import com.r35157.libs.valuetypes.basic.MoneyAmount;
/**
* Represents the price of a Raydium liquidity pool.
*
* <p>The pool id identifies the Raydium liquidity pool for which the price applies.
* The amount contains the price value returned or calculated for that pool.</p>
*
* @param poolId the Raydium liquidity pool id that the price belongs to
* @param amount the price amount for the liquidity pool
*/
public record RaydiumLiquidityPoolPrice(
ΩRaydiumLiquidityPoolIdΩ poolId,
MoneyAmount amount
) {
}
@@ -0,0 +1,28 @@
package com.r35157.libs.raydium;
import java.math.BigDecimal;
/**
* Represents token amounts for a Raydium liquidity pool or liquidity position.
*
* <p>The pool id identifies the Raydium liquidity pool that the amounts belong to.
* The two mint addresses identify the tokens in the pool, and the corresponding
* amounts describe how much of each token is represented.</p>
*
* <p>This record can be used for total pool amounts as well as calculated position
* amounts, depending on the method returning it.</p>
*
* @param poolId the Raydium liquidity pool id
* @param mintA the SPL mint address of token A
* @param amountA the amount of token A
* @param mintB the SPL mint address of token B
* @param amountB the amount of token B
*/
public record RaydiumLiquidityPoolTokenAmounts(
ΩRaydiumLiquidityPoolIdΩ poolId,
ΩSPLMintAddressΩ mintA,
ΩAmountΩ amountA,
ΩSPLMintAddressΩ mintB,
ΩAmountΩ amountB
) {
}
@@ -0,0 +1,30 @@
package com.r35157.libs.solana;
import java.math.BigDecimal;
/**
* Represents an SPL token holding owned by a Solana address.
*
* <p>The holding describes one SPL token account and the token mint it belongs to.
* The amount is represented both as a UI amount and as the raw on-chain amount,
* together with the number of decimals used by the token mint.</p>
*
* <p>The program id identifies which SPL token program owns the token account,
* for example the original SPL Token Program or the Token-2022 Program.</p>
*
* @param tokenAccount the SPL token account holding the token balance
* @param mintAddress the SPL mint address of the token
* @param uiAmount the human-readable token amount
* @param rawAmount the raw on-chain token amount before decimal conversion
* @param decimals the number of decimals used by the token mint
* @param programId the SPL token program id that owns the token account
*/
public record SPLTokenHolding(
ΩSPLTokenAccountΩ tokenAccount,
ΩSPLMintAddressΩ mintAddress,
ΩAmountΩ uiAmount,
ΩRawAmountΩ rawAmount,
ΩamountDecimalsΩ decimals,
ΩSPLProgramIdΩ programId
) {
}
@@ -0,0 +1,24 @@
package com.r35157.libs.solana;
import java.math.BigDecimal;
/**
* Represents the total supply of an SPL token mint.
*
* <p>The supply is represented both as a UI amount and as the raw on-chain amount,
* together with the number of decimals used by the token mint.</p>
*
* @param mintAddress the SPL mint address whose supply was fetched
* @param uiAmount the human-readable token supply
* @param rawAmount the raw on-chain token supply before decimal conversion
* @param decimals the number of decimals used by the token mint
* @param programId the SPL token program id for the mint
*/
public record SPLTokenSupply(
ΩSPLMintAddressΩ mintAddress,
ΩAmountΩ uiAmount,
ΩRawAmountΩ rawAmount,
ΩamountDecimalsΩ decimals,
ΩSPLProgramIdΩ programId
) {
}
@@ -0,0 +1,24 @@
package com.r35157.libs.solana;
/**
* Represents basic information about a Solana account.
*
* <p>The address identifies the account that was queried. The owner identifies
* the Solana program that owns the account. The account data is represented as
* a Base64 encoded string, matching the encoding returned by the Solana RPC
* account-info response.</p>
*
* <p>For normal wallet/system accounts, the data may be empty. Program-owned
* accounts, token accounts, mint accounts and application-specific state
* accounts may contain encoded account data.</p>
*
* @param address the Solana account address
* @param owner the Solana program id that owns the account
* @param dataBase64 the account data encoded as Base64, or an empty string if the account has no data
*/
public record SolanaAccountInfo(
ΩSolanaAddressΩ address,
ΩSolanaProgramIdΩ owner,
String dataBase64
) {
}
@@ -0,0 +1,146 @@
package com.r35157.libs.solana;
import com.r35157.libs.solana.valuetypes.SolanaProgramDerivedAddress;
import com.r35157.libs.solana.valuetypes.economic.SolanaSPLTokenProgram;
import com.r35157.libs.valuetypes.basic.MoneyAmount;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Provides read-oriented access to the Solana blockchain.
*
* <p>This interface exposes the Solana operations needed by higher-level
* integrations. It can fetch native SOL balances, SPL token holdings, NFT-like
* token holding candidates, account information and program derived addresses.</p>
*
* <p>The interface is intentionally generic and does not contain Raydium-specific
* logic. Higher-level integrations are expected to interpret Solana accounts,
* token holdings and derived addresses according to their own domain rules.</p>
*/
public interface SolanaBlockChain {
/**
* Fetches the native SOL balance for a Solana address.
*
* @param address the Solana address to inspect
* @return the native SOL balance for the address
* @throws IOException if the balance could not be fetched or parsed
* @throws InterruptedException if the calling thread is interrupted while fetching the balance
*/
ΩSolanaAmountΩ getBalanceInSolana(ΩSolanaAddressΩ address) throws IOException, InterruptedException;
/**
* Fetches the native SOL balance for a Solana address in lamports.
*
* <p>Lamports are the smallest unit of native SOL.</p>
*
* @param address the Solana address to inspect
* @return the native SOL balance for the address in lamports
* @throws IOException if the balance could not be fetched or parsed
* @throws InterruptedException if the calling thread is interrupted while fetching the balance
*/
ΩlamportsΩ getBalanceInLamport(ΩSolanaAddressΩ address) throws IOException, InterruptedException;
/**
* Fetches SPL token holdings owned by a Solana address for a specific token program.
*
* <p>The supplied token program decides which token accounts are inspected. For example,
* callers may query the original SPL Token Program or the Token-2022 Program depending
* on which token accounts they need to discover.</p>
*
* @param ownerAddress the Solana owner address whose token holdings should be inspected
* @param splProgramId the SPL token program to query
* @return a map of SPL mint addresses to token holding information
* @throws IOException if the token holdings could not be fetched or parsed
* @throws InterruptedException if the calling thread is interrupted while fetching token holdings
*/
Map<ΩSPLMintAddressΩ, SPLTokenHolding> getSPLTokenHoldings(
ΩSolanaAddressΩ ownerAddress,
SolanaSPLTokenProgram splProgramId
) throws IOException, InterruptedException;
/**
* Fetches NFT-like token mint address candidates owned by a Solana address for a specific token program.
*
* <p>This method identifies token holdings that look like NFTs within the supplied token
* program. A returned address is only a candidate. Higher-level integrations are responsible
* for deciding whether the returned address has domain-specific meaning.</p>
*
* // TODO This method currently identifies candidates from the owner's token holdings only.
* // A token with zero decimals and an owner balance of one is not guaranteed to be a real NFT,
* // because the mint's total supply may still be greater than one. A future implementation
* // should verify the mint supply, for example by using Solana getTokenSupply, before treating
* // the result as a confirmed NFT.
*
* @param ownerAddress the Solana owner address whose NFT-like holdings should be inspected
* @param splProgram the SPL token program to query
* @return the NFT-like Solana mint address candidates owned by the address
* @throws IOException if the NFT candidate addresses could not be fetched or parsed
* @throws InterruptedException if the calling thread is interrupted while fetching NFT candidate addresses
*/
Set<ΩSolanaNFTAddressΩ> getSolanaNFTCandidateAddresses(
ΩSolanaAddressΩ ownerAddress,
SolanaSPLTokenProgram splProgram
) throws IOException, InterruptedException;
/**
* Finds a Solana program derived address for a program id and a set of seeds.
*
* <p>The seeds describe the logical inputs used to derive the address. The implementation
* is responsible for converting each seed into the byte representation required by Solana.</p>
*
* @param programId the Solana program id used to derive the address
* @param seeds the seeds used when deriving the program address
* @return the derived Solana address together with its bump value
*/
SolanaProgramDerivedAddress findProgramAddress(
ΩSolanaProgramIdΩ programId,
List<SolanaProgramAddressSeed> seeds
);
/**
* Fetches account information for a Solana account address.
*
* <p>If the account does not exist, this method returns {@code null}. If the account exists,
* the returned value contains the account address, the owning Solana program id and the
* account data encoded as Base64.</p>
*
* @param accountAddress the Solana account address to inspect
* @return account information, or {@code null} if the account does not exist
* @throws IOException if the account information could not be fetched or parsed
* @throws InterruptedException if the calling thread is interrupted while fetching account information
*/
SolanaAccountInfo getAccountInfo(ΩSolanaAddressΩ accountAddress)
throws IOException, InterruptedException;
/**
* Encodes a raw 32-byte Solana address into its textual Solana address representation.
*
* <p>This method is intended for callers that have obtained raw Solana address bytes from
* account data and need the normal string representation used elsewhere in the API.</p>
*
* @param addressBytes the raw 32-byte Solana address
* @return the encoded Solana address
* @throws IllegalArgumentException if the supplied byte array is not a valid Solana address length
*/
ΩSolanaAddressΩ encodeSolanaAddress(byte[] addressBytes);
/**
* Fetches the total supply of an SPL token mint for a specific token program.
*
* <p>The supplied token program identifies which SPL token program owns the mint,
* for example the original SPL Token Program or the Token-2022 Program.</p>
*
* @param mintAddress the SPL mint address whose supply should be fetched
* @param splProgram the SPL token program to query
* @return the SPL token supply for the mint
* @throws IOException if the token supply could not be fetched or parsed
* @throws InterruptedException if the calling thread is interrupted while fetching token supply
*/
SPLTokenSupply getSPLTokenSupply(
ΩSPLMintAddressΩ mintAddress,
SolanaSPLTokenProgram splProgram
) throws IOException, InterruptedException;
}
@@ -0,0 +1,19 @@
package com.r35157.libs.solana;
/**
* Contains Solana-related constants used by the Solana integration.
*
* <p>This class is intended for shared constants that are part of the public
* Solana API surface or are useful across Solana-related modules.</p>
*/
public class SolanaConstants {
/**
* The default Solana JSON-RPC endpoint used by the integration.
*/
public static final String RPC_URL = "https://api.mainnet.solana.com";
/**
* The SPL mint address for Syrup USDC on Solana.
*/
public static final String SPL_TOKEN_SYRUPUSDC = "AvZZF1YaZDziPY2RCK4oJrRVrbN3mTD9NL24hPeaZeUj";
}
@@ -0,0 +1,51 @@
package com.r35157.libs.solana;
/**
* Represents a seed used when deriving a Solana program derived address.
*
* <p>A seed has a kind and a textual value. The kind tells the Solana
* implementation how the value should be converted to bytes before it is used
* in program address derivation.</p>
*
* <p>This keeps callers from having to perform encoding or decoding themselves.
* For example, a caller can provide a UTF-8 seed or a Solana address seed, and
* the implementation decides how each seed is converted to the byte format
* required by Solana.</p>
*
* @param kind the kind of seed
* @param value the textual seed value
*/
public record SolanaProgramAddressSeed(
SolanaProgramAddressSeedKind kind,
String value
) {
/**
* Creates a UTF-8 seed.
*
* @param value the text value to encode as UTF-8
* @return a program address seed representing the supplied UTF-8 text
*/
public static SolanaProgramAddressSeed utf8(String value) {
return new SolanaProgramAddressSeed(
SolanaProgramAddressSeedKind.UTF8,
value
);
}
/**
* Creates a Solana address seed.
*
* <p>The supplied address is represented textually here. The implementation
* deriving the program address is responsible for decoding the address into
* its raw Solana address bytes.</p>
*
* @param address the Solana address to use as a seed
* @return a program address seed representing the supplied Solana address
*/
public static SolanaProgramAddressSeed solanaAddress(ΩSolanaAddressΩ address) {
return new SolanaProgramAddressSeed(
SolanaProgramAddressSeedKind.SOLANA_ADDRESS,
address
);
}
}
@@ -0,0 +1,21 @@
package com.r35157.libs.solana;
/**
* Defines how a Solana program address seed should be converted to bytes.
*
* <p>Program derived addresses are calculated from byte seeds. This enum allows
* callers to describe the meaning of a seed without doing the byte conversion
* themselves.</p>
*/
public enum SolanaProgramAddressSeedKind {
/**
* A seed that should be encoded as UTF-8 text.
*/
UTF8,
/**
* A seed that represents a Solana address and should be decoded from its
* textual Solana address representation to raw address bytes.
*/
SOLANA_ADDRESS
}
@@ -0,0 +1,17 @@
package com.r35157.libs.solana.valuetypes;
/**
* Represents a Solana program derived address and its bump value.
*
* <p>A program derived address is a Solana address generated deterministically
* from a program id and a set of seeds. The bump value is the extra seed value
* used to find a valid program derived address for those inputs.</p>
*
* @param address the derived Solana address
* @param bump the bump value used when deriving the address
*/
public record SolanaProgramDerivedAddress(
ΩSolanaAddressΩ address,
int bump
) {
}
@@ -0,0 +1,21 @@
package com.r35157.libs.solana.valuetypes.economic;
import com.r35157.libs.valuetypes.basic.CurrencyType;
/**
* Represents an SPL token known to the Solana integration.
*
* <p>The currency type describes the economic identity of the token, while the
* mint address identifies the SPL token mint on Solana. The token address is the
* Solana address associated with the token in this model.</p>
*
* @param currencyType the currency type represented by this SPL token
* @param mintAddress the SPL mint address of the token
* @param tokenAddress the Solana address associated with the token
*/
public record SolanaSPLToken (
CurrencyType currencyType,
ΩSPLMintAddressΩ mintAddress,
ΩSolanaAddressΩ tokenAddress
) {
}
@@ -0,0 +1,44 @@
package com.r35157.libs.solana.valuetypes.economic;
/**
* Represents a Solana SPL token program supported by this integration.
*
* <p>Solana has more than one token program. The original SPL Token Program is
* used by many existing tokens, while the Token-2022 Program supports newer token
* functionality and extensions.</p>
*
* <p>The program address is used when querying token accounts owned by a wallet,
* for example when discovering SPL token holdings or NFT-like token holdings
* under a specific token program.</p>
*/
public enum SolanaSPLTokenProgram {
/**
* The original Solana SPL Token Program.
*/
SPL_TOKEN_PROGRAM("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
/**
* The Solana Token-2022 Program.
*/
TOKEN_2022_PROGRAM("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb");
/**
* Creates a Solana SPL token program entry.
*
* @param address the Solana program address for the token program
*/
SolanaSPLTokenProgram(ΩSPLProgramIdΩ address) {
this.address = address;
}
/**
* Returns the Solana program address for this token program.
*
* @return the SPL token program address
*/
public ΩSPLProgramIdΩ getAddress() {
return address;
}
private final ΩSPLProgramIdΩ address;
}
@@ -0,0 +1,6 @@
package com.r35157.libs.valuetypes.basic;
public record Credentials(
ΩUserNameΩ userName,
ΩPasswordΩ password
) {}
@@ -0,0 +1,15 @@
package com.r35157.libs.valuetypes.basic;
import org.jetbrains.annotations.NotNull;
import java.math.BigDecimal;
public record MoneyAmount(
ΩAmountΩ amount,
CurrencyType currencyType
) {
@Override
public @NotNull String toString() {
return amount + " " + currencyType();
}
}
@@ -0,0 +1,8 @@
package com.r35157.libs.valuetypes.basic;
import java.math.BigDecimal;
public record MoneyPrice(
ΩPriceΩ price,
CurrencyType currencyType
) { }
@@ -0,0 +1,7 @@
package com.r35157.libs.valuetypes.basic;
public record NetworkEndPoint(
ΩHostnameΩ hostName,
ΩportNumberΩ portNumber
) {
}
@@ -0,0 +1,43 @@
package com.r35157.libs.valuetypes.basic;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
public record Range<T extends Comparable<T>>(
T from,
boolean fromIncluding,
T to,
boolean toIncluding
) {
public Range {
Objects.requireNonNull(from, "from");
Objects.requireNonNull(to, "to");
if (from.compareTo(to) > 0) {
throw new IllegalArgumentException("Range from-value must not be greater than to-value.");
}
}
public boolean contains(T value) {
Objects.requireNonNull(value, "value");
int fromComparison = value.compareTo(from);
int toComparison = value.compareTo(to);
boolean afterFrom = fromIncluding
? fromComparison >= 0
: fromComparison > 0;
boolean beforeTo = toIncluding
? toComparison <= 0
: toComparison < 0;
return afterFrom && beforeTo;
}
@Override
public @NotNull String toString() {
return (fromIncluding() ? "[" : "(") + from + "," + to + (toIncluding() ? "]" : ")");
}
}
@@ -0,0 +1,9 @@
package com.r35157.nenjim.hubd.ctx;
import java.util.Set;
public interface ContextManager {
Context getDefault();
Context get(ΩContextIdΩ contextName);
Set<ΩContextIdΩ> getList();
}
@@ -0,0 +1,26 @@
package com.r35157.nenjim.hubd.journal;
import com.r35157.libs.valuetypes.basic.SemanticVersion;
import com.r35157.nenjim.hubd.module.Dependency;
import com.r35157.nenjim.hubd.module.Release;
import org.jetbrains.annotations.NotNull;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public record Journal(
@NotNull ΩJournalIdΩ id,
@NotNull String name,
@NotNull Set<Release> releases
) {
public Release getRelease(SemanticVersion version) {
Set<Dependency> dependencies = new HashSet<>();
return new Release(
new SemanticVersion(0, 1, 0),
new Date(),
null,
dependencies);
}
}
@@ -0,0 +1,8 @@
package com.r35157.nenjim.hubd.module;
import org.jetbrains.annotations.NotNull;
public record Dependency(
@NotNull ΩJournalIdΩ dependencyId
) {
}
@@ -0,0 +1,14 @@
package com.r35157.nenjim.hubd.module;
import com.r35157.libs.valuetypes.basic.SemanticVersion;
import org.jetbrains.annotations.NotNull;
import java.util.Date;
import java.util.Set;
public record Release(
@NotNull SemanticVersion version,
@NotNull Date releaseDate,
@NotNull ΩChecksumΩ checksum,
@NotNull Set<Dependency> dependencies
) {}