1 package com.syntifi.near.api.service;
2
3 import com.syntifi.crypto.key.hash.Sha256;
4 import com.syntifi.near.api.model.accesskey.AccessKey;
5 import com.syntifi.near.api.model.block.Block;
6 import com.syntifi.near.api.model.common.EncodedHash;
7 import com.syntifi.near.api.model.identifier.Finality;
8 import com.syntifi.near.api.model.key.AbstractKeyTest;
9 import com.syntifi.near.api.model.key.PrivateKey;
10 import com.syntifi.near.api.model.key.PublicKey;
11 import com.syntifi.near.api.model.key.Signature;
12 import com.syntifi.near.api.model.transaction.SignedTransaction;
13 import com.syntifi.near.api.model.transaction.SuccessValueStatus;
14 import com.syntifi.near.api.model.transaction.Transaction;
15 import com.syntifi.near.api.model.transaction.TransactionAwait;
16 import com.syntifi.near.api.model.transaction.TransferAction;
17 import com.syntifi.near.borshj.Borsh;
18 import org.junit.jupiter.api.Test;
19
20 import java.math.BigInteger;
21 import java.security.GeneralSecurityException;
22 import java.util.Arrays;
23 import java.util.Base64;
24
25 import static com.syntifi.near.api.service.NearServiceHelper.nearService;
26 import static org.junit.jupiter.api.Assertions.assertEquals;
27 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
28 import static org.junit.jupiter.api.Assertions.assertNotNull;
29 import static org.junit.jupiter.api.Assertions.assertTrue;
30
31 public class TransactionServiceTest extends AbstractKeyTest {
32
33 @Test
34 void serializeSignAndDeserializeVerifyTransaction_should_match() throws GeneralSecurityException {
35 String signerId = "syntifi-alice.testnet";
36 String receiverId = "syntifi-bob.testnet";
37 String amount = "100";
38 PublicKey publicKey = aliceNearPublicKey;
39
40 Block block = nearService.getBlock(Finality.FINAL);
41
42 AccessKey accessKey = nearService.viewAccessKey(Finality.FINAL, signerId, publicKey.toEncodedBase58String());
43
44 long nextNonce = accessKey.getNonce() + 1L;
45
46 Transaction transaction = Transaction
47 .builder()
48 .signerId(signerId)
49 .publicKey(publicKey)
50 .nonce(nextNonce)
51 .receiverId(receiverId)
52 .blockHash(block.getHeader().getHash().getDecodedHash())
53 .actions(Arrays.asList(
54 TransferAction.builder()
55 .deposit(new BigInteger(amount, 10))
56 .build()))
57 .build();
58
59 byte[] serializedTx = Borsh.serialize(transaction);
60 byte[] hashedTx = Sha256.digest(serializedTx);
61 byte[] signedTx = alicePrivateKey.sign(hashedTx);
62
63 SignedTransaction signedTransaction =
64 SignedTransaction.builder()
65 .transaction(transaction)
66 .signature(Signature.builder()
67 .keyType(publicKey.getType())
68 .data(signedTx).build())
69 .build();
70
71 byte[] borshTx = Borsh.serialize(signedTransaction);
72
73 String base64Tx = Base64.getEncoder().encodeToString(borshTx);
74
75 byte[] base64TxDec = Base64.getDecoder().decode(base64Tx);
76
77 SignedTransaction signedTransactionDec = Borsh.deserialize(base64TxDec, SignedTransaction.class);
78
79 assertEquals(signedTransaction, signedTransactionDec);
80
81 Transaction transactionDec = signedTransactionDec.getTransaction();
82
83 assertEquals(transaction, transactionDec);
84
85 assertTrue(publicKey.getPublicKey().verify(hashedTx, signedTransactionDec.getSignature().getData()));
86 }
87
88 @Test
89 void sent100toBobAwait_should_getStatus_SuccessValueStatus() throws GeneralSecurityException {
90 String signerId = "syntifi-alice.testnet";
91 String receiverId = "syntifi-bob.testnet";
92 BigInteger amount = new BigInteger("100", 10);
93 PrivateKey privateKey = aliceNearPrivateKey;
94 PublicKey publicKey = aliceNearPublicKey;
95
96 TransactionAwait transactionAwait = TransactionService
97 .sendTransferActionAwait(nearService, signerId, receiverId, publicKey, privateKey, amount);
98
99 assertInstanceOf(SuccessValueStatus.class, transactionAwait.getStatus());
100 }
101
102 @Test
103 void sent100toAliceAwait_should_getStatus_SuccessValueStatus() throws GeneralSecurityException {
104 String signerId = "syntifi-bob.testnet";
105 String receiverId = "syntifi-alice.testnet";
106 BigInteger amount = new BigInteger("100", 10);
107 PrivateKey privateKey = bobNearPrivateKey;
108 PublicKey publicKey = bobNearPublicKey;
109
110 TransactionAwait transactionAwait = TransactionService
111 .sendTransferActionAwait(nearService, signerId, receiverId, publicKey, privateKey, amount);
112
113 assertInstanceOf(SuccessValueStatus.class, transactionAwait.getStatus());
114 }
115
116 @Test
117 void sent100toBobAsync_should_getStatus_SuccessValueStatus() throws GeneralSecurityException {
118 String signerId = "syntifi-alice.testnet";
119 String receiverId = "syntifi-bob.testnet";
120 BigInteger amount = new BigInteger("100", 10);
121 PrivateKey privateKey = aliceNearPrivateKey;
122 PublicKey publicKey = aliceNearPublicKey;
123
124 EncodedHash transactionAsync = TransactionService
125 .sendTransferActionAsync(nearService, signerId, receiverId, publicKey, privateKey, amount);
126
127 assertNotNull(transactionAsync.getEncodedHash());
128 }
129
130 @Test
131 void sent100toAliceAsync_should_getStatus_SuccessValueStatus() throws GeneralSecurityException {
132 String signerId = "syntifi-bob.testnet";
133 String receiverId = "syntifi-alice.testnet";
134 BigInteger amount = new BigInteger("100", 10);
135 PrivateKey privateKey = bobNearPrivateKey;
136 PublicKey publicKey = bobNearPublicKey;
137
138 EncodedHash transactionAsync = TransactionService
139 .sendTransferActionAsync(nearService, signerId, receiverId, publicKey, privateKey, amount);
140
141 assertNotNull(transactionAsync.getEncodedHash());
142 }
143 }