diff --git a/src/main/kotlin/com/rootsid/wal/library/dlt/Dlt.kt b/src/main/kotlin/com/rootsid/wal/library/dlt/Dlt.kt index 8b5b50e..a1c8b06 100644 --- a/src/main/kotlin/com/rootsid/wal/library/dlt/Dlt.kt +++ b/src/main/kotlin/com/rootsid/wal/library/dlt/Dlt.kt @@ -8,7 +8,9 @@ import io.iohk.atala.prism.api.CredentialClaim import io.iohk.atala.prism.api.KeyGenerator import io.iohk.atala.prism.api.VerificationResult import io.iohk.atala.prism.api.models.AtalaOperationId +import io.iohk.atala.prism.api.models.AtalaOperationInfo import io.iohk.atala.prism.api.models.AtalaOperationStatus +import io.iohk.atala.prism.api.models.AtalaOperationStatusEnum import io.iohk.atala.prism.api.node.NodeAuthApiImpl import io.iohk.atala.prism.api.node.NodePayloadGenerator import io.iohk.atala.prism.api.node.NodePublicApi @@ -26,8 +28,9 @@ import kotlinx.serialization.json.* import pbandk.ByteArr import pbandk.json.encodeToJsonString -class Dlt { +private const val TESTNET_URL = "https://explorer.cardano-testnet.iohkdev.io/en/transaction?id=" +class Dlt { /** * Use this function to get the blockchain transaction ID associated with an operationID * @param operationId operation identifier @@ -42,6 +45,32 @@ class Dlt { return response.transactionId } + fun getDidPublishOperationInfo(did: Did): AtalaOperationStatusEnum { + val operationId = did.publishedOperationId + + if("" == operationId) { + throw Exception("Unable to find operation information because operation id was empty.") + } + + val operationInfo = getOperationInfo(AtalaOperationId.fromHex(operationId)) + operationInfo.transactionId?.let { BlockchainTxLogEntry(it, BlockchainTxAction.PUBLISH_DID, + "${TESTNET_URL}$it", did.alias) } + + return operationInfo.status + } + + /** + * Get operation information using the operationId + * + * @param operationId operation identifier + * @return operation information from the blockchain transaction + */ + private fun getOperationInfo(operationId: AtalaOperationId): AtalaOperationInfo { + val nodeAuthApi = NodeAuthApiImpl(GrpcConfig.options()) + + return runBlocking { nodeAuthApi.getOperationInfo(operationId) } + } + /** * Waits until the operationId status changes from [AtalaOperationStatus.PENDING_SUBMISSION] to [AtalaOperationStatus.AWAIT_CONFIRMATION] * @@ -170,7 +199,7 @@ class Dlt { } else { PrismDid.buildLongFormFromMasterPublicKey(masterKeyPair.publicKey) } - return Did(didAlias, didIdx, unpublishedDid.asCanonical().did.toString(), unpublishedDid.did.toString(), "", keyPaths) + return Did(didAlias, didIdx, unpublishedDid.asCanonical().did.toString(), unpublishedDid.did.toString(), keyPaths) } /** diff --git a/src/main/kotlin/com/rootsid/wal/library/dlt/model/Did.kt b/src/main/kotlin/com/rootsid/wal/library/dlt/model/Did.kt index f6ba965..9f70b1e 100644 --- a/src/main/kotlin/com/rootsid/wal/library/dlt/model/Did.kt +++ b/src/main/kotlin/com/rootsid/wal/library/dlt/model/Did.kt @@ -1,5 +1,7 @@ package com.rootsid.wal.library.dlt.model +import io.iohk.atala.prism.api.models.AtalaOperationStatus +import io.iohk.atala.prism.api.models.AtalaOperationStatusEnum import kotlinx.serialization.Serializable /** @@ -19,6 +21,8 @@ data class Did( val didIdx: Int, val uriCanonical: String, val uriLongForm: String, + var keyPaths: MutableList = mutableListOf(), var operationHash: String = "", - var keyPaths: MutableList = mutableListOf() + var publishedStatus: AtalaOperationStatusEnum = AtalaOperationStatus.UNKNOWN_OPERATION, + var publishedOperationId: String = "" ) diff --git a/src/main/kotlin/com/rootsid/wal/library/wallet/WalletService.kt b/src/main/kotlin/com/rootsid/wal/library/wallet/WalletService.kt index 25e3ae5..e04adfd 100644 --- a/src/main/kotlin/com/rootsid/wal/library/wallet/WalletService.kt +++ b/src/main/kotlin/com/rootsid/wal/library/wallet/WalletService.kt @@ -7,6 +7,8 @@ import com.rootsid.wal.library.mongoimpl.document.WalletDocument import com.rootsid.wal.library.wallet.model.Wallet import com.rootsid.wal.library.wallet.model.addDid import com.rootsid.wal.library.wallet.storage.WalletStorage +import io.iohk.atala.prism.api.models.AtalaOperationStatus +import io.iohk.atala.prism.api.models.AtalaOperationStatusEnum import io.iohk.atala.prism.api.node.PrismDidState import io.iohk.atala.prism.common.PrismSdkInternal import io.iohk.atala.prism.crypto.derivation.KeyDerivation @@ -111,14 +113,17 @@ class WalletService(private val walletStorage: WalletStorage, private val dlt: D w.dids.firstOrNull { it.alias.equals(didAlias, true) } ?.let { d -> val dltDidUpdate = dlt.publishDid(d, w.seed.toByteArray()) - d.operationHash = dltDidUpdate.operationId ?: "N/A" + + d.publishedStatus = AtalaOperationStatus.PENDING_SUBMISSION + d.publishedOperationId = dltDidUpdate.operationId ?: throw Exception("Unable to find operation id.") + d.operationHash = dltDidUpdate.did?.operationHash ?: throw Exception("Unable to find operation hash.") walletStorage.update(w) println("DID '$didAlias' published.") return d } - ?: throw Exception("DidAlias '$didAlias' not found") + ?: throw Exception("Did alias '$didAlias' not found") } } @@ -130,4 +135,17 @@ class WalletService(private val walletStorage: WalletStorage, private val dlt: D fun getDidDocumentStatus(didAlias: String): PrismDidState { return dlt.getDidState(didAlias) } + + fun getDidPublishOperationStatus(walletId: String, didAlias: String): AtalaOperationStatusEnum { + return getDidPublishOperationStatus(findWalletById(walletId), didAlias) + } + + fun getDidPublishOperationStatus(wallet: Wallet, didAlias: String): AtalaOperationStatusEnum { + wallet.dids.firstOrNull { it.alias.equals(didAlias, true) } + ?.let { d -> + val publishOperationInfo = dlt.getDidPublishOperationInfo(d) + d.publishedStatus = publishOperationInfo + return publishOperationInfo + } ?: throw Exception("Did alias '$didAlias' not found") + } }