606 lines
15 KiB
TypeScript
606 lines
15 KiB
TypeScript
import {
|
|
Address,
|
|
BlockHeader,
|
|
Bytes,
|
|
encodeExtendedJson,
|
|
decodeExtendedJson,
|
|
// Encrypter,
|
|
// Hasher,
|
|
HDPrivateNode,
|
|
HDPublicNode,
|
|
Mnemonic,
|
|
PrivateKey,
|
|
PublicKey,
|
|
Satoshis,
|
|
Script,
|
|
Transaction,
|
|
} from '@xocash/primitives';
|
|
|
|
export const address = {
|
|
from: [
|
|
{
|
|
label: 'From',
|
|
inputs: ['CashAddr or Legacy Address'],
|
|
models: [''],
|
|
callback: (args: [string]) => Address.from(...args),
|
|
extendedInput: true,
|
|
},
|
|
{
|
|
label: 'From CashAddr',
|
|
inputs: ['CashAddr'],
|
|
models: [''],
|
|
callback: (args: [string]) => Address.fromCashAddr(...args),
|
|
extendedInput: true,
|
|
},
|
|
{
|
|
label: 'From Legacy',
|
|
inputs: ['Legacy Address'],
|
|
models: [''],
|
|
callback: (args: [string]) => Address.fromLegacy(...args),
|
|
extendedInput: true,
|
|
},
|
|
{
|
|
label: 'From Redeem Script Hex (P2SH20)',
|
|
inputs: ['RedeemScript Hex'],
|
|
models: [''],
|
|
callback: (args: [string]) =>
|
|
Address.fromRedeemScriptHex(...args, 'P2SH20'),
|
|
extendedInput: true,
|
|
},
|
|
{
|
|
label: 'From Redeem Script Hex (P2SH32)',
|
|
inputs: ['RedeemScript Hex'],
|
|
models: [''],
|
|
callback: (args: [string]) =>
|
|
Address.fromRedeemScriptHex(...args, 'P2SH32'),
|
|
extendedInput: true,
|
|
},
|
|
{
|
|
label: 'From Lockscript Hex',
|
|
inputs: ['Lockscript Hex'],
|
|
models: [''],
|
|
callback: (args: [string]) => Address.fromLockscriptHex(...args),
|
|
extendedInput: true,
|
|
},
|
|
{
|
|
label: 'From Hash160 Hex',
|
|
inputs: ['Hash160 Hex'],
|
|
models: [''],
|
|
callback: (args: [string]) => Address.fromHash160Hex(...args),
|
|
extendedInput: true,
|
|
},
|
|
],
|
|
to: [
|
|
{
|
|
label: 'To CashAddr (mainnet)',
|
|
callback: (address: Address) => address.toCashAddr('bitcoincash'),
|
|
},
|
|
{
|
|
label: 'To CashAddr (testnet)',
|
|
callback: (address: Address) => address.toCashAddr('bchtest'),
|
|
},
|
|
{
|
|
label: 'To CashAddr (regtest)',
|
|
callback: (address: Address) => address.toCashAddr('bchreg'),
|
|
},
|
|
{
|
|
label: 'To TokenAware CashAddr (mainnet)',
|
|
callback: (address: Address) => address.toTokenAddress('bitcoincash'),
|
|
},
|
|
{
|
|
label: 'To TokenAware CashAddr (testnet)',
|
|
callback: (address: Address) => address.toTokenAddress('bchtest'),
|
|
},
|
|
{
|
|
label: 'To TokenAware CashAddr (regtest)',
|
|
callback: (address: Address) => address.toTokenAddress('bchreg'),
|
|
},
|
|
{
|
|
label: 'To Legacy',
|
|
callback: (address: Address) => address.toLegacy(),
|
|
},
|
|
{
|
|
label: 'To Hash160/RIPEMD Hex',
|
|
callback: (address: Address) => address.toHash160Hex(),
|
|
},
|
|
{
|
|
label: 'To Lockscript Hex',
|
|
callback: (address: Address) => address.toLockscriptHex(),
|
|
},
|
|
{
|
|
label: 'To Lockscript ASM',
|
|
callback: (address: Address) => address.toLockscriptAsm(),
|
|
},
|
|
],
|
|
};
|
|
|
|
export const blockHeader = {
|
|
from: [
|
|
{
|
|
label: 'From',
|
|
inputs: ['Hex'],
|
|
models: [''],
|
|
callback: (args: [string]) => BlockHeader.from(...args),
|
|
},
|
|
],
|
|
to: [
|
|
{
|
|
label: 'Hash (Hex)',
|
|
callback: (blockHeader: BlockHeader) => blockHeader.getHashHex(),
|
|
},
|
|
{
|
|
label: 'Version (Hex)',
|
|
callback: (blockHeader: BlockHeader) => blockHeader.getVersionHex(),
|
|
},
|
|
{
|
|
label: 'Timestamp (Unix)',
|
|
callback: (blockHeader: BlockHeader) =>
|
|
blockHeader.getTimestamp().toString(),
|
|
},
|
|
{
|
|
label: 'Timestamp (ISO)',
|
|
callback: (blockHeader: BlockHeader) =>
|
|
blockHeader.getTimestampDate().toISOString(),
|
|
},
|
|
{
|
|
label: 'Bits (Hex)',
|
|
callback: (blockHeader: BlockHeader) => blockHeader.getBitsHex(),
|
|
},
|
|
{
|
|
label: 'Nonce (Hex)',
|
|
callback: (blockHeader: BlockHeader) => blockHeader.getNonceHex(),
|
|
},
|
|
{
|
|
label: 'Previous Block Hash',
|
|
callback: (blockHeader: BlockHeader) =>
|
|
blockHeader.getPreviousBlockHashHex(),
|
|
},
|
|
{
|
|
label: 'Merkle Root',
|
|
callback: (blockHeader: BlockHeader) => blockHeader.getMerkleRootHex(),
|
|
},
|
|
{
|
|
label: 'To Raw',
|
|
callback: (blockHeader: BlockHeader) =>
|
|
encodeExtendedJson(blockHeader.toRaw(), 2),
|
|
},
|
|
],
|
|
};
|
|
|
|
export const bytes = {
|
|
from: [
|
|
{
|
|
label: 'From Base64',
|
|
inputs: ['Base64'],
|
|
models: [''],
|
|
callback: (args: [string]) => Bytes.fromBase64(...args),
|
|
},
|
|
{
|
|
label: 'From Hex',
|
|
inputs: ['Hex'],
|
|
models: [''],
|
|
callback: (args: [string]) => Bytes.fromHex(...args),
|
|
},
|
|
{
|
|
label: 'From UTF-8',
|
|
inputs: ['UTF-8'],
|
|
models: [''],
|
|
callback: (args: [string]) => Bytes.fromUtf8(...args),
|
|
},
|
|
],
|
|
to: [
|
|
{
|
|
label: 'To Base64',
|
|
callback: (bytes: Bytes) => bytes.toBase64(),
|
|
},
|
|
{
|
|
label: 'To Hex',
|
|
callback: (bytes: Bytes) => bytes.toHex(),
|
|
},
|
|
{
|
|
label: 'To UTF-8',
|
|
callback: (bytes: Bytes) => bytes.toUtf8(),
|
|
},
|
|
],
|
|
};
|
|
|
|
export const hdPrivateNode = {
|
|
from: [
|
|
{
|
|
label: 'Generate Random',
|
|
callback: () => HDPrivateNode.generateRandom(),
|
|
},
|
|
{
|
|
label: 'From Mnemonic Phrase',
|
|
inputs: ['Mnemonic'],
|
|
models: [''],
|
|
callback: (args: [string]) => HDPrivateNode.fromMnemonic(...args),
|
|
},
|
|
{
|
|
label: 'From XPriv Key',
|
|
inputs: ['XPriv Key'],
|
|
models: [''],
|
|
callback: (args: [string]) => HDPrivateNode.fromXPriv(...args),
|
|
},
|
|
{
|
|
label: 'From Seed',
|
|
inputs: ['Seed (Hex)'],
|
|
models: [''],
|
|
callback: (args: [string]) => HDPrivateNode.fromSeed(...args),
|
|
},
|
|
{
|
|
label: 'From Raw',
|
|
inputs: ['Raw (LibAuth Format/ExtJSON Encoded)'],
|
|
models: [''],
|
|
callback: (args: [string]) =>
|
|
HDPrivateNode.fromRaw(decodeExtendedJson(args.join(''))),
|
|
extendedInput: true,
|
|
},
|
|
],
|
|
to: [
|
|
{
|
|
label: 'To XPriv Key',
|
|
callback: (hdPrivateNode: HDPrivateNode) => hdPrivateNode.toXPriv(),
|
|
},
|
|
{
|
|
label: 'To String',
|
|
callback: (hdPrivateNode: HDPrivateNode) => hdPrivateNode.toString(),
|
|
},
|
|
{
|
|
label: 'To Raw (LibAuth Format/ExtJSON Encoded)',
|
|
callback: (hdPrivateNode: HDPrivateNode) =>
|
|
encodeExtendedJson(hdPrivateNode.toRaw(), 2),
|
|
},
|
|
{
|
|
label: 'To XPub Key',
|
|
callback: (hdPrivateNode: HDPrivateNode) =>
|
|
hdPrivateNode.deriveHDPublicNode().toXPub(),
|
|
},
|
|
],
|
|
methods: [
|
|
{
|
|
label: 'Derive Path',
|
|
inputs: ['BIP32 Path'],
|
|
models: ["m/44'/145'/0'/0/0"],
|
|
callback: (hdPrivateNode: HDPrivateNode, args: [string]) =>
|
|
hdPrivateNode
|
|
.derivePath(...args)
|
|
.toPrivateKey()
|
|
.toWif(),
|
|
},
|
|
],
|
|
};
|
|
|
|
export const hdPublicNode = {
|
|
from: [
|
|
{
|
|
label: 'From XPub Key',
|
|
inputs: ['XPub Key'],
|
|
models: [''],
|
|
callback: (args: [string]) => HDPublicNode.fromXPub(...args),
|
|
},
|
|
{
|
|
label: 'From Raw',
|
|
inputs: ['Raw (LibAuth Format/ExtJSON Encoded)'],
|
|
models: [''],
|
|
callback: (args: [string]) =>
|
|
HDPublicNode.fromRaw(decodeExtendedJson(args.join(''))),
|
|
extendedInput: true,
|
|
},
|
|
],
|
|
to: [
|
|
{
|
|
label: 'To XPub Key',
|
|
callback: (hdPublicNode: HDPublicNode) => hdPublicNode.toXPub(),
|
|
},
|
|
{
|
|
label: 'To String',
|
|
callback: (hdPublicNode: HDPublicNode) => hdPublicNode.toString(),
|
|
},
|
|
{
|
|
label: 'To Raw (LibAuth Format/ExtJSON Encoded)',
|
|
callback: (hdPublicNode: HDPublicNode) =>
|
|
encodeExtendedJson(hdPublicNode.toRaw(), 2),
|
|
},
|
|
],
|
|
methods: [
|
|
{
|
|
label: 'Derive Path',
|
|
inputs: ['BIP32 Public Key Path'],
|
|
models: ['M/0/0'],
|
|
callback: (hdPublicNode: HDPublicNode, args: [string]) =>
|
|
hdPublicNode
|
|
.derivePath(...args)
|
|
.toPublicKey()
|
|
.deriveAddress()
|
|
.toCashAddr(),
|
|
},
|
|
],
|
|
};
|
|
|
|
export const mnemonic = {
|
|
from: [
|
|
{
|
|
label: 'Generate Random',
|
|
inputs: ['Passphrase (Optional)'],
|
|
models: [undefined],
|
|
callback: (args: [string?]) => Mnemonic.generateRandom(...args),
|
|
},
|
|
{
|
|
label: 'From Phrase',
|
|
inputs: ['Mnemonic Phrase'],
|
|
models: [''],
|
|
callback: (args: [string]) => Mnemonic.fromPhrase(...args),
|
|
extendedInput: true,
|
|
},
|
|
],
|
|
to: [
|
|
{
|
|
label: 'To Seed',
|
|
callback: (mnemonic: Mnemonic) =>
|
|
Bytes.fromBytes(mnemonic.toSeed()).toHex(),
|
|
},
|
|
{
|
|
label: 'To Phrase (without passphrase)',
|
|
callback: (mnemonic: Mnemonic) => mnemonic.toPhrase(false),
|
|
},
|
|
{
|
|
label: 'To Phrase (with passphrase)',
|
|
callback: (mnemonic: Mnemonic) => mnemonic.toPhrase(true),
|
|
},
|
|
{
|
|
label: 'Words',
|
|
callback: (mnemonic: Mnemonic) => mnemonic.toWords(),
|
|
},
|
|
{
|
|
label: 'Passphrase',
|
|
callback: (mnemonic: Mnemonic) => mnemonic.getPassphrase(),
|
|
},
|
|
],
|
|
};
|
|
|
|
// TODO: Message Signing outputs. Maybe add an `extension` flag to the `to` that allows another input field and uses that to generate the outputs
|
|
export const privateKey = {
|
|
from: [
|
|
{
|
|
label: 'Generate Random',
|
|
callback: () => PrivateKey.generateRandom(),
|
|
},
|
|
{
|
|
label: 'From Hex or WIF',
|
|
inputs: ['Hex or WIF'],
|
|
models: [''],
|
|
callback: (args: [string]) => PrivateKey.from(...args),
|
|
},
|
|
],
|
|
to: [
|
|
{
|
|
label: 'To Hex',
|
|
callback: (privateKey: PrivateKey) => privateKey.toHex(),
|
|
},
|
|
{
|
|
label: 'To WIF',
|
|
callback: (privateKey: PrivateKey) => privateKey.toWif(),
|
|
},
|
|
{
|
|
label: 'To String',
|
|
callback: (privateKey: PrivateKey) => privateKey.toString(),
|
|
},
|
|
{
|
|
label: 'Derived Public Key (Hex)',
|
|
callback: (privateKey: PrivateKey) =>
|
|
privateKey.derivePublicKey().toString(),
|
|
},
|
|
{
|
|
label: 'Derived BCH Address (CashAddr)',
|
|
callback: (privateKey: PrivateKey) =>
|
|
privateKey.derivePublicKey().deriveAddress().toCashAddr('bitcoincash'),
|
|
},
|
|
],
|
|
methods: [
|
|
{
|
|
label: 'Sign Message (Schnorr)',
|
|
inputs: ['UTF8'],
|
|
models: ['Your text here'],
|
|
callback: (privateKey: PrivateKey, args: [string]) =>
|
|
Bytes.fromBytes(privateKey.signMessageSchnorr(...args)).toHex(),
|
|
},
|
|
{
|
|
label: 'Sign Message (DER)',
|
|
inputs: ['UTF8'],
|
|
models: ['Your text here'],
|
|
callback: (privateKey: PrivateKey, args: [string]) =>
|
|
Bytes.fromBytes(privateKey.signMessageDER(...args)).toHex(),
|
|
},
|
|
],
|
|
};
|
|
|
|
export const publicKey = {
|
|
from: [
|
|
{
|
|
label: 'From Hex',
|
|
inputs: ['Hex'],
|
|
models: [''],
|
|
callback: (args: [string]) => PublicKey.fromHex(...args),
|
|
},
|
|
{
|
|
label: 'From WIF',
|
|
inputs: ['WIF'],
|
|
models: [''],
|
|
callback: (args: [string]) =>
|
|
PrivateKey.fromWIF(...args).derivePublicKey(),
|
|
},
|
|
],
|
|
to: [
|
|
{
|
|
label: 'Derived Hash160 Hex',
|
|
callback: (publicKey: PublicKey) => publicKey.deriveHash160Hex(),
|
|
},
|
|
{
|
|
label: 'Derived Address',
|
|
callback: (publicKey: PublicKey) =>
|
|
publicKey.deriveAddress().toCashAddr(),
|
|
},
|
|
{
|
|
label: 'To Hex',
|
|
callback: (publicKey: PublicKey) => publicKey.toHex(),
|
|
},
|
|
{
|
|
label: 'To String',
|
|
callback: (publicKey: PublicKey) => publicKey.toString(),
|
|
},
|
|
],
|
|
methods: [
|
|
{
|
|
label: 'Verify Message (Schnorr)',
|
|
inputs: ['Message (UTF8)', 'Signature (Hex)'],
|
|
models: ['Your text here'],
|
|
callback: (publicKey: PublicKey, args: [string, string]) =>
|
|
publicKey.verifyMessageSchnorr(...args).toString(),
|
|
},
|
|
{
|
|
label: 'Verify Message (DER)',
|
|
inputs: ['Message (UTF8)', 'Signature (Hex)'],
|
|
models: ['Your text here'],
|
|
callback: (publicKey: PublicKey, args: [string, string]) =>
|
|
publicKey.verifyMessageDER(...args).toString(),
|
|
},
|
|
],
|
|
};
|
|
|
|
export const satoshis = {
|
|
from: [
|
|
{
|
|
label: 'From Sats',
|
|
inputs: ['Sats'],
|
|
models: [''],
|
|
callback: (args: [number]) => Satoshis.fromSats(...args),
|
|
},
|
|
{
|
|
label: 'From Bits',
|
|
inputs: ['Bits'],
|
|
models: [''],
|
|
callback: (args: [number]) => Satoshis.fromBits(...args),
|
|
},
|
|
{
|
|
label: 'From MBCH',
|
|
inputs: ['MBCH'],
|
|
models: [''],
|
|
callback: (args: [number]) => Satoshis.fromMBCH(...args),
|
|
},
|
|
{
|
|
label: 'From BCH',
|
|
inputs: ['BCH'],
|
|
models: [''],
|
|
callback: (args: [number]) => Satoshis.fromBCH(...args),
|
|
},
|
|
],
|
|
to: [
|
|
{
|
|
label: 'To Sats',
|
|
callback: (satoshis: Satoshis) => satoshis.toSats().toString(),
|
|
},
|
|
{
|
|
label: 'To Bits',
|
|
callback: (satoshis: Satoshis) => satoshis.toBits().toString(),
|
|
},
|
|
{
|
|
label: 'To MBCH',
|
|
callback: (satoshis: Satoshis) => satoshis.toMBCH().toString(),
|
|
},
|
|
{
|
|
label: 'To BCH',
|
|
callback: (satoshis: Satoshis) => satoshis.toBCH().toString(),
|
|
},
|
|
],
|
|
};
|
|
|
|
export const script = {
|
|
from: [
|
|
{
|
|
label: 'From ASM',
|
|
inputs: ['ASM'],
|
|
models: [''],
|
|
callback: (args: [string]) => Script.fromASM(...args),
|
|
},
|
|
{
|
|
label: 'From Hex',
|
|
inputs: ['Hex'],
|
|
models: [''],
|
|
callback: (args: [string]) => Script.fromHex(...args),
|
|
},
|
|
],
|
|
to: [
|
|
{
|
|
label: 'To ASM',
|
|
callback: (script: Script) => script.toASM(),
|
|
},
|
|
{
|
|
label: 'To Hex',
|
|
callback: (script: Script) => script.toHex(),
|
|
},
|
|
],
|
|
};
|
|
|
|
export const transaction = {
|
|
from: [
|
|
{
|
|
label: 'From Hex',
|
|
inputs: ['Hex'],
|
|
models: [''],
|
|
callback: (args: [string]) => Transaction.fromHex(...args),
|
|
extendedInput: true,
|
|
},
|
|
{
|
|
label: 'From Raw',
|
|
inputs: ['Raw (LibAuth Format/ExtJSON Encoded)'],
|
|
models: [''],
|
|
callback: (args: [...string[]]) =>
|
|
Transaction.fromRaw(decodeExtendedJson(args.join(''))),
|
|
extendedInput: true,
|
|
},
|
|
],
|
|
to: [
|
|
{
|
|
label: 'To Transaction Hash Hex',
|
|
callback: (transaction: Transaction) => transaction.toHashHex(),
|
|
},
|
|
{
|
|
label: 'To Raw (LibAuth Format/ExtJSON Encoded)',
|
|
callback: (transaction: Transaction) =>
|
|
encodeExtendedJson(transaction.toRaw(), 2),
|
|
},
|
|
{
|
|
label: 'To Hex',
|
|
callback: (transaction: Transaction) => transaction.toHex(),
|
|
},
|
|
{
|
|
label: 'Version',
|
|
callback: (transaction: Transaction) =>
|
|
transaction.getVersion().toString(),
|
|
},
|
|
{
|
|
label: 'Inputs',
|
|
callback: (transaction: Transaction) => {
|
|
return encodeExtendedJson(transaction.getInputs(), 2);
|
|
},
|
|
},
|
|
{
|
|
label: 'Outputs',
|
|
callback: (transaction: Transaction) => {
|
|
return encodeExtendedJson(transaction.getOutputs(), 2);
|
|
},
|
|
},
|
|
{
|
|
label: 'Locktime',
|
|
callback: (transaction: Transaction) =>
|
|
transaction.getLocktime().toString(),
|
|
},
|
|
{
|
|
label: 'Is Coinbase',
|
|
callback: (transaction: Transaction) =>
|
|
transaction.isCoinbase().toString(),
|
|
},
|
|
],
|
|
};
|