Skip to content

Commit

Permalink
Merge pull request #49 from walt-id/feat/polkadot-support
Browse files Browse the repository at this point in the history
feat: add polkadot support
  • Loading branch information
taminobaumann authored Apr 26, 2023
2 parents 73cd4f8 + af96e58 commit 2c99706
Show file tree
Hide file tree
Showing 12 changed files with 460 additions and 268 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ dependencies {
testImplementation("io.kotest:kotest-assertions-json:5.5.0")

// NftKit
implementation("id.walt:waltid-nftkit:1.0.0")
implementation("id.walt:waltid-nftkit:1.2304191004.0")

// HTTP / Client: ktor
implementation("io.ktor:ktor-client-core:2.0.0")
Expand Down
8 changes: 7 additions & 1 deletion config/idp-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
}
],
"default_nft_token_claim": {
"ecosystems": [ "EVM", "TEZOS", "NEAR" ],
"ecosystems": [ "EVM", "TEZOS", "NEAR" ,"POLKADOT"],
"nftTokenContraints": {
"EVM": {
"chain": "POLYGON",
Expand All @@ -85,6 +85,12 @@
"chain": "TESTNET",
"factorySmartContractAddress": "",
"smartContractAddress": "demo.khaled_lightency1.testnet"
},
"POLKADOT": {
"chain": "OPAL",
"factorySmartContractAddress": "",
"smartContractAddress": "1062"

}
}
},
Expand Down
4 changes: 3 additions & 1 deletion src/main/kotlin/id/walt/idp/config/ClaimConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ class NFTClaimMapping(
val claimValue = when(verificationResult.nftresponseVerificationResult.ecosystem) {
ChainEcosystem.EVM -> verificationResult.nftresponseVerificationResult.metadata?.evmNftMetadata?.attributes?.firstOrNull { a -> a.trait_type == mappingDefinition.trait }?.value
ChainEcosystem.TEZOS -> verificationResult.nftresponseVerificationResult.metadata?.tezosNftMetadata?.attributes?.firstOrNull { a -> a.name == mappingDefinition.trait }?.value
ChainEcosystem.NEAR -> verificationResult.nftresponseVerificationResult.metadata?.nearNftMetadata?.metadata?.let { NFTManager.getNearNftAttributeValue(it, mappingDefinition.trait) }
ChainEcosystem.NEAR -> verificationResult.nftresponseVerificationResult.metadata?.nearNftMetadata?.metadata?.let { NFTManager.getNearNftAttributeValue(it, mappingDefinition.trait)
}
ChainEcosystem.POLKADOT -> verificationResult.nftresponseVerificationResult.metadata?.uniqueNftMetadata?.attributes?.let { a -> a.firstOrNull { a -> a.name == mappingDefinition.trait }?.value }
}?: throw BadRequestResponse("Requested nft metadata trait not found in verification response")

claimBuilder.claim(mappingDefinition.trait, claimValue)
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/id/walt/idp/nfts/NFTClaims.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ data class NftTokenConstraint(
)

enum class ChainEcosystem {
EVM, TEZOS, NEAR
EVM, TEZOS, NEAR , POLKADOT
}

data class NftTokenClaim(
Expand Down
20 changes: 16 additions & 4 deletions src/main/kotlin/id/walt/idp/nfts/NFTController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import id.walt.idp.oidc.OIDCManager
import id.walt.idp.oidc.ResponseVerificationResult
import id.walt.idp.siwe.SiweManager
import id.walt.idp.siwe.SiwnManager
import id.walt.idp.siwe.SiwpManager
import id.walt.idp.siwe.SiwtManager
import id.walt.siwe.SiweRequest
import id.walt.siwe.eip4361.Eip4361Message
Expand Down Expand Up @@ -39,12 +40,15 @@ object NFTController {
}

fun nftVerification(ctx: Context) {
val test = "TESTNET";

val sessionId = ctx.queryParam("session") ?: throw BadRequestResponse("Session not specified")
print("Session ID: $sessionId")
val message = ctx.queryParam("message") ?: throw BadRequestResponse("Message not specified")
print("Message: $message")
val ecosystem = ctx.queryParam("ecosystem")?.let { ChainEcosystem.valueOf(it.uppercase()) } ?: throw BadRequestResponse("Ecosystem not specified")
print("Ecosystem: $ecosystem")
val signature = ctx.queryParam("signature") ?: throw BadRequestResponse("Signature not specified")
val ecosystem = ctx.queryParam("ecosystem")?.let { ChainEcosystem.valueOf(it.toUpperCase()) } ?: throw BadRequestResponse("Ecosystem not specified")
print("Signature: $signature")


val session = OIDCManager.getOIDCSession(sessionId)
Expand Down Expand Up @@ -72,11 +76,19 @@ object NFTController {
}
ChainEcosystem.NEAR -> {
val publicKey = SiwnManager.getPublicKey(message)
print( "is the public key" + publicKey )
print("Public Key: $publicKey")
address = SiwnManager.getAddress(message)
print("is address " + address)
print("Address: $address")
SiwnManager.verifySignature(session!!, message, publicKey, signature)
}
ChainEcosystem.POLKADOT -> {
val publicKey = SiwpManager.getPublicKey(message)
address = SiwpManager.getPublicKey(message)


SiwpManager.verifySignature(session!!, message, publicKey, signature)
}

}

if(!siwxResult) {
Expand Down
5 changes: 3 additions & 2 deletions src/main/kotlin/id/walt/idp/nfts/NFTManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ object NFTManager {
Common.getEVMChain(tokenConstraint.chain!!.toString()),
tokenConstraint.smartContractAddress!!, account.trim()
)?.compareTo(BigInteger("0")) == 1
ChainEcosystem.TEZOS, ChainEcosystem.NEAR -> VerificationService.verifyNftOwnershipWithinCollection(
ChainEcosystem.TEZOS, ChainEcosystem.NEAR , ChainEcosystem.POLKADOT-> VerificationService.verifyNftOwnershipWithinCollection(
tokenConstraint.chain!!,
tokenConstraint.smartContractAddress!!,account)
}
Expand Down Expand Up @@ -117,7 +117,8 @@ object NFTManager {
NearNftService.getNFTforAccount( account, it, NearChain.valueOf(
tokenConstraint.chain!!.toString()
))}?.get(0)
else null
else null,

)
}

Expand Down
4 changes: 1 addition & 3 deletions src/main/kotlin/id/walt/idp/siwe/SiwnManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ object SiwnManager {
expectSuccess = false
}
fun verifySignature(session: OIDCSession, message: String, publicKey: String, signature: String): Boolean{
println("this is the message: $message")
println("this is the public key: $publicKey")
println("this is the signature: $signature")


val nonce= getNonce(message)
if (session.siweSession?.nonce != nonce) {
Expand Down
70 changes: 70 additions & 0 deletions src/main/kotlin/id/walt/idp/siwe/siwpManager.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package id.walt.idp.siwe

import id.walt.idp.config.IDPConfig
import id.walt.idp.oidc.OIDCSession
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.plugins.logging.*
import io.ktor.client.request.*
import io.ktor.serialization.kotlinx.json.*
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.json.Json
import java.net.URLEncoder
import java.nio.charset.StandardCharsets

object SiwpManager {
val client = HttpClient(CIO.create { requestTimeout = 0 }) {
install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = true
})
}
install(Logging) {
logger = Logger.SIMPLE
level = LogLevel.ALL
}
expectSuccess = false
}
fun verifySignature(session: OIDCSession, message: String, publicKey: String, signature: String): Boolean{
val nonce= getNonce(message)
if (session.siweSession?.nonce != nonce) {
return false;
}
if (SiweManager.nonceBlacklists.contains(nonce)) {
return false
}
SiweManager.nonceBlacklists.add(nonce)


return runBlocking {
val result = client.get("${IDPConfig.config.jsProjectExternalUrl}/Polkadot/test?publicKey=${publicKey}&signature=${signature}&message=${URLEncoder.encode(message, StandardCharsets.UTF_8)}") {
}.body<Boolean>()
return@runBlocking result
}
}


fun getAddress(message:String): String{
val address= message.split(" .").get(0).split(":").last().trim()
return address
}

fun getNonce(message: String): String{
val nonce= message.split(".").last().split(":").last().trim()

return nonce
}

fun getPublicKey(message: String): String{
val startIndex = message.indexOf("Public Key: ")


val endIndex = message.indexOf(" ", startIndex + 12)

return message.substring(startIndex + 12, endIndex)
}


}
4 changes: 4 additions & 0 deletions src/main/resources/walt-default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ keys:
0xc8ca7c4f2dc014d7e4fc6973052da1517b4c54da: "9b9c46d0873a9982ade718ab3f4cfc57172b2f07c21b9901ddf239e931d2d6dc"


