From 044408c4970e169d0cb1b34f3e954eb9182cbfd4 Mon Sep 17 00:00:00 2001 From: Benjamin Smith Date: Sat, 28 Sep 2024 10:52:28 +0200 Subject: [PATCH 1/4] use own base58 --- packages/utils/package.json | 2 +- packages/utils/src/b58.ts | 14 ++++++++++++++ packages/utils/src/format.ts | 3 +-- pnpm-lock.yaml | 11 ++++++++--- 4 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 packages/utils/src/b58.ts diff --git a/packages/utils/package.json b/packages/utils/package.json index 043bac4038..40b0a147e3 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -17,7 +17,7 @@ "license": "ISC", "dependencies": { "@near-js/types": "workspace:*", - "bs58": "4.0.0", + "base-x": "5.0.0", "depd": "2.0.0", "mustache": "4.0.0" }, diff --git a/packages/utils/src/b58.ts b/packages/utils/src/b58.ts new file mode 100644 index 0000000000..1758809548 --- /dev/null +++ b/packages/utils/src/b58.ts @@ -0,0 +1,14 @@ +/** + * This code is copied verbatim from + * https://github.com/cryptocoinjs/bs58/blob/master/ts_src/index.ts + * because + * 1. Its very minimal middleware. + * 2. The latest version (v6.0.0) has an incorrect build. + * https://www.npmjs.com/package/bs58/v/6.0.0 + * 3. It doesn't doesn't actively update the primary dependency: + * https://www.npmjs.com/package/base-x + */ +import basex from "base-x"; +const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; + +export default basex(ALPHABET); \ No newline at end of file diff --git a/packages/utils/src/format.ts b/packages/utils/src/format.ts index 56df34607c..3b5f92e934 100644 --- a/packages/utils/src/format.ts +++ b/packages/utils/src/format.ts @@ -1,5 +1,4 @@ -import bs58 from "bs58"; - +import bs58 from "./b58"; /** * Exponent for calculating how many indivisible units are there in one NEAR. See {@link NEAR_NOMINATION}. */ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f2be411fb0..d4552e26cb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -619,9 +619,9 @@ importers: '@near-js/types': specifier: workspace:* version: link:../types - bs58: - specifier: 4.0.0 - version: 4.0.0 + base-x: + specifier: 5.0.0 + version: 5.0.0 depd: specifier: 2.0.0 version: 2.0.0 @@ -1563,6 +1563,9 @@ packages: base-x@3.0.9: resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + base-x@5.0.0: + resolution: {integrity: sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -5358,6 +5361,8 @@ snapshots: dependencies: safe-buffer: 5.2.1 + base-x@5.0.0: {} + base64-js@1.5.1: {} base64url@3.0.1: {} From 099f3c9ff9f101a20ca7f955f2688db2fb19283f Mon Sep 17 00:00:00 2001 From: Benjamin Smith Date: Sat, 28 Sep 2024 11:14:05 +0200 Subject: [PATCH 2/4] add changeset --- .changeset/warm-insects-yell.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/warm-insects-yell.md diff --git a/.changeset/warm-insects-yell.md b/.changeset/warm-insects-yell.md new file mode 100644 index 0000000000..b8568b4a62 --- /dev/null +++ b/.changeset/warm-insects-yell.md @@ -0,0 +1,5 @@ +--- +"@near-js/utils": patch +--- + +use own base58 and depend directly on base-x From ac33b76e35e513ed33fcbde24ed63922579f6297 Mon Sep 17 00:00:00 2001 From: Benjamin Smith Date: Sat, 28 Sep 2024 11:23:43 +0200 Subject: [PATCH 3/4] transcribe unit tests --- packages/utils/test/base58.test.ts | 72 ++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 packages/utils/test/base58.test.ts diff --git a/packages/utils/test/base58.test.ts b/packages/utils/test/base58.test.ts new file mode 100644 index 0000000000..24acfed2cb --- /dev/null +++ b/packages/utils/test/base58.test.ts @@ -0,0 +1,72 @@ +import { describe, test, expect } from '@jest/globals'; +import base58 from '../src/b58'; + +const fixtures = { + valid: [ + { hex: '', string: '' }, + { hex: '61', string: '2g' }, + { hex: '626262', string: 'a3gV' }, + { hex: '636363', string: 'aPEr' }, + { + hex: '73696d706c792061206c6f6e6720737472696e67', + string: '2cFupjhnEsSn59qHXstmK2ffpLv2', + }, + { + hex: '00eb15231dfceb60925886b67d065299925915aeb172c06647', + string: '1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L', + }, + { hex: '516b6fcd0f', string: 'ABnLTmg' }, + { hex: 'bf4f89001e670274dd', string: '3SEo3LWLoPntC' }, + { hex: '572e4794', string: '3EFU7m' }, + { hex: 'ecac89cad93923c02321', string: 'EJDM8drfXA6uyA' }, + { hex: '10c8511e', string: 'Rt5zm' }, + { hex: '00000000000000000000', string: '1111111111' }, + { + hex: '801184cd2cdd640ca42cfc3a091c51d549b2f016d454b2774019c2b2d2e08529fd206ec97e', + string: '5Hx15HFGyep2CfPxsJKe2fXJsCVn5DEiyoeGGF6JZjGbTRnqfiD', + }, + { + hex: '003c176e659bea0f29a3e9bf7880c112b1b31b4dc826268187', + string: '16UjcYNBG9GTK4uq2f7yYEbuifqCzoLMGS', + }, + ], + invalid: [ + { description: 'non-base58 string', string: 'invalid' }, + { description: 'non-base58 alphabet', string: 'c2F0b3NoaQo=' }, + { description: 'leading whitespace', string: ' 1111111111' }, + { description: 'trailing whitespace', string: '1111111111 ' }, + { + description: 'unexpected character after whitespace', + string: ' \t\n\u000b\f\r skip \r\f\u000b\n\t a', + }, + ], +}; + +const { encode, decode } = base58; +const { valid, invalid } = fixtures; + +describe('base58', () => { + describe('encode', () => { + valid.forEach((f) => { + test(`can encode ${f.hex}`, () => { + const actual = encode(Buffer.from(f.hex, 'hex')); + expect(actual).toBe(f.string); + }); + }); + }); + + describe('decode', () => { + valid.forEach((f) => { + test(`can decode ${f.string}`, () => { + const actual = Buffer.from(decode(f.string)).toString('hex'); + expect(actual).toBe(f.hex); + }); + }); + + invalid.forEach((f) => { + test(`throws on ${f.description}`, () => { + expect(() => decode(f.string)).toThrow("Non-base58 character"); + }); + }); + }); +}); \ No newline at end of file From 4eae9d0dd929d1b6b3681ae94be534d71f20f5aa Mon Sep 17 00:00:00 2001 From: Benjamin Smith Date: Sat, 28 Sep 2024 14:28:46 +0200 Subject: [PATCH 4/4] transcribe unit tests --- packages/utils/test/base58.test.ts | 114 ++++++++++++++--------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/packages/utils/test/base58.test.ts b/packages/utils/test/base58.test.ts index 24acfed2cb..ae140b4680 100644 --- a/packages/utils/test/base58.test.ts +++ b/packages/utils/test/base58.test.ts @@ -2,71 +2,71 @@ import { describe, test, expect } from '@jest/globals'; import base58 from '../src/b58'; const fixtures = { - valid: [ - { hex: '', string: '' }, - { hex: '61', string: '2g' }, - { hex: '626262', string: 'a3gV' }, - { hex: '636363', string: 'aPEr' }, - { - hex: '73696d706c792061206c6f6e6720737472696e67', - string: '2cFupjhnEsSn59qHXstmK2ffpLv2', - }, - { - hex: '00eb15231dfceb60925886b67d065299925915aeb172c06647', - string: '1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L', - }, - { hex: '516b6fcd0f', string: 'ABnLTmg' }, - { hex: 'bf4f89001e670274dd', string: '3SEo3LWLoPntC' }, - { hex: '572e4794', string: '3EFU7m' }, - { hex: 'ecac89cad93923c02321', string: 'EJDM8drfXA6uyA' }, - { hex: '10c8511e', string: 'Rt5zm' }, - { hex: '00000000000000000000', string: '1111111111' }, - { - hex: '801184cd2cdd640ca42cfc3a091c51d549b2f016d454b2774019c2b2d2e08529fd206ec97e', - string: '5Hx15HFGyep2CfPxsJKe2fXJsCVn5DEiyoeGGF6JZjGbTRnqfiD', - }, - { - hex: '003c176e659bea0f29a3e9bf7880c112b1b31b4dc826268187', - string: '16UjcYNBG9GTK4uq2f7yYEbuifqCzoLMGS', - }, - ], - invalid: [ - { description: 'non-base58 string', string: 'invalid' }, - { description: 'non-base58 alphabet', string: 'c2F0b3NoaQo=' }, - { description: 'leading whitespace', string: ' 1111111111' }, - { description: 'trailing whitespace', string: '1111111111 ' }, - { - description: 'unexpected character after whitespace', - string: ' \t\n\u000b\f\r skip \r\f\u000b\n\t a', - }, - ], + valid: [ + { hex: '', string: '' }, + { hex: '61', string: '2g' }, + { hex: '626262', string: 'a3gV' }, + { hex: '636363', string: 'aPEr' }, + { + hex: '73696d706c792061206c6f6e6720737472696e67', + string: '2cFupjhnEsSn59qHXstmK2ffpLv2', + }, + { + hex: '00eb15231dfceb60925886b67d065299925915aeb172c06647', + string: '1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L', + }, + { hex: '516b6fcd0f', string: 'ABnLTmg' }, + { hex: 'bf4f89001e670274dd', string: '3SEo3LWLoPntC' }, + { hex: '572e4794', string: '3EFU7m' }, + { hex: 'ecac89cad93923c02321', string: 'EJDM8drfXA6uyA' }, + { hex: '10c8511e', string: 'Rt5zm' }, + { hex: '00000000000000000000', string: '1111111111' }, + { + hex: '801184cd2cdd640ca42cfc3a091c51d549b2f016d454b2774019c2b2d2e08529fd206ec97e', + string: '5Hx15HFGyep2CfPxsJKe2fXJsCVn5DEiyoeGGF6JZjGbTRnqfiD', + }, + { + hex: '003c176e659bea0f29a3e9bf7880c112b1b31b4dc826268187', + string: '16UjcYNBG9GTK4uq2f7yYEbuifqCzoLMGS', + }, + ], + invalid: [ + { description: 'non-base58 string', string: 'invalid' }, + { description: 'non-base58 alphabet', string: 'c2F0b3NoaQo=' }, + { description: 'leading whitespace', string: ' 1111111111' }, + { description: 'trailing whitespace', string: '1111111111 ' }, + { + description: 'unexpected character after whitespace', + string: ' \t\n\u000b\f\r skip \r\f\u000b\n\t a', + }, + ], }; const { encode, decode } = base58; const { valid, invalid } = fixtures; describe('base58', () => { - describe('encode', () => { - valid.forEach((f) => { - test(`can encode ${f.hex}`, () => { - const actual = encode(Buffer.from(f.hex, 'hex')); - expect(actual).toBe(f.string); - }); + describe('encode', () => { + valid.forEach((f) => { + test(`can encode ${f.hex}`, () => { + const actual = encode(Buffer.from(f.hex, 'hex')); + expect(actual).toBe(f.string); + }); + }); }); - }); - describe('decode', () => { - valid.forEach((f) => { - test(`can decode ${f.string}`, () => { - const actual = Buffer.from(decode(f.string)).toString('hex'); - expect(actual).toBe(f.hex); - }); - }); + describe('decode', () => { + valid.forEach((f) => { + test(`can decode ${f.string}`, () => { + const actual = Buffer.from(decode(f.string)).toString('hex'); + expect(actual).toBe(f.hex); + }); + }); - invalid.forEach((f) => { - test(`throws on ${f.description}`, () => { - expect(() => decode(f.string)).toThrow("Non-base58 character"); - }); + invalid.forEach((f) => { + test(`throws on ${f.description}`, () => { + expect(() => decode(f.string)).toThrow('Non-base58 character'); + }); + }); }); - }); }); \ No newline at end of file