From ee407ef345f6ac8dd44047a01ddbfe620621e5b7 Mon Sep 17 00:00:00 2001 From: ashalaginov Date: Tue, 14 Nov 2023 05:31:28 +0000 Subject: [PATCH] [WTCH-185] Add signMessage, verifyMessageSignature to AddressService --- .../client/blocking/address/AddressService.kt | 15 +- .../lb/LoadBalancingServiceFactoryTest.kt | 3 +- .../sdk/node/domain/address/Message.kt | 11 ++ .../node/domain/address/SignMessageRequest.kt | 8 + .../domain/address/SignMessageResponse.kt | 10 + .../address/VerifyMessageSignatureRequest.kt | 10 + .../address/VerifyMessageSignatureResponse.kt | 5 + .../sdk/node/exception/NodeErrorCode.kt | 3 + .../specific/InvalidPasswordException.kt | 10 + .../specific/InvalidPublicKeyException.kt | 10 + .../specific/SpecificExceptionMapper.kt | 4 + .../node/AddressGrpcBlockingService.kt | 27 ++- .../feign/address/FeignAddressService.kt | 60 ++++++ .../feign/address/WeAddressServiceApiFeign.kt | 44 +++++ .../feign/factory/FeignNodeServiceFactory.kt | 4 +- .../client/feign/node/FeignAddressService.kt | 23 --- .../feign/node/WeAddressServiceApiFeign.kt | 16 -- .../feign/address/FeignAddressServiceTest.kt | 142 +++++++++++++++ .../address/WeAddressServiceApiFeignTest.kt | 171 ++++++++++++++++++ .../node/WeAddressServiceApiFeignTest.kt | 43 ----- .../address/address_by_public_key_200.json | 15 ++ .../address/address_by_public_key_400.json | 16 ++ .../mappings/address/address_value_200.json | 17 ++ .../mappings/address/address_values_200.json | 24 +++ .../{address_200.json => addresses_200.json} | 0 .../mappings/address/sign_message_200.json | 25 +++ .../mappings/address/sign_message_400.json | 24 +++ .../address/verify_message_signature_200.json | 24 +++ .../sdk/node/client/http/AddressDto.kt | 5 - .../node/client/http/address/AddressDto.kt | 18 ++ .../http/address/SignMessageRequestDto.kt | 17 ++ .../http/address/SignMessageResponseDto.kt | 30 +++ .../VerifyMessageSignatureRequestDto.kt | 19 ++ .../VerifyMessageSignatureResponseDto.kt | 21 +++ .../sdk/node/test/data/TestDataFactory.kt | 67 +++++++ 35 files changed, 845 insertions(+), 96 deletions(-) create mode 100644 we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/Message.kt create mode 100644 we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/SignMessageRequest.kt create mode 100644 we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/SignMessageResponse.kt create mode 100644 we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/VerifyMessageSignatureRequest.kt create mode 100644 we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/VerifyMessageSignatureResponse.kt create mode 100644 we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/specific/InvalidPasswordException.kt create mode 100644 we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/specific/InvalidPublicKeyException.kt create mode 100644 we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/address/FeignAddressService.kt create mode 100644 we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/address/WeAddressServiceApiFeign.kt delete mode 100644 we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/node/FeignAddressService.kt delete mode 100644 we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/node/WeAddressServiceApiFeign.kt create mode 100644 we-node-client-http/we-node-client-feign-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/feign/address/FeignAddressServiceTest.kt create mode 100644 we-node-client-http/we-node-client-feign-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/feign/address/WeAddressServiceApiFeignTest.kt delete mode 100644 we-node-client-http/we-node-client-feign-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/feign/node/WeAddressServiceApiFeignTest.kt create mode 100644 we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_by_public_key_200.json create mode 100644 we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_by_public_key_400.json create mode 100644 we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_value_200.json create mode 100644 we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_values_200.json rename we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/{address_200.json => addresses_200.json} (100%) create mode 100644 we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/sign_message_200.json create mode 100644 we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/sign_message_400.json create mode 100644 we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/verify_message_signature_200.json delete mode 100644 we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/AddressDto.kt create mode 100644 we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/AddressDto.kt create mode 100644 we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/SignMessageRequestDto.kt create mode 100644 we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/SignMessageResponseDto.kt create mode 100644 we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/VerifyMessageSignatureRequestDto.kt create mode 100644 we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/VerifyMessageSignatureResponseDto.kt diff --git a/we-node-client-blocking-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/blocking/address/AddressService.kt b/we-node-client-blocking-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/blocking/address/AddressService.kt index 74bd2783..ff89b91f 100644 --- a/we-node-client-blocking-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/blocking/address/AddressService.kt +++ b/we-node-client-blocking-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/blocking/address/AddressService.kt @@ -2,10 +2,19 @@ package com.wavesenterprise.sdk.node.client.blocking.address import com.wavesenterprise.sdk.node.domain.Address import com.wavesenterprise.sdk.node.domain.DataEntry +import com.wavesenterprise.sdk.node.domain.DataKey +import com.wavesenterprise.sdk.node.domain.PublicKey +import com.wavesenterprise.sdk.node.domain.address.SignMessageRequest +import com.wavesenterprise.sdk.node.domain.address.SignMessageResponse +import com.wavesenterprise.sdk.node.domain.address.VerifyMessageSignatureRequest +import com.wavesenterprise.sdk.node.domain.address.VerifyMessageSignatureResponse +import java.util.Optional interface AddressService { fun getAddresses(): List
- fun getAddressByPublicKey(publicKey: String): Address - fun getAddressValue(address: String, key: String): DataEntry? - fun getAddressValues(address: String): List + fun getAddressByPublicKey(publicKey: PublicKey): Address + fun getAddressValue(address: Address, key: DataKey): Optional + fun getAddressValues(address: Address): List + fun signMessage(address: Address, request: SignMessageRequest): SignMessageResponse + fun verifyMessageSignature(address: Address, request: VerifyMessageSignatureRequest): VerifyMessageSignatureResponse } diff --git a/we-node-client-blocking-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/blocking/lb/LoadBalancingServiceFactoryTest.kt b/we-node-client-blocking-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/blocking/lb/LoadBalancingServiceFactoryTest.kt index 1b96ae07..fd109312 100644 --- a/we-node-client-blocking-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/blocking/lb/LoadBalancingServiceFactoryTest.kt +++ b/we-node-client-blocking-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/blocking/lb/LoadBalancingServiceFactoryTest.kt @@ -16,6 +16,7 @@ import com.wavesenterprise.sdk.node.exception.NodeInternalServerErrorException import com.wavesenterprise.sdk.node.exception.NodeServiceUnavailableException import com.wavesenterprise.sdk.node.exception.specific.ContractNotFoundException import com.wavesenterprise.sdk.node.exception.specific.PolicyItemDataIsMissingException +import com.wavesenterprise.sdk.node.test.data.TestDataFactory.Companion.address import io.mockk.Called import io.mockk.every import io.mockk.verify @@ -355,7 +356,7 @@ class LoadBalancingServiceFactoryTest { mockkAddressService2.getAddressValues(any()) } throws NodeServiceUnavailableException(cause = Exception()) - val address = "address" + val address = address() repeat(TESTS) { lb.addressService().getAddressValues(address) } verify(atLeast = 50) { mockkAddressService1.getAddressValues(address) } verify(atLeast = 1) { mockkAddressService2.getAddressValues(address) } diff --git a/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/Message.kt b/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/Message.kt new file mode 100644 index 00000000..d6892ea5 --- /dev/null +++ b/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/Message.kt @@ -0,0 +1,11 @@ +package com.wavesenterprise.sdk.node.domain.address + +data class Message(val value: String) { + companion object { + @JvmStatic + fun fromString(value: String): Message = + Message(value) + + inline val String.message: Message get() = Message(this) + } +} diff --git a/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/SignMessageRequest.kt b/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/SignMessageRequest.kt new file mode 100644 index 00000000..b829cb1a --- /dev/null +++ b/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/SignMessageRequest.kt @@ -0,0 +1,8 @@ +package com.wavesenterprise.sdk.node.domain.address + +import com.wavesenterprise.sdk.node.domain.Password + +data class SignMessageRequest( + val message: Message, + val password: Password, +) diff --git a/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/SignMessageResponse.kt b/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/SignMessageResponse.kt new file mode 100644 index 00000000..9e865f0a --- /dev/null +++ b/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/SignMessageResponse.kt @@ -0,0 +1,10 @@ +package com.wavesenterprise.sdk.node.domain.address + +import com.wavesenterprise.sdk.node.domain.PublicKey +import com.wavesenterprise.sdk.node.domain.Signature + +data class SignMessageResponse( + val message: Message, + val publicKey: PublicKey, + val signature: Signature, +) diff --git a/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/VerifyMessageSignatureRequest.kt b/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/VerifyMessageSignatureRequest.kt new file mode 100644 index 00000000..428492f2 --- /dev/null +++ b/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/VerifyMessageSignatureRequest.kt @@ -0,0 +1,10 @@ +package com.wavesenterprise.sdk.node.domain.address + +import com.wavesenterprise.sdk.node.domain.PublicKey +import com.wavesenterprise.sdk.node.domain.Signature + +data class VerifyMessageSignatureRequest( + val message: Message, + val publicKey: PublicKey, + val signature: Signature, +) diff --git a/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/VerifyMessageSignatureResponse.kt b/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/VerifyMessageSignatureResponse.kt new file mode 100644 index 00000000..e2f8ebbc --- /dev/null +++ b/we-node-client-domain/src/main/kotlin/com/wavesenterprise/sdk/node/domain/address/VerifyMessageSignatureResponse.kt @@ -0,0 +1,5 @@ +package com.wavesenterprise.sdk.node.domain.address + +data class VerifyMessageSignatureResponse( + val valid: Boolean, +) diff --git a/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/NodeErrorCode.kt b/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/NodeErrorCode.kt index 3bffd14b..51f1e8ee 100644 --- a/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/NodeErrorCode.kt +++ b/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/NodeErrorCode.kt @@ -1,8 +1,11 @@ package com.wavesenterprise.sdk.node.exception +@Suppress("MagicNumber") enum class NodeErrorCode(val code: Int) { INVALID_SIGNATURE(101), INVALID_ADDRESS(102), + INVALID_PUBLIC_KEY(108), + INVALID_PASSWORD(115), CUSTOM_VALIDATION_ERROR(199), DATA_KEY_NOT_EXISTS(304), CONTRACT_NOT_FOUND(600), diff --git a/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/specific/InvalidPasswordException.kt b/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/specific/InvalidPasswordException.kt new file mode 100644 index 00000000..933d1fc5 --- /dev/null +++ b/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/specific/InvalidPasswordException.kt @@ -0,0 +1,10 @@ +package com.wavesenterprise.sdk.node.exception.specific + +import com.wavesenterprise.sdk.node.exception.NodeError +import com.wavesenterprise.sdk.node.exception.NodeErrorInfoHolder +import com.wavesenterprise.sdk.node.exception.NodeException + +class InvalidPasswordException( + override val nodeError: NodeError, + override val cause: Exception, +) : NodeException(cause), NodeErrorInfoHolder diff --git a/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/specific/InvalidPublicKeyException.kt b/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/specific/InvalidPublicKeyException.kt new file mode 100644 index 00000000..1f6d2620 --- /dev/null +++ b/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/specific/InvalidPublicKeyException.kt @@ -0,0 +1,10 @@ +package com.wavesenterprise.sdk.node.exception.specific + +import com.wavesenterprise.sdk.node.exception.NodeError +import com.wavesenterprise.sdk.node.exception.NodeErrorInfoHolder +import com.wavesenterprise.sdk.node.exception.NodeException + +class InvalidPublicKeyException( + override val nodeError: NodeError, + override val cause: Exception, +) : NodeException(cause), NodeErrorInfoHolder diff --git a/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/specific/SpecificExceptionMapper.kt b/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/specific/SpecificExceptionMapper.kt index ebba3eca..4684726a 100644 --- a/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/specific/SpecificExceptionMapper.kt +++ b/we-node-client-error/src/main/kotlin/com/wavesenterprise/sdk/node/exception/specific/SpecificExceptionMapper.kt @@ -6,6 +6,8 @@ import com.wavesenterprise.sdk.node.exception.NodeErrorCode.CONTRACT_NOT_FOUND import com.wavesenterprise.sdk.node.exception.NodeErrorCode.CUSTOM_VALIDATION_ERROR import com.wavesenterprise.sdk.node.exception.NodeErrorCode.DATA_KEY_NOT_EXISTS import com.wavesenterprise.sdk.node.exception.NodeErrorCode.INVALID_ADDRESS +import com.wavesenterprise.sdk.node.exception.NodeErrorCode.INVALID_PASSWORD +import com.wavesenterprise.sdk.node.exception.NodeErrorCode.INVALID_PUBLIC_KEY import com.wavesenterprise.sdk.node.exception.NodeErrorCode.INVALID_SIGNATURE import com.wavesenterprise.sdk.node.exception.NodeErrorCode.POLICY_DOES_NOT_EXIST import com.wavesenterprise.sdk.node.exception.NodeErrorCode.POLICY_ITEM_DATA_IS_MISSING @@ -21,6 +23,8 @@ object SpecificExceptionMapper { when (code) { INVALID_SIGNATURE -> InvalidSignatureException(nodeError, cause = exception) INVALID_ADDRESS -> InvalidAddressException(nodeError, cause = exception) + INVALID_PUBLIC_KEY -> InvalidPublicKeyException(nodeError, cause = exception) + INVALID_PASSWORD -> InvalidPasswordException(nodeError, cause = exception) CUSTOM_VALIDATION_ERROR -> CustomValidationErrorException(nodeError, cause = exception) DATA_KEY_NOT_EXISTS -> DataKeyNotExistsException(nodeError, cause = exception) CONTRACT_NOT_FOUND -> ContractNotFoundException(nodeError, cause = exception) diff --git a/we-node-client-grpc/we-node-client-grpc-blocking-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/grpc/blocking/node/AddressGrpcBlockingService.kt b/we-node-client-grpc/we-node-client-grpc-blocking-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/grpc/blocking/node/AddressGrpcBlockingService.kt index 6648ee2b..8272a838 100644 --- a/we-node-client-grpc/we-node-client-grpc-blocking-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/grpc/blocking/node/AddressGrpcBlockingService.kt +++ b/we-node-client-grpc/we-node-client-grpc-blocking-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/grpc/blocking/node/AddressGrpcBlockingService.kt @@ -3,21 +3,42 @@ package com.wavesenterprise.sdk.node.client.grpc.blocking.node import com.wavesenterprise.sdk.node.client.blocking.address.AddressService import com.wavesenterprise.sdk.node.domain.Address import com.wavesenterprise.sdk.node.domain.DataEntry +import com.wavesenterprise.sdk.node.domain.DataKey +import com.wavesenterprise.sdk.node.domain.PublicKey +import com.wavesenterprise.sdk.node.domain.address.SignMessageRequest +import com.wavesenterprise.sdk.node.domain.address.SignMessageResponse +import com.wavesenterprise.sdk.node.domain.address.VerifyMessageSignatureRequest +import com.wavesenterprise.sdk.node.domain.address.VerifyMessageSignatureResponse +import java.util.Optional class AddressGrpcBlockingService : AddressService { override fun getAddresses(): List
{ TODO("Not yet implemented") } - override fun getAddressByPublicKey(publicKey: String): Address { + override fun getAddressByPublicKey(publicKey: PublicKey): Address { TODO("Not yet implemented") } - override fun getAddressValue(address: String, key: String): DataEntry? { + override fun getAddressValue(address: Address, key: DataKey): Optional { TODO("Not yet implemented") } - override fun getAddressValues(address: String): List { + override fun getAddressValues(address: Address): List { + TODO("Not yet implemented") + } + + override fun signMessage( + address: Address, + request: SignMessageRequest + ): SignMessageResponse { + TODO("Not yet implemented") + } + + override fun verifyMessageSignature( + address: Address, + request: VerifyMessageSignatureRequest + ): VerifyMessageSignatureResponse { TODO("Not yet implemented") } } diff --git a/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/address/FeignAddressService.kt b/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/address/FeignAddressService.kt new file mode 100644 index 00000000..9af14138 --- /dev/null +++ b/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/address/FeignAddressService.kt @@ -0,0 +1,60 @@ +package com.wavesenterprise.sdk.node.client.feign.address + +import com.wavesenterprise.sdk.node.client.blocking.address.AddressService +import com.wavesenterprise.sdk.node.client.http.DataEntryDto.Companion.toDomain +import com.wavesenterprise.sdk.node.client.http.address.AddressDto.Companion.toDomain +import com.wavesenterprise.sdk.node.client.http.address.SignMessageRequestDto.Companion.toDto +import com.wavesenterprise.sdk.node.client.http.address.SignMessageResponseDto.Companion.toDomain +import com.wavesenterprise.sdk.node.client.http.address.VerifyMessageSignatureRequestDto.Companion.toDto +import com.wavesenterprise.sdk.node.client.http.address.VerifyMessageSignatureResponseDto.Companion.toDomain +import com.wavesenterprise.sdk.node.domain.Address +import com.wavesenterprise.sdk.node.domain.DataEntry +import com.wavesenterprise.sdk.node.domain.DataKey +import com.wavesenterprise.sdk.node.domain.PublicKey +import com.wavesenterprise.sdk.node.domain.address.SignMessageRequest +import com.wavesenterprise.sdk.node.domain.address.SignMessageResponse +import com.wavesenterprise.sdk.node.domain.address.VerifyMessageSignatureRequest +import com.wavesenterprise.sdk.node.domain.address.VerifyMessageSignatureResponse +import com.wavesenterprise.sdk.node.exception.specific.DataKeyNotExistsException +import java.util.Optional + +class FeignAddressService( + private val weAddressServiceApiFeign: WeAddressServiceApiFeign, +) : AddressService { + override fun getAddresses(): List
= + weAddressServiceApiFeign.getAddresses().map { it.toDomain() } + + override fun getAddressByPublicKey(publicKey: PublicKey): Address = + weAddressServiceApiFeign.getAddressByPublicKey(publicKey.asBase58String()).toDomain() + + override fun getAddressValue(address: Address, key: DataKey): Optional = + try { + weAddressServiceApiFeign.getAddressValue( + address = address.asBase58String(), + key = key.value, + ).map { it.toDomain() } + } catch (ex: DataKeyNotExistsException) { + Optional.empty() + } + + override fun getAddressValues(address: Address): List = + weAddressServiceApiFeign.getAddressValues(address.asBase58String()).map { it.toDomain() } + + override fun signMessage( + address: Address, + request: SignMessageRequest + ): SignMessageResponse = + weAddressServiceApiFeign.signMessage( + address = address.asBase58String(), + request = request.toDto(), + ).toDomain() + + override fun verifyMessageSignature( + address: Address, + request: VerifyMessageSignatureRequest + ): VerifyMessageSignatureResponse = + weAddressServiceApiFeign.verifyMessageSignature( + address = address.asBase58String(), + request = request.toDto(), + ).toDomain() +} diff --git a/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/address/WeAddressServiceApiFeign.kt b/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/address/WeAddressServiceApiFeign.kt new file mode 100644 index 00000000..52b90a70 --- /dev/null +++ b/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/address/WeAddressServiceApiFeign.kt @@ -0,0 +1,44 @@ +package com.wavesenterprise.sdk.node.client.feign.address + +import com.wavesenterprise.sdk.node.client.http.DataEntryDto +import com.wavesenterprise.sdk.node.client.http.address.AddressDto +import com.wavesenterprise.sdk.node.client.http.address.SignMessageRequestDto +import com.wavesenterprise.sdk.node.client.http.address.SignMessageResponseDto +import com.wavesenterprise.sdk.node.client.http.address.VerifyMessageSignatureRequestDto +import com.wavesenterprise.sdk.node.client.http.address.VerifyMessageSignatureResponseDto +import feign.Headers +import feign.Param +import feign.RequestLine +import java.util.Optional + +interface WeAddressServiceApiFeign { + + @RequestLine("GET /addresses") + fun getAddresses(): List + + @RequestLine("GET /addresses/publicKey/{publicKey}") + fun getAddressByPublicKey(@Param("publicKey") publicKey: String): AddressDto + + @RequestLine("GET /addresses/data/{address}/{key}") + fun getAddressValue( + @Param("address") address: String, + @Param("key") key: String + ): Optional + + @RequestLine("GET /addresses/data/{address}") + fun getAddressValues(@Param("address") address: String): List + + @Headers("Content-Type: application/json") + @RequestLine("POST /addresses/sign/{address}") + fun signMessage( + @Param("address") address: String, + request: SignMessageRequestDto, + ): SignMessageResponseDto + + @Headers("Content-Type: application/json") + @RequestLine("POST /addresses/verify/{address}") + fun verifyMessageSignature( + @Param("address") address: String, + request: VerifyMessageSignatureRequestDto, + ): VerifyMessageSignatureResponseDto +} diff --git a/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/factory/FeignNodeServiceFactory.kt b/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/factory/FeignNodeServiceFactory.kt index 3906354f..f00d4503 100644 --- a/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/factory/FeignNodeServiceFactory.kt +++ b/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/factory/FeignNodeServiceFactory.kt @@ -12,13 +12,13 @@ import com.wavesenterprise.sdk.node.client.blocking.tx.TxService import com.wavesenterprise.sdk.node.client.blocking.util.NodeUtilsService import com.wavesenterprise.sdk.node.client.feign.FeignNodeClientParams import com.wavesenterprise.sdk.node.client.feign.FeignWeApiFactory +import com.wavesenterprise.sdk.node.client.feign.address.FeignAddressService +import com.wavesenterprise.sdk.node.client.feign.address.WeAddressServiceApiFeign import com.wavesenterprise.sdk.node.client.feign.blocks.FeignBlocksService import com.wavesenterprise.sdk.node.client.feign.blocks.WeBlocksServiceApiFeign import com.wavesenterprise.sdk.node.client.feign.contract.FeignContractService import com.wavesenterprise.sdk.node.client.feign.contract.WeContractServiceApiFeign -import com.wavesenterprise.sdk.node.client.feign.node.FeignAddressService import com.wavesenterprise.sdk.node.client.feign.node.FeignNodeInfoService -import com.wavesenterprise.sdk.node.client.feign.node.WeAddressServiceApiFeign import com.wavesenterprise.sdk.node.client.feign.node.WeNodeInfoServiceApiFeign import com.wavesenterprise.sdk.node.client.feign.pki.FeignPkiService import com.wavesenterprise.sdk.node.client.feign.pki.WePkiServiceApiFeign diff --git a/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/node/FeignAddressService.kt b/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/node/FeignAddressService.kt deleted file mode 100644 index 5be9a838..00000000 --- a/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/node/FeignAddressService.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.wavesenterprise.sdk.node.client.feign.node - -import com.wavesenterprise.sdk.node.client.blocking.address.AddressService -import com.wavesenterprise.sdk.node.domain.Address -import com.wavesenterprise.sdk.node.domain.DataEntry - -class FeignAddressService( - private val weAddressServiceApiFeign: WeAddressServiceApiFeign, -) : AddressService { - override fun getAddresses(): List
= - weAddressServiceApiFeign.getAddresses().map { Address.fromBase58(it) } - - override fun getAddressByPublicKey(publicKey: String): Address = - Address.fromBase58(weAddressServiceApiFeign.getAddressByPublicKey(publicKey).address) - - override fun getAddressValue(address: String, key: String): DataEntry? { - TODO("Not yet implemented") - } - - override fun getAddressValues(address: String): List { - TODO("Not yet implemented") - } -} diff --git a/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/node/WeAddressServiceApiFeign.kt b/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/node/WeAddressServiceApiFeign.kt deleted file mode 100644 index 76506ea1..00000000 --- a/we-node-client-http/we-node-client-feign-client/src/main/kotlin/com/wavesenterprise/sdk/node/client/feign/node/WeAddressServiceApiFeign.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.wavesenterprise.sdk.node.client.feign.node - -import com.wavesenterprise.sdk.node.client.http.AddressDto -import feign.Headers -import feign.RequestLine - -interface WeAddressServiceApiFeign { - - @Headers("Content-Type: application/json") - @RequestLine("GET /addresses") - fun getAddresses(): List - - @Headers("Content-Type: application/json") - @RequestLine("GET /addresses") - fun getAddressByPublicKey(publicKey: String): AddressDto -} diff --git a/we-node-client-http/we-node-client-feign-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/feign/address/FeignAddressServiceTest.kt b/we-node-client-http/we-node-client-feign-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/feign/address/FeignAddressServiceTest.kt new file mode 100644 index 00000000..73c82c88 --- /dev/null +++ b/we-node-client-http/we-node-client-feign-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/feign/address/FeignAddressServiceTest.kt @@ -0,0 +1,142 @@ +package com.wavesenterprise.sdk.node.client.feign.address + +import com.wavesenterprise.sdk.node.client.http.DataEntryDto.Companion.toDto +import com.wavesenterprise.sdk.node.client.http.address.AddressDto.Companion.toDto +import com.wavesenterprise.sdk.node.client.http.address.SignMessageResponseDto.Companion.toDto +import com.wavesenterprise.sdk.node.client.http.address.VerifyMessageSignatureResponseDto.Companion.toDto +import com.wavesenterprise.sdk.node.domain.Address +import com.wavesenterprise.sdk.node.domain.DataEntry +import com.wavesenterprise.sdk.node.domain.DataKey +import com.wavesenterprise.sdk.node.exception.NodeError +import com.wavesenterprise.sdk.node.exception.specific.DataKeyNotExistsException +import com.wavesenterprise.sdk.node.test.data.TestDataFactory.Companion.address +import com.wavesenterprise.sdk.node.test.data.TestDataFactory.Companion.dataEntry +import com.wavesenterprise.sdk.node.test.data.TestDataFactory.Companion.dataKey +import com.wavesenterprise.sdk.node.test.data.TestDataFactory.Companion.publicKey +import com.wavesenterprise.sdk.node.test.data.TestDataFactory.Companion.signMessageRequest +import com.wavesenterprise.sdk.node.test.data.TestDataFactory.Companion.signMessageResponse +import com.wavesenterprise.sdk.node.test.data.TestDataFactory.Companion.verifyMessageSignatureRequest +import com.wavesenterprise.sdk.node.test.data.TestDataFactory.Companion.verifyMessageSignatureResponse +import io.mockk.every +import io.mockk.mockk +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import java.util.Optional + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class FeignAddressServiceTest { + private lateinit var feignAddressService: FeignAddressService + private val weAddressServiceApiFeign: WeAddressServiceApiFeign = mockk() + + @BeforeEach + fun setUp() { + feignAddressService = FeignAddressService( + weAddressServiceApiFeign = weAddressServiceApiFeign, + ) + } + + @Test + fun `should return addresses`() { + val expectedResponse = listOf(address(), address()) + every { + weAddressServiceApiFeign.getAddresses() + } returns expectedResponse.map { it.asBase58String() } + assertEquals( + expectedResponse, + feignAddressService.getAddresses() + ) + } + + @Test + fun `should return address by publicKey`() { + val expectedResponse = address() + every { + weAddressServiceApiFeign.getAddressByPublicKey(any()) + } returns expectedResponse.toDto() + assertEquals( + expectedResponse, + feignAddressService.getAddressByPublicKey( + publicKey = publicKey(), + ) + ) + } + + @Test + fun `should return address value`() { + val expectedResponse = Optional.of(dataEntry()) + every { + weAddressServiceApiFeign.getAddressValue(any(), any()) + } returns expectedResponse.map { it.toDto() } + assertEquals( + expectedResponse, + feignAddressService.getAddressValue( + address = address(), + key = dataKey(), + ) + ) + } + + @Test + fun `should return address values`() { + val expectedResponse = listOf(dataEntry(), dataEntry()) + every { + weAddressServiceApiFeign.getAddressValues(any()) + } returns expectedResponse.map { it.toDto() } + assertEquals( + expectedResponse, + feignAddressService.getAddressValues( + address = address(), + ) + ) + } + + @Test + fun `should return sign message response`() { + val expectedResponse = signMessageResponse() + every { + weAddressServiceApiFeign.signMessage(any(), any()) + } returns expectedResponse.toDto() + assertEquals( + expectedResponse, + feignAddressService.signMessage( + address = address(), + request = signMessageRequest() + ) + ) + } + + @Test + fun `should return verify message signature response`() { + val expectedResponse = verifyMessageSignatureResponse() + every { + weAddressServiceApiFeign.verifyMessageSignature(any(), any()) + } returns expectedResponse.toDto() + assertEquals( + expectedResponse, + feignAddressService.verifyMessageSignature( + address = address(), + request = verifyMessageSignatureRequest() + ) + ) + } + + @Test + fun `should return null when catch DataKeyNotExistsException`() { + feignAddressService = FeignAddressService(weAddressServiceApiFeign) + every { + weAddressServiceApiFeign.getAddressValue(any(), any()) + } throws DataKeyNotExistsException( + nodeError = NodeError(error = 304, message = "no data for this key"), + cause = Exception(), + ) + assertEquals( + Optional.empty(), + feignAddressService.getAddressValue( + address = Address.fromBase58("3M3ybNZvLG7o7rnM4F7ViRPnDTfVggdfmRX"), + key = DataKey("not-existing-key") + ) + ) + } +} diff --git a/we-node-client-http/we-node-client-feign-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/feign/address/WeAddressServiceApiFeignTest.kt b/we-node-client-http/we-node-client-feign-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/feign/address/WeAddressServiceApiFeignTest.kt new file mode 100644 index 00000000..9758b98a --- /dev/null +++ b/we-node-client-http/we-node-client-feign-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/feign/address/WeAddressServiceApiFeignTest.kt @@ -0,0 +1,171 @@ +package com.wavesenterprise.sdk.node.client.feign.address + +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo +import com.github.tomakehurst.wiremock.junit5.WireMockTest +import com.wavesenterprise.sdk.node.client.feign.FeignNodeClientParams +import com.wavesenterprise.sdk.node.client.feign.FeignNodeErrorDecoder +import com.wavesenterprise.sdk.node.client.feign.FeignNodeErrorMapper +import com.wavesenterprise.sdk.node.client.feign.FeignWeApiFactory +import com.wavesenterprise.sdk.node.client.http.DataEntryDto +import com.wavesenterprise.sdk.node.client.http.address.AddressDto +import com.wavesenterprise.sdk.node.client.http.address.SignMessageRequestDto +import com.wavesenterprise.sdk.node.client.http.address.SignMessageResponseDto +import com.wavesenterprise.sdk.node.client.http.address.VerifyMessageSignatureRequestDto +import com.wavesenterprise.sdk.node.client.http.address.VerifyMessageSignatureResponseDto +import com.wavesenterprise.sdk.node.exception.NodeErrorCode +import com.wavesenterprise.sdk.node.exception.specific.InvalidPasswordException +import com.wavesenterprise.sdk.node.exception.specific.InvalidPublicKeyException +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.assertThrows +import java.util.Optional + +@WireMockTest +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class WeAddressServiceApiFeignTest { + + lateinit var weAddressServiceApiFeign: WeAddressServiceApiFeign + + private val address = "3M3ybNZvLG7o7rnM4F7ViRPnDTfVggdfmRX" + private val publicKey = "4L4XEpNpesX9r6rVJ8hW1TrMiNCZ6SMvRuWPKB7T47wKfnp4D84XBUv7xsa36CGwoyK3fzfojivwonHNrsX2fLBL" + private val signature = "2CE7zZqJ2zXphCweDbvMMCvYYcc7AsHHNdf9jGLHDX4FMqN1G7HwN2SF91rdUyBP6oKRYqNE1gcVU2xJuM1B4mEX" + + @BeforeAll + fun init(wireMockRuntimeInfo: WireMockRuntimeInfo) { + weAddressServiceApiFeign = FeignWeApiFactory.createClient( + clientClass = WeAddressServiceApiFeign::class.java, + feignProperties = FeignNodeClientParams(url = wireMockRuntimeInfo.httpBaseUrl), + errorDecoder = FeignNodeErrorDecoder(FeignNodeErrorMapper(jacksonObjectMapper())), + ) + } + + @Test + fun `should get addresses`() { + assertEquals( + listOf( + "3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh", + "3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv", + "3M3ybNZvLG7o7rnM4F7ViRPnDTfVggdfmRX", + ), + weAddressServiceApiFeign.getAddresses(), + ) + } + + @Test + fun `should get address by publicKey`() { + assertEquals( + AddressDto(address), + weAddressServiceApiFeign.getAddressByPublicKey(publicKey) + ) + } + + @Test + fun `should get address value`() { + val addressValue = DataEntryDto( + type = "integer", + key = "some-key", + value = 100, + ) + assertEquals( + Optional.of(addressValue), + weAddressServiceApiFeign.getAddressValue( + address = address, + key = "some-key" + ), + ) + } + + @Test + fun `should get address values`() { + val addressValues = listOf( + DataEntryDto( + type = "integer", + key = "some-key", + value = 100, + ), + DataEntryDto( + type = "string", + key = "another-key", + value = "testValue", + ), + ) + assertEquals( + addressValues, + weAddressServiceApiFeign.getAddressValues(address) + ) + } + + @Test + fun `should sign message`() { + val request = SignMessageRequestDto( + message = "message", + password = "password" + ) + val response = SignMessageResponseDto( + message = "59Su1K4KSU", + publicKey = publicKey, + signature = signature, + ) + assertEquals( + response, + weAddressServiceApiFeign.signMessage( + address = address, + request = request, + ) + ) + } + + @Test + fun `should verify message signature`() { + val request = VerifyMessageSignatureRequestDto( + message = "59Su1K4KSU", + publicKey = publicKey, + signature = signature, + ) + val response = VerifyMessageSignatureResponseDto(valid = true) + assertEquals( + response, + weAddressServiceApiFeign.verifyMessageSignature( + address = address, + request = request, + ) + ) + } + + @Test + fun `should throw InvalidPublicKeyException`() { + assertThrows { + weAddressServiceApiFeign.getAddressByPublicKey("invalid-public-key") + }.apply { + assertEquals(NodeErrorCode.INVALID_PUBLIC_KEY.code, nodeError.error) + assertEquals( + "invalid public key: Can't create public key from string 'invalid-public-key': " + + "Unable to create public key: null", + nodeError.message + ) + } + } + + @Test + fun `should throw InvalidPasswordException`() { + val request = SignMessageRequestDto( + message = "message", + password = "incorrect-password" + ) + assertThrows { + weAddressServiceApiFeign.signMessage( + address = address, + request = request, + ) + }.apply { + assertEquals(NodeErrorCode.INVALID_PASSWORD.code, nodeError.error) + assertEquals( + "no private key for sender address in wallet or provided password is incorrect", + nodeError.message + ) + } + } +} diff --git a/we-node-client-http/we-node-client-feign-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/feign/node/WeAddressServiceApiFeignTest.kt b/we-node-client-http/we-node-client-feign-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/feign/node/WeAddressServiceApiFeignTest.kt deleted file mode 100644 index 7c55cb97..00000000 --- a/we-node-client-http/we-node-client-feign-client/src/test/kotlin/com/wavesenterprise/sdk/node/client/feign/node/WeAddressServiceApiFeignTest.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.wavesenterprise.sdk.node.client.feign.node - -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo -import com.github.tomakehurst.wiremock.junit5.WireMockTest -import com.wavesenterprise.sdk.node.client.feign.FeignNodeClientParams -import com.wavesenterprise.sdk.node.client.feign.FeignNodeErrorDecoder -import com.wavesenterprise.sdk.node.client.feign.FeignNodeErrorMapper -import com.wavesenterprise.sdk.node.client.feign.FeignWeApiFactory -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.TestInstance - -@WireMockTest -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -class WeAddressServiceApiFeignTest { - - lateinit var weAddressServiceApiFeign: WeAddressServiceApiFeign - - @BeforeAll - fun init(wireMockRuntimeInfo: WireMockRuntimeInfo) { - weAddressServiceApiFeign = FeignWeApiFactory.createClient( - clientClass = WeAddressServiceApiFeign::class.java, - feignProperties = FeignNodeClientParams(url = wireMockRuntimeInfo.httpBaseUrl), - errorDecoder = FeignNodeErrorDecoder(FeignNodeErrorMapper(jacksonObjectMapper())), - ) - } - - @Test - fun `should get addresses`() { - val addressesList = weAddressServiceApiFeign.getAddresses() - - assertEquals( - listOf( - "3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh", - "3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv", - "3M3ybNZvLG7o7rnM4F7ViRPnDTfVggdfmRX", - ), - addressesList, - ) - } -} diff --git a/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_by_public_key_200.json b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_by_public_key_200.json new file mode 100644 index 00000000..91b6b1d8 --- /dev/null +++ b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_by_public_key_200.json @@ -0,0 +1,15 @@ +{ + "request": { + "method": "GET", + "url": "/addresses/publicKey/4L4XEpNpesX9r6rVJ8hW1TrMiNCZ6SMvRuWPKB7T47wKfnp4D84XBUv7xsa36CGwoyK3fzfojivwonHNrsX2fLBL" + }, + "response": { + "status": 200, + "jsonBody": { + "address": "3M3ybNZvLG7o7rnM4F7ViRPnDTfVggdfmRX" + }, + "headers": { + "Content-Type": "application/json" + } + } +} \ No newline at end of file diff --git a/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_by_public_key_400.json b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_by_public_key_400.json new file mode 100644 index 00000000..6abf894d --- /dev/null +++ b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_by_public_key_400.json @@ -0,0 +1,16 @@ +{ + "request": { + "method": "GET", + "url": "/addresses/publicKey/invalid-public-key" + }, + "response": { + "status": 400, + "jsonBody": { + "error": 108, + "message": "invalid public key: Can't create public key from string 'invalid-public-key': Unable to create public key: null" + }, + "headers": { + "Content-Type": "application/json" + } + } +} \ No newline at end of file diff --git a/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_value_200.json b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_value_200.json new file mode 100644 index 00000000..b4ac4916 --- /dev/null +++ b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_value_200.json @@ -0,0 +1,17 @@ +{ + "request": { + "method": "GET", + "url": "/addresses/data/3M3ybNZvLG7o7rnM4F7ViRPnDTfVggdfmRX/some-key" + }, + "response": { + "status": 200, + "jsonBody": { + "type": "integer", + "key": "some-key", + "value": 100 + }, + "headers": { + "Content-Type": "application/json" + } + } +} \ No newline at end of file diff --git a/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_values_200.json b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_values_200.json new file mode 100644 index 00000000..604c3281 --- /dev/null +++ b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_values_200.json @@ -0,0 +1,24 @@ +{ + "request": { + "method": "GET", + "url": "/addresses/data/3M3ybNZvLG7o7rnM4F7ViRPnDTfVggdfmRX" + }, + "response": { + "status": 200, + "jsonBody": [ + { + "type": "integer", + "key": "some-key", + "value": 100 + }, + { + "type": "string", + "key": "another-key", + "value": "testValue" + } + ], + "headers": { + "Content-Type": "application/json" + } + } +} \ No newline at end of file diff --git a/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_200.json b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/addresses_200.json similarity index 100% rename from we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/address_200.json rename to we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/addresses_200.json diff --git a/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/sign_message_200.json b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/sign_message_200.json new file mode 100644 index 00000000..4cc2b53b --- /dev/null +++ b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/sign_message_200.json @@ -0,0 +1,25 @@ +{ + "request": { + "method": "POST", + "url": "/addresses/sign/3M3ybNZvLG7o7rnM4F7ViRPnDTfVggdfmRX", + "bodyPatterns": [ + { + "equalToJson": { + "message": "message", + "password": "password" + } + } + ] + }, + "response": { + "status": 200, + "jsonBody": { + "message": "59Su1K4KSU", + "publicKey": "4L4XEpNpesX9r6rVJ8hW1TrMiNCZ6SMvRuWPKB7T47wKfnp4D84XBUv7xsa36CGwoyK3fzfojivwonHNrsX2fLBL", + "signature": "2CE7zZqJ2zXphCweDbvMMCvYYcc7AsHHNdf9jGLHDX4FMqN1G7HwN2SF91rdUyBP6oKRYqNE1gcVU2xJuM1B4mEX" + }, + "headers": { + "Content-Type": "application/json" + } + } +} diff --git a/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/sign_message_400.json b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/sign_message_400.json new file mode 100644 index 00000000..19a7c0d0 --- /dev/null +++ b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/sign_message_400.json @@ -0,0 +1,24 @@ +{ + "request": { + "method": "POST", + "url": "/addresses/sign/3M3ybNZvLG7o7rnM4F7ViRPnDTfVggdfmRX", + "bodyPatterns": [ + { + "equalToJson": { + "message": "message", + "password": "incorrect-password" + } + } + ] + }, + "response": { + "status": 400, + "jsonBody": { + "error": 115, + "message": "no private key for sender address in wallet or provided password is incorrect" + }, + "headers": { + "Content-Type": "application/json" + } + } +} diff --git a/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/verify_message_signature_200.json b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/verify_message_signature_200.json new file mode 100644 index 00000000..12476fbd --- /dev/null +++ b/we-node-client-http/we-node-client-feign-client/src/test/resources/mappings/address/verify_message_signature_200.json @@ -0,0 +1,24 @@ +{ + "request": { + "method": "POST", + "url": "/addresses/verify/3M3ybNZvLG7o7rnM4F7ViRPnDTfVggdfmRX", + "bodyPatterns": [ + { + "equalToJson": { + "message": "59Su1K4KSU", + "publicKey": "4L4XEpNpesX9r6rVJ8hW1TrMiNCZ6SMvRuWPKB7T47wKfnp4D84XBUv7xsa36CGwoyK3fzfojivwonHNrsX2fLBL", + "signature": "2CE7zZqJ2zXphCweDbvMMCvYYcc7AsHHNdf9jGLHDX4FMqN1G7HwN2SF91rdUyBP6oKRYqNE1gcVU2xJuM1B4mEX" + } + } + ] + }, + "response": { + "status": 200, + "jsonBody": { + "valid": true + }, + "headers": { + "Content-Type": "application/json" + } + } +} diff --git a/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/AddressDto.kt b/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/AddressDto.kt deleted file mode 100644 index 8941395c..00000000 --- a/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/AddressDto.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.wavesenterprise.sdk.node.client.http - -data class AddressDto( - val address: String, -) diff --git a/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/AddressDto.kt b/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/AddressDto.kt new file mode 100644 index 00000000..56185b7d --- /dev/null +++ b/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/AddressDto.kt @@ -0,0 +1,18 @@ +package com.wavesenterprise.sdk.node.client.http.address + +import com.wavesenterprise.sdk.node.domain.Address + +data class AddressDto( + val address: String, +) { + companion object { + @JvmStatic + fun AddressDto.toDomain(): Address = Address.fromBase58(address) + + @JvmStatic + fun Address.toDto(): AddressDto = AddressDto(address = asBase58String()) + + @JvmStatic + fun String.toDomain(): Address = Address.fromBase58(this) + } +} diff --git a/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/SignMessageRequestDto.kt b/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/SignMessageRequestDto.kt new file mode 100644 index 00000000..f3806746 --- /dev/null +++ b/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/SignMessageRequestDto.kt @@ -0,0 +1,17 @@ +package com.wavesenterprise.sdk.node.client.http.address + +import com.wavesenterprise.sdk.node.domain.address.SignMessageRequest + +data class SignMessageRequestDto( + val message: String, + val password: String +) { + companion object { + @JvmStatic + fun SignMessageRequest.toDto(): SignMessageRequestDto = + SignMessageRequestDto( + message = message.value, + password = password.value, + ) + } +} diff --git a/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/SignMessageResponseDto.kt b/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/SignMessageResponseDto.kt new file mode 100644 index 00000000..4c19caa0 --- /dev/null +++ b/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/SignMessageResponseDto.kt @@ -0,0 +1,30 @@ +package com.wavesenterprise.sdk.node.client.http.address + +import com.wavesenterprise.sdk.node.domain.PublicKey +import com.wavesenterprise.sdk.node.domain.Signature +import com.wavesenterprise.sdk.node.domain.address.Message +import com.wavesenterprise.sdk.node.domain.address.SignMessageResponse + +data class SignMessageResponseDto( + val message: String, + val publicKey: String, + val signature: String +) { + companion object { + @JvmStatic + fun SignMessageResponse.toDto(): SignMessageResponseDto = + SignMessageResponseDto( + message = message.value, + publicKey = publicKey.asBase58String(), + signature = signature.asBase58String(), + ) + + @JvmStatic + fun SignMessageResponseDto.toDomain(): SignMessageResponse = + SignMessageResponse( + message = Message(value = message), + publicKey = PublicKey.fromBase58(publicKey), + signature = Signature.fromBase58(signature) + ) + } +} diff --git a/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/VerifyMessageSignatureRequestDto.kt b/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/VerifyMessageSignatureRequestDto.kt new file mode 100644 index 00000000..51326b2f --- /dev/null +++ b/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/VerifyMessageSignatureRequestDto.kt @@ -0,0 +1,19 @@ +package com.wavesenterprise.sdk.node.client.http.address + +import com.wavesenterprise.sdk.node.domain.address.VerifyMessageSignatureRequest + +data class VerifyMessageSignatureRequestDto( + val message: String, + val publicKey: String, + val signature: String +) { + companion object { + @JvmStatic + fun VerifyMessageSignatureRequest.toDto(): VerifyMessageSignatureRequestDto = + VerifyMessageSignatureRequestDto( + message = message.value, + publicKey = publicKey.asBase58String(), + signature = signature.asBase58String(), + ) + } +} diff --git a/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/VerifyMessageSignatureResponseDto.kt b/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/VerifyMessageSignatureResponseDto.kt new file mode 100644 index 00000000..1d66663e --- /dev/null +++ b/we-node-client-json/src/main/kotlin/com/wavesenterprise/sdk/node/client/http/address/VerifyMessageSignatureResponseDto.kt @@ -0,0 +1,21 @@ +package com.wavesenterprise.sdk.node.client.http.address + +import com.wavesenterprise.sdk.node.domain.address.VerifyMessageSignatureResponse + +data class VerifyMessageSignatureResponseDto( + val valid: Boolean +) { + companion object { + @JvmStatic + fun VerifyMessageSignatureResponse.toDto(): VerifyMessageSignatureResponseDto = + VerifyMessageSignatureResponseDto( + valid = valid + ) + + @JvmStatic + fun VerifyMessageSignatureResponseDto.toDomain(): VerifyMessageSignatureResponse = + VerifyMessageSignatureResponse( + valid = valid + ) + } +} diff --git a/we-node-domain-test/src/main/kotlin/com/wavesenterprise/sdk/node/test/data/TestDataFactory.kt b/we-node-domain-test/src/main/kotlin/com/wavesenterprise/sdk/node/test/data/TestDataFactory.kt index 16c1b3cf..f53e3581 100644 --- a/we-node-domain-test/src/main/kotlin/com/wavesenterprise/sdk/node/test/data/TestDataFactory.kt +++ b/we-node-domain-test/src/main/kotlin/com/wavesenterprise/sdk/node/test/data/TestDataFactory.kt @@ -6,7 +6,10 @@ import com.wavesenterprise.sdk.node.domain.AssetId import com.wavesenterprise.sdk.node.domain.Attachment import com.wavesenterprise.sdk.node.domain.ChainId import com.wavesenterprise.sdk.node.domain.DataEntry +import com.wavesenterprise.sdk.node.domain.DataKey import com.wavesenterprise.sdk.node.domain.DataSize +import com.wavesenterprise.sdk.node.domain.DataValue +import com.wavesenterprise.sdk.node.domain.DataValue.IntegerDataValue import com.wavesenterprise.sdk.node.domain.Decimals import com.wavesenterprise.sdk.node.domain.Fee import com.wavesenterprise.sdk.node.domain.FeeAssetId @@ -31,6 +34,11 @@ import com.wavesenterprise.sdk.node.domain.TxId import com.wavesenterprise.sdk.node.domain.TxType import com.wavesenterprise.sdk.node.domain.TxVersion import com.wavesenterprise.sdk.node.domain.ValidationProof +import com.wavesenterprise.sdk.node.domain.address.Message +import com.wavesenterprise.sdk.node.domain.address.SignMessageRequest +import com.wavesenterprise.sdk.node.domain.address.SignMessageResponse +import com.wavesenterprise.sdk.node.domain.address.VerifyMessageSignatureRequest +import com.wavesenterprise.sdk.node.domain.address.VerifyMessageSignatureResponse import com.wavesenterprise.sdk.node.domain.atomic.AtomicBadge import com.wavesenterprise.sdk.node.domain.contract.CallContractTransaction import com.wavesenterprise.sdk.node.domain.contract.ContractId @@ -104,6 +112,27 @@ class TestDataFactory private constructor() { @JvmStatic fun fee(value: Long = 0) = Fee(value) + @JvmStatic + fun publicKey(bytes: ByteArray = randomBytesFromUUID()) = PublicKey(bytes) + + @JvmStatic + fun message(value: String = "message") = Message(value) + + @JvmStatic + fun signature(bytes: ByteArray = randomBytesFromUUID()) = Signature(bytes) + + @JvmStatic + fun dataKey(value: String = "dataKey") = DataKey(value) + + @JvmStatic + fun dataEntry( + key: DataKey = dataKey(), + value: DataValue = IntegerDataValue(0L), + ) = DataEntry( + key = key, + value = value, + ) + @JvmStatic fun contractTransaction( sender: Address, @@ -789,5 +818,43 @@ class TestDataFactory private constructor() { version = version, active = active, ) + + @JvmStatic + fun signMessageRequest( + message: Message = message(), + password: Password = password(), + ) = SignMessageRequest( + message = message, + password = password, + ) + + @JvmStatic + fun signMessageResponse( + message: Message = message(), + publicKey: PublicKey = publicKey(), + signature: Signature = signature(), + ) = SignMessageResponse( + message = message, + publicKey = publicKey, + signature = signature, + ) + + @JvmStatic + fun verifyMessageSignatureRequest( + message: Message = message(), + publicKey: PublicKey = publicKey(), + signature: Signature = signature(), + ) = VerifyMessageSignatureRequest( + message = message, + publicKey = publicKey, + signature = signature, + ) + + @JvmStatic + fun verifyMessageSignatureResponse( + valid: Boolean = true, + ) = VerifyMessageSignatureResponse( + valid = valid, + ) } }