indexersUrl:
uniqueUrl: "https://api-unique.uniquescan.io/v1/graphql"
opalUrl: "https://api-opal.uniquescan.io/v1/graphql"

apiKeys:
ethereumBlockExplorer: "JGD5ZUUBHE8CUXPNKZASVQPHRGBMB7A5XV"
polygonBlockExplorer: "DZ3PFVWGJE5B8DMDQPRZ5JFBR6U484B82G"
Expand Down
40 changes: 39 additions & 1 deletion web/waltid-idpkit-ui/nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,45 @@ export default {
],

// Build Configuration: https://go.nuxtjs.dev/config-build
build: {},
build: {
babel: {
compact: true,
},
extend(config, { isClient }) {
// Extend only webpack config for client-bundle
if (isClient) {
config.devtool = "source-map";
}
config.module.rules.push(
{
test: /\.js$/,
loader: require.resolve(
"@open-wc/webpack-import-meta-loader"
),
exclude: /\.vue$/,
},
{
test: /\.m?js$/,
include: /node_modules[/\\|]@polkadot/i,
use: {
loader: "babel-loader",
options: {
presets: [
"@babel/preset-env",
"@vue/cli-plugin-babel/preset",
],
plugins: [
"@babel/plugin-proposal-private-methods",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-object-rest-spread",
],
},
},
}
);
},
},


