{"_id":"@didux-io/commons-js-web","_rev":"1-a49ff722bac53d3106f80569a375c767","name":"@didux-io/commons-js-web","dist-tags":{"latest":"0.0.1"},"versions":{"0.0.1":{"name":"@didux-io/commons-js-web","version":"0.0.1","description":"Common set of Javascript functionality for the Didux.io Platform.","main":"diduxio-web.js","author":{"name":"DiduxIo"},"license":"Apache-2.0","typings":"diduxio-web.d.ts","private":false,"keywords":["diduxio","blockchain","merkle","lamport"],"_id":"@didux-io/commons-js-web@0.0.1","_nodeVersion":"14.15.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-ufbx1BphGRrsk1M33siUZjrsB0dJqz2jKC27o9YrGgQThUJypJ79kyD5taOrs+eCSeTHhWtwXhgKEDXzKk1RbA==","shasum":"7aaab8fa1c5543b1461abc56553ca5a7dca1ba6d","tarball":"https://registry.npmjs.org/@didux-io/commons-js-web/-/commons-js-web-0.0.1.tgz","fileCount":14,"unpackedSize":10013172,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoSEkCRA9TVsSAnZWagAAcIcP+gIy5Lo0E+nRSZMPMH+d\n1ATE+MwJMOv+S4wXFX2/46q+quRvo6nYSQssBpS3GFgqlndfzso1+EnMHlAT\n4+S6gPfLtisK9tM0enLNN5ACisNYXVRXQPR9XN7pYwjlgJTnpx1mlB8ZJfPr\n1K0vrbmOkjWSooUYib+Bc+pIbdUprm+68/qV4LqG4Wxf9n7PuiKqlPGXuH7g\n1l8ivijFalCQgpsJEIeIXcKiaRhOs5IEPHsLkUk96yrJC7OTOMBXVfGIM6Gr\nv3xkctOqf0GUQ/vXjWd5/ODBLx1S9xPOstnZPaXCtAizY/VVT/RMnlPeBdI6\n2GKqTD5CkSJ7mfa3PFZOOB+veBihj3Oe/78vc8oTH1NMzCCB9nEmEvuERBhr\nMAPPxFc/lLkwOZIvfGFzk19shhVc3oSxJgutvf9jkCW2pfMtsrL7v/lIbggN\n4RLXGgHqJ0v0UJO/dKv4IbB9uWh9X/uOgdvIyoqxW6oRTL6Soo8iCPL/xn8a\niT0dzR5S79RT1WOh0zebOK4+c/zVman+h49rnjsPMNwVctA2vNyKAwpcXMCH\nggMhgjzcrwIDJcbagWCRvf3sURKDb7vhqMa5uiJkKFcTFRGrgmBVmUNeQ1q1\n/h14sdQ2tIa9bB1n1Eq+u2zuMQseBx2Kk5iOkmvvtHMw8j/N8T4PXzH8GNAz\nAXRX\r\n=l0YZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCaUpaiJSgmenryBCdknZqj6F2fPIq3LjmDQdAHvEu+kQIgNu00ESEgWWjxs5Y5ltb9DBmK42ohPklAyzUy6kA6/Zg="}]},"maintainers":[{"name":"elkan","email":"info@smilo.io"},{"name":"danielsmilo","email":"daniel@smilo.io"}],"_npmUser":{"name":"danielsmilo","email":"daniel@smilo.io"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/commons-js-web_0.0.1_1604395299722_0.6541990677842537"},"_hasShrinkwrap":false}},"time":{"created":"2020-11-03T09:21:39.518Z","0.0.1":"2020-11-03T09:21:40.005Z","modified":"2022-04-05T04:23:48.843Z"},"maintainers":[{"name":"elkan","email":"info@smilo.io"},{"name":"danielsmilo","email":"daniel@smilo.io"}],"description":"Common set of Javascript functionality for the Didux.io Platform.","keywords":["diduxio","blockchain","merkle","lamport"],"author":{"name":"DiduxIo"},"license":"Apache-2.0","readme":"# DiduxIo Commons JS for Web\n\nThe DiduxIo Commons JS library contains several building blocks to make it easier for developers to integrate with the Didux Blockchain in a Javascript environment.\n\n## Installation\n\nYou can install this package with NPM:\n\n```\nnpm install @didux-io/commons-js-web\n```\n\nNext make sure the file 'diduxio-web.js' is loaded in your web page.\n\n## A note about UglifyJS\n\nThis library does not play nicely with the `typeofs` compress option of [UglifyJS](https://www.npmjs.com/package/uglify-js).\n\nWhen this compression option is enabled an error will be thrown when generating a Merkle Tree.\n\nIf you are using UglifyJS either do not uglify/compress this library or disable this option.\n\nA minimal working configuration file for UglifyJS could look like this:\n\n```\n{\n    \"compress\": {\n        \"typeofs\": false\n    }\n}\n```\n\n## Examples\n\nBelow you will find several examples on how to use the most common functionality of the library. As part of this library we also provide a Typescript definitions file ('diduxio-*.d.ts') with a more detailed description of each part of this library.\n\n#### Generating\n\nTo generate a new Merkle Tree you must use the `MerkleTreeBuilder` class.\n\n```\nvar builder = new DiduxIo.MerkleTreeBuilder();\n\nvar privateKey = \"PRIVATE_KEY\";\nvar layerCount = 14;\n\nbuilder.generate(\n    privateKey, \n    layerCount, \n    function(progress) {\n        var progressPercentage = Math.round(progress * 100);\n\n        console.log(`Progress = ${ progressPercentage }%`);\n    }\n).then(\n    function(merkleTree) {\n        // Merkle Tree generated!\n    },\n    function(error) {\n        // Something went wrong...\n        console.error(error);\n    }\n);\n```\n\nFor web environments [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) will be used to efficiently generate the layers of the Merkle Tree. Node environments will use [child processes](https://nodejs.org/api/child_process.html) to achieve the same effect.\n\n#### Write to storage\n\nThe `MerkleTreeBuilder` is only responsible for creating a Merkle Tree. It is not responsible for storing a Merkle Tree. \n\nTo serialize and deserialize a Merkle Tree you can use the `MerkleTreeSerializer` class.\n\nThis class requires a storage manager responsible for the actual writing and reading from whatever storage device you require.\n\nA storage manager is defined, in Typescript, as shown below:\n\n```\ninterface IStorageManager {\n    /**\n     * Reads the content of a file as text.\n     */\n    read(path: string): Promise<string>;\n    /**\n     * Writes the given text data to the given path.\n     */\n    write(path: string, data: string): Promise<void>;\n\n    /**\n     * Reads the content of a file and parses it as JSON.\n     * A Javascript object will be returned.\n     */\n    readJSON<T>(path: string): Promise<T>;\n    /**\n     * Writes the given Javascript object as JSON to the given path.\n     */\n    writeJSON(path: string, data: any): Promise<void>;\n\n    /**\n     * Removes the data at the given path from storage.\n     */\n    remove(path: string): Promise<void>;\n}\n```\n\nA simple storage manager writing to local storage could then look like this:\n\n```\nfunction LocalStorageManager() {\n    this.read = function(path) {\n        var data = localStorage.getItem(path);\n\n        return Promise.resolve(data);\n    }    \n    this.write = function(path, data) {\n        localStorage.setItem(path, data);\n\n        return Promise.resolve();\n    }\n\n    this.readJSON = function(path) {\n        return this.read(path).then(\n            function(data){ \n                return JSON.parse(data);\n            }\n        );\n    }\n    this.writeJSON = function(path, data) {\n        return this.write(path, JSON.stringify(data));\n    }\n\n    this.remove = function(path) {\n        localStorage.removeItem(path);\n\n        return Promise.resolve();\n    }\n}\n```\n\nThe storage manager will be passed a fully encrypted Merkle Tree.\n\nTo serialize a Merkle Tree you could do this:\n\n```\n// We use the LocalStorageManager described above.\nvar storageManager = new LocalStorageManager();\nvar serializer = new DiduxIo.MerkleTreeSerializer(storageManager);\nvar merkleTree = ...;\n\nserializer.serialize(merkleTree).then(\n    function() {\n        // Merkle Tree was written to storage.\n    },\n    function(error) {\n        // Failed to write Merkle Tree to storage.\n    }\n);\n```\n\nTo deserialize a Merkle Tree you could do this:\n\n```\n// We use the LocalStorageManager described above.\nvar storageManager = new LocalStorageManager();\nvar serializer = new DiduxIo.MerkleTreeSerializer(storageManager);\n\nserializer.serialize(\"path/to/merkle/tree\").then(\n    function(merkleTree) {\n        // Merkle tree was read from storage.\n    },\n    function(error) {\n        // Something went wrong reading the Merkle Tree.\n    }\n);\n```\n\nTo clean a Merkle Tree from storage you could do this:\n\n```\n// We use the LocalStorageManager described above.\nvar storageManager = new LocalStorageManager();\nvar serializer = new DiduxIo.MerkleTreeSerializer(storageManager);\n\nserializer.clean(\"path/to/merkle/tree\").then(\n    function() {\n        // Merkle tree was cleaned from storage\n    },\n    function(error) {\n        // Something went wrong cleaning the Merkle Tree from storage\n    }\n);\n```\n### Signatures\n\nEvery transaction on the Didux.io Blockchain has to be cryptographically signed with a valid Lamport signature. Because a Lamport private key, used to create a Lamport signature, should only ever be used once we use a Merkle Tree to easily provide many private keys derived from a single root key.\n\nTo sign a message you therefore need a Merkle Tree. You also need to provide a signature index which specifies which private key in the Merkle Tree should be used. The DiduxIo Commons JS library does __not__ track which index has been used and/or is available.\n\n#### Sign a message\n\nTo sign a message use the `MerkleLamportSigner` class.\n\n```\nvar signer = new DiduxIo.MerkleLamportSigner();\n\nvar merkleTree = ...;           // Your Merkle Tree\nvar data = \"Hello World\";       // Data you want to sign\nvar privateKey = \"PRIVATE_KEY\"; // Private key used to generate the Merkle Tree\nvar signatureIndex = 0;         // Merkle Tree leaf index\n\nvar signature = signer.getSignature(merkleTree, data, privateKey, signatureIndex);\n```\n\nThe signature is a string combining the signature and the authentication path. The authentication path is used when other people want to verify the signature.\n\n#### Verify a signature\n\nTo verify a message signature use the `MerkleLamportVerifier` class.\n\n```\nvar verifier = new DiduxIo.MerkleLamportVerifier();\n\nvar data = \"Hello World\";       // The message\nvar signature = ...;            // The signature part of the message\nvar signatureIndex = 0;         // The Merkle tree leaf index used to sign this message\nvar layerCount = 14;            // The amount of layers of the Merkle Tree\nvar expectedRootAddress = ...;  // The expected root address e.g. public key\n\nif(verifier.verifyMerkleSignature(data, signature, signatureIndex, layerCount, expectedRootAddress)) {\n    // Valid signature\n}\nelse {\n    // Invalid signature\n}\n```\n\n### Transactions\n\nThe below example demonstrates how to create and sign a transaction. Next you could send this transaction to the blockchain for processing.\n\nNote how we use the `TransactionHelper` class. This class contains several methods which help when creating a transaction.\n\n```\n// Create the base of the transaction\nvar transaction = {\n    timestamp: Date().now(),\n    inputAddress: \"FROM_ADDRESS\",                               // The address we are sending from.\n    fee: new DiduxIo.FixedBigNumber(0, 0),                       // The fee for the miners.\n    assetId: \"000x0123\",                                        // The asset we are sending.\n    inputAmount: new DiduxIo.FixedBigNumber(100, 0),             // The amount of the asset we want to send.\n    transactionOutputs: [\n        {\n            outputAddress: \"TO_ADDRESS\",                        // The address we are sending to.\n            outputAmount: new DiduxIo.FixedBigNumber(100, 0)     // The amount of we are sending to this address.\n        }\n    ]\n};\n\n// Compute data hash for transaction\nvar transactionHelper = new DiduxIo.TransactionHelper();\ntransaction.dataHash = transactionHelper.getDataHash(transaction);\n\n// Sign transaction\nvar signer = new DiduxIo.MerkleLamportSigner();\n\nvar merkleTree = ...;           // Your Merkle Tree\nvar privateKey = \"PRIVATE_KEY\"; // Private key used to generate the Merkle Tree\nvar signatureIndex = 0;         // Merkle Tree leaf index\n\ntransaction.signatureData = signer.getSignature(merkleTree, transactionHelper.transactionToString(transaction), privateKey, signatureIndex);\ntransaction.signatureIndex = signatureIndex;\n```\n\nYou can also add input data to a transaction. This data will be used by smart contracts. This input data must be formatted correctly as shown in the example below.\n\n```\nvar transaction = {...};\nvar transactionHelper = new DiduxIo.TransactionHelper();\n\ntransaction.inputData = transactionHelper.formatInputData(\"Your input data goes here\");\n```\n\n### Big Number\n\nBecause Javascript numbers are not precise enough to accurately describe all transaction amounts on the Didux blockchain we use big numbers instead.\n\nThese numbers are defined with two parameters. The initial value and the amount of decimals.\n\nWe have defined the `FixedBigNumber` class to easily deal with big numbers.\n\n### Defining big numbers\n\nTo define a `FixedBigNumber` you need to pass an initial value and the amount of decimals.\n\n__100 Didux__\n\nDidux does not support fractional numbers. Therefore we set the amount of decimals to 0. Values like 0.1 can therefore never be defined.\n\n```\nvar amount = new DiduxIo.FixedBigNumber(100, 0);\n```\n\n__100 DiduxPay__\n\nDiduxPay does support fractional numbers up to 18 decimals.\n\n```\nvar amount = new DiduxIo.FixedBigNumber(100, 18);\n```\n\n### Comparing big numbers\n\nBig numbers can be compared against each other:\n\n```\nvar bn1 = new DiduxIo.FixedBigNumber(100, 18);\nvar bn2 = new DiduxIo.FixedBigNumber(200, 18);\n\n// ==\nbn1.eq(bn2);    // false\n\n// >\nbn1.gt(bn2);    // false\n\n// >=\nbn1.gte(bn2);   // false\n\n// <\nbn1.lt(bn2);    // true\n\n// <=\nbn1.lte(bn2);   // true\n```\n\nYou can also mix `FixedBigNumbers` with Javascript numbers or strings:\n\n```\nvar bn1 = new DiduxIo.FixedBigNumber(100, 18);\n\nbn1.eq(100);    // true\n\nbn1.lte(\"90\");  // false\n```\n\n### Doing math on big numbers\n\nBasic mathematical operations can be performed on big numbers. The decimal count of the big number you call these methods on are preserved. For example if you multiply a `FixedBigNumber` with 10 decimals with another `FixedBigNumber` with 20 decimals the resulting `FixedBigNumber` will have 10 decimals.\n\n```\nvar bn1 = new DiduxIo.FixedBigNumber(100, 18);\nvar bn2 = new DiduxIo.FixedBigNumber(200, 18);\n\n// Multiply\nbn1.mul(bn2);\n\n// Divide\nbn1.div(bn2);\n\n// Add\nbn1.add(bn2);\n\n// Subtract\nbn1.sub(bn2);\n```\n\nThese operations return a new `FixedBigNumber` so the original operand remain unaltered. This also allows for chaining function calls:\n\n```\nvar bn1 = new DiduxIo.FixedBigNumber(100, 18);\nvar bn2 = new DiduxIo.FixedBigNumber(200, 18);\nvar bn3 = new DiduxIo.FixedBigNumber(300, 18);\n\n// (bn1 + bn2) * bn3;\nbn1.add(bn2).mul(bn3);\n```\n\nYou can also mix `FixedBigNumbers` with Javascript numbers or strings:\n\n```\nvar bn1 = new DiduxIo.FixedBigNumber(100, 18);\n\nbn1.add(10);\n\nbn1.mul(\"100\");\n```\n\n### BIP39\n\nThe BIP39 standard can be used to generate mnemonic phrases which serve as a base for a private key seed.\n\nThe DiduxIo Commons JS has integrated support for BIP39.\n\nThe example below shows how to generate a mnemonic phrase.\n\n```\nvar bip39 = new DiduxIo.BIP39();\n\nvar mnemonicPhrase = bip39.generate(256);\n```\n\nTo generate a phrase a strength in bits must be given. This number will determine how many words are generated. You cannot however just enter any number.\n\nFor reference the following parameters generate X amount of words:\n- 128 bits = 12 words\n- 160 bits = 15 words\n- 192 bits = 18 words\n- 224 bits = 21 words\n- 256 bits = 24 words\n\nGiven a mnemonic passphrase you can also validate its correctness:\n\n```\nvar bip39 = new DiduxIo.BIP39();\n\nvar phrase = ...;\n\nvar result = bip39.check(phrase);\nif(result.isValid) {\n    // Phrase is valid\n}\nelse if(!result.isBlocking) {\n    // Phrase might not be valid\n    // This happens when the checksum is invalid\n    // At the very least we can say the phrase was not \n    // generated by this library. It can still be used\n    // to generate a seed though.\n}\nelse {\n    // Phrase is certainly not valid\n    // This can mean:\n    // - The phrase has an invalid size\n    // - The phrase contains an unrecognized word\n    // Check result.errorMessage for more info\n}\n```\n\nTo convert the phrase to a seed ready for a random number generator do:\n\n```\nvar bip39 = new DiduxIo.BIP39();\n\nvar phrase = ...;\n\n// Seed without passphrase\nvar seed = bip39.toSeed(phrase);\n\n// Seed with extra passphrase\nvar seedWithPassphrase = bip39.toSeed(phrase, \"PASSPHRASE\");\n```\n\nThe generated seed can then be used to generate a private key (see chapter `BIP32`).\n\n### BIP32\n\nThe BIP32 standard is used to generate a private key from a seed. The DiduxIo Commons JS library combines BIP32 with BIP44.\n\nTo generate a private key do:\n\n```\nvar bip32 = new DiduxIo.BIP32();\n\nvar privateKey = bip32.getPrivateKey(\"SOME_RANDOM_SEED\");\n```\n\nThis will generate a private key using the BIP32 path `m/44'/0x1991'/0'/0/0`.\n\nYou can change the coin type and index:\n\n```\nvar bip32 = new DiduxIo.BIP32();\n\nvar coinType = ...;\nvar index = ...;\n\nvar privateKey = bip32.getPrivateKey(\"SOME_RANDOM_SEED\", coinType, index);\n```\n","readmeFilename":"README.md"}