-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #53 from Nesopie/feat/hybrid
feat: add hybrid cjs-esm support
- Loading branch information
Showing
15 changed files
with
3,217 additions
and
739 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
name: Node.js CI | ||
|
||
on: | ||
push: | ||
branches: | ||
- "**" | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
node-version: | ||
- 10 | ||
- 11 | ||
- 13 | ||
- lts/* | ||
test-suite: | ||
- test | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Use Node.js ${{ matrix.node-version }} | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
- name: Install dependencies | ||
run: npm install | ||
- name: Setup | ||
run: npm run build | ||
- name: Run test suite | ||
run: npm run ${{ matrix.test-suite }} |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
"use strict"; | ||
// This is a simple example file that shows the usage of this library in TypeScript. | ||
// When you open it in Visual Studio Code, the built-in TypeScript server should run all | ||
// the type checks. For manually runtime testing you can use ts-node to run this file. | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// @ts-ignore | ||
const index_cjs_1 = require("../index.cjs"); | ||
function encodeUint8Array(prefix, data) { | ||
const address = index_cjs_1.bech32.encode(prefix, index_cjs_1.bech32.toWords(data)); | ||
return address; | ||
} | ||
function decodeUint8Array(address) { | ||
const decodedAddress = index_cjs_1.bech32.decode(address); | ||
return { | ||
prefix: decodedAddress.prefix, | ||
data: new Uint8Array(index_cjs_1.bech32.fromWords(decodedAddress.words)), | ||
}; | ||
} | ||
function encodeBuffer(prefix, data) { | ||
const address = index_cjs_1.bech32.encode(prefix, index_cjs_1.bech32.toWords(data)); | ||
return address; | ||
} | ||
function decodeBuffer(address) { | ||
const decodedAddress = index_cjs_1.bech32.decode(address); | ||
return { | ||
prefix: decodedAddress.prefix, | ||
data: Buffer.from(index_cjs_1.bech32.fromWords(decodedAddress.words)), | ||
}; | ||
} | ||
function encodeUnsafe(prefix, data) { | ||
const address = index_cjs_1.bech32.encode(prefix, index_cjs_1.bech32.toWords(data)); | ||
return address; | ||
} | ||
function decodeUnsafe(address) { | ||
const decodedAddress = index_cjs_1.bech32.decodeUnsafe(address); | ||
return { | ||
prefix: decodedAddress.prefix, | ||
data: new Uint8Array(index_cjs_1.bech32.fromWordsUnsafe(decodedAddress.words)), | ||
}; | ||
} | ||
function main() { | ||
{ | ||
const prefix = 'foo'; | ||
const data = new Uint8Array([0x00, 0x11, 0x22]); | ||
const address = encodeUint8Array(prefix, data); | ||
const decoded = decodeUint8Array(address); | ||
console.log(prefix, data, address, decoded); | ||
} | ||
{ | ||
const prefix = 'foo'; | ||
const data = Buffer.from([0x00, 0x11, 0x22]); | ||
const address = encodeBuffer(prefix, data); | ||
const decoded = decodeBuffer(address); | ||
console.log(prefix, data, address, decoded); | ||
} | ||
{ | ||
const prefix = 'foo'; | ||
const data = new Uint8Array([0x00, 0x11, 0x22]); | ||
const address = encodeUnsafe(prefix, data); | ||
const decoded = decodeUnsafe(address); | ||
console.log(prefix, data, address, decoded); | ||
} | ||
} | ||
main(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
'use strict'; | ||
const ALPHABET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'; | ||
const ALPHABET_MAP = {}; | ||
for (let z = 0; z < ALPHABET.length; z++) { | ||
const x = ALPHABET.charAt(z); | ||
ALPHABET_MAP[x] = z; | ||
} | ||
function polymodStep(pre) { | ||
const b = pre >> 25; | ||
return (((pre & 0x1ffffff) << 5) ^ | ||
(-((b >> 0) & 1) & 0x3b6a57b2) ^ | ||
(-((b >> 1) & 1) & 0x26508e6d) ^ | ||
(-((b >> 2) & 1) & 0x1ea119fa) ^ | ||
(-((b >> 3) & 1) & 0x3d4233dd) ^ | ||
(-((b >> 4) & 1) & 0x2a1462b3)); | ||
} | ||
function prefixChk(prefix) { | ||
let chk = 1; | ||
for (let i = 0; i < prefix.length; ++i) { | ||
const c = prefix.charCodeAt(i); | ||
if (c < 33 || c > 126) | ||
return 'Invalid prefix (' + prefix + ')'; | ||
chk = polymodStep(chk) ^ (c >> 5); | ||
} | ||
chk = polymodStep(chk); | ||
for (let i = 0; i < prefix.length; ++i) { | ||
const v = prefix.charCodeAt(i); | ||
chk = polymodStep(chk) ^ (v & 0x1f); | ||
} | ||
return chk; | ||
} | ||
function convert(data, inBits, outBits, pad) { | ||
let value = 0; | ||
let bits = 0; | ||
const maxV = (1 << outBits) - 1; | ||
const result = []; | ||
for (let i = 0; i < data.length; ++i) { | ||
value = (value << inBits) | data[i]; | ||
bits += inBits; | ||
while (bits >= outBits) { | ||
bits -= outBits; | ||
result.push((value >> bits) & maxV); | ||
} | ||
} | ||
if (pad) { | ||
if (bits > 0) { | ||
result.push((value << (outBits - bits)) & maxV); | ||
} | ||
} | ||
else { | ||
if (bits >= inBits) | ||
return 'Excess padding'; | ||
if ((value << (outBits - bits)) & maxV) | ||
return 'Non-zero padding'; | ||
} | ||
return result; | ||
} | ||
function toWords(bytes) { | ||
return convert(bytes, 8, 5, true); | ||
} | ||
function fromWordsUnsafe(words) { | ||
const res = convert(words, 5, 8, false); | ||
if (Array.isArray(res)) | ||
return res; | ||
} | ||
function fromWords(words) { | ||
const res = convert(words, 5, 8, false); | ||
if (Array.isArray(res)) | ||
return res; | ||
throw new Error(res); | ||
} | ||
function getLibraryFromEncoding(encoding) { | ||
let ENCODING_CONST; | ||
if (encoding === 'bech32') { | ||
ENCODING_CONST = 1; | ||
} | ||
else { | ||
ENCODING_CONST = 0x2bc830a3; | ||
} | ||
function encode(prefix, words, LIMIT) { | ||
LIMIT = LIMIT || 90; | ||
if (prefix.length + 7 + words.length > LIMIT) | ||
throw new TypeError('Exceeds length limit'); | ||
prefix = prefix.toLowerCase(); | ||
// determine chk mod | ||
let chk = prefixChk(prefix); | ||
if (typeof chk === 'string') | ||
throw new Error(chk); | ||
let result = prefix + '1'; | ||
for (let i = 0; i < words.length; ++i) { | ||
const x = words[i]; | ||
if (x >> 5 !== 0) | ||
throw new Error('Non 5-bit word'); | ||
chk = polymodStep(chk) ^ x; | ||
result += ALPHABET.charAt(x); | ||
} | ||
for (let i = 0; i < 6; ++i) { | ||
chk = polymodStep(chk); | ||
} | ||
chk ^= ENCODING_CONST; | ||
for (let i = 0; i < 6; ++i) { | ||
const v = (chk >> ((5 - i) * 5)) & 0x1f; | ||
result += ALPHABET.charAt(v); | ||
} | ||
return result; | ||
} | ||
function __decode(str, LIMIT) { | ||
LIMIT = LIMIT || 90; | ||
if (str.length < 8) | ||
return str + ' too short'; | ||
if (str.length > LIMIT) | ||
return 'Exceeds length limit'; | ||
// don't allow mixed case | ||
const lowered = str.toLowerCase(); | ||
const uppered = str.toUpperCase(); | ||
if (str !== lowered && str !== uppered) | ||
return 'Mixed-case string ' + str; | ||
str = lowered; | ||
const split = str.lastIndexOf('1'); | ||
if (split === -1) | ||
return 'No separator character for ' + str; | ||
if (split === 0) | ||
return 'Missing prefix for ' + str; | ||
const prefix = str.slice(0, split); | ||
const wordChars = str.slice(split + 1); | ||
if (wordChars.length < 6) | ||
return 'Data too short'; | ||
let chk = prefixChk(prefix); | ||
if (typeof chk === 'string') | ||
return chk; | ||
const words = []; | ||
for (let i = 0; i < wordChars.length; ++i) { | ||
const c = wordChars.charAt(i); | ||
const v = ALPHABET_MAP[c]; | ||
if (v === undefined) | ||
return 'Unknown character ' + c; | ||
chk = polymodStep(chk) ^ v; | ||
// not in the checksum? | ||
if (i + 6 >= wordChars.length) | ||
continue; | ||
words.push(v); | ||
} | ||
if (chk !== ENCODING_CONST) | ||
return 'Invalid checksum for ' + str; | ||
return { prefix, words }; | ||
} | ||
function decodeUnsafe(str, LIMIT) { | ||
const res = __decode(str, LIMIT); | ||
if (typeof res === 'object') | ||
return res; | ||
} | ||
function decode(str, LIMIT) { | ||
const res = __decode(str, LIMIT); | ||
if (typeof res === 'object') | ||
return res; | ||
throw new Error(res); | ||
} | ||
return { | ||
decodeUnsafe, | ||
decode, | ||
encode, | ||
toWords, | ||
fromWordsUnsafe, | ||
fromWords, | ||
}; | ||
} | ||
export const bech32 = getLibraryFromEncoding('bech32'); | ||
export const bech32m = getLibraryFromEncoding('bech32m'); |
Oops, something went wrong.