TransactionService.java

  1. package com.syntifi.near.api.service;

  2. import com.syntifi.crypto.key.hash.Sha256;
  3. import com.syntifi.near.api.model.accesskey.AccessKey;
  4. import com.syntifi.near.api.model.block.Block;
  5. import com.syntifi.near.api.model.common.EncodedHash;
  6. import com.syntifi.near.api.model.identifier.Finality;
  7. import com.syntifi.near.api.model.key.PrivateKey;
  8. import com.syntifi.near.api.model.key.PublicKey;
  9. import com.syntifi.near.api.model.key.Signature;
  10. import com.syntifi.near.api.model.transaction.Action;
  11. import com.syntifi.near.api.model.transaction.SignedTransaction;
  12. import com.syntifi.near.api.model.transaction.Transaction;
  13. import com.syntifi.near.api.model.transaction.TransactionAwait;
  14. import com.syntifi.near.api.model.transaction.TransferAction;
  15. import com.syntifi.near.borshj.Borsh;

  16. import java.math.BigInteger;
  17. import java.security.GeneralSecurityException;
  18. import java.util.Arrays;
  19. import java.util.Base64;
  20. import java.util.List;

  21. /**
  22.  * Transaction service provides methods to easily work with transactions
  23.  *
  24.  * @author Alexandre Carvalho
  25.  * @author Andre Bertolace
  26.  * @since 0.0.1
  27.  */
  28. public class TransactionService {
  29.     /**
  30.      * Sends a {@link TransferAction} transaction waiting for result using  {@link NearService#sendTransactionAwait(String)}
  31.      *
  32.      * @param nearService      the near service instance to use
  33.      * @param signerId         the signer id
  34.      * @param receiverId       the receiver id
  35.      * @param signerPublicKey  signer public key
  36.      * @param signerPrivateKey signer private key
  37.      * @param amount           the amount to transfer
  38.      * @return {@link TransactionAwait} object with the result
  39.      * @throws GeneralSecurityException thrown if failed to sign the transaction
  40.      */
  41.     public static TransactionAwait sendTransferActionAwait(NearService nearService, String signerId, String receiverId,
  42.                                                            PublicKey signerPublicKey, PrivateKey signerPrivateKey,
  43.                                                            BigInteger amount)
  44.             throws GeneralSecurityException {
  45.         return sendTransactionAwait(nearService, signerId, receiverId, signerPublicKey, signerPrivateKey,
  46.                 Arrays.asList(
  47.                         TransferAction.builder()
  48.                                 .deposit(amount)
  49.                                 .build()));
  50.     }

  51.     /**
  52.      * Sends a {@link TransferAction} transaction async using {@link NearService#sendTransactionAsync(String)}
  53.      *
  54.      * @param nearService      the near service instance to use
  55.      * @param signerId         the signer id
  56.      * @param receiverId       the receiver id
  57.      * @param signerPublicKey  signer public key
  58.      * @param signerPrivateKey signer private key
  59.      * @param amount           the amount to transfer
  60.      * @return transaction Hash
  61.      * @throws GeneralSecurityException thrown if failed to sign the transaction
  62.      */
  63.     public static EncodedHash sendTransferActionAsync(NearService nearService, String signerId, String receiverId,
  64.                                                       PublicKey signerPublicKey, PrivateKey signerPrivateKey,
  65.                                                       BigInteger amount)
  66.             throws GeneralSecurityException {
  67.         return sendTransactionAsync(nearService, signerId, receiverId, signerPublicKey, signerPrivateKey,
  68.                 Arrays.asList(
  69.                         TransferAction.builder()
  70.                                 .deposit(amount)
  71.                                 .build()));
  72.     }

  73.     /**
  74.      * Sends a list of {@link Action} transaction waiting for result using {@link NearService#sendTransactionAwait(String)}
  75.      *
  76.      * @param nearService      the near service instance to use
  77.      * @param signerId         the signer id
  78.      * @param receiverId       the receiver id
  79.      * @param signerPublicKey  signer public key
  80.      * @param signerPrivateKey signer private key
  81.      * @param actionList       list of {@link Action} to send
  82.      * @return {@link TransactionAwait} object with the result
  83.      * @throws GeneralSecurityException thrown if failed to sign the transaction
  84.      */
  85.     public static TransactionAwait sendTransactionAwait(NearService nearService, String signerId, String receiverId,
  86.                                                         PublicKey signerPublicKey, PrivateKey signerPrivateKey,
  87.                                                         List<Action> actionList)
  88.             throws GeneralSecurityException {
  89.         return nearService.sendTransactionAwait(prepareTransactionForActionList(nearService, signerId, receiverId, signerPublicKey, signerPrivateKey, actionList));
  90.     }

  91.     /**
  92.      * Sends a list of {@link Action} transaction waiting for result using  {@link NearService#sendTransactionAsync(String)}
  93.      *
  94.      * @param nearService      the near service instance to use
  95.      * @param signerId         the signer id
  96.      * @param receiverId       the receiver id
  97.      * @param signerPublicKey  signer public key
  98.      * @param signerPrivateKey signer private key
  99.      * @param actionList       list of {@link Action} to send
  100.      * @return {@link TransactionAwait} object with the result
  101.      * @throws GeneralSecurityException thrown if failed to sign the transaction
  102.      */
  103.     public static EncodedHash sendTransactionAsync(NearService nearService, String signerId, String receiverId,
  104.                                                    PublicKey signerPublicKey, PrivateKey signerPrivateKey,
  105.                                                    List<Action> actionList)
  106.             throws GeneralSecurityException {
  107.         return EncodedHash.builder()
  108.                 .encodedHash(nearService.sendTransactionAsync(
  109.                         prepareTransactionForActionList(nearService, signerId, receiverId, signerPublicKey, signerPrivateKey, actionList)))
  110.                 .build();
  111.     }

  112.     /**
  113.      * Prepares the transaction to send
  114.      *
  115.      * @param nearService      the near service instance to use
  116.      * @param signerId         the signer id
  117.      * @param receiverId       the receiver id
  118.      * @param signerPublicKey  signer public key
  119.      * @param signerPrivateKey signer private key
  120.      * @param actionList       list of {@link Action} to send
  121.      * @return the base64 encoded signed transaction string
  122.      * @throws GeneralSecurityException thrown if failed to sign the transaction
  123.      */
  124.     private static String prepareTransactionForActionList(NearService nearService, String signerId, String receiverId,
  125.                                                           PublicKey signerPublicKey, PrivateKey signerPrivateKey,
  126.                                                           List<Action> actionList)
  127.             throws GeneralSecurityException {
  128.         Block block = nearService.getBlock(Finality.FINAL);

  129.         AccessKey accessKey = nearService.viewAccessKey(Finality.FINAL, signerId, signerPublicKey.toEncodedBase58String());

  130.         long nextNonce = accessKey.getNonce() + 1L;

  131.         Transaction transaction = Transaction
  132.                 .builder()
  133.                 .signerId(signerId)
  134.                 .publicKey(signerPublicKey)
  135.                 .nonce(nextNonce)
  136.                 .receiverId(receiverId)
  137.                 .blockHash(block.getHeader().getHash().getDecodedHash())
  138.                 .actions(actionList)
  139.                 .build();

  140.         byte[] serializedTx = Borsh.serialize(transaction);
  141.         byte[] hashedTx = Sha256.digest(serializedTx);
  142.         byte[] signedTx = signerPrivateKey.getPrivateKey().sign(hashedTx);

  143.         SignedTransaction signedTransaction =
  144.                 SignedTransaction.builder()
  145.                         .transaction(transaction)
  146.                         .signature(Signature.builder()
  147.                                 .keyType(signerPublicKey.getType())
  148.                                 .data(signedTx).build())
  149.                         .build();

  150.         byte[] borshTx = Borsh.serialize(signedTransaction);

  151.         return Base64.getEncoder().encodeToString(borshTx);
  152.     }
  153. }