Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

invoices

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

invoices - npm Package Compare versions

Comparing version 1.2.0 to 1.2.1

bolt11/hrp_as_mtokens.js

21

bolt11/byte_decode_request.js

@@ -15,4 +15,5 @@ const {bech32} = require('bech32');

encoded: <Payment Request Details Hex String>
mtokens: <Millitokens Number String>
[mtokens]: <Millitokens Number String>
network: <Network Name String>
words: <Words Count Number>
}

@@ -28,3 +29,3 @@

*/
module.exports = ({encoded, mtokens, network}) => {
module.exports = ({encoded, mtokens, network, words}) => {
if (!isHex(encoded)) {

@@ -34,6 +35,2 @@ throw new Error('ExpectedHexEncodedPaymentRequestDataToDecodeRequest');

if (!mtokens) {
throw new Error('ExpectedAmountToDecodeByteEncodedRequest');
}
if (!network) {

@@ -43,2 +40,7 @@ throw new Error('ExpectedNetworkToDecodeByteEncodedRequest');

if (!words) {
throw new Error('ExpectedWordsCountToDecodeByteEncodedRequest');
}
// Lookup the BOLT 11 network prefix for the request
const currencyPrefix = keys(currencyCodes)

@@ -52,6 +54,9 @@ .map(code => ({code, network: currencyCodes[code]}))

// Before the encoded data is a network code and the amount
const prefix = `ln${currencyPrefix.code}${mtokensAsHrp({mtokens}).hrp}`;
const words = bech32.toWords(hexAsBuffer(encoded));
return {request: bech32.encode(prefix, words, limit)};
// The data of the request is encoded in 5 bit words ie bech32
const fiveBit = bech32.toWords(hexAsBuffer(encoded)).slice(Number(), words);
return {request: bech32.encode(prefix, fiveBit, limit)};
};
const {bech32} = require('bech32');
const decodePrefix = require('./decode_prefix');
const hrpAsTokens = require('./hrp_as_tokens');
const hrpAsMtokens = require('./hrp_as_mtokens');
const wordsAsBuffer = require('./words_as_buffer');

@@ -11,3 +11,2 @@

const maxRequestLength = Number.MAX_SAFE_INTEGER;
const trim = true;

@@ -28,2 +27,3 @@ /** Derive bytes for payment request details

network: <Network Name String>
words: <Word Length Number>
}

@@ -44,7 +44,9 @@ */

const {mtokens} = hrpAsTokens({amount, units});
// Decode the request amount millitokens requested amount
const {mtokens} = hrpAsMtokens({amount, units});
const encoded = bufferAsHex(wordsAsBuffer({trim, words}));
// Encode the words as binary data in a hex string
const encoded = bufferAsHex(wordsAsBuffer({words}));
return {encoded, mtokens, network};
return {encoded, network, mtokens, words: words.length};
};

@@ -16,6 +16,2 @@ {

{
"letter": "p",
"value": "10"
},
{
"letter": "u",

@@ -22,0 +18,0 @@ "value": "100000"

@@ -27,2 +27,3 @@ const {createHash} = require('crypto');

const {sha256} = crypto;
const tokensAsMtokens = n => !n ? '0' : (BigInt(n) * BigInt(1e3)).toString();

@@ -94,3 +95,3 @@ /** Create an unsigned payment request

const createdAtWords = numberAsWords({number: floor(createdAt)}).words;
const mtokens = args.mtokens || args.tokens * mtokPerTok;
const mtokens = args.mtokens || tokensAsMtokens(args.tokens);

@@ -97,0 +98,0 @@ const hrp = `ln${currencyPrefix.code}${mtokensAsHrp({mtokens}).hrp}`;

const {multipliers} = require('./conf/multipliers');
const isEmpty = n => !n || n === '0';
const isNumeric = n => /^\d+$/.test(n);
const asPico = amount => (amount * BigInt(10)).toString() + 'p';
const isString = n => typeof n === 'string';
/** Get Tokens as the Human Readable Part of a BOLT11 payment request

@@ -9,3 +14,6 @@

@returns via cbk
@throws
<Error>
@returns
{

@@ -16,8 +24,18 @@ hrp: <Human Readable Part String>

module.exports = ({mtokens}) => {
if (!mtokens) {
return {hrp: ''};
// Exit early when there are no mtokens
if (isEmpty(mtokens)) {
return {hrp: String()};
}
if (!isString(mtokens)) {
throw new Error('ExpectedStringValueToConvertMtokensToHrp');
}
if (!isNumeric(mtokens)) {
throw new Error('ExpectedNumericStringValueToConvertMtokensToHrp');
}
const amount = BigInt(mtokens);
// Map the amount into multiplier representations and select the shortest
const [hrp] = multipliers

@@ -29,3 +47,8 @@ .map(({letter, value}) => ({letter, value: BigInt(value)}))

// The smallest amounts do not have any multiplier
if (!hrp) {
return {hrp: asPico(amount)};
}
return {hrp};
};

@@ -6,3 +6,3 @@ const {bech32} = require('bech32');

const fieldAsDetails = require('./field_as_details');
const hrpAsTokens = require('./hrp_as_tokens');
const hrpAsMtokens = require('./hrp_as_mtokens');
const requestDetails = require('./request_details');

@@ -93,3 +93,3 @@ const signatureFromWords = require('./signature_from_words');

})),
mtokens: hrpAsTokens({amount, units}).mtokens,
mtokens: hrpAsMtokens({amount, units}).mtokens,
timestamp: wordsAsNumber({words: timestampWords}) * msPerSec,

@@ -96,0 +96,0 @@ });

# Versions
## 1.2.1
Fix issues with millitoken value invoices and add additional test coverage for sub-token requests.
- `byteDecodeRequest`: Fix decoding issue, add required word count argument
- `byteEncodeRequest`: Return word count with encoding
## 1.2.0

@@ -4,0 +11,0 @@

@@ -7,4 +7,4 @@ {

"dependencies": {
"bolt07": "1.7.2",
"bolt09": "0.1.4",
"bolt07": "1.7.3",
"bolt09": "0.1.5",
"bech32": "2.0.0",

@@ -17,3 +17,3 @@ "bitcoinjs-lib": "5.2.0",

"devDependencies": {
"tap": "15.0.2"
"tap": "15.0.9"
},

@@ -40,3 +40,3 @@ "engines": {

},
"version": "1.2.0"
"version": "1.2.1"
}

@@ -14,4 +14,5 @@ # Invoices

encoded: <Payment Request Details Hex String>
mtokens: <Millitokens Number String>
[mtokens]: <Millitokens Number String>
network: <Network Name String>
words: <Words Count Number>
}

@@ -56,2 +57,3 @@

network: <Network Name String>
words: <Word Length Number>
}

@@ -58,0 +60,0 @@

@@ -7,5 +7,6 @@ const {test} = require('tap');

const args = {
encoded: '0b675c0ac10d388683237d00319b98b8c56c7325aaee5728c2ec02506fcd790d8406bcbd6d3a81a1ea932b0b21d1023b637b130b61021b93cb83a37b1bab93932b731bc902932b3bab630ba34b7b73001120dfa2ed0f3bee3252b6132a943032fe0158340b6784a5a9b2b018ec3ed2ee3fa8a0b8102e27747c432917543ea7476b2d43a33d6a55198d0f3fc4a89b2e5c8bd0',
encoded: '0b25fe64410d00004080c1014181c20240004080c1014181c20240004080c1014181c202404081a1fa83632b0b9b29031b7b739b4b232b91039bab83837b93a34b733903a3434b990383937b532b1ba038ec6891345e204145be8a3a99de38e98a39d6a569434e1845c8af7205afcfcc7f425fcd1463e93c32881ead0d6e356d467ec8c02553f9aab15e5738b11f127f00',
mtokens: '150000',
network: 'testnet',
words: 232,
};

@@ -25,7 +26,2 @@

{
args: makeArgs({mtokens: undefined}),
description: 'Millitokens is required',
error: 'ExpectedAmountToDecodeByteEncodedRequest',
},
{
args: makeArgs({network: undefined}),

@@ -44,3 +40,3 @@ description: 'Network is required',

expected: {
request: 'lntb1500n1pdn4czkpp5ugdqer05qrrxuchrzkcue94th9w2xzasp9qm7d0yxcgp4uh4kn4qdpa2fjkzep6yprkcmmzv9kzqsmj09c8gmmrw4e8yetwvdujq5n9va6kcct5d9hkucqzysdlghdpua7uvjjkcfj49psxtlqzkp5pdncffdfk2cp3mp76thrl29qhqgzufm503pjj96586n5w6edgw3n66j4rxxs707y4zdjuhyt6quatqte',
request: 'lntb1500n1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq8rkx3yf5tcsyz3d73gafnh3cax9rn449d9p5uxz9ezhhypd0elx87sjle52x86fux2ypatgddc6k63n7erqz25le42c4u4ecky03ylcqz03uuk',
},

@@ -47,0 +43,0 @@ },

const {test} = require('tap');
const {byteDecodeRequest} = require('./../../');
const {byteEncodeRequest} = require('./../../');
const {parsePaymentRequest} = require('./../../');

@@ -18,11 +20,48 @@ const tests = [

args: {
request: 'lntb1500n1pdn4czkpp5ugdqer05qrrxuchrzkcue94th9w2xzasp9qm7d0yxcgp4uh4kn4qdpa2fjkzep6yprkcmmzv9kzqsmj09c8gmmrw4e8yetwvdujq5n9va6kcct5d9hkucqzysdlghdpua7uvjjkcfj49psxtlqzkp5pdncffdfk2cp3mp76thrl29qhqgzufm503pjj96586n5w6edgw3n66j4rxxs707y4zdjuhyt6qqe5weu4',
request: 'lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq8rkx3yf5tcsyz3d73gafnh3cax9rn449d9p5uxz9ezhhypd0elx87sjle52x86fux2ypatgddc6k63n7erqz25le42c4u4ecky03ylcqca784w',
},
description: 'Byte encode a payment request',
expected: {
encoded: '0b675c0ac10d388683237d00319b98b8c56c7325aaee5728c2ec02506fcd790d8406bcbd6d3a81a1ea932b0b21d1023b637b130b61021b93cb83a37b1bab93932b731bc902932b3bab630ba34b7b73001120dfa2ed0f3bee3252b6132a943032fe0158340b6784a5a9b2b018ec3ed2ee3fa8a0b8102e27747c432917543ea7476b2d43a33d6a55198d0f3fc4a89b2e5c8bd0',
mtokens: '150000',
network: 'testnet',
encoded: '0b25fe64410d00004080c1014181c20240004080c1014181c20240004080c1014181c202404081a1fa83632b0b9b29031b7b739b4b232b91039bab83837b93a34b733903a3434b990383937b532b1ba038ec6891345e204145be8a3a99de38e98a39d6a569434e1845c8af7205afcfcc7f425fcd1463e93c32881ead0d6e356d467ec8c02553f9aab15e5738b11f127f00',
mtokens: undefined,
network: 'bitcoin',
words: 232,
},
},
{
args: {
request: 'lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpuaztrnwngzn3kdzw5hydlzf03qdgm2hdq27cqv3agm2awhz5se903vruatfhq77w3ls4evs3ch9zw97j25emudupq63nyw24cg27h2rspfj9srp',
},
description: 'Byte encode a payment request with an amount',
expected: {
encoded: '0b25fe64410d00004080c1014181c20240004080c1014181c20240004080c1014181c202404081a0a189031bab81031b7b33332b2818020f3a258e6e9a0538d9a2752e46fc497c40d46d576815ec0191ea36aebae2a43257c583e7569b83de747f0ae5908e2e5138be92a99df1bc08351991caae10af5d438040',
mtokens: '250000000',
network: 'bitcoin',
words: 194,
},
},
{
args: {
request: 'lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny',
},
description: 'Byte encode a payment request with an amount',
expected: {
encoded: '0b25fe64410d00004080c1014181c20240004080c1014181c20240004080c1014181c202404081a1071c1c571c1d9f1c15df1c1d9f1c15c9018f34ed798020f0967c114479fbcaa9dfdbfc13546d2ba482541210f96ae59cb38ca854da07da1d456dcf395fb8c276d622843ae3906d68b4af05c51377ce600cfea927ffa56b9800',
mtokens: '250000000',
network: 'bitcoin',
words: 206,
},
},
{
args: {
request: 'lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqscc6gd6ql3jrc5yzme8v4ntcewwz5cnw92tz0pc8qcuufvq7khhr8wpald05e92xw006sq94mg8v2ndf4sefvf9sygkshp5zfem29trqq2yxxz7',
},
description: 'Byte encode a payment request with a desc hash',
expected: {
encoded: '0b25fe64410d00004080c1014181c20240004080c1014181c20240004080c1014181c202404082e1a1c92db7b3f161a001b7689049eea2701b46f8db7513629edf2408fac7eaedc608631a43740fc643c5082de4ecacd78cb9c2a626e2a962787070639c4b01eb5ee33b83dfb5f4c954673dfa800b5da0ec54da9ac329624b0222d0b86824e76a2ac60000',
mtokens: '2000000000',
network: 'bitcoin',
words: 221,
},
},
];

@@ -37,2 +76,8 @@

const {request} = byteDecodeRequest(details);
const original = parsePaymentRequest({request: args.request});
const decoded = parsePaymentRequest({request})
strictSame(original, decoded, 'Original payment details preserved');
strictSame(details, expected, 'Got expected byte encoding');

@@ -39,0 +84,0 @@ }

@@ -7,2 +7,17 @@ const {test} = require('tap');

{
args: {mtokens: '1'},
description: 'The smallest possible',
expected: '10p',
},
{
args: {mtokens: '10'},
description: 'Test smaller than a nano',
expected: '100p',
},
{
args: {mtokens: '100'},
description: 'Test smaller than a token',
expected: '1n',
},
{
args: {mtokens: '1000'}, description: 'Test nano tokens', expected: '10n',

@@ -17,5 +32,2 @@ },

{
args: {mtokens: '1', description: 'Test pico', expected: '10p'},
},
{
args: {mtokens: '100000000'}, description: 'Test milli', expected: '1m',

@@ -22,0 +34,0 @@ },

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc