mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-19 19:55:51 +00:00
feat: add xrpl-secret-numbers to the monorepo (#2445)
- Add `xrpl-secret-numbers` by @WietseWind to the mono repo. - `unpkg` and `jsdelivr` support was simplified by adding fields to package.json. - Unit tests run in a browser and node. BREAKING CHANGES: - `xrpl-secret-numbers` is now `@xrplf/secret-numbers`. - Changed the bundled file produced changed from `dist/browerified.js` to `build/xrplf-secret-numbers-latest.js`. - Bundle variable is `xrplf_secret_numbers` instead of using browserify's loader. - If using CDN instructions in README will need to update to `https://cdn.jsdelivr.net/npm/@xrplf/secret-numbers` Making this library part of the monorepo was discussed in #1788. This solves several problems with the upcoming `xrpl.js@3.0`. `xrpl-secret-numbers` has a dependency of `ripple-keypairs` and `xrpl` has a depenendecy on `xrpl-secret-numbers`. This means that any change would require a separate release of `ripple-keypairs`, then a release of `xrpl-secret-numbers`, followed by `xrpl`. Now they can be released all at once In 3.0 we eliminated the need for many polyfills like `util`, `assert`, and soon to be `buffer` (after noble libs PR is merged). `xrpl-secret-numbers` still needs those. This will also eliminate them and anytime similar changes in the future will be much easier. This further reduces the bundle size of 3.0 branch by over 10% as well as reducing bundler setup.
This commit is contained in:
99
packages/secret-numbers/test/api.test.ts
Normal file
99
packages/secret-numbers/test/api.test.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import * as keypairs from "ripple-keypairs";
|
||||
|
||||
import { Account, Utils } from "../src";
|
||||
|
||||
describe("API: XRPL Secret Numbers", () => {
|
||||
describe("Generate new account", () => {
|
||||
const account = new Account();
|
||||
it("Output sanity checks", () => {
|
||||
expect(account.getAddress()).toMatch(/^r[a-zA-Z0-9]{19,}$/u);
|
||||
const entropy = Utils.secretToEntropy(`${account.toString()}`.split(" "));
|
||||
const familySeed = keypairs.generateSeed({ entropy });
|
||||
const keypair = keypairs.deriveKeypair(familySeed);
|
||||
const address = keypairs.deriveAddress(keypair.publicKey);
|
||||
expect(address).toEqual(account.getAddress());
|
||||
expect(familySeed).toEqual(account.getFamilySeed());
|
||||
});
|
||||
});
|
||||
|
||||
describe("Account based on entropy", () => {
|
||||
const entropy = Buffer.from("0123456789ABCDEF0123456789ABCDEF", "hex");
|
||||
const account = new Account(entropy);
|
||||
|
||||
it("familySeed as expected", () => {
|
||||
expect(account.getFamilySeed()).toEqual("sp5DmDCut79BpgumfHhvRzdxXYQyU");
|
||||
});
|
||||
it("address as expected", () => {
|
||||
expect(account.getAddress()).toEqual(
|
||||
"rMCcybKHfwCSkDHd3M36PAeUniEoygwjR3"
|
||||
);
|
||||
});
|
||||
it("Account object to string as expected", () => {
|
||||
const accountAsStr =
|
||||
"002913 177673 352434 527196 002910 177672 352435 527190";
|
||||
expect(`${account.toString()}`).toEqual(accountAsStr);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Account based on existing secret", () => {
|
||||
const secret = [
|
||||
"084677",
|
||||
"005323",
|
||||
"580272",
|
||||
"282388",
|
||||
"626800",
|
||||
"105300",
|
||||
"560913",
|
||||
"071783",
|
||||
];
|
||||
|
||||
const account = new Account(secret);
|
||||
|
||||
it("familySeed as expected", () => {
|
||||
expect(account.getFamilySeed()).toEqual("sswpWwri7Y11dNCSmXdphgcoPZk3y");
|
||||
});
|
||||
it("publicKey as expected", () => {
|
||||
const pubkey =
|
||||
"020526A0EDC9123F7FBB7588402518B80FCD2C8D8AB4C45F5A68A2F220098EA06F";
|
||||
expect(account.getKeypair().publicKey).toEqual(pubkey);
|
||||
});
|
||||
it("privateKey as expected", () => {
|
||||
const privkey =
|
||||
"005122B2127B4635FEE7D242FA6EC9B02B611C04494D0D7D49764374D90C8BC8D3";
|
||||
expect(account.getKeypair().privateKey).toEqual(privkey);
|
||||
});
|
||||
it("address as expected", () => {
|
||||
expect(account.getAddress()).toEqual(
|
||||
"rfqJsRLLmr7wdWnEzW1mP6AVaPSdzmso9Z"
|
||||
);
|
||||
});
|
||||
it("Account object to string as expected", () => {
|
||||
const accountAsStr =
|
||||
"084677 005323 580272 282388 626800 105300 560913 071783";
|
||||
expect(`${account.toString()}`).toEqual(accountAsStr);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Checksum error", () => {
|
||||
const secret = [
|
||||
"084677",
|
||||
"005324",
|
||||
"580272",
|
||||
"626800",
|
||||
"282388",
|
||||
"105300",
|
||||
"560913",
|
||||
"071783",
|
||||
];
|
||||
it("Should throw an Checksum Error", () => {
|
||||
expect(() => {
|
||||
// eslint-disable-next-line no-new -- Don't want unused variable
|
||||
new Account(secret);
|
||||
})
|
||||
// TODO: Remove if jest is removed.
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment -- Jest and Jasmine have two different signatures.
|
||||
// @ts-expect-error
|
||||
.toThrowError(Error, "Invalid secret part: checksum invalid");
|
||||
});
|
||||
});
|
||||
});
|
||||
1
packages/secret-numbers/test/index.ts
Normal file
1
packages/secret-numbers/test/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
/* eslint-disable import/unambiguous -- silence is golden */
|
||||
107
packages/secret-numbers/test/utils.test.ts
Normal file
107
packages/secret-numbers/test/utils.test.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import * as utils from "../src/utils";
|
||||
|
||||
describe("Utils", () => {
|
||||
it("randomEntropy: valid output", () => {
|
||||
const data = utils.randomEntropy();
|
||||
expect(typeof data).toEqual("object");
|
||||
expect(data instanceof Buffer).toBeTruthy();
|
||||
expect(data.length).toEqual(16);
|
||||
expect(data.toString("hex").length).toEqual(32);
|
||||
expect(data.toString("hex")).toMatch(/^[a-f0-9]+$/u);
|
||||
});
|
||||
|
||||
it("calculateChecksum: 1st position", () => {
|
||||
expect(utils.calculateChecksum(0, 55988)).toEqual(8);
|
||||
});
|
||||
|
||||
it("calculateChecksum: 8th position", () => {
|
||||
expect(utils.calculateChecksum(7, 49962)).toEqual(0);
|
||||
});
|
||||
|
||||
it("checkChecksum: 2nd position, split numbers", () => {
|
||||
expect(utils.checkChecksum(1, 55450, 3)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("checkChecksum: 7th position, split numbers", () => {
|
||||
expect(utils.checkChecksum(6, 18373, 7)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("checkChecksum: 4th position, as string", () => {
|
||||
expect(utils.checkChecksum(3, "391566")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("randomSecret: valid checksums", () => {
|
||||
utils.randomSecret();
|
||||
expect(0).toEqual(0);
|
||||
});
|
||||
|
||||
it("randomSecret: valid output", () => {
|
||||
const data = utils.randomSecret();
|
||||
expect(Array.isArray(data)).toBeTruthy();
|
||||
expect(data.length).toEqual(8);
|
||||
expect(typeof data[0]).toEqual("string");
|
||||
expect(data[0].length).toEqual(6);
|
||||
expect(data[7].length).toEqual(6);
|
||||
});
|
||||
|
||||
it("entropyToSecret", () => {
|
||||
const entropy = Buffer.from("76ebb2d06879b45b7568fb9c1ded097c", "hex");
|
||||
const secret = [
|
||||
"304435",
|
||||
"457766",
|
||||
"267453",
|
||||
"461717",
|
||||
"300560",
|
||||
"644127",
|
||||
"076618",
|
||||
"024286",
|
||||
];
|
||||
expect(utils.entropyToSecret(entropy)).toEqual(secret);
|
||||
});
|
||||
|
||||
it("secretToEntropy", () => {
|
||||
const secret = [
|
||||
"304435",
|
||||
"457766",
|
||||
"267453",
|
||||
"461717",
|
||||
"300560",
|
||||
"644127",
|
||||
"076618",
|
||||
"024286",
|
||||
];
|
||||
const entropy = Buffer.from("76ebb2d06879b45b7568fb9c1ded097c", "hex");
|
||||
expect(utils.secretToEntropy(secret)).toEqual(entropy);
|
||||
});
|
||||
|
||||
it("parseSecretString with spaces valid", () => {
|
||||
const secret = [
|
||||
"304435",
|
||||
"457766",
|
||||
"267453",
|
||||
"461717",
|
||||
"300560",
|
||||
"644127",
|
||||
"076618",
|
||||
"024286",
|
||||
];
|
||||
expect(
|
||||
utils.parseSecretString(
|
||||
"304435 457766 267453 461717 300560 644127 076618 024286"
|
||||
)
|
||||
).toEqual(secret);
|
||||
expect(
|
||||
utils.parseSecretString(
|
||||
"304435457766267453461717300560644127076618024286"
|
||||
)
|
||||
).toEqual(secret);
|
||||
expect(
|
||||
utils.parseSecretString(`
|
||||
304435 457766
|
||||
267453 461717
|
||||
300560 644127
|
||||
076618 024286
|
||||
`)
|
||||
).toEqual(secret);
|
||||
});
|
||||
});
|
||||
61
packages/secret-numbers/test/webpack.config.js
Normal file
61
packages/secret-numbers/test/webpack.config.js
Normal file
@@ -0,0 +1,61 @@
|
||||
"use strict";
|
||||
const assert = require("assert");
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const { merge } = require("webpack-merge");
|
||||
|
||||
function webpackForTest(testFileName) {
|
||||
const match = testFileName.match(/\/?([^\/]*)\.ts$/);
|
||||
if (!match) {
|
||||
assert(false, "wrong filename:" + testFileName);
|
||||
}
|
||||
|
||||
const test = merge(require("../webpack.base.config"), {
|
||||
mode: "production",
|
||||
cache: true,
|
||||
entry: testFileName,
|
||||
output: {
|
||||
library: match[1].replace(/-/g, "_"),
|
||||
path: path.join(__dirname, "./testCompiledForWeb/"),
|
||||
filename: match[1] + ".js",
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
"process.stdout": {},
|
||||
}),
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
// Compile the tests
|
||||
{
|
||||
test: /\.ts$/,
|
||||
use: [
|
||||
{
|
||||
loader: "ts-loader",
|
||||
options: {
|
||||
compilerOptions: {
|
||||
lib: ["esnext", "dom"],
|
||||
composite: false,
|
||||
declaration: false,
|
||||
declarationMap: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
node: {
|
||||
global: true,
|
||||
__filename: false,
|
||||
__dirname: true,
|
||||
},
|
||||
resolve: {
|
||||
extensions: [".ts", ".js", ".json"],
|
||||
},
|
||||
});
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
module.exports = webpackForTest("./test/index.ts");
|
||||
Reference in New Issue
Block a user