List HCX in your Exchange

HCX Send/Receive tutorial

To list HCX to your exchange you need to build two HCNet services as mentioned below and all the code snippets are given in the appendix section.Most importantly you have to add hashcash-sdk.jar with your project and you can download it from the below link. This jar is required to build HCX related code in your project.

https://github.com/HashCash-Consultants/java-hashcash-sdk/releases

1.HCNet Services

a.getBalance:- For balance check. (Please Review Appendix (a)).

b.sendHCX:- For HCX send. (Please Review Appendix (b))

2.Pool Account Management

Before jumping into implementation we shall know what is a pool account and why it is needed?

Pool account is an account which holds all HCX balances of your customers. When somebody wants to transfer HCX from his address to another, the pool account is going to send on behalf of that customer. When sending HCX to somebody you should ask about MemoId which we have seen in our sendHCX service API. Similarly when your pool account receives HCX from others you have to give your Memoid. Because every customer has the same pool account we can differentiate the customers using MemoId. Now how do we create a poll account and all let's discuss below.

You need to create a HCX Pool Account for your exchange. You can do this by using the HCX accountviewer link as given below.

https://www.hashcashconsultants.com/developers-sign-in

In that portal you need to generate HCX key by hitting the Generate button, after that you will get HCX Private Key which starts with S….. and HCX Public Key which starts with G… Then you can sign in that portal by your private key. Till now your address has not been activated. To activate this please go through the paragraph below.

Only you would hold the private key of this Pool Account. You can fund this Pool Account by either buying HCX from another exchange or requesting us to send HCX to your Pool Account. You can buy HCX by registering an account on PayBito exchange hosted at https://trade.paybito.com. If you have bought HCX at PayBito or another exchange, you will need to transfer the HCX from that exchange's account to your Pool Account address. You can create any number of accounts by using HCX accountviewer and transfer funds between them using sendHCX service (you only need one Pool Account for integrating HCX to your exchange).

Note:- Please do remember to activate the HCX address 20 HCX is required. After that you have to deposit more HCX to send/receive as per your requirement.

3.HCX Notifier

HCXNotifier notifies you when a payment is being received by your exchange pool HCX address. Mainly its job is to listen to all deposit transactions. After receiving funds by your pool account you need to identify for which customer it has received. So you can easily identify it by MemoId which needs to be sent during sendHCX API call. So in this case MemoId represents to customerid or any reference to identify your customer. After identifying Memo id you need to update customer balance. Regarding this you may have a customer table and hopefully payment_history table. In this demo we will record all receiving transactions into a table called customer_HCX_tables and this table contains address,amount,memo,transactionhash columns and when row is inserted into this table one trigger will fire to update customer balance and payment_history table. (Please review appendix C)

Appendix

HCNet Services

You can use the below code to build up HCNet services. To get hashcash-sdk.jar, use the link below and add this jar to your project.

