avaxwallet/avaxCrypto.js
2025-10-24 14:17:23 +05:30

163 lines
5.2 KiB
JavaScript

(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 = {}));