generate: {
dir: 'dist'
Expand Down
106 changes: 55 additions & 51 deletions web/waltid-idpkit-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,53 +1,57 @@
{
"name": "waltid-idpkit-ui",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate"
},
"dependencies": {
"@airgap/beacon-sdk": "^3.3.0",
"@nuxtjs/axios": "^5.13.6",
"@taquito/beacon-wallet": "^15.0.0",
"@taquito/taquito": "^15.0.0",
"@walletconnect/web3-provider": "^1.8.0",
"bootstrap": "^4.6.2",
"bootstrap-vue": "^2.23.1",
"core-js": "^3.26.0",
"ethers": "^5.7.2",
"nuxt": "^2.15.8",
"qrious": "^4.0.2",
"vue": "2.7.14",
"vue-server-renderer": "2.7.14",
"vue-template-compiler": "2.7.14",
"web3modal": "^1.9.9",
"webpack": "^4.46.0",
"@near-wallet-selector/coin98-wallet": "^7.6.0",
"@near-wallet-selector/core": "^7.6.0",
"@near-wallet-selector/default-wallets": "^7.6.0",
"@near-wallet-selector/here-wallet": "^7.6.0",
"@near-wallet-selector/ledger": "^7.6.0",
"@near-wallet-selector/math-wallet": "^7.6.0",
"@near-wallet-selector/meteor-wallet": "^7.6.0",
"@near-wallet-selector/modal-ui": "^7.6.0",
"@near-wallet-selector/my-near-wallet": "^7.6.0",
"@near-wallet-selector/narwallets": "^7.6.0",
"@near-wallet-selector/near-wallet": "^7.6.0",
"@near-wallet-selector/nearfi": "^7.6.0",
"@near-wallet-selector/neth": "^7.6.0",
"@near-wallet-selector/nightly": "^7.6.0",
"@near-wallet-selector/nightly-connect": "^7.6.0",
"@near-wallet-selector/opto-wallet": "^7.6.0",
"@near-wallet-selector/sender": "^7.6.0",
"@near-wallet-selector/wallet-connect": "^7.6.0",
"@near-wallet-selector/welldone-wallet": "^7.6.0",
"@near-wallet-selector/xdefi": "^7.6.0",
"near-api-js": "^1.1.0"
},
"devDependencies": {
"@nuxt/types": "~2.15.8"
}
"name": "waltid-idpkit-ui",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate"
},
"dependencies": {
"@airgap/beacon-sdk": "^3.3.0",
"@near-wallet-selector/coin98-wallet": "^7.6.0",
"@near-wallet-selector/core": "^7.6.0",
"@near-wallet-selector/default-wallets": "^7.6.0",
"@near-wallet-selector/here-wallet": "^7.6.0",
"@near-wallet-selector/ledger": "^7.6.0",
"@near-wallet-selector/math-wallet": "^7.6.0",
"@near-wallet-selector/meteor-wallet": "^7.6.0",
"@near-wallet-selector/modal-ui": "^7.6.0",
"@near-wallet-selector/my-near-wallet": "^7.6.0",
"@near-wallet-selector/narwallets": "^7.6.0",
"@near-wallet-selector/near-wallet": "^7.6.0",
"@near-wallet-selector/nearfi": "^7.6.0",
"@near-wallet-selector/neth": "^7.6.0",
"@near-wallet-selector/nightly": "^7.6.0",
"@near-wallet-selector/nightly-connect": "^7.6.0",
"@near-wallet-selector/opto-wallet": "^7.6.0",
"@near-wallet-selector/sender": "^7.6.0",
"@near-wallet-selector/wallet-connect": "^7.6.0",
"@near-wallet-selector/welldone-wallet": "^7.6.0",
"@near-wallet-selector/xdefi": "^7.6.0",
"@nuxtjs/axios": "^5.13.6",
"@open-wc/webpack-import-meta-loader": "^0.4.7",
"@polkadot/api": "^10.3.2",
"@polkadot/extension-dapp": "^0.45.5",
"@taquito/beacon-wallet": "^15.0.0",
"@taquito/taquito": "^15.0.0",
"@vue/cli-plugin-babel": "^5.0.8",
"@walletconnect/web3-provider": "^1.8.0",
"bootstrap": "^4.6.2",
"bootstrap-vue": "^2.23.1",
"core-js": "^3.26.0",
"ethers": "^5.7.2",
"near-api-js": "^1.1.0",
"nuxt": "^2.15.8",
"qrious": "^4.0.2",
"vue": "2.7.14",
"vue-server-renderer": "2.7.14",
"vue-template-compiler": "2.7.14",
"web3modal": "^1.9.9",
"webpack": "^4.46.0"
},
"devDependencies": {
"@nuxt/types": "~2.15.8"
}
}
Loading

0 comments on commit 2c99706

Please sign in to comment.