Skip to content

Commit ae60e71

Browse files
Merge pull request #100 from OpenFuturePlatform/key-master-fix
Update Wallet Api State Request
2 parents 4b82ffa + dd053e2 commit ae60e71

32 files changed

+326
-121
lines changed

frontend/src/components-ui/Table.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ export const Table = ({ data, columns, noDataText }) => (
66
data={data}
77
columns={columns}
88
className="-striped"
9-
showPagination={false}
10-
resizable={false}
9+
showPagination={true}
10+
resizable={true}
1111
minRows={1}
1212
pageSize={data.length}
1313
noDataText={noDataText}

frontend/src/components/GatewayApplicationWallet.js

+11-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React from "react";
2-
import {Button, Divider, Grid, Icon, Input, Modal, Segment} from "semantic-ui-react";
3-
import {EtherscanLink} from "../components-ui/EtherscanLink";
2+
import {Segment} from "semantic-ui-react";
43
import {connect} from "react-redux";
54

65

@@ -15,11 +14,17 @@ import {
1514
import {getGatewayWalletSelector} from "../selectors/getGatewayWalletsSelector";
1615

1716
import {GatewayApplicationWalletRemove} from "./GatewayApplicationWalletRemove";
18-
import {GatewayApplicationWalletPrivateKey} from "./GatewayApplicationWalletPrivateKey";
1917
import {WalletImport} from "./GatewayApplicationWalletImport";
2018
import {OpenScanLink} from "../components-ui/OpenScanLink";
2119

2220
const getColumns = (wallets, onRemove, onExport) => [
21+
{
22+
Header: 'Wallet Type',
23+
accessor: 'walletType',
24+
width: 200,
25+
Cell: ({ value }) => <span>{value}</span>,
26+
sortable: false
27+
},
2328
{
2429
Header: 'Wallet Address',
2530
accessor: 'address',
@@ -44,7 +49,7 @@ const getColumns = (wallets, onRemove, onExport) => [
4449
),
4550
sortable: false
4651
},
47-
{
52+
/*{
4853
Header: '',
4954
accessor: 'address',
5055
width: 150,
@@ -54,7 +59,7 @@ const getColumns = (wallets, onRemove, onExport) => [
5459
</span>
5560
),
5661
sortable: false
57-
}
62+
}*/
5863
];
5964

6065
class GatewayApplicationWalletComponent extends React.Component {
@@ -85,7 +90,7 @@ class GatewayApplicationWalletComponent extends React.Component {
8590
return (
8691
<div className="table-with-add">
8792
<WalletGenerate gateway={gateway} onSubmit={this.onGenerateWallet} />
88-
<WalletImport gateway={gateway} onSubmit={this.onImportWallet} />
93+
8994
<Segment attached styles={{ padding: 0 }}>
9095
<Table data={wallets.list} columns={columns} noDataText={noDataText} />
9196
</Segment>

payment-chooser/build/resources/static/static/js/payment-chooser.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

payment-chooser/build/resources/static/static/js/payment-chooser.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

payment-chooser/build/static/js/payment-chooser.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

payment-chooser/build/static/js/payment-chooser.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/kotlin/io/openfuture/api/component/key/DefaultKeyApi.kt

+14-6
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ import org.springframework.web.client.RestTemplate
66

77

88
@Component
9-
class DefaultKeyApi(private val keyRestTemplate: RestTemplate): KeyApi {
10-
override fun generateKey(createKeyRequest: CreateKeyRequest): KeyWalletDto {
9+
class DefaultKeyApi(
10+
private val keyRestTemplate: RestTemplate
11+
): KeyApi {
12+
13+
override fun generateWallet(createKeyRequest: CreateKeyRequest): KeyWalletDto {
1114
val response = keyRestTemplate.postForEntity("/key", createKeyRequest, KeyWalletDto::class.java)
1215
return response.body!!
1316
}
@@ -17,17 +20,22 @@ class DefaultKeyApi(private val keyRestTemplate: RestTemplate): KeyApi {
1720
return response.body!!
1821
}
1922

20-
override fun generateMultipleKey(createMultipleKeyRequest: CreateMultipleKeyRequest): Array<KeyWalletDto> {
23+
override fun generateMultipleWallets(createMultipleKeyRequest: CreateMultipleKeyRequest): Array<KeyWalletDto> {
2124
val response = keyRestTemplate.postForEntity("/key/multiple", createMultipleKeyRequest, Array<KeyWalletDto>::class.java)
2225
return response.body!!
2326
}
2427

25-
override fun getAllKeysByApplication(applicationId: String): Array<KeyWalletDto> {
28+
override fun updateWallets(createMultipleKeyRequest: CreateMultipleKeyRequest): Array<KeyWalletDto> {
29+
val response = keyRestTemplate.postForEntity("/key/update", createMultipleKeyRequest, Array<KeyWalletDto>::class.java)
30+
return response.body!!
31+
}
32+
33+
override fun getAllWalletsByApplication(applicationId: String): Array<KeyWalletDto> {
2634
val response = keyRestTemplate.getForEntity("/key?applicationId={applicationId}", Array<KeyWalletDto>::class.java, applicationId)
2735
return response.body!!
2836
}
2937

30-
override fun getAllKeysByOrderKey(orderKey: String): Array<KeyWalletDto> {
38+
override fun getAllWalletsByOrderKey(orderKey: String): Array<KeyWalletDto> {
3139
val url = "/key/order/${orderKey}"
3240
val response = keyRestTemplate.getForEntity(url, Array<KeyWalletDto>::class.java)
3341
return response.body!!
@@ -38,7 +46,7 @@ class DefaultKeyApi(private val keyRestTemplate: RestTemplate): KeyApi {
3846
return response.body!!
3947
}
4048

41-
override fun deleteAllKeysByApplicationAddress(applicationId: String, address: String) {
49+
override fun deleteAllWalletsByApplicationAddress(applicationId: String, address: String) {
4250
val url = "/key?applicationId=${applicationId}&address=${address}"
4351
keyRestTemplate.delete(url)
4452
}

src/main/kotlin/io/openfuture/api/component/key/KeyApi.kt

+6-5
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package io.openfuture.api.component.key
33
import io.openfuture.api.domain.key.*
44

55
interface KeyApi {
6-
fun generateKey(createKeyRequest: CreateKeyRequest): KeyWalletDto
6+
fun generateWallet(createKeyRequest: CreateKeyRequest): KeyWalletDto
77
fun importWallet(request: ImportKeyRequest): KeyWalletDto
8-
fun generateMultipleKey(createMultipleKeyRequest: CreateMultipleKeyRequest): Array<KeyWalletDto>
9-
fun getAllKeysByApplication(applicationId: String): Array<KeyWalletDto>
10-
fun getAllKeysByOrderKey(orderKey: String): Array<KeyWalletDto>
8+
fun generateMultipleWallets(createMultipleKeyRequest: CreateMultipleKeyRequest): Array<KeyWalletDto>
9+
fun updateWallets(createMultipleKeyRequest: CreateMultipleKeyRequest): Array<KeyWalletDto>
10+
fun getAllWalletsByApplication(applicationId: String): Array<KeyWalletDto>
11+
fun getAllWalletsByOrderKey(orderKey: String): Array<KeyWalletDto>
1112
fun getApplicationByAddress(address: String): WalletAddressResponse
12-
fun deleteAllKeysByApplicationAddress(applicationId: String, address: String)
13+
fun deleteAllWalletsByApplicationAddress(applicationId: String, address: String)
1314
fun exportPrivateKey(keyWalletDto: KeyWalletDto): String
1415
}

src/main/kotlin/io/openfuture/api/component/state/DefaultStateApi.kt

+15-18
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,41 @@
11
package io.openfuture.api.component.state
22

3-
import io.openfuture.api.domain.key.KeyWalletDto
3+
import io.openfuture.api.domain.state.WalletApiStateResponse
44
import io.openfuture.api.domain.state.*
55
import io.openfuture.api.domain.transaction.TransactionDto
66
import io.openfuture.api.domain.widget.PaymentWidgetResponse
77
import io.openfuture.api.entity.state.Blockchain
8-
import io.openfuture.api.util.getOrderKey
9-
import io.openfuture.api.util.getRandomNumber
108
import org.springframework.stereotype.Component
119
import org.springframework.web.client.RestTemplate
12-
import java.math.BigDecimal
1310

1411
@Component
1512
class DefaultStateApi(private val stateRestTemplate: RestTemplate) : StateApi {
1613

17-
override fun createWallet(address: String, webHook: String, blockchain: Blockchain): CreateStateWalletResponse {
18-
val request = CreateStateWalletRequestMetadata(
19-
webHook,
20-
listOf(KeyWalletDto(address, blockchain.getValue())),
21-
WalletMetaData(
22-
"0",
23-
"1000",
24-
"op_UxQr1LLdREboF",
25-
"USD",
26-
"open",
27-
false
28-
)
29-
)
30-
return stateRestTemplate.postForEntity("/wallets", request, CreateStateWalletResponse::class.java).body!!
14+
override fun createWallet(address: String, webHook: String, blockchain: Blockchain, applicationId: String): StateWalletDto {
15+
val request = CreateStateWalletRequest(address, webHook, blockchain.getValue(), applicationId)
16+
println("Blockchain : $blockchain")
17+
val response = stateRestTemplate.postForEntity("/wallets/single", request, StateWalletDto::class.java)
18+
return response.body!!
3119
}
3220

3321
override fun createWalletWithMetadata(request: CreateStateWalletRequestMetadata): CreateStateWalletResponse {
3422
return stateRestTemplate.postForEntity("/wallets", request, CreateStateWalletResponse::class.java).body!!
3523
}
3624

25+
override fun updateWalletWithMetadata(request: UpdateStateWalletMetadata) {
26+
stateRestTemplate.postForEntity("/wallets/update", request, Void::class.java)
27+
}
28+
3729
override fun deleteWallet(address: String, blockchain: Blockchain) {
3830
val url = "/wallets/blockchain/${blockchain.getValue()}/address/${address}"
3931
stateRestTemplate.delete(url)
4032
}
4133

34+
override fun getWallet(address: String, blockchain: Blockchain): WalletApiStateResponse {
35+
val url = "/wallets/blockchain/${blockchain.getValue()}/address/${address}"
36+
return stateRestTemplate.getForEntity(url, WalletApiStateResponse::class.java).body!!
37+
}
38+
4239
override fun getAddressTransactionsByAddress(address: String): StateWalletTransactionDetail {
4340
val url = "/wallets/transactions/address/${address}"
4441
return stateRestTemplate.getForEntity(url, StateWalletTransactionDetail::class.java).body!!

src/main/kotlin/io/openfuture/api/component/state/StateApi.kt

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
package io.openfuture.api.component.state
22

3+
import io.openfuture.api.domain.state.WalletApiStateResponse
34
import io.openfuture.api.domain.state.*
45
import io.openfuture.api.domain.transaction.TransactionDto
56
import io.openfuture.api.domain.widget.PaymentWidgetResponse
67
import io.openfuture.api.entity.state.Blockchain
78

89
interface StateApi {
910

10-
fun createWallet(address: String, webHook: String, blockchain: Blockchain): CreateStateWalletResponse
11+
fun createWallet(address: String, webHook: String, blockchain: Blockchain, applicationId: String): StateWalletDto
1112

1213
fun createWalletWithMetadata(request: CreateStateWalletRequestMetadata): CreateStateWalletResponse
1314

15+
fun updateWalletWithMetadata(request: UpdateStateWalletMetadata)
16+
1417
fun deleteWallet(address: String, blockchain: Blockchain)
1518

19+
fun getWallet(address: String, blockchain: Blockchain): WalletApiStateResponse
20+
1621
fun getAddressTransactionsByAddress(address: String): StateWalletTransactionDetail
1722

1823
fun getTransactionsByAddress(address: String): Array<TransactionDto>

src/main/kotlin/io/openfuture/api/component/web3/Web3Wrapper.kt

+10-1
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,18 @@ class Web3Wrapper(
6969

7070
fun getNetVersion(): String = web3j.netVersion().send().netVersion
7171

72+
fun broadcastTransaction(signedTransaction: String): TransactionReceipt {
73+
return sendRawTransaction("0x$signedTransaction")
74+
}
75+
7276
private fun executeTransaction(transaction: RawTransaction, credentials: Credentials): TransactionReceipt {
7377
val encodedTransaction = signMessage(transaction, credentials)
74-
val result = web3j.ethSendRawTransaction(toHexString(encodedTransaction)).send()
78+
79+
return sendRawTransaction(toHexString(encodedTransaction))
80+
}
81+
82+
private fun sendRawTransaction(signedTransaction: String): TransactionReceipt {
83+
val result = web3j.ethSendRawTransaction(signedTransaction).send()
7584

7685
if (result.hasError()) {
7786
throw ExecuteTransactionException(result.error.message)

src/main/kotlin/io/openfuture/api/config/filter/PublicApiAuthorizationFilter.kt

+44-9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import io.openfuture.api.config.propety.AuthorizationProperties
66
import org.springframework.http.HttpStatus.UNAUTHORIZED
77
import io.openfuture.api.domain.exception.ExceptionResponse
88
import io.openfuture.api.domain.key.WalletApiCreateRequest
9+
import io.openfuture.api.domain.state.WalletApiStateRequest
910
import io.openfuture.api.service.ApplicationService
1011
import io.openfuture.api.util.*
1112
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
@@ -34,24 +35,43 @@ class PublicApiAuthorizationFilter(
3435

3536
val accessKey = request.getHeader("X-API-KEY")
3637
val signature = request.getHeader("X-API-SIGNATURE")
37-
val expirePeriod = properties.expireApi!!
3838

3939
val requestWrapper = CustomHttpRequestWrapper(request)
4040
val walletApiCreateRequest =
4141
mapper.readValue(requestWrapper.bodyInStringFormat, WalletApiCreateRequest::class.java)
42-
43-
val diffMinutes = differenceEpochs(currentEpochs(), walletApiCreateRequest.timestamp.toLong())
42+
val mapper = jacksonObjectMapper()
43+
val str = mapper.writeValueAsString(walletApiCreateRequest)
4444

4545
val application = applicationService.getByAccessKey(accessKey)
4646

47+
if (!checkHash(accessKey, signature, walletApiCreateRequest.timestamp.toLong(), str)) {
48+
val exceptionResponse = ExceptionResponse(UNAUTHORIZED.value(), "Signature mismatch or request timeout")
49+
response.status = exceptionResponse.status
50+
response.writer.write(mapper.writeValueAsString(exceptionResponse))
51+
return
52+
}
53+
54+
val token = UsernamePasswordAuthenticationToken(application.user, null, listOf(SimpleGrantedAuthority("ROLE_APPLICATION")))
55+
SecurityContextHolder.getContext().authentication = token
56+
57+
chain.doFilter(requestWrapper, response)
58+
return
59+
}
60+
61+
else if (request.requestURI.startsWith("/public") && request.getHeader("OPEN-API-KEY") != null) {
62+
63+
val accessKey = request.getHeader("OPEN-API-KEY")
64+
val signature = request.getHeader("OPEN-API-SIGNATURE")
65+
66+
val requestWrapper = CustomHttpRequestWrapper(request)
67+
val walletApiStateRequest =
68+
mapper.readValue(requestWrapper.bodyInStringFormat, WalletApiStateRequest::class.java)
4769
val mapper = jacksonObjectMapper()
48-
val str = mapper.writeValueAsString(walletApiCreateRequest)
70+
val str = mapper.writeValueAsString(walletApiStateRequest)
4971

50-
val hmacSha256 = application.let {
51-
KeyGeneratorUtils.calcHmacSha256(it.apiSecretKey, str)
52-
}
72+
val application = applicationService.getByAccessKey(accessKey)
5373

54-
if (hmacSha256 != signature || diffMinutes > expirePeriod) {
74+
if (!checkHash(accessKey, signature, walletApiStateRequest.timestamp.toLong(), str)) {
5575
val exceptionResponse = ExceptionResponse(UNAUTHORIZED.value(), "Signature mismatch or request timeout")
5676
response.status = exceptionResponse.status
5777
response.writer.write(mapper.writeValueAsString(exceptionResponse))
@@ -65,11 +85,26 @@ class PublicApiAuthorizationFilter(
6585
return
6686
}
6787

68-
6988
chain.doFilter(request, response)
7089
}
7190

7291
override fun destroy() {
7392
// Do nothing
7493
}
94+
95+
private fun checkHash(accessKey: String, signature: String, timestamp: Long, str: String): Boolean{
96+
val diffMinutes = differenceEpochs(currentEpochs(), timestamp)
97+
val expirePeriod = properties.expireApi!!
98+
99+
val application = applicationService.getByAccessKey(accessKey)
100+
101+
val hmacSha256 = application.let {
102+
KeyGeneratorUtils.calcHmacSha256(it.apiSecretKey, str)
103+
}
104+
105+
if (hmacSha256 != signature || diffMinutes > expirePeriod) {
106+
return false
107+
}
108+
return true
109+
}
75110
}

src/main/kotlin/io/openfuture/api/controller/api/PublicWalletApiController.kt

+26-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package io.openfuture.api.controller.api
22

33
import io.openfuture.api.domain.key.KeyWalletDto
44
import io.openfuture.api.domain.key.WalletApiCreateRequest
5+
import io.openfuture.api.domain.state.WalletApiStateRequest
6+
import io.openfuture.api.domain.state.WalletApiStateResponse
57
import io.openfuture.api.service.ApplicationService
68
import io.openfuture.api.service.WalletApiService
7-
import org.springframework.security.access.prepost.PreAuthorize
89
import org.springframework.web.bind.annotation.*
10+
import org.web3j.protocol.core.methods.response.TransactionReceipt
911

1012

1113
@RestController
@@ -16,14 +18,35 @@ class PublicWalletApiController(
1618
) {
1719

1820
//@PreAuthorize(value = "hasAnyRole('ROLE_APPLICATION')")
19-
@PostMapping("/generate")
21+
@PostMapping("/process")
2022
fun generateWallet(
2123
@RequestBody walletApiCreateRequest: WalletApiCreateRequest,
2224
@RequestHeader("X-API-KEY") accessKey: String
2325
): Array<KeyWalletDto> {
26+
val application = applicationService.getByAccessKey(accessKey)
27+
return service.processWalletSDK(walletApiCreateRequest, application, application.user)
28+
}
2429

30+
@PostMapping("/save")
31+
fun saveWallet(
32+
@RequestBody walletApiStateRequest: WalletApiStateRequest,
33+
@RequestHeader("OPEN-API-KEY") accessKey: String
34+
): Boolean {
2535
val application = applicationService.getByAccessKey(accessKey)
36+
return service.saveWalletSDK(walletApiStateRequest, application, application.user)
37+
}
38+
39+
@PostMapping("/fetch")
40+
fun getWallet(
41+
@RequestBody walletApiStateRequest: WalletApiStateRequest
42+
): WalletApiStateResponse {
43+
return service.getWallet(walletApiStateRequest.address, walletApiStateRequest.blockchain)
44+
}
2645

27-
return service.generateWallet(walletApiCreateRequest, application, application.user)
46+
@PostMapping("/broadcast")
47+
fun broadcastTransaction(
48+
@RequestBody walletApiStateRequest: WalletApiStateRequest
49+
): TransactionReceipt {
50+
return service.broadcastTransaction(walletApiStateRequest.address, walletApiStateRequest.blockchain)
2851
}
2952
}

src/main/kotlin/io/openfuture/api/domain/key/ImportKeyRequest.kt

+3-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ data class ImportKeyRequest(
66
val applicationId: String,
77
val userId: String,
88
val blockchainType: BlockchainType,
9-
val address: String
10-
){
11-
12-
}
9+
val address: String,
10+
val hex: String
11+
)

src/main/kotlin/io/openfuture/api/domain/key/KeyWalletDto.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ package io.openfuture.api.domain.key
22

33
data class KeyWalletDto(
44
val address: String,
5-
val blockchain: String
5+
val blockchain: String,
6+
val walletType: String
67
)

0 commit comments

Comments
 (0)