Skip to content

Commit 49a045b

Browse files
committed
Add transactions api
1 parent 742786f commit 49a045b

File tree

8 files changed

+117
-8
lines changed

8 files changed

+117
-8
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22
buildscript {
3-
ext.kotlinVersion = '1.4.21'
3+
ext.kotlinVersion = '1.4.32'
44
ext.okhttpVersion = '4.9.0'
55
ext.gsonVersion = '2.8.6'
66
ext.jjwtVersion = 'd6feebe558'

library/src/main/kotlin/one/mixin/bot/api/call/AssetCallService.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ import one.mixin.bot.vo.Fiat
77
import one.mixin.bot.vo.PendingDeposit
88
import one.mixin.bot.vo.Ticker
99
import one.mixin.bot.vo.TopAsset
10+
import one.mixin.bot.vo.TransactionRequest
11+
import one.mixin.bot.vo.TransactionResponse
1012
import retrofit2.Call
13+
import retrofit2.http.Body
1114
import retrofit2.http.GET
15+
import retrofit2.http.POST
1216
import retrofit2.http.Path
1317
import retrofit2.http.Query
1418

@@ -44,4 +48,7 @@ interface AssetCallService {
4448

4549
@GET("assets/{id}/fee")
4650
fun assetsFeeCall(@Path("id") id: String): Call<MixinResponse<AssetFee>>
51+
52+
@POST("transactions")
53+
fun transactionsCall(@Body request: TransactionRequest): Call<MixinResponse<TransactionResponse>>
4754
}

library/src/main/kotlin/one/mixin/bot/api/coroutine/AssetCoroutineService.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ import one.mixin.bot.vo.Fiat
77
import one.mixin.bot.vo.PendingDeposit
88
import one.mixin.bot.vo.Ticker
99
import one.mixin.bot.vo.TopAsset
10+
import one.mixin.bot.vo.TransactionRequest
11+
import one.mixin.bot.vo.TransactionResponse
12+
import retrofit2.http.Body
1013
import retrofit2.http.GET
14+
import retrofit2.http.POST
1115
import retrofit2.http.Path
1216
import retrofit2.http.Query
1317

@@ -42,4 +46,7 @@ interface AssetCoroutineService {
4246

4347
@GET("assets/{id}/fee")
4448
suspend fun assetsFee(@Path("id") id: String): MixinResponse<AssetFee>
49+
50+
@POST("transactions")
51+
suspend fun transactions(@Body request: TransactionRequest): MixinResponse<TransactionResponse>
4552
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package one.mixin.bot.vo
2+
3+
import com.google.gson.annotations.SerializedName
4+
5+
data class TransactionRequest(
6+
@SerializedName("asset_id")
7+
val assetId: String,
8+
@SerializedName("opponent_multisig")
9+
val opponentMultisig: OpponentMultisig,
10+
val amount: String,
11+
val pin: String,
12+
@SerializedName("trace_id")
13+
val traceId: String?,
14+
val memo: String?
15+
)
16+
17+
data class OpponentMultisig(
18+
val receivers: List<String>,
19+
val threshold: Int
20+
)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package one.mixin.bot.vo
2+
3+
import com.google.gson.annotations.SerializedName
4+
5+
data class TransactionResponse(
6+
val type: String,
7+
@SerializedName("snapshot_id")
8+
val snapshotId: String,
9+
@SerializedName("opponent_receivers")
10+
val opponentReceivers: List<String>,
11+
@SerializedName("opponent_threshold")
12+
val opponentThreshold: Int,
13+
@SerializedName("asset_id")
14+
val assetId: String,
15+
val amount: String,
16+
@SerializedName("trace_id")
17+
val traceId: String,
18+
val memo: String?,
19+
@SerializedName("created_at")
20+
val createdAt: String
21+
)

samples/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ java {
99
}
1010

1111
dependencies {
12-
implementation project(':library')
13-
// implementation 'com.github.MixinNetwork:bot-api-kotlin-client:main-SNAPSHOT'
12+
implementation project(':library')
13+
// implementation 'com.github.MixinNetwork:bot-api-kotlin-client:main-SNAPSHOT'
1414

1515
// Kotlin
1616
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"

samples/src/main/java/jvmMain/java/Sample.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public static void main(String[] args) {
4242
// decrypt pin token
4343
String userAesKey;
4444
EdDSAPrivateKey userPrivateKey = (EdDSAPrivateKey) sessionKey.getPrivate();
45-
userAesKey = base64Encode(calculateAgreement(base64Decode(user.getPinToken()), userPrivateKey));
45+
userAesKey = base64Encode(calculateAgreement(Objects.requireNonNull(base64Decode(user.getPinToken())), userPrivateKey));
4646

4747
// get fiats
4848
getFiats(client);
@@ -76,6 +76,12 @@ public static void main(String[] args) {
7676
client.setUserToken(null);
7777
// Send text message
7878
sendTextMessage(client, "639ec50a-d4f1-4135-8624-3c71189dcdcc", "Test message");
79+
80+
List<String> receivers = new ArrayList<>();
81+
receivers.add("00c5a4ae-dcdc-48db-ab8e-a7eef69b441d");
82+
receivers.add("087e91ff-7169-451a-aaaa-5b3297411a4b");
83+
receivers.add("105f6e8b-d249-4b4d-9beb-e03cefaebc37");
84+
transactions(client, receivers, pinToken, pin);
7985
} catch (InterruptedException | IOException e) {
8086
System.out.println(e.getMessage());
8187
}
@@ -192,7 +198,7 @@ private static void getFiats(HttpClient client) throws IOException {
192198
MixinResponse<List<Fiat>> fiatsResponse = client.getAssetService().getFiatsCall().execute().body();
193199
assert fiatsResponse != null;
194200
if (fiatsResponse.isSuccess()) {
195-
System.out.printf("Fiats success: %f%n", fiatsResponse.getData().get(0).getRate());
201+
System.out.printf("Fiats success: %f%n", Objects.requireNonNull(fiatsResponse.getData()).get(0).getRate());
196202
} else {
197203
System.out.println("Fiats fail");
198204
}
@@ -216,6 +222,7 @@ private static void sendTextMessage(HttpClient client, String recipientId, Strin
216222
Base64.getEncoder().encodeToString(text.getBytes()), null, null
217223
));
218224
MixinResponse messageResponse = client.getMessageService().postMessageCall(messageRequests).execute().body();
225+
assert messageResponse != null;
219226
if (messageResponse.isSuccess()) {
220227
System.out.println("Send success");
221228
} else {
@@ -232,4 +239,19 @@ private static SessionToken getUserToken(User user, KeyPair sessionKey, boolean
232239
}
233240
}
234241

242+
243+
private static void transactions(HttpClient client, List<String> receivers, String aseKey, String pin) throws IOException {
244+
MixinResponse<TransactionResponse> transactionResponse = client.getAssetService().transactionsCall(
245+
new TransactionRequest(Sample.CNB_assetId, new OpponentMultisig(
246+
receivers,
247+
2
248+
), Sample.amount, encryptPin(aseKey, pin, System.nanoTime())
249+
, null, null)).execute().body();
250+
assert transactionResponse != null;
251+
if (transactionResponse.isSuccess()) {
252+
System.out.printf("TransactionsResponse success: %s%n", Objects.requireNonNull(transactionResponse.getData()).getSnapshotId());
253+
} else {
254+
System.out.printf("Transactions fail: %s", Objects.requireNonNull(transactionResponse.getError()).getDescription());
255+
}
256+
}
235257
}

samples/src/main/java/jvmMain/kotlin/Sample.kt

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ import one.mixin.bot.util.generateEd25519KeyPair
1616
import one.mixin.bot.util.getEdDSAPrivateKeyFromString
1717
import one.mixin.bot.vo.AccountRequest
1818
import one.mixin.bot.vo.AddressRequest
19+
import one.mixin.bot.vo.OpponentMultisig
1920
import one.mixin.bot.vo.PinRequest
21+
import one.mixin.bot.vo.TransactionRequest
2022
import one.mixin.bot.vo.TransferRequest
2123
import one.mixin.bot.vo.User
2224
import one.mixin.bot.vo.WithdrawalRequest
@@ -27,7 +29,7 @@ import java.util.UUID
2729
const val CNB_ID = "965e5c6e-434c-3fa9-b780-c50f43cd955c"
2830
const val BTC_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa"
2931
const val DEFAULT_PIN = "131416"
30-
const val DEFAULT_AMOUNT = "2"
32+
const val DEFAULT_AMOUNT = "1"
3133

3234
fun main() = runBlocking {
3335
val key = getEdDSAPrivateKeyFromString(Config.privateKey)
@@ -92,6 +94,10 @@ fun main() = runBlocking {
9294
client.setUserToken(null)
9395
// Send text message
9496
sendTextMessage(client, "639ec50a-d4f1-4135-8624-3c71189dcdcc", "Text message")
97+
98+
// Transactions
99+
transactions(client, pinToken)
100+
95101
return@runBlocking
96102
}
97103

@@ -228,9 +234,35 @@ private suspend fun sendTextMessage(client: HttpClient, recipientId: String, tex
228234
)
229235
)
230236
)
231-
if(response.isSuccess()){
237+
if (response.isSuccess()) {
232238
println("Send success")
233-
}else{
239+
} else {
234240
println("Send fail")
235241
}
242+
}
243+
244+
private suspend fun transactions(
245+
client: HttpClient,
246+
userAesKey: String,
247+
) {
248+
// Transactions
249+
val transactionsResponse = client.assetService.transactions(
250+
TransactionRequest(
251+
CNB_ID,
252+
OpponentMultisig(listOf("00c5a4ae-dcdc-48db-ab8e-a7eef69b441d", "087e91ff-7169-451a-aaaa-5b3297411a4b", "4e0e6e6b-6c9d-4e99-b7f1-1356322abec3"), 2),
253+
DEFAULT_AMOUNT,
254+
encryptPin(
255+
userAesKey,
256+
DEFAULT_PIN,
257+
System.nanoTime()
258+
),
259+
UUID.randomUUID().toString(),
260+
"memo"
261+
)
262+
)
263+
if (transactionsResponse.isSuccess()) {
264+
println("Transactions success: ${transactionsResponse.data?.snapshotId}")
265+
} else {
266+
println("Transactions fail")
267+
}
236268
}

0 commit comments

Comments
 (0)