@mybucks.online/core 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,14 @@
1
1
  # @mybucks.online/core
2
2
 
3
- This is a core part of [mybucks.online](https://mybucks.online) crypto wallet, involving hashing and private key generation.
3
+ This is a core part of [mybucks.online](https://mybucks.online) crypto wallet, involving hash and private key generation, generate and parse transfer-link token.
4
4
 
5
5
  ## mybucks.online
6
6
 
7
- [Mybucks.online](https://mybucks.online) is a **password-only, self-custodial and browser-based cryptocurrency wallet** built with Javascript. It generates a private key from your password and passcode using an industry-standard, verified **one-way hash function**. Your private key forms your account, allowing you to transfer, receive, and hold your crypto assets permanently.
7
+ [Mybucks.online](https://mybucks.online) is a **password-only, self-custodial and browser-based cryptocurrency wallet** built with Javascript. It generates a private key from your password and passcode using an industry-standard, verified **one-way hash function**. Your private key forms your account, allowing you to transfer, receive, and hold your crypto assets instantly.
8
+
9
+ As a hash function, the **scrypt** Key Derivation Function (KDF) increases the computational effort required to crack passwords, effectively delaying **brute-force** attacks and making them impractical.
10
+
11
+ It fully runs on your **browser side** without using any storage or invoking any 3rd-party APIs for key management. It instantly generates your private key from your password input, and whenever you close or refresh, there is no footprint. This absolutely protects your privacy.
8
12
 
9
13
  ## Quick start
10
14
 
@@ -29,6 +33,21 @@ const privateKey = getEvmPrivateKey(hash);
29
33
  console.log("Private key: ", privateKey);
30
34
  ```
31
35
 
36
+ ### 3. Generate and parse (transfer-link's)token
37
+ ```javascript
38
+ import { generateToken } from "@mybucks.online/core";
39
+ const token = generateToken(password, passcode, network);
40
+
41
+ console.log("https://app.mybucks.online?wallet=" + token);
42
+ ```
43
+
44
+ ```javascript
45
+ import { parseToken } from "@mybucks.online/core";
46
+ const [password, passcode, network] = parseToken(token);
47
+ console.log("Account credentials are: ", password, passcode);
48
+ console.log("Network: ", network);
49
+ ```
50
+
32
51
  ## Test
33
52
  ```bash
34
53
  npm run test
@@ -42,3 +61,4 @@ Find the docs [here](https://docs.mybucks.online).
42
61
 
43
62
  - https://github.com/mybucks.online/app
44
63
  - https://app.mybucks.online
64
+ - https://app.mybucks.online/?wallet=VWnsSGRGVtb0FjY291bnQ1JgIxMTIzMjQCb3B0aW1pc20=_wNovT
package/index.js CHANGED
@@ -1,14 +1,11 @@
1
- const { Buffer } = require("buffer");
2
- const { ethers } = require("ethers");
3
- const { scrypt } = require("scrypt-js");
1
+ import { Buffer } from "buffer";
2
+ import { ethers } from "ethers";
3
+ import scryptJS from "scrypt-js";
4
+ import { nanoid } from "nanoid";
4
5
 
6
+ const { scrypt } = scryptJS;
5
7
  const abi = new ethers.AbiCoder();
6
8
 
7
- /**
8
- * [CRITICAL] DON'T CHANGE FOREVER!!!
9
- * Reference:
10
- * https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#scrypt
11
- */
12
9
  const HASH_OPTIONS = {
13
10
  N: 32768, // CPU/memory cost parameter, 2^15
14
11
  r: 8, // block size parameter
@@ -24,7 +21,7 @@ const HASH_OPTIONS = {
24
21
  * @param {*} cb a callback function designed to receive the progress updates during the scrypt hashing process.
25
22
  * @returns hash result as string format
26
23
  */
27
- async function generateHash(password, passcode, cb = () => {}) {
24
+ export async function generateHash(password, passcode, cb = () => {}) {
28
25
  if (!password || !passcode) {
29
26
  return "";
30
27
  }
@@ -52,11 +49,53 @@ async function generateHash(password, passcode, cb = () => {}) {
52
49
  * @param {*} hash
53
50
  * @returns private key as string format
54
51
  */
55
- function getEvmPrivateKey(hash) {
52
+ export function getEvmPrivateKey(hash) {
56
53
  return ethers.keccak256(abi.encode(["string"], [hash]));
57
54
  }
58
55
 
59
- module.exports = {
60
- generateHash,
61
- getEvmPrivateKey,
62
- };
56
+ const URL_DELIMITER = "\u0002";
57
+ const NETWORKS = [
58
+ "ethereum",
59
+ "polygon",
60
+ "arbitrum",
61
+ "optimism",
62
+ "bsc",
63
+ "avalanche",
64
+ "tron",
65
+ ];
66
+ /**
67
+ * This function generates a transfer-link by combining credentials and randomly generated padding.
68
+ * The transfer-link introduces a nice feature that enables the transfer of full ownership of a wallet account.
69
+ * @param {*} password
70
+ * @param {*} passcode
71
+ * @param {*} network ethereum | polygon | arbitrum | optimism | bsc | avalanche | tron
72
+ * @returns A string formatted as a transfer-link token, which can be appended to `https://app.mybucks.online?wallet=`
73
+ */
74
+ export function generateToken(password, passcode, network) {
75
+ if (!password || !passcode || !network) {
76
+ return null;
77
+ }
78
+ if (!NETWORKS.find((n) => n === network)) {
79
+ return null;
80
+ }
81
+
82
+ const merged = Buffer.from(
83
+ password + URL_DELIMITER + passcode + URL_DELIMITER + network,
84
+ "utf-8"
85
+ );
86
+ const base64Encoded = merged.toString("base64");
87
+ const padding = nanoid(12);
88
+ return padding.slice(0, 6) + base64Encoded + padding.slice(6);
89
+ }
90
+
91
+ /**
92
+ * This function parses a transfer-link token generated by generateToken().
93
+ * @param {*} token
94
+ * @returns an array of strings, including the password, passcode and network.
95
+ */
96
+ export function parseToken(token) {
97
+ const payload = token.slice(6, token.length - 6);
98
+ const base64Decoded = Buffer.from(payload, "base64").toString("utf-8");
99
+ const [password, passcode, network] = base64Decoded.split(URL_DELIMITER);
100
+ return [password, passcode, network];
101
+ }
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@mybucks.online/core",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Core module for mybucks.online crypto wallet",
5
5
  "main": "index.js",
6
+ "type": "module",
6
7
  "scripts": {
7
8
  "test": "node test/index.test.js"
8
9
  },
@@ -19,7 +20,11 @@
19
20
  "browser-based",
20
21
  "ethereum",
21
22
  "tron",
22
- "open-source"
23
+ "scrypt",
24
+ "keccak256",
25
+ "key-generation",
26
+ "open-source",
27
+ "mybucks.online"
23
28
  ],
24
29
  "author": "koko37",
25
30
  "license": "MIT",
@@ -30,6 +35,7 @@
30
35
  "dependencies": {
31
36
  "buffer": "^6.0.3",
32
37
  "ethers": "^6.13.5",
38
+ "nanoid": "^5.0.9",
33
39
  "scrypt-js": "^3.0.1"
34
40
  }
35
41
  }
@@ -1,13 +1,21 @@
1
- const assert = require("node:assert");
2
- const { describe, test } = require("node:test");
3
- const { generateHash, getEvmPrivateKey } = require("../index.js");
1
+ import assert from "node:assert";
2
+ import { describe, test } from "node:test";
3
+ import {
4
+ generateHash,
5
+ getEvmPrivateKey,
6
+ generateToken,
7
+ parseToken,
8
+ } from "../index.js";
4
9
 
5
10
  const DEMO_PASSWORD = "DemoAccount5&";
6
11
  const DEMO_PASSCODE = "112324";
12
+ const DEMO_NETWORK = "optimism";
7
13
  const DEMO_HASH =
8
14
  "af9a22d75f8f69d33fe8fc294e8f413219d9c75374dec07fda2e4a66868599609887a10e04981e17356d2c07432fc89c11089172fdf91c0015b9a4beef11e447";
9
15
  const DEMO_PRIVATE_KEY =
10
16
  "0x71743de900c63ed741263a2a4513c1b1829e80bd9f18d5d3a593e651b914cb3b";
17
+ const DEMO_TOKEN =
18
+ "VWnsSGRGVtb0FjY291bnQ1JgIxMTIzMjQCb3B0aW1pc20=_wNovT";
11
19
 
12
20
  describe("generateHash", () => {
13
21
  test("should return empty string if password or passcode is blank", async () => {
@@ -29,3 +37,37 @@ describe("getEvmPrivateKey", () => {
29
37
  assert.strictEqual(privateKey, DEMO_PRIVATE_KEY);
30
38
  });
31
39
  });
40
+
41
+ describe("generateToken", () => {
42
+ test("should return null if password, passcode or network is invalid", async () => {
43
+ assert.strictEqual(generateToken("", "123345", "ethereum"), null);
44
+ assert.strictEqual(generateToken("", "123345"), null);
45
+ assert.strictEqual(generateToken("password", "", "ethereum"), null);
46
+ assert.strictEqual(generateToken("password", "123456", ""), null);
47
+ assert.strictEqual(generateToken("password", "123456", "invalid"), null);
48
+ });
49
+ });
50
+
51
+ describe("parseToken", () => {
52
+ test("should return array of password, passcode, and network", () => {
53
+ const [password, passcode, network] = parseToken(DEMO_TOKEN);
54
+
55
+ assert.strictEqual(password, DEMO_PASSWORD);
56
+ assert.strictEqual(passcode, DEMO_PASSCODE);
57
+ assert.strictEqual(network, DEMO_NETWORK);
58
+ });
59
+ });
60
+
61
+ describe("generateToken and parseToken", () => {
62
+ test("should be compatible and return correct result", () => {
63
+ const testPassword = "random^Password9";
64
+ const testPasscode = "909011";
65
+ const testNetwork = "polygon";
66
+ const token = generateToken(testPassword, testPasscode, testNetwork);
67
+
68
+ const [password, passcode, network] = parseToken(token);
69
+ assert.strictEqual(password, testPassword);
70
+ assert.strictEqual(passcode, testPasscode);
71
+ assert.strictEqual(network, testNetwork);
72
+ });
73
+ });