package com.binance.dex.api.client.ledger; import com.google.common.primitives.Bytes; import java.math.BigInteger; import java.util.Arrays; public class LedgerUtils { private static final int bipPurpose = 44; private static final int bipCoinType = 714; private static final int bipChange = 0; public static byte[] bipPathToBytes(int[] bip32Path, int hardenCount) { byte[] result = new byte[41]; if (!verifyBIP44Path(bip32Path)) { return null; } result[0] = (byte) bip32Path.length; for (int index = 0; index < bip32Path.length; index++) { int pos = 1 + index * 4; int value = bip32Path[index]; if (index < hardenCount) { value = 0x80000000 | bip32Path[index]; } for (int i = 0; i < 4; i++) { result[pos + i] = (byte) (value & 0xFF); value = value >> 8; } } return result; } public static byte[] compressedLedgerPubkey(byte[] pubkey) { if (pubkey.length != 65) { return null; } byte[] result = new byte[1]; BigInteger bigX = new BigInteger(Arrays.copyOfRange(pubkey, 1, 33)); BigInteger bigY = new BigInteger(Arrays.copyOfRange(pubkey, 33, 65)); result[0] = (byte) 0x2; if (bigY.toByteArray()[0] % 2 != 0) { result[0] = (byte) (result[0] | 0x1); } return Bytes.concat(result, bigX.toByteArray()); } public static int[] createBIP44Path(int account, int index) { if (account < 0 || index < 0) { return null; } return new int[]{bipPurpose, bipCoinType, account, bipChange, index}; } public static boolean verifyBIP44Path(int[] bip44Path) { if (bip44Path.length != 5) { return false; } if (bip44Path[0] != bipPurpose || bip44Path[1] != bipCoinType || bip44Path[3] != bipChange) { return false; } if (bip44Path[2] < 0 || bip44Path[4] < 0) { return false; } return true; } }