Compare commits
40 Commits
0.0.0
...
8de6dc259e
| Author | SHA256 | Date | |
|---|---|---|---|
| 8de6dc259e | |||
| 86171c9440 | |||
| 092ea1e320 | |||
| 214bb2ceeb | |||
| 5c87451208 | |||
| 922bdb58b0 | |||
| 62bee4feef | |||
| 83ef722d5b | |||
| 3b40027724 | |||
| 8af76e126a | |||
| 10fc0ff41c | |||
| f7e08b46b7 | |||
| 393a3a38b3 | |||
| 9cda922162 | |||
| 7935c8ae52 | |||
| 710ca98b43 | |||
| b33b35ba1e | |||
| 9716864f2e | |||
| 971c8b0f94 | |||
| f0bab2f5d9 | |||
| 3b0e916d46 | |||
| 7b319d8eb9 | |||
| 0b7c61393f | |||
| 8036892e07 | |||
| 82d9d4186a | |||
| c46a02472a | |||
| 1644631d96 | |||
| 26237b20d2 | |||
| 0a85f032d1 | |||
| e460b01bf1 | |||
| 185f03a98a | |||
| 64d58b2793 | |||
| 04e3bfbbee | |||
| 7f518109fc | |||
| e155df5ffd | |||
| cb7a341b75 | |||
| 58ff2751aa | |||
| 9988e03759 | |||
| eda81e73c6 | |||
| eccc5bcf62 |
+82
-4
@@ -1,3 +1,6 @@
|
|||||||
|
import org.gradle.api.tasks.Delete
|
||||||
|
import org.gradle.kotlin.dsl.registering
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
id("maven-publish")
|
id("maven-publish")
|
||||||
@@ -27,16 +30,91 @@ repositories {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val detag by configurations.creating {
|
||||||
|
isCanBeConsumed = false
|
||||||
|
isCanBeResolved = true
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.jetbrains:annotations:26.0.1")
|
detag("com.r35157.tools:detag-impl_ref:0.1.0")
|
||||||
|
compileOnly("org.jetbrains:annotations:26.1.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
toolchain { languageVersion.set(JavaLanguageVersion.of(24)) }
|
toolchain { languageVersion.set(JavaLanguageVersion.of(25)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<JavaCompile> {
|
tasks.withType<JavaCompile>().configureEach {
|
||||||
options.release.set(24)
|
options.release.set(25)
|
||||||
|
}
|
||||||
|
|
||||||
|
val generatedDetagMain = layout.buildDirectory.dir("generated/sources/detag/main/java")
|
||||||
|
|
||||||
|
val cleanGeneratedDetagMain by tasks.registering(Delete::class) {
|
||||||
|
delete(generatedDetagMain)
|
||||||
|
}
|
||||||
|
|
||||||
|
val detagMain by tasks.registering(JavaExec::class) {
|
||||||
|
group = "build"
|
||||||
|
description = "Generates Java sources from .tjava files"
|
||||||
|
|
||||||
|
classpath = detag
|
||||||
|
mainClass.set("com.r35157.tools.detag.impl.ref.Main")
|
||||||
|
|
||||||
|
val configFile = layout.projectDirectory.file("../detag.conf")
|
||||||
|
val sourceRoot = layout.projectDirectory.dir("src/main/tjava")
|
||||||
|
|
||||||
|
inputs.file(configFile)
|
||||||
|
inputs.dir(sourceRoot)
|
||||||
|
outputs.dir(generatedDetagMain)
|
||||||
|
|
||||||
|
dependsOn(cleanGeneratedDetagMain)
|
||||||
|
|
||||||
|
args(
|
||||||
|
"--config", configFile.asFile.absolutePath,
|
||||||
|
"--source-root", sourceRoot.asFile.absolutePath,
|
||||||
|
"--out", generatedDetagMain.get().asFile.absolutePath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
// Human-written Detag source files. IntelliJ should treat this as a source root.
|
||||||
|
// Gradle's Java compiler will still only compile .java files directly from sourceSets,
|
||||||
|
// so the .tjava files are not compiled directly.
|
||||||
|
java.srcDir("src/main/tjava")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.named<JavaCompile>("compileJava") {
|
||||||
|
dependsOn(detagMain)
|
||||||
|
|
||||||
|
// Compiler input generated from src/main/tjava.
|
||||||
|
// Do not add this directory to sourceSets, or IntelliJ will see duplicate classes:
|
||||||
|
// MyClass.tjava + build/generated/.../MyClass.java.
|
||||||
|
source(generatedDetagMain)
|
||||||
|
}
|
||||||
|
|
||||||
|
val libsDir = layout.buildDirectory.dir("libs")
|
||||||
|
|
||||||
|
tasks.register<Sync>("prepareLibs") {
|
||||||
|
group = "distribution"
|
||||||
|
description = "Copies runtime deps to build/libs without deleting the app jar"
|
||||||
|
|
||||||
|
val jarTask = tasks.named<Jar>("jar")
|
||||||
|
dependsOn(jarTask)
|
||||||
|
|
||||||
|
into(libsDir)
|
||||||
|
|
||||||
|
// Kun deps (transitivt)
|
||||||
|
from(configurations.runtimeClasspath)
|
||||||
|
|
||||||
|
// Bevar jar-filen som jar-tasken allerede har lagt i build/libs
|
||||||
|
preserve {
|
||||||
|
include(jarTask.get().archiveFileName.get())
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
export VERSION=$(git describe --tags --exact-match 2>/dev/null \
|
export VERSION=$(git describe --tags --exact-match 2>/dev/null \
|
||||||
|| git symbolic-ref --short -q HEAD \
|
|| git symbolic-ref --short -q HEAD \
|
||||||
|| git rev-parse --short HEAD)
|
|| git rev-parse --short HEAD)
|
||||||
|
|
||||||
echo "Building $VERSION..."
|
GITHASH=$(git rev-parse --short=8 HEAD)
|
||||||
|
|
||||||
|
export VERSION_LONG=${VERSION}_${GITHASH}
|
||||||
|
|
||||||
|
# Build this artifact
|
||||||
|
echo "Building 'NenjimHub API v${VERSION_LONG}'..."
|
||||||
|
|
||||||
./gradlew -Pversion=$VERSION jar
|
./gradlew -Pversion=$VERSION jar
|
||||||
|
|||||||
@@ -1 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
./gradlew clean ; rm -rf build
|
./gradlew clean ; rm -rf build
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
org.gradle.java.installations.auto-detect=true
|
org.gradle.java.installations.auto-detect=true
|
||||||
org.gradle.java.installations.fromEnv=JAVA_HOME
|
org.gradle.java.installations.fromEnv=JAVA_HOME
|
||||||
org.gradle.java.installations.paths=/usr/local/software/java/jfx-24
|
org.gradle.java.installations.paths=/usr/local/software/java/jfx-25
|
||||||
org.gradle.java.installations.auto-download=false
|
org.gradle.java.installations.auto-download=false
|
||||||
org.gradle.configuration-cache=true
|
org.gradle.configuration-cache=true
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-all.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
export VERSION=$(git describe --tags --exact-match 2>/dev/null \
|
export VERSION=$(git describe --tags --exact-match 2>/dev/null \
|
||||||
|| git symbolic-ref --short -q HEAD \
|
|| git symbolic-ref --short -q HEAD \
|
||||||
|| git rev-parse --short HEAD)
|
|| git rev-parse --short HEAD)
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
export VERSION=$(git describe --tags --exact-match 2>/dev/null \
|
export VERSION=$(git describe --tags --exact-match 2>/dev/null \
|
||||||
|| git symbolic-ref --short -q HEAD \
|
|| git symbolic-ref --short -q HEAD \
|
||||||
|| git rev-parse --short HEAD)
|
|| git rev-parse --short HEAD)
|
||||||
|
|||||||
Executable
+21
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SOURCE="$HOME/projects/com_r35157_nenjim-hubd-api"
|
||||||
|
TARGET="$HOME/projects/com_r35157_nenjim-hubd-api_github_snapshot"
|
||||||
|
|
||||||
|
rsync -a --delete \
|
||||||
|
--exclude '.git' \
|
||||||
|
"$SOURCE/" \
|
||||||
|
"$TARGET/"
|
||||||
|
|
||||||
|
cd "$TARGET"
|
||||||
|
git add -A
|
||||||
|
|
||||||
|
if git diff --cached --quiet; then
|
||||||
|
echo "No snapshot changes to publish."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
git commit -m "Mirror snapshot"
|
||||||
|
git push
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.r35157.libs.math;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.MathContext;
|
||||||
|
|
||||||
|
public interface UtilsBigDecimal {
|
||||||
|
BigDecimal min(BigDecimal a, BigDecimal b);
|
||||||
|
BigDecimal max(BigDecimal a, BigDecimal b);
|
||||||
|
BigDecimal sqrt(BigDecimal value, MathContext mc);
|
||||||
|
|
||||||
|
BigDecimal TWO = new BigDecimal("2");
|
||||||
|
BigDecimal THREE = new BigDecimal("3");
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.r35157.libs.math;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
public interface UtilsDouble {
|
||||||
|
double erf(BigDecimal x);
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.r35157.libs.notification;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface AddressedNotifier<
|
||||||
|
D extends NotificationDestination,
|
||||||
|
M extends NotificationMessage>
|
||||||
|
{
|
||||||
|
void push(D destination, M message) throws IOException;
|
||||||
|
|
||||||
|
default BoundNotifier<M> bind(D destination) {
|
||||||
|
return message -> push(destination, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.r35157.libs.notification;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface BoundNotifier<M extends NotificationMessage> {
|
||||||
|
void push(M message) throws IOException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package com.r35157.libs.notification;
|
||||||
|
|
||||||
|
public interface NotificationDestination {}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package com.r35157.libs.notification;
|
||||||
|
|
||||||
|
public interface NotificationMessage {
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.r35157.libs.solana.valuetypes;
|
||||||
|
|
||||||
|
import com.r35157.libs.valuetypes.basic.CurrencyType;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines well-known currency types used by the Solana integration.
|
||||||
|
*
|
||||||
|
* <p>Each enum value wraps a {@link CurrencyType} with a stable identifier and a
|
||||||
|
* human-readable currency name. These predefined values are intended for common
|
||||||
|
* currencies that the Solana-related modules need to reference consistently.</p>
|
||||||
|
*/
|
||||||
|
public enum WellKnownCurrencyTypes {
|
||||||
|
/**
|
||||||
|
* Native Solana currency.
|
||||||
|
*/
|
||||||
|
SOLANA(new CurrencyType(
|
||||||
|
UUID.fromString("019e0116-fce5-792f-a647-fa6da4dffec5"),
|
||||||
|
"Solana",
|
||||||
|
"SOL")
|
||||||
|
),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Syrup USDC token currency.
|
||||||
|
*/
|
||||||
|
SYRUPUSDC(new CurrencyType(
|
||||||
|
UUID.fromString("019e1d51-0600-7956-8231-f3b7058a91c2"),
|
||||||
|
"SyrupUSDC",
|
||||||
|
"SyrupUSDC")
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a well-known currency type entry.
|
||||||
|
*
|
||||||
|
* @param currencyType the currency type represented by this enum value
|
||||||
|
*/
|
||||||
|
WellKnownCurrencyTypes(CurrencyType currencyType) {
|
||||||
|
this.currencyType = currencyType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currency type represented by this enum value.
|
||||||
|
*
|
||||||
|
* @return the represented currency type
|
||||||
|
*/
|
||||||
|
public CurrencyType getCurrencyType() {
|
||||||
|
return currencyType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final CurrencyType currencyType;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.r35157.libs.valuetypes.basic;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public record CurrencyType(
|
||||||
|
UUID id,
|
||||||
|
String name,
|
||||||
|
String symbol
|
||||||
|
) {
|
||||||
|
@Override
|
||||||
|
public @NotNull String toString() {
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package com.r35157.libs.valuetypes.basic;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semantic Versioning (SemVer):
|
||||||
|
* A version number has the form MAJOR.MINOR.PATCH.
|
||||||
|
* - Increment MAJOR for incompatible API changes,
|
||||||
|
* - Increment MINOR for added functionality in a backward-compatible way,
|
||||||
|
* - Increment PATCH for backward-compatible bug fixes or improvements.
|
||||||
|
* TODO: Not the whole specification is implemented yet!
|
||||||
|
*/
|
||||||
|
public record SemanticVersion(int major, int minor, int patch) {
|
||||||
|
/**
|
||||||
|
* Creates a SemanticVersion and validates that all components are valid.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if any of {@code major}, {@code minor}, or {@code patch} is negative
|
||||||
|
*/
|
||||||
|
public SemanticVersion {
|
||||||
|
initializationGuardClause(major, minor, patch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SemanticVersion of(int major, int minor, int patch) {
|
||||||
|
return new SemanticVersion(major, minor, patch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SemanticVersion of(int major, int minor) {
|
||||||
|
return of(major, minor, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SemanticVersion of(int major) {
|
||||||
|
return of(major, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SemanticVersion of(@NotNull String versionStr) {
|
||||||
|
final String s = versionStr.trim();
|
||||||
|
|
||||||
|
final Matcher m = SEMVER_REGEX.matcher(s);
|
||||||
|
if (!m.matches()) {
|
||||||
|
throw new IllegalArgumentException("Invalid semantic version: '" + versionStr + "'!");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final int major = Integer.parseInt(m.group(1));
|
||||||
|
final int minor = m.group(2) != null ? Integer.parseInt(m.group(2)) : 0;
|
||||||
|
final int patch = m.group(3) != null ? Integer.parseInt(m.group(3)) : 0;
|
||||||
|
return of(major, minor, patch);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// Happens only with overruns
|
||||||
|
throw new IllegalArgumentException("Invalid semantic version: '" + versionStr + "'!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String toString() {
|
||||||
|
return "%d.%d.%d".formatted(major, minor, patch);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializationGuardClause(int major, int minor, int patch) throws IllegalArgumentException {
|
||||||
|
if (major < 0) throw new IllegalArgumentException("Version element 'major' cannot be negative - was '" + major + "'!");
|
||||||
|
if (minor < 0) throw new IllegalArgumentException("Version element 'minor' cannot be negative - was '" + minor + "'!");
|
||||||
|
if (patch < 0) throw new IllegalArgumentException("Version element 'patch' cannot be negative - was '" + patch + "'!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Pattern SEMVER_REGEX =
|
||||||
|
Pattern.compile("^(\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?$");
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.r35157.libs.valuetypes.basic;
|
||||||
|
|
||||||
|
public record SmtpConfiguration(
|
||||||
|
NetworkEndPoint networkEndPoint,
|
||||||
|
Credentials credentials
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package com.r35157.libs.valuetypes.basic;
|
||||||
|
|
||||||
|
public record TradingPair(
|
||||||
|
CurrencyType base, // The thing you are buying or selling.
|
||||||
|
CurrencyType quote // The currency/unit used to price the base asset.
|
||||||
|
) { }
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.r35157.nenjim.hubd;
|
||||||
|
|
||||||
|
import com.r35157.nenjim.hubd.journal.Journal;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public interface NenjimHub {
|
||||||
|
/**
|
||||||
|
* A no-operation (noop). This method is suppoted to do nothing.
|
||||||
|
*/
|
||||||
|
void noop();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param journal
|
||||||
|
*/
|
||||||
|
void monitorJournal(@NotNull Journal journal);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package com.r35157.nenjim.hubd;
|
|
||||||
|
|
||||||
public interface SomeInterface {
|
|
||||||
String concat(String x, String y);
|
|
||||||
void divideByZero() throws ArithmeticException;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.r35157.nenjim.hubd.ctx;
|
||||||
|
|
||||||
|
import com.r35157.libs.valuetypes.basic.SemanticVersion;
|
||||||
|
|
||||||
|
public record Context(
|
||||||
|
) {
|
||||||
|
public String getName() {
|
||||||
|
return "Some Context";
|
||||||
|
}
|
||||||
|
|
||||||
|
public SemanticVersion getVersion(String fqPackageName) {
|
||||||
|
return null; // new SemanticVersion(0, 1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.r35157.nenjim.hubd.journal;
|
||||||
|
|
||||||
|
public interface JournalManager {
|
||||||
|
Journal getJournal(String moduleName);
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package com.r35157.nenjim.hubd.module;
|
||||||
|
|
||||||
|
public record Module() {
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.r35157.libs.codec;
|
||||||
|
|
||||||
|
public interface Base58Codec {
|
||||||
|
String encode(byte[] input);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.r35157.libs.jupiter.perps;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Jupiter Perps position.
|
||||||
|
*
|
||||||
|
* <p>A Jupiter Perps position is represented on-chain by a Solana account owned by
|
||||||
|
* the Jupiter Perps program. This record contains the public API view of such a
|
||||||
|
* position.</p>
|
||||||
|
*
|
||||||
|
* @param positionAccount the Solana account address of the Jupiter Perps position
|
||||||
|
* @param entryPrice the entry price of the position, denominated in USDC
|
||||||
|
* @param direction whether the position is long or short
|
||||||
|
* @param tradedTokenMint the mint address of the token being traded
|
||||||
|
* @param collateralUsd the amount of USD representing the collateral for this position
|
||||||
|
*/
|
||||||
|
public record JupiterPerpsPositiono(
|
||||||
|
ΩJupiterPerpsPositionAccountΩ positionAccount,
|
||||||
|
ΩUSDCPriceΩ entryPrice,
|
||||||
|
JupiterPerpsPositionDirection direction,
|
||||||
|
ΩSPLMintAddressΩ tradedTokenMint,
|
||||||
|
ΩUSDCAmountΩ collateralUsd
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.r35157.libs.jupiter.perps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Direction of a Jupiter Perps position.
|
||||||
|
*/
|
||||||
|
public enum JupiterPerpsPositionDirection {
|
||||||
|
LONG,
|
||||||
|
SHORT
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.r35157.libs.jupiter.perps;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service for reading Jupiter Perps data.
|
||||||
|
*
|
||||||
|
* <p>This service is read-only. It does not open, close, modify, or sign transactions
|
||||||
|
* for Jupiter Perpetual Contracts.</p>
|
||||||
|
*
|
||||||
|
* <p>NOTICE: The first supported operation is reading a known Jupiter Perps position account
|
||||||
|
* and returning its decoded position data.</p>
|
||||||
|
*/
|
||||||
|
public interface JupiterPerpsService {
|
||||||
|
/**
|
||||||
|
* Reads a Jupiter Perps position from a known position account.
|
||||||
|
*
|
||||||
|
* <p>The supplied account must be the Solana account that stores the Jupiter Perps
|
||||||
|
* position state. It is not the wallet address, token account, custody account, pool
|
||||||
|
* account, or position request account.</p>
|
||||||
|
*
|
||||||
|
* @param positionAccount the Solana account address of the Jupiter Perps position
|
||||||
|
* @return the decoded Jupiter Perps position
|
||||||
|
* @throws IOException if the position account could not be fetched or decoded
|
||||||
|
* @throws InterruptedException if the calling thread is interrupted while fetching
|
||||||
|
* the position account
|
||||||
|
*/
|
||||||
|
JupiterPerpsPosition getPosition(ΩJupiterPerpsPositionAccountΩ positionAccount)
|
||||||
|
throws IOException, InterruptedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds open Jupiter Perps positions owned by a wallet.
|
||||||
|
*
|
||||||
|
* <p>This method returns decoded Jupiter Perps position objects. It does not return
|
||||||
|
* raw Solana accounts or account ids.</p>
|
||||||
|
*
|
||||||
|
* @param owner the wallet address that owns the Jupiter Perps positions
|
||||||
|
* @return the open Jupiter Perps positions owned by the wallet
|
||||||
|
* @throws IOException if the position accounts could not be fetched or decoded
|
||||||
|
* @throws InterruptedException if the calling thread is interrupted while fetching positions
|
||||||
|
*/
|
||||||
|
Set<JupiterPerpsPosition> getOpenPositions(ΩSolanaWalletIdΩ owner)
|
||||||
|
throws IOException, InterruptedException;
|
||||||
|
}
|
||||||
@@ -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,13 @@
|
|||||||
|
package com.r35157.libs.raydium;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
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,167 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches accounts owned by a Solana program using server-side account data filters.
|
||||||
|
*
|
||||||
|
* <p>This method uses Solana's {@code getProgramAccounts} RPC call. The supplied filters
|
||||||
|
* are sent to the RPC node, so matching is performed server-side instead of fetching all
|
||||||
|
* accounts owned by the program and filtering them locally.</p>
|
||||||
|
*
|
||||||
|
* <p>The initial supported filter type is {@link SolanaProgramAccountMemcmpFilter}, which
|
||||||
|
* matches bytes at a specific offset in the account data.</p>
|
||||||
|
*
|
||||||
|
* @param programId the Solana program id that owns the accounts to search
|
||||||
|
* @param filters the memcmp filters to apply when searching program accounts
|
||||||
|
* @return the matching program accounts
|
||||||
|
* @throws IOException if the program accounts could not be fetched or parsed
|
||||||
|
* @throws InterruptedException if the calling thread is interrupted while fetching program accounts
|
||||||
|
*/
|
||||||
|
Set<SolanaAccountInfo> getProgramAccounts(
|
||||||
|
ΩSolanaProgramIdΩ programId,
|
||||||
|
Set<SolanaProgramAccountMemcmpFilter> filters
|
||||||
|
) 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,17 @@
|
|||||||
|
package com.r35157.libs.solana;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter used when fetching accounts owned by a Solana program.
|
||||||
|
*
|
||||||
|
* <p>The initial supported filter type is {@code memcmp}, which asks the
|
||||||
|
* Solana RPC node to only return accounts where the account data at a specific
|
||||||
|
* byte offset matches a base58 encoded value.</p>
|
||||||
|
*
|
||||||
|
* @param offset the byte offset in the account data where comparison starts
|
||||||
|
* @param bytes the base58 encoded bytes to match
|
||||||
|
*/
|
||||||
|
public record SolanaProgramAccountMemcmpFilter(
|
||||||
|
int offset,
|
||||||
|
String bytes
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
) {}
|
||||||
Reference in New Issue
Block a user