diff --git a/build.gradle.kts b/build.gradle.kts index c459dd42..7f489482 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -52,6 +52,8 @@ dependencies { implementation("io.ktor:ktor-client-logging:2.1.3") implementation("io.ktor:ktor-client-auth:2.1.3") + + // Persistence implementation("org.jetbrains.exposed:exposed-core:0.38.2") implementation("org.jetbrains.exposed:exposed-dao:0.38.2") diff --git a/src/main/kotlin/id/walt/nftkit/App.kt b/src/main/kotlin/id/walt/nftkit/App.kt index 5ae40bdb..ef3bf102 100644 --- a/src/main/kotlin/id/walt/nftkit/App.kt +++ b/src/main/kotlin/id/walt/nftkit/App.kt @@ -1,19 +1,23 @@ package id.walt.nftkit +import com.beust.klaxon.JsonObject +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import id.walt.nftkit.rest.NftKitApi +import id.walt.nftkit.services.AlgorandChain +import id.walt.nftkit.services.AlgorandNftService +import id.walt.nftkit.services.NftService +import id.walt.nftkit.services.OffChainMetadataStorageType fun main() { + println("\n\n\n") /* /////////// */ /* /////////// */ /* /////////// */ - NftKitApi.start() - - } diff --git a/src/main/kotlin/id/walt/nftkit/rest/AlgorandNftController.kt b/src/main/kotlin/id/walt/nftkit/rest/AlgorandNftController.kt index fee45897..460057a6 100644 --- a/src/main/kotlin/id/walt/nftkit/rest/AlgorandNftController.kt +++ b/src/main/kotlin/id/walt/nftkit/rest/AlgorandNftController.kt @@ -60,6 +60,10 @@ object AlgorandNftController{ .pathParam("chain") { it.schema{}} .pathParam("assetId"){} + .json(200.toString()) { + it.description("Algorand Token") + } + /////////////////////////////////////////////////////////////////////////// @@ -81,7 +85,6 @@ object AlgorandNftController{ it.schema{}} .pathParam("assetId"){} .json("200"){ - it.description("Fetched token parameteres") } @@ -100,8 +103,8 @@ object AlgorandNftController{ .pathParam("chain") { it.schema{}} .pathParam("address"){} - .json("200"){ - it.description("Fetched Tokens") + .json>("200"){ + it.description("Account tokens") } @@ -121,6 +124,9 @@ object AlgorandNftController{ .pathParam("chain") { it.schema{}} .pathParam("assetId"){} + .json(200.toString()) { + it.description("Algorand NFT Metadata") + } } diff --git a/src/main/kotlin/id/walt/nftkit/services/AlgorandNftService.kt b/src/main/kotlin/id/walt/nftkit/services/AlgorandNftService.kt index 63034b98..cda0ca20 100644 --- a/src/main/kotlin/id/walt/nftkit/services/AlgorandNftService.kt +++ b/src/main/kotlin/id/walt/nftkit/services/AlgorandNftService.kt @@ -1,19 +1,17 @@ package id.walt.nftkit.services import com.algorand.algosdk.account.Account -import com.algorand.algosdk.crypto.Address import com.algorand.algosdk.transaction.Transaction import com.algorand.algosdk.util.Encoder import com.algorand.algosdk.v2.client.common.AlgodClient -import com.algorand.algosdk.v2.client.common.IndexerClient +import com.beust.klaxon.JsonObject +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import id.walt.nftkit.Values.ALGORAND_BETANET_EXPLORER - - -import id.walt.nftkit.Values.ALGORAND_TESTNET_EXPLORER import id.walt.nftkit.Values.ALGORAND_MAINNET_EXPLORER - +import id.walt.nftkit.Values.ALGORAND_TESTNET_EXPLORER import id.walt.nftkit.metadata.IPFSMetadata import id.walt.nftkit.services.WaltIdServices.loadAlgorand +import id.walt.nftkit.utilis.Common import io.ktor.client.* import io.ktor.client.call.* import io.ktor.client.engine.cio.* @@ -122,10 +120,7 @@ object AlgorandNftService { - val ALGOD_API_ADDR = "https://testnet-algorand.api.purestake.io/ps2" - - val ALGOD_PORT = 443 val ALGOD_API_TOKEN_KEY = "X-API-Key" val ALGOD_API_TOKEN = "B3SU4KcVKi94Jap2VXkK83xx38bsv95K5UZm2lab" @@ -136,7 +131,6 @@ object AlgorandNftService { return AlgorandAccount(account.address.toString(), account.toMnemonic()) } - fun createAssetArc3(chain : AlgorandChain ,assetName : String , assetUnitName : String , url : String) : AlgodResponse{ val client_algod = when(chain) { @@ -144,11 +138,8 @@ object AlgorandNftService { AlgorandChain.ALGORAND_TESTNET -> AlgodClient("https://testnet-algorand.api.purestake.io/ps2", ALGOD_PORT, ALGOD_API_TOKEN, ALGOD_API_TOKEN_KEY) AlgorandChain.ALGORAND_BETANET -> AlgodClient("https://betanet-algorand.api.purestake.io/ps2", ALGOD_PORT, ALGOD_API_TOKEN, ALGOD_API_TOKEN_KEY) } - val SRC_ACCOUNT = loadAlgorand().algorandConfig.algorand_seed_Mnemonic val src = Account(SRC_ACCOUNT) - println(src.getAddress()) - val params = client_algod.TransactionParams().execute().body() val tx = Transaction.AssetCreateTransactionBuilder() @@ -166,57 +157,59 @@ object AlgorandNftService { .url("$url#arc3") .build() val signedTx = src.signTransaction(tx) - // send the transaction to the network try { val txHeaders = arrayOf("Content-Type") val txValues = arrayOf("application/x-binary") val encodedTxBytes = Encoder.encodeToMsgPack(signedTx) - val txResponse = client_algod.RawTransaction().rawtxn(encodedTxBytes).execute(txHeaders, txValues).body() - return when(chain) { AlgorandChain.ALGORAND_MAINNET -> AlgodResponse(txResponse.txId, "$ALGORAND_MAINNET_EXPLORER"+"tx/${txResponse.txId}") AlgorandChain.ALGORAND_TESTNET -> AlgodResponse(txResponse.txId, "$ALGORAND_TESTNET_EXPLORER"+"tx/${txResponse.txId}") AlgorandChain.ALGORAND_BETANET -> AlgodResponse(txResponse.txId, "$ALGORAND_BETANET_EXPLORER"+"tx/${txResponse.txId}") } - } catch (e: Exception) { e.printStackTrace() } return AlgodResponse("Null" , "Null") } + + fun getToken(assetId: String, chain: AlgorandChain): AlgorandToken { return runBlocking { - val ALGOD_API_ADDR = when (chain) { + val API_ADDR = when (chain) { AlgorandChain.ALGORAND_MAINNET -> "https://mainnet-api.algonode.cloud" AlgorandChain.ALGORAND_TESTNET -> "https://testnet-api.algonode.cloud" AlgorandChain.ALGORAND_BETANET -> "https://betanet-api.algonode.cloud" } - val tokenParams = client.get(ALGOD_API_ADDR + "/v2/assets/" + assetId){ + val tokenParams = client.get(API_ADDR + "/v2/assets/" + assetId){ contentType(ContentType.Application.Json) }.body() + var result = AlgorandToken() - var cid = (tokenParams.params?.url)?.substringAfter("ipfs://") - val nft = - IPFSMetadata.client.get("https://ipfs.io/ipfs/$cid") - { contentType(ContentType.Application.Json)}.body() + if (tokenParams.params?.url != null) { + var cid = (tokenParams.params?.url)?.substringAfter("ipfs://") + val nft = + IPFSMetadata.client.get("https://ipfs.io/ipfs/$cid") + { contentType(ContentType.Application.Json)}.body() + result.TokenParams = tokenParams + result.Metadata = nft + } - var result = AlgorandToken() + else + result.TokenParams = tokenParams - result.TokenParams = tokenParams - result.Metadata = nft return@runBlocking result } } fun getAssetMeatadata(assetId: String, chain: AlgorandChain): Asset { return runBlocking { - val ALGOD_API_ADDR = when (chain) { + val API_ADDR = when (chain) { AlgorandChain.ALGORAND_MAINNET -> "https://mainnet-api.algonode.cloud" AlgorandChain.ALGORAND_TESTNET -> "https://testnet-api.algonode.cloud" AlgorandChain.ALGORAND_BETANET -> "https://betanet-api.algonode.cloud" } - val asset = client.get(ALGOD_API_ADDR + "/v2/assets/" + assetId){ + val asset = client.get(API_ADDR + "/v2/assets/" + assetId){ contentType(ContentType.Application.Json) }.body() @@ -235,31 +228,35 @@ object AlgorandNftService { } } - fun getAccountAssets(address: String, chain: AlgorandChain): AssetHoldingsResponse { + fun getAccountAssets(address: String, chain: AlgorandChain): Any { return runBlocking { - var ALGOD_API_ADDR = when (chain) { + var API_ADDR = when (chain) { AlgorandChain.ALGORAND_MAINNET -> "https://mainnet-idx.algonode.cloud" AlgorandChain.ALGORAND_TESTNET -> "https://testnet-idx.algonode.cloud" AlgorandChain.ALGORAND_BETANET -> "https://betanet-idx.algonode.cloud" } - val result = - client.get(ALGOD_API_ADDR + "/v2/accounts/" + address + "/assets") { + val resp = client.get(API_ADDR + "/v2/accounts/" + address + "/assets") { contentType(ContentType.Application.Json) }.body() + + val result = mutableListOf() + for (a in resp.assets){ + result.add(getToken(a.assetId.toString(), chain)) + } return@runBlocking result; } } + fun verifyOwnership(address: String, assetId:String, chain: AlgorandChain): AccountAssetResponse{ return runBlocking { - val ALGOD_API_ADDR = when (chain) { + val API_ADDR = when (chain) { AlgorandChain.ALGORAND_MAINNET -> "https://mainnet-api.algonode.cloud" AlgorandChain.ALGORAND_TESTNET -> "https://testnet-api.algonode.cloud" AlgorandChain.ALGORAND_BETANET -> "https://betanet-api.algonode.cloud" - else -> throw Exception ("Must be an algorand api") } val response = - client.get(ALGOD_API_ADDR+"/v2/accounts/"+address+"/assets/"+assetId){ + client.get(API_ADDR+"/v2/accounts/"+address+"/assets/"+assetId){ contentType(ContentType.Application.Json) }.body() return@runBlocking response