(a) getBalance(Below code snippet shows how to check balance of a HCX address)

  • KeyPair source = KeyPair.fromAccountId(“GAAYN……………..R); // Here one dummy address is given (You have to put your HCX address, usually exchange put pool account)
  • String mybalance = null;
  • String url =”https://bitpaymentz.com” //Aurora of HCX
  • try {
  • Server server = new Server(url);
  • AccountResponse accountResponse = server.accounts().account(source);
  • if (accountResponse == null) {
  • System.out.println("Not Found");
  • } else {
  • for (AccountResponse.Balance balance : accountResponse.getBalances()) {
  • if (balance.getAssetType().equalsIgnoreCase("native")) {
  • if (balance.getAssetType().equalsIgnoreCase("native")) {
  • break;
  • }
  • }
  • }
  • } catch (org.hashcash.sdk.requests.ErrorResponse e) {
  • System.out.println(e.getMessage());
  • } catch (IOException e) {
  • e.printStackTrace();
  • }
You can take a reference of below JSON to build up a getBalance api(REST API) .

yourserver:port/getBalance

  • Request Param:-
  • {
  • "pubkey":"GAAYNMBGSXBYYTDVM4TYDWN26E2N5BZ4BWBM4BCSNRC3KFDANPC6DCQR"
  • }
  • Response:-
  • {
  • "balance": "31.9999900", //balance may change in your case
  • "message": "Balance Found",
  • "statuscode": "1"
  • }
(b) sendHCX (Below code snippet shows how to send HCX from one address to other)
  • Network network = new Network(“HCX MainNet”); //HCX Mainnet is the Network passphrase
  • Network.use(network);
  • Server server = new Server(“https://bitpaymentz.com”);
  • KeyPair source = KeyPair.fromSecretSeed(“Sender_HCX_PrivateKey”);//Here you need to put sender private key
  • KeyPair destination = KeyPair.fromAccountId(“Receiver_HCX_Pub_key”);//Here you need to put receiver HCX public key
  • AccountResponse sourceAccount;
  • Memo memo=Memo.text(“Exchange_customer_id”)//Here you need to put receiver customer id who is going to receive HCX
  • try {
  • sourceAccount = server.accounts().account(source);
  • transaction = new Transaction.Builder(sourceAccount).addOperation(
  • new PaymentOperation.Builder(destination, new AssetTypeNative(), “SENDING-AMOUNT”).build()) //put how much HCX you want to transfer
  • .addMemo(memo).setTimeout(5000).build();
  • transaction.sign(source);
  • SubmitTransactionResponse response = server.submitTransaction(transaction);
  • if (response.isSuccess()) {
  • logger.info("Hash of transaction: " + response.getHash()); //if transaction Successful then you will get transaction hash
  • }
  • else
  • {
  • //This code execute only when receiving address is not activate and sending amount is >=20, if your address is not activate an sending amount is <=20 then will get address validation error
  • ArrayList list = response.getExtras().getResultCodes().getOperationsResultCodes();
  • String message = list.get(0);
  • if (message.equals("op_no_destination")) {
  • if (Double.parseDouble(request.getAmount()) >= 20) {
  • Network network = new Network(“HCX MainNet”);
  • Network.use(network);
  • server = new Server(“https://bitpaymentz.com”);
  • source = KeyPair.fromSecretSeed(“Sender_HCX_PrivateKey”);
  • destination = KeyPair.fromAccountId(“RECEIVER_HCX_ADDRESS”);
  • try {
  • sourceAccount = server.accounts().account(source);
  • CreateAccountOperation op = new CreateAccountOperation.Builder(destination, request.getAmount()).build();
  • transaction = new Transaction.Builder(sourceAccount).addOperation(op) Memo memo=Memo.text(“RECEIVER_CUSTOMER_ID”);
  • .addMemo(“memo”).setTimeout(5000).build();
  • transaction.sign(source);
  • System.out.println("seq no: " + transaction.getSequenceNumber());
  • response = server.submitTransaction(transaction);
  • if (response.isSuccess()) {
  • } else {
  • //This is error for Account Creation if any
  • logger.info("response is: "+ response.getExtras().getResultCodes().getTransactionResultCode());
  • logger.info("response is: “+response.getExtras().getResultCodes().getOperationsResultCodes());
  • }
  • } catch (IOException e1) {
  • e1.printStackTrace()
  • }
  • } else {
  • System.out.println(“Please activate your account by sending 20 or more than 20 HCX”);
  • }
  • else
  • {
  • //This is error for send transaction if any
  • logger.info("response is: "+ response.getExtras().getResultCodes().getTransactionResultCode());
  • logger.info("response is: “+response.getExtras().getResultCodes().getOperationsResultCodes());
  • }
  • }
  • }

Note:- Above code does the send transaction and if the receiving HCX address is not being activated then you might get an error if your sending amount is less than 20. To activate the address send at least 20 HCX to the receiving address. After that send transaction can happen as usual. You may ignore the memo when your pool account is going to receive the payment for the first time. After that when send/receive will originate from that pool account then you have to specify a memo(as customer reference).

You can take a reference from below JSON request and response, how to create sendHCX api.

You can take a reference from below JSON request and response, how to create sendHCX api.

yourserver:port/sendHcx

  • Request Param:-
  • {
  • "hcxprivkey":"SD……….Y", ---->This is the sender privkey, usually exchange put their poll address
  • "hcxpubkey":"G………...S", ------>This is the receiving address
  • "Amount":"20" -------->This is the sending HCX amount.
  • }
  • And response you may use below reference.
  • {
  • "message": "HCX Sent Successfully",
  • "statuscode": "1",
  • "hash": "8f721c9c63b94c676cbb38077b724ff4fed45c77a109600328c679e086f11ad9"
  • }
C. HCX Notifier:--

This project is having three .java classes as below and all are the code snippets only.

TokenDao.Java:-

It is basically DB layer and inserts data into table.( let's say customer_HCX_details table which we have discussed earlier)

  • public class TokenDao {
  • public static boolean insertToken(String address, String amount, String memo, String hash) {
  • boolean flag = false;
  • Connection con = null;
  • PreparedStatement preparedStatement = null;
  • try {
  • TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
  • Class.forName("oracle.jdbc.driver.OracleDriver");
  • con = DriverManager.getConnection(conurl, username, password);
  • preparedStatement = con.prepareStatement("insert into " + tablename + "(ADDRESS,AMOUNT,MEMO,TXNHASH)values(?,?,?,?)"); //Here table name represents your hcx_received_table
  • preparedStatement.setString(1, address);
  • preparedStatement.setString(2, amount);
  • preparedStatement.setString(3, memo);
  • preparedStatement.setString(4, hash);
  • int count = preparedStatement.executeUpdate();
  • if (count > 0) {
  • System.out.println("Row Inserted Successfully.." + count);
  • flag = true;
  • } else {
  • flag = false;
  • }
  • } catch (Exception e) {
  • flag = false;
  • e.printStackTrace();
  • } finally {
  • try {
  • preparedStatement.close();
  • con.close();
  • } catch (SQLException e) {
  • // TODO Auto-generated catch block
  • e.printStackTrace();
  • }
  • }
  • return flag;
  • }
  • }
Myoken.java

This class stores the address cursor into a file. Because if your app server has some problem and unfortunately in that period your pool address received some HCXs. So we need to start notification from the last cursor only.

  • public class MyToken {
  • static {
  • try {
  • String url = “https://bitpaymentz.com"
  • String poolaccount =”Your_Pool_Account”
  • Server server = new Server(url);
  • String fpath =”Your_cursor_file_location”;//first create one file called pagingtoken.txt and save it without any text and you can keep the file in your server where you will deploy HCX services and HCX Notification
  • BufferedReader bufferedReader = new BufferedReader(new FileReader(fpath))
  • String token = bufferedReader.readLine();
  • bufferedReader.close();
  • if (token == null) {
  • String myurl = url + "/accounts/" + poolaccount + "/payments?order=desc";
  • System.out.println(myurl);
  • URL url = new URL(myurl);
  • HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  • connection.connect();
  • InputStream inputStream = connection.getInputStream();
  • InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
  • BufferedReader bufferedReader1 = new BufferedReader(inputStreamReader);
  • String line = "";
  • StringBuffer buffer = new StringBuffer();
  • while ((line = bufferedReader1.readLine()) != null) {
  • buffer.append(line);
  • }
  • // System.out.println(buffer.toString());
  • System.out.println(" ");
  • String finalJSON = buffer.toString();
  • JSONObject jsonObject = new JSONObject(finalJSON);
  • JSONObject jsonObject1 = jsonObject.getJSONObject("_links");
  • JSONObject jsonObject2 = jsonObject1.getJSONObject("prev");
  • String next = jsonObject2.getString("href");
  • System.out.println();
  • System.out.println(next);
  • StringTokenizer stringTokenizer = new StringTokenizer(next, "= \u0026");
  • String[] tokens = new String[6];
  • while (stringTokenizer.hasMoreTokens()) {
  • for (int i = 0; i < tokens.length; i++) {
  • tokens[i] = stringTokenizer.nextToken();
  • }
  • }
  • String tokenid = tokens[1]; //Here we have got the cursor
  • System.out.println("Your Operation Id = " + tokenid);
  • FileWriter fileWriter;
  • try {
  • // URL fileurl=getClass().getResource("pagingtoken.txt");
  • // file=new File(fileurl.getFile());
  • fileWriter = new FileWriter(fpath);
  • BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
  • bufferedWriter.write(tokenid); //stores the cursor into a file
  • bufferedWriter.flush();
  • bufferedWriter.close();
  • fileWriter.close();
  • } catch (IOException e) {
  • // TODO Auto-generated catch block
  • e.printStackTrace();
  • } else {
  • System.out.println("Token already exists");
  • }
  • } catch (Exception e) {
  • }
  • }
  • }
Notification.java

This class is the main class which notifies when to receive a payment and identify the customer by MemoId and insert the record into hcx_received_table ( any name you can give) table and update the pagingtoken.txt file by latest cursor.

  • public class Notification {
  • try {
  • String url = “https://bitpaymentz.com"
  • String poolaccount =”Your Pool account”;
  • Server server = new Server(url);
  • String fpath = prop.getProperty("filepath");
  • MyToken myToken = new MyToken();
  • myToken.getToken();
  • BufferedReader bufferedReader = new BufferedReader(new FileReader(fpath));//Here first get cursor from the file
  • cursor = bufferedReader.readLine();
  • KeyPair pair = KeyPair.fromAccountId(poolaccount); //Your exchange pool account
  • server.payments().cursor(cursor).forAccount(pair).stream(new EventListener<OperationResponse>() {
  • @Override
  • public void onEvent(OperationResponse payment) {
  • if (payment instanceof PaymentOperationResponse) {
  • String c = null
  • System.out.println("Paging Token”+payment.getPagingToken());
  • try {
  • BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(fpath));
  • bufferedWriter.write(payment.getPagingToken());//Update the pagingtoken.txt by the latest cursor
  • bufferedWriter.flush();
  • bufferedWriter.close();
  • BufferedReader bufferedReader = new BufferedReader(new FileReader(fpath));
  • cursor = bufferedReader.readLine();
  • org.stellar.sdk.KeyPair senderkeypair = ((PaymentOperationResponse) payment).getFrom();
  • String sender = senderkeypair.getAccountId();
  • if (sender.equals(poolaccount)) {
  • //This checks is for when pool account sends out HCX
  • System.out.println("Now Poolaccount is sending");
  • }
  • else {
  • // When pool account received HCX and extracting all relevant details
  • org.stellar.sdk.KeyPair from = ((PaymentOperationResponse) payment).getFrom();
  • org.stellar.sdk.KeyPair to = ((PaymentOperationResponse) payment).getTo();
  • System.out.println("Sender.." + from.getAccountId()); //Identifying sender
  • String receiver = to.getAccountId(); //identifying receiver
  • System.out.println("Receiver.." + receiver);
  • System.out.println(payment.getCreatedAt()); // receiving Time
  • String amount = ((PaymentOperationResponse) payment).getAmount(); //Identifying how much HCX is received
  • String hash = payment.getTransactionHash(); //identifying transactional hash of this particular payment
  • System.out.println("Amount:" + amount + "hash " + hash);
  • String hashurl = url + "/transactions/" + hash;
  • URL url = new URL(hashurl);
  • HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  • conn.setRequestMethod("GET");
  • if (conn.getResponseCode() != 200) {
  • throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
  • }
  • BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
  • String output = null;
  • StringBuffer buffer = new StringBuffer();
  • System.out.println("Output from Server .... \n");
  • while ((output = br.readLine()) != null) {
  • System.out.println(output);
  • buffer.append(output);
  • }
  • conn.disconnect();
  • System.out.println("Buffer" + buffer);
  • JSONObject jsonObject = new JSONObject(buffer.toString());
  • String memo = jsonObject.getString("memo"); //Identifying memo,customerid or customer reference
  • System.out.println("Memo.." + memo);
  • boolean flag = TokenDao.insertToken(receiver, amount, memo, hash);
  • if (flag == true) {
  • System.out.println("Record Inserted");
  • } else {
  • System.out.println("Error");
  • }
  • }} catch (Exception e) {
  • // TODO Auto-generated catch block
  • e.printStackTrace();
  • }
  • }
  • }
  • });
  • } catch (Exception e) {
  • // TODO Auto-generated catch block
  • e.printStackTrace();}
  • }
  • }

Note: In our above HCX Notifier code , we can say your exchange pool account receives HCX then identifies sender address,receiver address,transactional hash,timestamp,deposit amount,memo id. After that it will insert the respective details into a table and you can create a trigger or if you have some better option to update the customer balance or your payment history table if any.

+
Chat Now
Welcome to HashCash Support