diff --git a/packages/kos-go/demo/go.mod b/packages/kos-go/demo/go.mod
index 7cebd7f2..d61afb71 100644
--- a/packages/kos-go/demo/go.mod
+++ b/packages/kos-go/demo/go.mod
@@ -2,6 +2,7 @@ module github.com/klever-io/kos-rs/packages/kos-go/demo
go 1.24.7
-require github.com/klever-io/kos-rs/packages/kos-go v0.2.37
-replace github.com/klever-io/kos-rs/packages/kos-go => ../
+require github.com/klever-io/kos-rs/packages/kos-go v0.2.40
+
+replace github.com/klever-io/kos-rs/packages/kos-go => ../
\ No newline at end of file
diff --git a/packages/kos-go/demo/go.sum b/packages/kos-go/demo/go.sum
index e69de29b..1d215ccd 100644
--- a/packages/kos-go/demo/go.sum
+++ b/packages/kos-go/demo/go.sum
@@ -0,0 +1,2 @@
+github.com/klever-io/kos-rs/packages/kos-go v0.2.40 h1:uMYtIRfGioNz+uYXW4fs7rUDmV6hgW1gEZ8tmhZjst0=
+github.com/klever-io/kos-rs/packages/kos-go v0.2.40/go.mod h1:ekYnxLsNZh51RGO8/X4WrhDWbUGmW0uUM7NxqE1P5sQ=
diff --git a/packages/kos-web/demo/README.md b/packages/kos-web/demo/README.md
deleted file mode 100644
index bee1eb06..00000000
--- a/packages/kos-web/demo/README.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# KOS Wallet Demo
-
-A demonstration of the KOS (Klever OS) TypeScript library capabilities, showcasing wallet management, cryptography, and signing operations in a simple web interface.
-
-## Overview
-
-This demo provides a user-friendly interface to interact with key functionality of the KOS library, including:
-
-- **Mnemonic Phrase Generation**: Create BIP39 mnemonic phrases with varying word counts (12 or 24 words)
-- **Wallet Creation**: Generate wallets from either mnemonic phrases or private keys
-- **Encryption/Decryption**: Encrypt and decrypt data with password protection
-- **Message Signing**: Sign messages using a wallet's private key
-
-## Getting Started
-
-### Prerequisites
-
-- A modern web browser
-- Node.js and npm (for development)
-
-### Installation
-
-1. Install dependencies:
-
-```bash
-npm install
-```
-
-2. Serve the application:
-
-```bash
-npm run dev
-```
diff --git a/packages/kos-web/demo/index.html b/packages/kos-web/demo/index.html
deleted file mode 100644
index b5655ef2..00000000
--- a/packages/kos-web/demo/index.html
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
-
- KOS-Rust example
-
-
-
-
KOS-Rust example
-
-
-
-
-
-
-
-
-
SDK Usage Examples in TypeScript
-
-// Example 1: Create a wallet from a mnemonic
-import { Wallet } from '@klever/kos-web';
-
-const mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
-const path = "m/44'/0'/0'/0/0";
-const wallet = Wallet.fromMnemonic(0, mnemonic, path);
-
-console.log("Address:", wallet.getAddress());
-console.log("Public Key:", wallet.getPublicKey());
-
-// Example 2: Sign a message
-const message = "Hello, World!";
-const messageBytes = new TextEncoder().encode(message);
-const signature = wallet.signMessage(messageBytes);
-
-console.log("Signature:", Array.from(signature).map(b => b.toString(16).padStart(2, '0')).join(''));
-
-// Example 3: Encrypt and decrypt data
-import { encrypt, decrypt, toBytes, toString } from '@klever/kos-web';
-
-const data = "Confidential data";
-const password = "secret-password";
-
-const encryptedData = encrypt(toBytes(data), password);
-const decryptedData = decrypt(encryptedData, password);
-
-console.log("Original data:", data);
-console.log("Decrypted data:", toString(decryptedData));
-
-// Don't forget to free resources
-wallet.free();
-
-
-
-
-
-
-
diff --git a/packages/kos-web/demo/package.json b/packages/kos-web/demo/package.json
deleted file mode 100644
index 7f3a0fe1..00000000
--- a/packages/kos-web/demo/package.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "demo",
- "private": true,
- "version": "0.0.0",
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "tsc && vite build",
- "preview": "vite preview"
- },
- "devDependencies": {
- "typescript": "~5.7.2",
- "vite": "^6.2.0"
- },
- "dependencies": {
- "kos": "file:./kos",
- "vite-plugin-wasm": "^3.4.1"
- }
-}
diff --git a/packages/kos-web/demo/src/components/cryptography-demo.ts b/packages/kos-web/demo/src/components/cryptography-demo.ts
deleted file mode 100644
index 13fb7345..00000000
--- a/packages/kos-web/demo/src/components/cryptography-demo.ts
+++ /dev/null
@@ -1,245 +0,0 @@
-import { decrypt, encrypt, fromPem, toBytes, toPem, toString } from "kos";
-
-export class CryptographyDemo {
- private container: HTMLElement;
- private result: HTMLDivElement;
-
- constructor(containerId: string) {
- const container = document.getElementById(containerId);
- if (!container) {
- throw new Error(`Container element with id "${containerId}" not found`);
- }
- this.container = container;
- this.initUI();
- this.result = document.createElement("div");
- this.result.className = "result";
- this.result.style.display = "none";
- this.container.appendChild(this.result);
- }
-
- private initUI(): void {
- const html = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `;
-
- this.container.innerHTML = html;
-
- // Add event listeners
- this.addEventListeners();
- }
-
- private addEventListeners(): void {
- const cryptoAction = document.getElementById(
- "crypto-action"
- ) as HTMLSelectElement;
- const pemTagGroup = document.getElementById(
- "pem-tag-group"
- ) as HTMLDivElement;
- const dataInputLabel = document.querySelector(
- "#data-input-group label"
- ) as HTMLLabelElement;
- const executeBtn = document.getElementById(
- "execute-crypto"
- ) as HTMLButtonElement;
-
- // Toggle between encryption options
- cryptoAction.addEventListener("change", () => {
- switch (cryptoAction.value) {
- case "encrypt":
- dataInputLabel.textContent = "Data:";
- pemTagGroup.style.display = "none";
- break;
- case "decrypt":
- dataInputLabel.textContent = "Data (Hex):";
- pemTagGroup.style.display = "none";
- break;
- case "to-pem":
- dataInputLabel.textContent = "Data (Hex):";
- pemTagGroup.style.display = "block";
- break;
- case "from-pem":
- dataInputLabel.textContent = "PEM Data:";
- pemTagGroup.style.display = "none";
- break;
- }
- });
-
- // Execute the cryptography action
- executeBtn.addEventListener("click", () => {
- this.executeCryptoAction();
- });
- }
-
- private executeCryptoAction(): void {
- try {
- const action = (
- document.getElementById("crypto-action") as HTMLSelectElement
- ).value;
- const inputData = (
- document.getElementById("data-input") as HTMLTextAreaElement
- ).value.trim();
- const password = (
- document.getElementById("password-input") as HTMLInputElement
- ).value;
-
- if (!inputData) {
- throw new Error("Input data is required");
- }
-
- switch (action) {
- case "encrypt":
- this.encryptData(inputData, password);
- break;
- case "decrypt":
- this.decryptData(inputData, password);
- break;
- case "to-pem":
- this.convertToPem(inputData);
- break;
- case "from-pem":
- this.convertFromPem(inputData, password);
- break;
- }
- } catch (error) {
- if (error instanceof Error) {
- this.showError(error.message);
- return;
- }
- if (typeof error === "string") {
- this.showError(error);
- return;
- }
-
- this.showError("An unknown error occurred");
- }
- }
-
- private encryptData(data: string, password: string): void {
- if (!password) {
- throw new Error("Password is required for encryption");
- }
-
- const dataBytes = toBytes(data);
- const encryptedBytes = encrypt(dataBytes, password);
-
- // Convert encrypted bytes to hexadecimal for display
- const hexEncrypted = Array.from(encryptedBytes)
- .map((b) => b.toString(16).padStart(2, "0"))
- .join("");
-
- this.showResult(`
- Encrypted Data
- Original Data: ${data}
- Encrypted Data (hex): ${hexEncrypted}
- `);
- }
-
- private decryptData(hexData: string, password: string): void {
- if (!password) {
- throw new Error("Password is required for decryption");
- }
-
- // Convert the hex string to bytes
- try {
- const encryptedBytes = new Uint8Array(
- hexData.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))
- );
- const decryptedBytes = decrypt(encryptedBytes, password);
- const decryptedText = toString(decryptedBytes);
-
- this.showResult(`
- Decrypted Data
- Encrypted Data (hex): ${hexData}
- Decrypted Data: ${decryptedText}
- `);
- } catch (e) {
- throw new Error(`Error converting hex to bytes: ${e}`);
- }
- }
-
- private convertToPem(hexData: string): void {
- // Convert the hex string to bytes
- try {
- const dataBytes = new Uint8Array(
- hexData.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))
- );
- const tag = (
- document.getElementById("pem-tag") as HTMLInputElement
- ).value.trim();
-
- if (!tag) {
- throw new Error("PEM tag is required");
- }
-
- const pemData = toPem(tag, dataBytes);
-
- this.showResult(`
- Conversion to PEM
- Original Data (hex): ${hexData}
- PEM Format:
- ${pemData}
- `);
- } catch (e) {
- throw new Error(`Error converting hex to bytes: ${e}`);
- }
- }
-
- private convertFromPem(pemData: string, password: string): void {
- try {
- if (!password) {
- throw new Error("Password is required for PEM decryption");
- }
-
- const bytes = fromPem(pemData, password);
-
- // Convert bytes to hexadecimal for display
- const hexData = Array.from(bytes)
- .map((b) => b.toString(16).padStart(2, "0"))
- .join("");
-
- this.showResult(`
- Conversion from PEM
- Original PEM Data:
- ${pemData}
- Converted Data (hex): ${hexData}
- `);
- } catch (e) {
- throw new Error(`Error converting from PEM: ${e}`);
- }
- }
-
- private showResult(html: string): void {
- this.result.innerHTML = html;
- this.result.style.display = "flex";
- }
-
- private showError(message: string): void {
- this.result.innerHTML = `${message}
`;
- this.result.style.display = "flex";
- }
-}
diff --git a/packages/kos-web/demo/src/components/transaction-signer.ts b/packages/kos-web/demo/src/components/transaction-signer.ts
deleted file mode 100644
index 8f24a11b..00000000
--- a/packages/kos-web/demo/src/components/transaction-signer.ts
+++ /dev/null
@@ -1,420 +0,0 @@
-import {
- ChainData,
- getSupportedChains,
- toBytes,
- TransactionChainOptions,
- Wallet,
-} from "kos";
-
-export class TransactionSigner {
- private container: HTMLElement;
- private wallet: Wallet | null = null;
- private result: HTMLDivElement;
- private chainMap: Map = new Map();
-
- constructor(containerId: string) {
- const container = document.getElementById(containerId);
- if (!container) {
- throw new Error(`Container element with id "${containerId}" not found`);
- }
- this.container = container;
- this.initUI();
- this.result = document.createElement("div");
- this.result.className = "result";
- this.result.style.display = "none";
- this.container.appendChild(this.result);
-
- this.populateBlockchainSelect();
- }
-
- private initUI(): void {
- const html = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `;
-
- this.container.innerHTML = html;
-
- // Add event listeners
- this.addEventListeners();
- }
-
- private populateBlockchainSelect(): void {
- try {
- const blockchainSelect = document.getElementById(
- "blockchain-tx"
- ) as HTMLSelectElement;
- if (!blockchainSelect) return;
-
- blockchainSelect.innerHTML = "";
-
- const chains = getSupportedChains();
-
- chains.forEach((chain) => {
- this.chainMap.set(chain.id, chain);
- });
-
- chains.sort((a, b) => a.getName().localeCompare(b.getName()));
-
- chains.forEach((chain) => {
- const option = document.createElement("option");
- option.value = chain.getId().toString();
- option.textContent = `${chain.getName()} (${chain.getSymbol()})`;
- blockchainSelect.appendChild(option);
- });
-
- // Free the chains after populating the select element
- chains.forEach((chain) => {
- chain.free();
- });
- } catch (error) {
- console.error("Erro ao carregar blockchains:", error);
- const blockchainSelect = document.getElementById(
- "blockchain-tx"
- ) as HTMLSelectElement;
- if (blockchainSelect) {
- blockchainSelect.innerHTML =
- '';
- }
- }
- }
-
- private addEventListeners(): void {
- const txType = document.getElementById("tx-type") as HTMLSelectElement;
- const messageGroup = document.getElementById(
- "message-group"
- ) as HTMLDivElement;
- const transactionGroup = document.getElementById(
- "transaction-group"
- ) as HTMLDivElement;
- const loadWalletBtn = document.getElementById(
- "load-wallet-btn"
- ) as HTMLButtonElement;
- const signBtn = document.getElementById("sign-btn") as HTMLButtonElement;
- const chainOptionType = document.getElementById(
- "chain-option-type"
- ) as HTMLSelectElement;
- const ethereumOptions = document.getElementById(
- "ethereum-options"
- ) as HTMLDivElement;
- const bitcoinOptions = document.getElementById(
- "bitcoin-options"
- ) as HTMLDivElement;
- const cosmosOptions = document.getElementById(
- "cosmos-options"
- ) as HTMLDivElement;
-
- // Toggle between message and transaction
- txType.addEventListener("change", () => {
- if (txType.value === "message") {
- messageGroup.style.display = "block";
- transactionGroup.style.display = "none";
- } else {
- messageGroup.style.display = "none";
- transactionGroup.style.display = "block";
- }
- });
-
- // Toggle between chain options
- chainOptionType.addEventListener("change", () => {
- ethereumOptions.style.display = "none";
- bitcoinOptions.style.display = "none";
- cosmosOptions.style.display = "none";
-
- switch (chainOptionType.value) {
- case "ethereum":
- ethereumOptions.style.display = "block";
- break;
- case "bitcoin":
- bitcoinOptions.style.display = "block";
- break;
- case "cosmos":
- cosmosOptions.style.display = "block";
- break;
- }
- });
-
- // Load the wallet
- loadWalletBtn.addEventListener("click", () => {
- this.loadWallet();
- signBtn.disabled = false;
- });
-
- // Sign the message or transaction
- signBtn.addEventListener("click", () => {
- if (txType.value === "message") {
- this.signMessage();
- } else {
- this.signTransaction();
- }
- });
- }
-
- private loadWallet(): void {
- try {
- const privateKey = (
- document.getElementById("private-key-tx") as HTMLInputElement
- ).value.trim();
- const chainId = parseInt(
- (document.getElementById("blockchain-tx") as HTMLSelectElement).value
- );
-
- if (!privateKey) {
- throw new Error("Private key is required");
- }
-
- // Free the previous wallet if it exists
- if (this.wallet) {
- this.wallet.free();
- }
-
- this.wallet = Wallet.fromPrivateKey(chainId, privateKey);
-
- this.showSuccess(
- `Wallet successfully loaded! Address: ${this.wallet.getAddress()}`
- );
- } catch (error) {
- if (error instanceof Error) {
- this.showError(error.message);
- return;
- }
- if (typeof error === "string") {
- this.showError(error);
- return;
- }
-
- this.showError("An unknown error occurred");
- }
- }
-
- private signMessage(): void {
- if (!this.wallet) {
- this.showError("Wallet not loaded");
- return;
- }
-
- try {
- const message = (
- document.getElementById("message-input") as HTMLTextAreaElement
- ).value;
- if (!message) {
- throw new Error("Message is required");
- }
-
- const messageBytes = toBytes(message);
- const signature = this.wallet.signMessage(messageBytes);
-
- // Convert to hexadecimal for display
- const hexSignature = Array.from(signature)
- .map((b) => b.toString(16).padStart(2, "0"))
- .join("");
-
- this.showResult(`
- Message Signature
- Message: ${message}
- Signature (hex): ${hexSignature}
- `);
- } catch (error) {
- if (error instanceof Error) {
- this.showError(error.message);
- return;
- }
- if (typeof error === "string") {
- this.showError(error);
- return;
- }
-
- this.showError("An unknown error occurred");
- }
- }
-
- private signTransaction(): void {
- if (!this.wallet) {
- this.showError("Wallet not loaded");
- return;
- }
-
- try {
- const txDataHex = (
- document.getElementById("transaction-data") as HTMLTextAreaElement
- ).value.trim();
- if (!txDataHex) {
- throw new Error("Transaction data is required");
- }
-
- // Convert the hex string to bytes
- const txData = new Uint8Array(
- txDataHex.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))
- );
-
- // Get chain options, if any
- let chainOptions: TransactionChainOptions | null = null;
- const chainOptionType = (
- document.getElementById("chain-option-type") as HTMLSelectElement
- ).value;
-
- if (chainOptionType !== "none") {
- chainOptions = this.createChainOptions(chainOptionType);
- }
-
- const transaction = this.wallet.sign(txData, chainOptions);
-
- // Convert values to hexadecimal for display
- const rawDataHex = Array.from(transaction.getRawData())
- .map((b) => b.toString(16).padStart(2, "0"))
- .join("");
-
- const signatureHex = Array.from(transaction.getSignature())
- .map((b) => b.toString(16).padStart(2, "0"))
- .join("");
-
- const txHashHex = Array.from(transaction.getTxHash())
- .map((b) => b.toString(16).padStart(2, "0"))
- .join("");
-
- this.showResult(`
- Transaction Hash: ${txHashHex}
- Signature (hex): ${signatureHex}
- Raw Data (hex): ${rawDataHex}
- `);
-
- // Free the transaction
- transaction.free();
- } catch (error) {
- if (error instanceof Error) {
- this.showError(error.message);
- return;
- }
- if (typeof error === "string") {
- this.showError(error);
- return;
- }
-
- this.showError("An unknown error occurred");
- }
- }
-
- private createChainOptions(optionType: string): TransactionChainOptions {
- switch (optionType) {
- case "ethereum": {
- const chainId = parseInt(
- (document.getElementById("eth-chain-id") as HTMLInputElement).value
- );
- return TransactionChainOptions.newEthereumSignOptions(chainId);
- }
- case "bitcoin": {
- const amountsStr = (
- document.getElementById("btc-input-amounts") as HTMLInputElement
- ).value;
- const scriptsStr = (
- document.getElementById("btc-prev-scripts") as HTMLTextAreaElement
- ).value;
-
- const amounts = amountsStr.split(",").map((a) => BigInt(a.trim()));
- const scripts = scriptsStr.split(",").map((s) => s.trim());
-
- // Create array of BigUint64Array
- const inputAmounts = new BigUint64Array(amounts.length);
- amounts.forEach((amount, index) => {
- inputAmounts[index] = amount;
- });
-
- return TransactionChainOptions.newBitcoinSignOptions(
- inputAmounts,
- scripts
- );
- }
- case "cosmos": {
- const chainId = (
- document.getElementById("cosmos-chain-id") as HTMLInputElement
- ).value;
- const accountNumber = BigInt(
- (document.getElementById("cosmos-account-number") as HTMLInputElement)
- .value
- );
- return TransactionChainOptions.newCosmosSignOptions(
- chainId,
- accountNumber
- );
- }
- default:
- throw new Error(`Unsupported chain option type: ${optionType}`);
- }
- }
-
- private showResult(html: string): void {
- this.result.innerHTML = html;
- this.result.style.display = "flex";
- }
-
- private showError(message: string): void {
- this.result.innerHTML = `${message}
`;
- this.result.style.display = "flex";
- }
-
- private showSuccess(message: string): void {
- this.result.innerHTML = `${message}
`;
- this.result.style.display = "flex";
- }
-}
diff --git a/packages/kos-web/demo/src/components/wallet-generator.ts b/packages/kos-web/demo/src/components/wallet-generator.ts
deleted file mode 100644
index 8155cd54..00000000
--- a/packages/kos-web/demo/src/components/wallet-generator.ts
+++ /dev/null
@@ -1,294 +0,0 @@
-import {
- AccountType,
- ChainData,
- generateMnemonicPhrase,
- getSupportedChains,
- isChainSupported,
- PathOptions,
- Wallet,
-} from "kos";
-
-export class WalletGenerator {
- private container: HTMLElement;
- private result: HTMLDivElement;
- private chainMap: Map = new Map();
-
- constructor(containerId: string) {
- const container = document.getElementById(containerId);
- if (!container) {
- throw new Error(`Container element with id "${containerId}" not found`);
- }
- this.container = container;
- this.initUI();
- this.result = document.createElement("div");
- this.result.className = "result";
- this.result.style.display = "none";
- this.container.appendChild(this.result);
-
- this.populateBlockchainSelect();
- }
-
- private initUI(): void {
- const html = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `;
-
- this.container.innerHTML = html;
-
- // Add event listeners
- this.addEventListeners();
- }
-
- private populateBlockchainSelect(): void {
- try {
- const blockchainSelect = document.getElementById(
- "blockchain"
- ) as HTMLSelectElement;
- if (!blockchainSelect) return;
-
- blockchainSelect.innerHTML = "";
-
- const chains = getSupportedChains();
-
- chains.forEach((chain) => {
- this.chainMap.set(chain.id, chain);
- });
-
- chains.sort((a, b) => a.getName().localeCompare(b.getName()));
-
- chains.forEach((chain) => {
- const option = document.createElement("option");
- option.value = chain.getId().toString();
- option.textContent = `${chain.getName()} (${chain.getSymbol()})`;
- blockchainSelect.appendChild(option);
- });
-
- chains.forEach((chain) => {
- chain.free();
- });
- } catch (error) {
- console.error(error);
- const blockchainSelect = document.getElementById(
- "blockchain"
- ) as HTMLSelectElement;
- if (blockchainSelect) {
- blockchainSelect.innerHTML =
- '';
- }
- }
- }
-
- private addEventListeners(): void {
- const walletType = document.getElementById(
- "wallet-type"
- ) as HTMLSelectElement;
- const mnemonicOptions = document.getElementById(
- "mnemonic-options"
- ) as HTMLDivElement;
- const privateKeyGroup = document.getElementById(
- "private-key-group"
- ) as HTMLDivElement;
- const generateMnemonicBtn = document.getElementById(
- "generate-mnemonic"
- ) as HTMLButtonElement;
- const mnemonicInputGroup = document.getElementById(
- "mnemonic-input-group"
- ) as HTMLDivElement;
- const mnemonicInput = document.getElementById(
- "mnemonic-input"
- ) as HTMLTextAreaElement;
- const useIndexCheckbox = document.getElementById(
- "use-index"
- ) as HTMLInputElement;
- const indexOptions = document.getElementById(
- "index-options"
- ) as HTMLDivElement;
- const createWalletBtn = document.getElementById(
- "create-wallet"
- ) as HTMLButtonElement;
-
- // Toggle wallet options
- walletType.addEventListener("change", () => {
- if (walletType.value === "mnemonic") {
- mnemonicOptions.style.display = "block";
- privateKeyGroup.style.display = "none";
- } else {
- mnemonicOptions.style.display = "none";
- privateKeyGroup.style.display = "block";
- }
- });
-
- // Generate a new mnemonic
- generateMnemonicBtn.addEventListener("click", () => {
- const wordCount = parseInt(
- (document.getElementById("mnemonic-words") as HTMLSelectElement).value
- );
- const mnemonic = generateMnemonicPhrase(wordCount);
- mnemonicInput.value = mnemonic;
- mnemonicInputGroup.style.display = "block";
- });
-
- // Toggle index options
- useIndexCheckbox.addEventListener("change", () => {
- indexOptions.style.display = useIndexCheckbox.checked ? "block" : "none";
- });
-
- // Create the wallet
- createWalletBtn.addEventListener("click", () => {
- this.createWallet();
- });
- }
-
- private createWallet(): void {
- try {
- const walletType = (
- document.getElementById("wallet-type") as HTMLSelectElement
- ).value;
- const chainId = parseInt(
- (document.getElementById("blockchain") as HTMLSelectElement).value
- );
-
- if (!isChainSupported(chainId)) {
- throw new Error(`Blockchain with ID ${chainId} is not supported`);
- }
-
- let wallet: Wallet;
-
- if (walletType === "mnemonic") {
- const mnemonic = (
- document.getElementById("mnemonic-input") as HTMLTextAreaElement
- ).value.trim();
- if (!mnemonic) {
- throw new Error("Mnemonic is required");
- }
-
- const useIndex = (
- document.getElementById("use-index") as HTMLInputElement
- ).checked;
-
- if (useIndex) {
- const index = parseInt(
- (document.getElementById("wallet-index") as HTMLInputElement).value
- );
- const useLegacy = (
- document.getElementById("use-legacy") as HTMLInputElement
- ).checked;
-
- const pathOptions = PathOptions.new(index);
- pathOptions.setLegacy(useLegacy);
-
- wallet = Wallet.fromMnemonicIndex(chainId, mnemonic, pathOptions);
- } else {
- const path = (
- document.getElementById("derivation-path") as HTMLInputElement
- ).value;
- wallet = Wallet.fromMnemonic(chainId, mnemonic, path);
- }
- } else {
- const privateKey = (
- document.getElementById("private-key-input") as HTMLTextAreaElement
- ).value.trim();
- if (!privateKey) {
- throw new Error("Private key is required");
- }
- wallet = Wallet.fromPrivateKey(chainId, privateKey);
- }
-
- this.displayWalletInfo(wallet);
-
- // Free resources
- wallet.free();
- } catch (error) {
- if (error instanceof Error) {
- this.showError(error.message);
- return;
- }
- if (typeof error === "string") {
- this.showError(error);
- return;
- }
-
- this.showError("An unknown error occurred");
- }
- }
-
- private displayWalletInfo(wallet: Wallet): void {
- const accountTypeLabels = {
- [AccountType.Mnemonic]: "Mnemonic",
- [AccountType.PrivateKey]: "Private Key",
- [AccountType.KleverSafe]: "KleverSafe",
- [AccountType.ReadOnly]: "Read Only",
- };
-
- let info = `Wallet Information
- Type: ${
- accountTypeLabels[wallet.getAccountType()]
- }
- Address: ${wallet.getAddress()}
- Public Key: ${wallet.getPublicKey()}
- Private Key: ${wallet.getPrivateKey()}
- `;
-
- this.result.innerHTML = info;
- this.result.style.display = "flex";
- }
-
- private showError(message: string): void {
- this.result.innerHTML = `${message}
`;
- this.result.style.display = "flex";
- }
-}
diff --git a/packages/kos-web/demo/src/index.js b/packages/kos-web/demo/src/index.js
new file mode 100644
index 00000000..10784ce9
--- /dev/null
+++ b/packages/kos-web/demo/src/index.js
@@ -0,0 +1,92 @@
+import {
+ Wallet,
+ PathOptions,
+ TransactionChainOptions
+} from '@klever/kos-web';
+
+function main() {
+ try {
+ const chainID = 18; // BCH
+
+ const pathOptions = PathOptions.new(0);
+ pathOptions.setLegacy(false);
+
+ const mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
+
+ const account = Wallet.fromMnemonicIndex(
+ chainID,
+ mnemonic,
+ pathOptions,
+ null,
+ null
+ );
+
+ console.log("Address:", account.getAddress());
+ console.log("Public Key:", account.getPublicKey());
+
+ const rawTx = "0100000002afa8838dbaa03cd3e4fee38bdcb6a428965559ae941dca5a8f91999cfd6d8b0d0100000000ffffffffdb6d60d4a93a95738e72f641bcdd166c94f6e1f439dfe695e40583997284463c0100000000ffffffff0240420f00000000001976a91434bf902df5d66f0e9b89d0f83fbcad638ad19ae988acea970700000000001976a9145bb0ba5ba58cdab459f27f2d29f40e1dd5db238188ac00000000";
+
+ // Convert hex to base64 for JavaScript binding
+ const hexToBase64 = (hex) => {
+ const bytes = new Uint8Array(hex.length / 2);
+ for (let i = 0; i < hex.length; i += 2) {
+ bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
+ }
+ return btoa(String.fromCharCode(...bytes));
+ };
+
+ const prevScript1 = hexToBase64("76a9145bb0ba5ba58cdab459f27f2d29f40e1dd5db238188ac");
+ const prevScript2 = hexToBase64("76a9145bb0ba5ba58cdab459f27f2d29f40e1dd5db238188ac");
+
+ const inputAmounts = new BigUint64Array([498870n, 1001016n]);
+ const prevScripts = [prevScript1, prevScript2];
+
+ const options = TransactionChainOptions.newBitcoinSignOptions(
+ inputAmounts,
+ prevScripts
+ );
+
+
+ // Convert raw transaction hex string to bytes using custom hex decoder
+ const hexToUint8Array = (hex) => {
+ const bytes = new Uint8Array(hex.length / 2);
+ for (let i = 0; i < hex.length; i += 2) {
+ bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
+ }
+ return bytes;
+ };
+
+ const uint8ArrayToHex = (bytes) => {
+ return Array.from(bytes)
+ .map(b => b.toString(16).padStart(2, '0'))
+ .join('');
+ };
+
+ const rawTxBytes = hexToUint8Array(rawTx);
+
+ const transaction = account.sign(rawTxBytes, options);
+
+ const signedRawBytes = transaction.getRawData();
+ const signedRaw = uint8ArrayToHex(signedRawBytes);
+
+ const expectedRaw = "0100000002afa8838dbaa03cd3e4fee38bdcb6a428965559ae941dca5a8f91999cfd6d8b0d010000006b48304502210099626d28374fa3d1a0034330fee7745ab02db07cd37649e6d3ffbe046ff92e9402203793bee2372ab59a05b45188c2bace3b48e73209a01e4d5d862925971632c80a412102bbe7dbcdf8b2261530a867df7180b17a90b482f74f2736b8a30d3f756e42e217ffffffffdb6d60d4a93a95738e72f641bcdd166c94f6e1f439dfe695e40583997284463c010000006a4730440220447084aae4c6800db7c86b8bc8da675e464991a035b2b4010cde48b64a1013a10220582acfb5265c22eae9c2880e07ae66fc86cbef2e97a2ca1bc513535ba322360d412102bbe7dbcdf8b2261530a867df7180b17a90b482f74f2736b8a30d3f756e42e217ffffffff0240420f00000000001976a91434bf902df5d66f0e9b89d0f83fbcad638ad19ae988acea970700000000001976a9145bb0ba5ba58cdab459f27f2d29f40e1dd5db238188ac00000000";
+
+ if (signedRaw !== expectedRaw) {
+ throw new Error(
+ `Signed transaction mismatch.\nExpected: ${expectedRaw}\nGot: ${signedRaw}`
+ );
+ }
+
+ console.log("\nTransaction signed correctly!");
+
+ console.log("\nSigned raw transaction:");
+ console.log(signedRaw + "\n");
+ } catch (error) {
+ const err = error instanceof Error ? error : new Error(String(error));
+ console.error("Error:", err.message);
+ console.error("Stack:", err.stack);
+ process.exitCode = 1;
+ }
+}
+
+main();
\ No newline at end of file
diff --git a/packages/kos-web/demo/src/main.ts b/packages/kos-web/demo/src/main.ts
deleted file mode 100644
index 10bcbd47..00000000
--- a/packages/kos-web/demo/src/main.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { CryptographyDemo } from "./components/cryptography-demo";
-import { TransactionSigner } from "./components/transaction-signer";
-import { WalletGenerator } from "./components/wallet-generator";
-import "./style.css";
-
-// Initialize components
-try {
- console.log("starting");
- new WalletGenerator("wallet-generator");
- new TransactionSigner("transaction-signer");
- new CryptographyDemo("cryptography-demo");
-} catch (error) {
- console.error("Error initializing the demonstration:", error);
-}
diff --git a/packages/kos-web/demo/src/package.json b/packages/kos-web/demo/src/package.json
new file mode 100644
index 00000000..c6d073e5
--- /dev/null
+++ b/packages/kos-web/demo/src/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "kos-web-demo",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "node index.js",
+ "dev": "node index.js"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "MIT",
+ "type": "module",
+ "dependencies": {
+ "@klever/kos-web": "^0.2.41"
+ }
+}
diff --git a/packages/kos-web/demo/src/style.css b/packages/kos-web/demo/src/style.css
deleted file mode 100644
index 7137b9ea..00000000
--- a/packages/kos-web/demo/src/style.css
+++ /dev/null
@@ -1,107 +0,0 @@
-:root {
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
- line-height: 1.5;
- font-weight: 400;
-
- color-scheme: light dark;
-
- font-synthesis: none;
- text-rendering: optimizeLegibility;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-body {
- margin: 0;
- display: flex;
- min-width: 320px;
- min-height: 100vh;
-}
-
-.container {
- max-width: 1200px;
- margin: 0 auto;
- padding: 2rem;
- width: 100%;
-}
-
-h1 {
- font-size: 2.5rem;
- line-height: 1.1;
- text-align: center;
- margin-bottom: 2rem;
-}
-
-.card {
- padding: 1.5rem;
- border-radius: 8px;
- background-color: #1a1a1a;
- margin-bottom: 1.5rem;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
-}
-
-h2 {
- margin-top: 0;
- margin-bottom: 1rem;
-}
-
-button {
- padding: 0.6em 1.2em;
- cursor: pointer;
-}
-
-button:focus,
-button:focus-visible {
- outline: 4px auto -webkit-focus-ring-color;
-}
-
-input,
-select,
-textarea {
- border-radius: 4px;
- padding: 0.5rem;
- margin-bottom: 1rem;
- background-color: #2a2a2a;
- border: 1px solid #3a3a3a;
- color: white;
- width: 100%;
-}
-
-.form-group {
- margin-bottom: 1rem;
-}
-
-.form-group label {
- display: block;
- margin-bottom: 0.5rem;
-}
-
-.result {
- display: flex;
- flex-direction: column;
- padding: 1rem;
- margin-top: 1rem;
- overflow-wrap: break-word;
- white-space: pre-wrap;
-}
-
-.error {
- color: #ff6b6b;
- font-size: 0.9rem;
- margin-top: 0.5rem;
-}
-
-.success {
- color: #4caf50;
- font-size: 0.9rem;
- margin-top: 0.5rem;
-}
-
-@media (prefers-color-scheme: light) {
- input,
- select,
- textarea {
- border: 1px solid #ddd;
- color: #213547;
- }
-}
diff --git a/packages/kos-web/demo/src/vite-env.d.ts b/packages/kos-web/demo/src/vite-env.d.ts
deleted file mode 100644
index 11f02fe2..00000000
--- a/packages/kos-web/demo/src/vite-env.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-///
diff --git a/packages/kos-web/demo/tsconfig.json b/packages/kos-web/demo/tsconfig.json
deleted file mode 100644
index a4883f28..00000000
--- a/packages/kos-web/demo/tsconfig.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "compilerOptions": {
- "target": "ES2020",
- "useDefineForClassFields": true,
- "module": "ESNext",
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
- "skipLibCheck": true,
-
- /* Bundler mode */
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "isolatedModules": true,
- "moduleDetection": "force",
- "noEmit": true,
-
- /* Linting */
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true,
- "noUncheckedSideEffectImports": true
- },
- "include": ["src"]
-}
diff --git a/packages/kos-web/demo/vite.config.ts b/packages/kos-web/demo/vite.config.ts
deleted file mode 100644
index eb74f2c9..00000000
--- a/packages/kos-web/demo/vite.config.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { defineConfig } from "vite";
-import wasm from "vite-plugin-wasm";
-
-export default defineConfig({
- plugins: [wasm()],
-});