avax wallet setup

This commit is contained in:
void-57 2025-10-24 14:17:23 +05:30
commit f81fa7220e
5 changed files with 14784 additions and 0 deletions

209
avaxBlockchainAPI.js Normal file
View File

@ -0,0 +1,209 @@
const RPC_URL =
"https://go.getblock.io/2e411fe60c824a94951fddbe9e7922ea/ext/bc/C/rpc";
function weiToAvax(weiAmount) {
try {
if (!weiAmount || weiAmount === "0" || weiAmount === 0) {
return "0.000000";
}
const weiString = weiAmount.toString();
let wei;
if (weiString.startsWith("0x")) {
// Hexadecimal input
wei = BigInteger(weiString.substring(2), 16);
} else {
// Decimal input
wei = BigInteger(weiString, 10);
}
const avaxDecimals = Math.pow(10, 18);
const result = (parseFloat(wei.toString()) / avaxDecimals).toFixed(6);
console.log("Wei conversion:", weiAmount, "->", result, "AVAX");
return result;
} catch (error) {
console.error("Error converting Wei to AVAX:", error, "Input:", weiAmount);
return "0.000000";
}
}
// Fetch balance via RPC
async function getBalanceRPC(address) {
try {
const body = {
jsonrpc: "2.0",
id: 1,
method: "eth_getBalance",
params: [address, "latest"],
};
const resp = await fetch(RPC_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
const j = await resp.json();
if (j.error) {
throw new Error(j.error.message);
}
return {
avax: weiToAvax(j.result),
};
} catch (error) {
console.error("Error fetching balance:", error);
throw error;
}
}
// Get transaction count (nonce)
async function getTransactionCount(address) {
try {
const body = {
jsonrpc: "2.0",
id: 1,
method: "eth_getTransactionCount",
params: [address, "latest"],
};
const resp = await fetch(RPC_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
const j = await resp.json();
if (j.error) {
throw new Error(j.error.message);
}
return parseInt(j.result, 16);
} catch (error) {
console.error("Error fetching nonce:", error);
throw error;
}
}
// Get current gas price
async function getGasPrice() {
try {
const body = {
jsonrpc: "2.0",
id: 1,
method: "eth_gasPrice",
params: [],
};
const resp = await fetch(RPC_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
const j = await resp.json();
if (j.error) {
throw new Error(j.error.message);
}
return j.result;
} catch (error) {
console.error("Error fetching gas price:", error);
throw error;
}
}
// Prepare transaction data for Avalanche C-Chain
async function prepareAvalancheTransaction(
privateKey,
recipientAddress,
amountInAvax
) {
try {
// Validate inputs
if (!privateKey || !recipientAddress || !amountInAvax) {
throw new Error(
"Missing required parameters: privateKey, recipientAddress, or amount"
);
}
if (!recipientAddress.startsWith("0x") || recipientAddress.length !== 42) {
throw new Error("Invalid recipient address format");
}
if (parseFloat(amountInAvax) <= 0) {
throw new Error("Amount must be greater than 0");
}
const wallet = await avaxCrypto.generateMultiChain(privateKey);
privateKey = wallet.AVAX.privateKey;
console.log(privateKey);
if (privateKey.length !== 64 || !/^[0-9a-fA-F]+$/.test(privateKey)) {
throw new Error(
"Invalid private key format. Must be 64 hexadecimal characters."
);
}
// Get AVAX sender address from private key (works with FLO/BTC/AVAX private keys)
const senderAddress = wallet.AVAX.address;
// Check sender balance
const balance = await getBalanceRPC(senderAddress);
if (parseFloat(balance.avax) < parseFloat(amountInAvax)) {
throw new Error(
`Insufficient balance. You have ${balance.avax} AVAX but trying to send ${amountInAvax} AVAX`
);
}
// Get transaction count (nonce)
const nonce = await getTransactionCount(senderAddress);
// Get current gas price
const gasPrice = await getGasPrice();
// Return prepared transaction data
return {
senderAddress: senderAddress,
recipientAddress: recipientAddress,
amount: amountInAvax,
nonce: nonce,
gasPrice: gasPrice,
gasLimit: 21000,
chainId: 43114,
balance: balance.avax,
cleanPrivateKey: privateKey,
rpcUrl: RPC_URL,
};
} catch (error) {
console.error("Transaction preparation error:", error);
throw new Error(`Transaction preparation failed: ${error.message}`);
}
}
// Fetch transaction history with pagination support
async function fetchAvalancheTxHistory(address, page = 1, pageSize = 10) {
try {
const url = `https://api.routescan.io/v2/network/mainnet/evm/43114/etherscan/api?module=account&action=txlist&address=${address}&startblock=0&endblock=99999999&page=${page}&offset=${pageSize}&sort=desc`;
const resp = await fetch(url);
const data = await resp.json();
if (data.status !== "1") {
if (data.message === "No transactions found") {
return { transactions: [], hasMore: false };
}
throw new Error(data.message || "Failed to fetch transaction history");
}
const transactions = data.result || [];
const hasMore = transactions.length === pageSize;
return {
transactions: transactions,
hasMore: hasMore,
};
} catch (error) {
console.error("Error fetching transaction history:", error);
throw error;
}
}

162
avaxCrypto.js Normal file
View File

@ -0,0 +1,162 @@
(function (EXPORTS) {
"use strict";
const avaxCrypto = EXPORTS;
// Generate a new random key
function generateNewID() {
var key = new Bitcoin.ECKey(false);
key.setCompressed(true);
return {
floID: key.getBitcoinAddress(),
pubKey: key.getPubKeyHex(),
privKey: key.getBitcoinWalletImportFormat(),
};
}
Object.defineProperties(avaxCrypto, {
newID: {
get: () => generateNewID(),
},
hashID: {
value: (str) => {
let bytes = ripemd160(Crypto.SHA256(str, { asBytes: true }), {
asBytes: true,
});
bytes.unshift(bitjs.pub);
var hash = Crypto.SHA256(
Crypto.SHA256(bytes, {
asBytes: true,
}),
{
asBytes: true,
}
);
var checksum = hash.slice(0, 4);
return bitjs.Base58.encode(bytes.concat(checksum));
},
},
tmpID: {
get: () => {
let bytes = Crypto.util.randomBytes(20);
bytes.unshift(bitjs.pub);
var hash = Crypto.SHA256(
Crypto.SHA256(bytes, {
asBytes: true,
}),
{
asBytes: true,
}
);
var checksum = hash.slice(0, 4);
return bitjs.Base58.encode(bytes.concat(checksum));
},
},
});
// --- Multi-chain Generator (BTC, FLO, AVAX) ---
avaxCrypto.generateMultiChain = async function (inputWif) {
const versions = {
BTC: { pub: 0x00, priv: 0x80 },
FLO: { pub: 0x23, priv: 0xa3 },
};
const origBitjsPub = bitjs.pub;
const origBitjsPriv = bitjs.priv;
const origBitjsCompressed = bitjs.compressed;
const origCoinJsCompressed = coinjs.compressed;
bitjs.compressed = true;
coinjs.compressed = true;
let privKeyHex;
let compressed = true;
// --- Decode input or generate new ---
if (typeof inputWif === "string" && inputWif.trim().length > 0) {
const hexOnly = /^[0-9a-fA-F]+$/.test(inputWif.trim());
if (hexOnly && (inputWif.length === 64 || inputWif.length === 128)) {
privKeyHex =
inputWif.length === 128 ? inputWif.substring(0, 64) : inputWif;
} else {
try {
const decode = Bitcoin.Base58.decode(inputWif);
const keyWithVersion = decode.slice(0, decode.length - 4);
let key = keyWithVersion.slice(1);
if (key.length >= 33 && key[key.length - 1] === 0x01) {
key = key.slice(0, key.length - 1);
compressed = true;
}
privKeyHex = Crypto.util.bytesToHex(key);
} catch (e) {
console.warn("Invalid WIF, generating new key:", e);
const newKey = generateNewID();
const decode = Bitcoin.Base58.decode(newKey.privKey);
const keyWithVersion = decode.slice(0, decode.length - 4);
let key = keyWithVersion.slice(1);
if (key.length >= 33 && key[key.length - 1] === 0x01)
key = key.slice(0, key.length - 1);
privKeyHex = Crypto.util.bytesToHex(key);
}
}
} else {
const newKey = generateNewID();
const decode = Bitcoin.Base58.decode(newKey.privKey);
const keyWithVersion = decode.slice(0, decode.length - 4);
let key = keyWithVersion.slice(1);
if (key.length >= 33 && key[key.length - 1] === 0x01)
key = key.slice(0, key.length - 1);
privKeyHex = Crypto.util.bytesToHex(key);
}
// --- Derive addresses for each chain ---
const result = { BTC: {}, FLO: {}, AVAX: {} };
// BTC
bitjs.pub = versions.BTC.pub;
bitjs.priv = versions.BTC.priv;
const pubKeyBTC = bitjs.newPubkey(privKeyHex);
result.BTC.address = coinjs.bech32Address(pubKeyBTC).address;
result.BTC.privateKey = bitjs.privkey2wif(privKeyHex);
// FLO
bitjs.pub = versions.FLO.pub;
bitjs.priv = versions.FLO.priv;
const pubKeyFLO = bitjs.newPubkey(privKeyHex);
result.FLO.address = bitjs.pubkey2address(pubKeyFLO);
result.FLO.privateKey = bitjs.privkey2wif(privKeyHex);
// AVAX
try {
const ecKey = new Bitcoin.ECKey(privKeyHex);
// Get the uncompressed public key (should start with 04 and be 65 bytes total)
const pubKeyFull = ecKey.getPubKeyHex();
// Already uncompressed, remove 04 prefix
let pubKeyUncompressed = pubKeyFull.substring(2);
// Convert to bytes
const pubKeyBytes = Crypto.util.hexToBytes(pubKeyUncompressed);
// Use Keccak-256 hash of the uncompressed public key
const hash = keccak_256.array(pubKeyBytes);
// Take the last 20 bytes for the address
const addressBytes = hash.slice(-20);
result.AVAX.address = "0x" + Crypto.util.bytesToHex(addressBytes);
result.AVAX.privateKey = privKeyHex;
} catch (error) {
console.error("Error generating AVAX address:", error);
console.error("Private key:", privKeyHex);
result.AVAX.address = "Error generating address";
result.AVAX.privateKey = privKeyHex;
}
// restore
bitjs.pub = origBitjsPub;
bitjs.priv = origBitjsPriv;
bitjs.compressed = origBitjsCompressed;
coinjs.compressed = origCoinJsCompressed;
return result;
};
})("object" === typeof module ? module.exports : (window.avaxCrypto = {}));

1806
index.html Normal file

File diff suppressed because it is too large Load Diff

9993
lib.avax.js Normal file

File diff suppressed because it is too large Load Diff

2614
style.css Normal file

File diff suppressed because it is too large Load Diff