{"id":13544389,"url":"https://github.com/sol4k/sol4k","last_synced_at":"2026-01-14T03:02:13.704Z","repository":{"id":65658548,"uuid":"595734363","full_name":"sol4k/sol4k","owner":"sol4k","description":"Kotlin, Java, and Android client for Solana ⛓️","archived":false,"fork":false,"pushed_at":"2025-12-27T21:57:40.000Z","size":489,"stargazers_count":120,"open_issues_count":10,"forks_count":31,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-12-29T22:57:35.708Z","etag":null,"topics":["blockchain","java","kotlin","solana","web3"],"latest_commit_sha":null,"homepage":"http://sol4k.org","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sol4k.png","metadata":{"files":{"readme":"docs/README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["Shpota"]}},"created_at":"2023-01-31T17:47:20.000Z","updated_at":"2025-12-29T13:30:52.000Z","dependencies_parsed_at":"2024-05-14T13:56:33.464Z","dependency_job_id":"32b1c9ac-958c-408f-a3de-62356562625c","html_url":"https://github.com/sol4k/sol4k","commit_stats":null,"previous_names":[],"tags_count":49,"template":false,"template_full_name":null,"purl":"pkg:github/sol4k/sol4k","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sol4k%2Fsol4k","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sol4k%2Fsol4k/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sol4k%2Fsol4k/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sol4k%2Fsol4k/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sol4k","download_url":"https://codeload.github.com/sol4k/sol4k/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sol4k%2Fsol4k/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408800,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","java","kotlin","solana","web3"],"created_at":"2024-08-01T11:00:47.539Z","updated_at":"2026-01-14T03:02:13.688Z","avatar_url":"https://github.com/sol4k.png","language":"Kotlin","readme":"# sol4k [![Maven Central](https://img.shields.io/maven-central/v/org.sol4k/sol4k?color=green)](https://central.sonatype.com/artifact/org.sol4k/sol4k) [![Build](https://github.com/sol4k/sol4k/actions/workflows/build.yml/badge.svg)](https://github.com/sol4k/sol4k/actions/workflows/build.yml) [![Style](https://github.com/sol4k/sol4k/actions/workflows/lint.yml/badge.svg)](https://github.com/sol4k/sol4k/actions/workflows/lint.yml) [![License](https://img.shields.io/badge/License-Apache_2.0-green.svg)](https://github.com/sol4k/sol4k/blob/main/LICENSE)\n\nEnglish │ \u003ca href=\"https://github.com/sol4k/sol4k/blob/main/docs/README_KR.md#sol4k----\"\u003e한국어 \u003c/a\u003e │ \u003ca href=\"https://github.com/sol4k/sol4k/blob/main/docs/README_ZH.md#sol4k----\"\u003e中文\u003c/a\u003e │ \u003ca href=\"https://github.com/sol4k/sol4k/blob/main/docs/README_JP.md#sol4k----\"\u003e日本語\u003c/a\u003e\n\nSol4k is a Kotlin client for Solana that can be used with Java or any other JVM\nlanguage, as well as on Android. It enables communication with an RPC node,\nallowing users to query information from the blockchain, create accounts, read\ndata from them, send different types of transactions, and work with key pairs\nand public keys. The client also exposes convenient APIs to make the developer\nexperience smooth and straightforward.\n\n## How to import\n\nGradle:\n```groovy\nimplementation 'org.sol4k:sol4k:0.7.0'\n```\n\nMaven:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.sol4k\u003c/groupId\u003e\n    \u003cartifactId\u003esol4k\u003c/artifactId\u003e\n    \u003cversion\u003e0.7.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## How to use\n\nCreate a connection, request the latest blockhash, and submit\na SOL transfer transaction from one account to another\n```kotlin\nval connection = Connection(RpcUrl.DEVNET)\nval blockhash = connection.getLatestBlockhash()\nval sender = Keypair.fromSecretKey(secretKeyBytes)\nval receiver = PublicKey(\"DxPv2QMA5cWR5Xfg7tXr5YtJ1EEStg5Kiag9HhkY1mSx\")\nval instruction = TransferInstruction(sender.publicKey, receiver, lamports = 1000)\nval message = TransactionMessage.newMessage(sender.publicKey, blockhash, instruction)\nval transaction = VersionedTransaction(message)\ntransaction.sign(sender)\nval signature = connection.sendTransaction(transaction)\n```\n\nCheck the [sol4k-examples](https://github.com/sol4k/sol4k-examples) repository to find\nready-to-use Java examples of sol4k APIs.\n\n## APIs\n\n### Working with key pairs and public keys.\n\nGenerating a keypair.\n```kotlin\nval generatedKeypair = Keypair.generate()\n```\n\nCreating a keypair from an existing secret.\n```kotlin\nval keypairFromSecretKey = Keypair.fromSecretKey(secretKeyByteArray)\n```\n\nCreating a public key from string.\n\n```kotlin\nval publicKey = PublicKey(\"DxPv2QMA5cWR5Xfg7tXr5YtJ1EEStg5Kiag9HhkY1mSx\")\n```\n\nCreating a public key from a byte array.\n\n```kotlin\nval publicKey = PublicKey(publicKeyByteArray)\n```\n\nObtaining an associated token account address for an SPL token.\n\n```kotlin\nval programDerivedAddress = PublicKey.findProgramDerivedAddress(holderAddress, tokenMintAddress)\n```\n\nConverting a public key to a string.\n\n```kotlin\nval publicKey = PublicKey(\"DxPv2QMA5cWR5Xfg7tXr5YtJ1EEStg5Kiag9HhkY1mSx\")\npublicKey.toBase58() // DxPv2QMA5cWR5Xfg7tXr5YtJ1EEStg5Kiag9HhkY1mSx\npublicKey.toString() // DxPv2QMA5cWR5Xfg7tXr5YtJ1EEStg5Kiag9HhkY1mSx\n```\n\n### Base 58 encoding\n\nDecoding data.\n\n```kotlin\nval decodedBytes: ByteArray = Base58.decode(\"DxPv2QMA5cWR5Xfg7tXr5YtJ1EEStg5Kiag9HhkY1mSx\")\n```\n\nEncoding data.\n```kotlin\nval encodedData: String = Base58.encode(inputByteArray)\n```\n\n### Working with signatures\n\nSigning a message.\n\n```kotlin\nval signature: ByteArray = keypair.sign(messageByteArray)\n```\n\nVerifying.\n\n```kotlin\nval result: Boolean = publicKey.verify(signature, message)\n```\n\n\n### RPC functions\n\nRPC calls are performed via a `Connection` class that exposes functions that mirror\n[the JSON RPC methods](https://docs.solana.com/api/http). A connection can be created\nwith an HTTP URL of an RPC node and a commitment.\n\n```kotlin\nval connection = Connection(RpcUrl.DEVNET, Commitment.PROCESSED)\n```\n\nIf commitment is not specified, `FINALIZED` is used by default.\n\n```kotlin\nval connection = Connection(RpcUrl.DEVNET)\n```\n\nYou can also pass RPC URL as a string.\n\n```kotlin\nval connection = Connection(\"https://api.devnet.solana.com\")\n```\n\nRPC methods that require commitment will use the one specified during the connection\ncreation or can be overridden by passing commitment as an additional argument.\n\n```kotlin\nval connection = Connection(RpcUrl.DEVNET, Commitment.CONFIRMED)\n// a blockhash with the 'confirmed' commitment\nval blockhash = connection.getLatestBlockhash() \n// commitment is overridden by 'finalized'\nval finalizedBlockhash = connection.getLatestBlockhash(Commitment.FINALIZED)\n```\n\nSupported APIs:\n- `getAccountInfo`\n- `getBalance`\n- `getEpochInfo`\n- `getFeeForMessage`\n- `getHealth`\n- `getIdentity`\n- `getLatestBlockhash`\n- `getMinimumBalanceForRentExemption`\n- `getMultipleAccounts`\n- `getRecentPrioritizationFees`\n- `getTokenAccountBalance`\n- `getTokenSupply`\n- `getTransactionCount`\n- `getVersion`\n- `isBlockhashValid`\n- `requestAirdrop`\n- `sendTransaction`\n- `simulateTransaction`\n\n### Transactions\n\nSol4k supports versioned transactions and legacy transactions with\nthe `VersionedTransaction` and `Transaction` classes correspondingly.\nBoth classes support similar APIs and can be used to build, sign,\nserialize, deserialize and send Solana transactions. It is recommended\nto use `VersionedTransaction` in the new code. A transaction can be\ncreated by specifying the latest blockhash, one or several instructions,\nand a fee payer.\n\n```kotlin\nval message = TransactionMessage.newMessage(feePayer, blockhash, instruction)\nval transaction = VersionedTransaction(message)\n```\n\nA versioned transaction with multiple instructions:\n\n```kotlin\nval message = TransactionMessage.newMessage(feePayer, blockhash, instructions)\nval transaction = VersionedTransaction(message)\n```\n\nLegacy transaction:\n```kotlin\nval transaction = Transaction(blockhash, instructions, feePayer)\n```\n\n`Instruction` is an interface that requires having the following data:\n```kotlin\ninterface Instruction {\n    val data: ByteArray\n    val keys: List\u003cAccountMeta\u003e\n    val programId: PublicKey\n}\n```\nThe `Instruction` interface has several implementations such as `TransferInstruction`,\n`SplTransferInstruction`, `CreateAssociatedTokenAccountInstruction`, and `BaseInstruction`\n(the one used for sending arbitrary transactions).\n\n`AccountMeta` is a class that lets you specify metadata for the accounts used in an instruction.\nIt requires a public key and two boolean values: `signer` and `writable`.\n\n```kotlin\nval accountMeta = AccountMeta(publicKey, signer = false, writable = true)\n```\nIt also has three convenience functions to construct objects with different combinations of\nproperties.\n\n```kotlin\nval signerAndWritable: AccountMeta = AccountMeta.signerAndWritable(publicKey)\nval signer: AccountMeta = AccountMeta.signer(publicKey)\nval writable: AccountMeta = AccountMeta.writable(publicKey)\n```\n\nHere's an example of combining everything together: creating a transaction that sends\ninformation to a game program.\n\n```kotlin\nval instructionData = byteArrayOf(-3, -42, 48, -55, 100, -55, -29, -37) \nval accounts = listOf(\n    AccountMeta.writable(gameAccount),\n    AccountMeta.signerAndWritable(playerPublicKey)\n)\nval joinGameInstruction = BaseInstruction(instructionData, accounts, programId)\nval blockhash = connection.getLatestBlockhash()\nval joinGameMessage = TransactionMessage.newMessage(playerPublicKey, blockhash, joinGameInstruction)\nval joinGameTransaction = VersionedTransaction(joinGameMessage)\njoinGameTransaction.sign(playerKeypair)\nval signature = connection.sendTransaction(joinGameTransaction)\n```\n\nHere's another example: creating an associated token account for a user's wallet.\n\n```kotlin\nval blockhash = connection.getLatestBlockhash()\nval payerWallet = Keypair.fromSecretKey(secretKeyBytes)\nval usdcMintAddress = PublicKey(\"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\")\nval destinationWallet = Keypair.generate().publicKey\nval (associatedAccount) = PublicKey.findProgramDerivedAddress(destinationWallet, usdcMintAddress)\nval instruction = CreateAssociatedTokenAccountInstruction(\n    payer = payerWallet.publicKey,\n    associatedToken = associatedAccount,\n    owner = destinationWallet,\n    mint = usdcMintAddress,\n)\nval message = TransactionMessage.newMessage(payerWallet.publicKey, blockhash, instruction)\nval transaction = Transaction(message)\ntransaction.sign(payerWallet)\nval signature = connection.sendTransaction(transaction)\n```\n\nYou can find more examples [in the project tests](https://github.com/sol4k/sol4k/blob/main/src/integration-test/kotlin/org/sol4k/ConnectionTest.kt).\n\n## Development setup\n\nIn order to build and run sol4k locally, perform the next steps:\n- Install JDK 11 or newer as a default version of JDK (running `java --version` should print 11 or newer).\n- Install JDK 8, but do not select it as a default. If you're using macOS, you can check for Java 8 in the list by running `/usr/libexec/java_home -V`.\n- Execute `./gradlew publishToMavenLocal`.\n\nThis would install sol4k in your local Maven repository, and you would be able to import it in other projects (make sure\n`mavenLocal` is among [your Maven repositories](https://github.com/sol4k/sol4k-examples/blob/main/build.gradle#L11-L14)).\nAdjust `currentVersion` in `gradle.properties` to be sure you are importing the version that\nyou have built.\n\nIn order to run end-to-end tests, you need to set two environment variables: an RPC URL and a Base-58 encoded\nsecret key of an account that you would be using for testing.\n\n```shell\nexport E2E_RPC_URL=\"https://api.devnet.solana.com\"\nexport E2E_SECRET_KEY=\"base-58-encode-secret-key...\"\n```\n\nExecute the tests:\n\n```shell\n./gradlew integrationTest\n```\n\nThe account needs to have some Devnet SOL as well as Devnet USDC in order to run the tests.\nYou can airdrop them both using [this faucet](https://spl-token-faucet.com/?token-name=USDC-Dev).\n\nIf you want to generate a new account for testing, you can do it like this:\n\n```shell\nval keypair = Keypair.generate()\nval secret = Base58.encode(keypair.secret)\nprintln(\"Secret: $secret\")\nprintln(\"Public Key: ${keypair.publicKey}\")\n```\n\nIf no environment variables are set, end-to-end tests would use `EwtJVgZQGHe9MXmrNWmujwcc6JoVESU2pmq7wTDBvReF`\nto interact with the blockchain. Its secret key is publicly available in the source code, that's why make sure\nit has Devnet USDC and SOL if you want to rely on it.\n\n## Support\n\nIf you like sol4k and want the project to keep going, consider sponsoring it\n[via GitHub Sponsors](https://github.com/sponsors/Shpota) or directly to the wallet address:\n\n```shell\nHNFoca4s9e9XG6KBpaQurVj4Yr6k3GQKhnubRxAGwAZs\n```\n","funding_links":["https://github.com/sponsors/Shpota"],"categories":["Development Tools and Libraries","Developer Resources"],"sub_categories":["Client Libraries","Dev Tooling"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsol4k%2Fsol4k","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsol4k%2Fsol4k","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsol4k%2Fsol4k/lists"}