@getalby/lightning-tools 4.2.0 → 5.0.0
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 +30 -8
- package/dist/index.cjs +1 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.modern.js +1 -2
- package/dist/index.module.js +1 -2
- package/dist/index.umd.js +1 -2
- package/dist/invoice.d.ts +1 -2
- package/dist/invoice.test.d.ts +0 -1
- package/dist/l402/index.d.ts +0 -1
- package/dist/l402/parse.d.ts +1 -4
- package/dist/l402/parse.test.d.ts +1 -0
- package/dist/lightning-address.d.ts +0 -1
- package/dist/lightning-address.test.d.ts +0 -1
- package/dist/podcasting2/boostagrams.d.ts +0 -1
- package/dist/types.d.ts +0 -1
- package/dist/utils/fiat.d.ts +0 -1
- package/dist/utils/hex.d.ts +1 -0
- package/dist/utils/invoice.d.ts +0 -1
- package/dist/utils/keysend.d.ts +0 -1
- package/dist/utils/lnurl.d.ts +1 -2
- package/dist/utils/lnurl.test.d.ts +0 -1
- package/dist/utils/nostr.d.ts +1 -2
- package/dist/utils/sha256.d.ts +1 -0
- package/dist/utils/storage.d.ts +0 -1
- package/package.json +5 -8
- package/dist/index.browser.js +0 -1834
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.modern.js.map +0 -1
- package/dist/index.module.js.map +0 -1
- package/dist/index.umd.js.map +0 -1
- package/dist/invoice.d.ts.map +0 -1
- package/dist/invoice.test.d.ts.map +0 -1
- package/dist/l402/index.d.ts.map +0 -1
- package/dist/l402/parse.d.ts.map +0 -1
- package/dist/lightning-address.d.ts.map +0 -1
- package/dist/lightning-address.test.d.ts.map +0 -1
- package/dist/podcasting2/boostagrams.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/utils/fiat.d.ts.map +0 -1
- package/dist/utils/invoice.d.ts.map +0 -1
- package/dist/utils/keysend.d.ts.map +0 -1
- package/dist/utils/lnurl.d.ts.map +0 -1
- package/dist/utils/lnurl.test.d.ts.map +0 -1
- package/dist/utils/nostr.d.ts.map +0 -1
- package/dist/utils/storage.d.ts.map +0 -1
- package/dist/window.d.ts +0 -2
- package/dist/window.d.ts.map +0 -1
- package/dist/window.js +0 -3
package/dist/index.browser.js
DELETED
|
@@ -1,1834 +0,0 @@
|
|
|
1
|
-
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
2
|
-
var e=require("crypto-js/enc-hex.js"),t=require("crypto-js/sha256.js"),r=require("light-bolt11-decoder");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=/*#__PURE__*/n(e),i=/*#__PURE__*/n(t),a=/*#__PURE__*/function(){function e(e){this.storage=void 0,this.storage=e||{}}var t=e.prototype;return t.getItem=function(e){return this.storage[e]},t.setItem=function(e,t){this.storage[e]=t},e}(),s={__proto__:null,MemoryStorage:a,NoStorage:/*#__PURE__*/function(){function e(e){}var t=e.prototype;return t.getItem=function(e){return null},t.setItem=function(e,t){},e}(),default:a},u=new a,l=function(e,t,r){try{var n,o=function(r){return n?r:(t.headers["Accept-Authenticate"]=i,Promise.resolve(fetch(e,t)).then(function(r){var n=r.headers.get("www-authenticate");if(!n)return r;var o,u=(o=n.replace("L402","").replace("LSAT","").split(",").map(function(e){var t=e.split("=").map(function(e){return e.trim()});return[t[0],t[1].match(/"?([^"]*)"?/)[1]]}),Object.fromEntries(o)),l=u.token||u.macaroon,c=u.invoice;return Promise.resolve(a.enable()).then(function(){return Promise.resolve(a.sendPayment(c)).then(function(r){return s.setItem(e,JSON.stringify({token:l,preimage:r.preimage})),t.headers.Authorization=i+" "+l+":"+r.preimage,Promise.resolve(fetch(e,t))})})}))};r||(r={});var i=r.headerKey||"L402",a=r.webln||globalThis.webln;if(!a)throw new Error("WebLN is missing");var s=r.store||u;t||(t={}),t.cache="no-store",t.mode="cors",t.headers||(t.headers={});var l=s.getItem(e),c=function(){if(l){var r=JSON.parse(l);return t.headers.Authorization=i+" "+r.token+":"+r.preimage,Promise.resolve(fetch(e,t)).then(function(e){return n=1,e})}}();return Promise.resolve(c&&c.then?c.then(o):o(c))}catch(e){return Promise.reject(e)}},c={__proto__:null,storage:s,fetchWithL402:l,default:l},h=function(e,t){try{var r=e.boost;t||(t={});var n=t.webln||globalThis.webln;if(!n)throw new Error("WebLN not available");if(!n.keysend)throw new Error("Keysend not available in current WebLN provider");var o=e.amount||Math.floor(r.value_msat/1e3),i={destination:e.destination,amount:o,customRecords:{7629169:JSON.stringify(r)}};return e.customKey&&e.customValue&&(i.customRecords[e.customKey]=e.customValue),Promise.resolve(n.enable()).then(function(){return Promise.resolve(n.keysend(i))})}catch(e){return Promise.reject(e)}},m={__proto__:null,boost:h,default:h};function f(){return f=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},f.apply(this,arguments)}var v=/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)/,p=function(e){return!!e&&v.test(e)},d=function(e){var t=e.amount;return t>0&&t>=e.min&&t<=e.max},y=/*#__PURE__*/function(){function e(e){var t,n,o;if(this.paymentRequest=void 0,this.paymentHash=void 0,this.preimage=void 0,this.verify=void 0,this.satoshi=void 0,this.expiry=void 0,this.timestamp=void 0,this.createdDate=void 0,this.expiryDate=void 0,this.description=void 0,this.paymentRequest=e.pr,!this.paymentRequest)throw new Error("Invalid payment request");var i=function(e){if(!e)return null;try{var t=r.decode(e);if(!t||!t.sections)return null;var n=t.sections.find(function(e){return"payment_hash"===e.name});if("payment_hash"!==(null==n?void 0:n.name)||!n.value)return null;var o=n.value,i=t.sections.find(function(e){return"amount"===e.name});if("amount"!==(null==i?void 0:i.name)||void 0===i.value)return null;var a=parseInt(i.value)/1e3,s=t.sections.find(function(e){return"expiry"===e.name}),u=t.sections.find(function(e){return"timestamp"===e.name});if("timestamp"!==(null==u?void 0:u.name)||!u.value)return null;var l=u.value;if("expiry"!==(null==s?void 0:s.name)||void 0===s.value)return null;var c=s.value,h=t.sections.find(function(e){return"description"===e.name});return{paymentHash:o,satoshi:a,timestamp:l,expiry:c,description:"description"===(null==h?void 0:h.name)?null==h?void 0:h.value:void 0}}catch(e){return null}}(this.paymentRequest);if(!i)throw new Error("Failed to decode payment request");this.paymentHash=i.paymentHash,this.satoshi=i.satoshi,this.timestamp=i.timestamp,this.expiry=i.expiry,this.createdDate=new Date(1e3*this.timestamp),this.expiryDate=new Date(1e3*(this.timestamp+this.expiry)),this.description=null!=(t=i.description)?t:null,this.verify=null!=(n=e.verify)?n:null,this.preimage=null!=(o=e.preimage)?o:null}var t=e.prototype;return t.isPaid=function(){try{var e=this;if(e.preimage)return Promise.resolve(e.validatePreimage(e.preimage));if(e.verify)return Promise.resolve(e.verifyPayment());throw new Error("Could not verify payment")}catch(e){return Promise.reject(e)}},t.validatePreimage=function(e){if(!e||!this.paymentHash)return!1;try{var t=i.default(o.default.parse(e)).toString(o.default);return this.paymentHash===t}catch(e){return!1}},t.verifyPayment=function(){try{var e=this;if(!e.verify)throw new Error("LNURL verify not available");return Promise.resolve(fetch(e.verify)).then(function(t){return Promise.resolve(t.json()).then(function(t){return t.preimage&&(e.preimage=t.preimage),t.settled})})}catch(e){return Promise.reject(e)}},e}(),w=function(e,t){var r=e.satoshi,n=e.comment,o=e.p,i=e.e,a=e.relays;void 0===t&&(t={});try{var s=t.nostr||globalThis.nostr;if(!s)throw new Error("nostr option or window.nostr is not available");var u=[["relays"].concat(a),["amount",r.toString()]];return o&&u.push(["p",o]),i&&u.push(["e",i]),Promise.resolve(s.getPublicKey()).then(function(e){var t={pubkey:e,created_at:Math.floor(Date.now()/1e3),kind:9734,tags:u,content:null!=n?n:""};return t.id=P(t),Promise.resolve(s.signEvent(t))})}catch(i){return Promise.reject(i)}};function g(e){if("string"!=typeof e.content)return!1;if("number"!=typeof e.created_at)return!1;if(!Array.isArray(e.tags))return!1;for(var t=0;t<e.tags.length;t++){var r=e.tags[t];if(!Array.isArray(r))return!1;for(var n=0;n<r.length;n++)if("object"==typeof r[n])return!1}return!0}function b(e){if(!g(e))throw new Error("can't serialize event with wrong or missing properties");return JSON.stringify([0,e.pubkey,e.created_at,e.kind,e.tags,e.content])}function P(e){return i.default(b(e)).toString(o.default)}function k(e,t){var r,n,o,i;return t&&e&&(n=(r=null==(o=e.names)?void 0:o[t])?null==(i=e.relays)?void 0:i[r]:void 0),[e,r,n]}var x={__proto__:null,generateZapEvent:w,validateEvent:g,serializeEvent:b,getEventHash:P,parseNostrResponse:k},D=/^((?:[^<>()[\]\\.,;:\s@"]+(?:\.[^<>()[\]\\.,;:\s@"]+)*)|(?:".+"))@((?:\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(?:(?:[a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,j=/*#__PURE__*/function(){function e(e,t){this.address=void 0,this.options=void 0,this.username=void 0,this.domain=void 0,this.pubkey=void 0,this.lnurlpData=void 0,this.keysendData=void 0,this.nostrData=void 0,this.nostrPubkey=void 0,this.nostrRelays=void 0,this.webln=void 0,this.address=e,this.options={proxy:"https://api.getalby.com/lnurl"},this.options=Object.assign(this.options,t),this.parse(),this.webln=this.options.webln}var t=e.prototype;return t.parse=function(){var e=D.exec(this.address.toLowerCase());e&&(this.username=e[1],this.domain=e[2])},t.getWebLN=function(){return this.webln||globalThis.webln},t.fetch=function(){try{var e=this;return Promise.resolve(e.options.proxy?e.fetchWithProxy():e.fetchWithoutProxy())}catch(e){return Promise.reject(e)}},t.fetchWithProxy=function(){try{var e=this;return Promise.resolve(fetch(e.options.proxy+"/lightning-address-details?"+new URLSearchParams({ln:e.address}).toString())).then(function(t){return Promise.resolve(t.json()).then(function(t){e.parseResponse(t.lnurlp,t.keysend,t.nostr)})})}catch(e){return Promise.reject(e)}},t.fetchWithoutProxy=function(){try{var e=this;return e.domain&&e.username?Promise.resolve(fetch(e.lnurlpUrl())).then(function(t){return Promise.resolve(fetch(e.keysendUrl())).then(function(r){return Promise.resolve(fetch(e.nostrUrl())).then(function(n){function o(){function t(){function t(){e.parseResponse(i,o,r)}var r,a=function(){if(n.ok)return Promise.resolve(n.json()).then(function(e){r=e})}();return a&&a.then?a.then(t):t()}var o,a=function(){if(r.ok)return Promise.resolve(r.json()).then(function(e){o=e})}();return a&&a.then?a.then(t):t()}var i,a=function(){if(t.ok)return Promise.resolve(t.json()).then(function(e){i=e})}();return a&&a.then?a.then(o):o()})})}):Promise.resolve()}catch(e){return Promise.reject(e)}},t.lnurlpUrl=function(){return"https://"+this.domain+"/.well-known/lnurlp/"+this.username},t.keysendUrl=function(){return"https://"+this.domain+"/.well-known/keysend/"+this.username},t.nostrUrl=function(){return"https://"+this.domain+"/.well-known/nostr.json?name="+this.username},t.generateInvoice=function(e){try{var t,r=function(e){var r=t&&t.pr&&t.pr.toString();if(!r)throw new Error("Invalid pay service invoice");var n={pr:r};return t&&t.verify&&(n.verify=t.verify.toString()),new y(n)},n=this,o=function(){if(n.options.proxy)return Promise.resolve(fetch(n.options.proxy+"/generate-invoice?"+new URLSearchParams(f({ln:n.address},e)).toString())).then(function(e){return Promise.resolve(e.json()).then(function(e){t=e.invoice})});if(!n.lnurlpData)throw new Error("No lnurlpData available. Please call fetch() first.");if(!n.lnurlpData.callback||!p(n.lnurlpData.callback))throw new Error("Valid callback does not exist in lnurlpData");var r=new URL(n.lnurlpData.callback);return r.search=new URLSearchParams(e).toString(),Promise.resolve(fetch(r)).then(function(e){return Promise.resolve(e.json()).then(function(e){t=e})})}();return Promise.resolve(o&&o.then?o.then(r):r())}catch(e){return Promise.reject(e)}},t.requestInvoice=function(e){try{var t=this;if(!t.lnurlpData)throw new Error("No lnurlpData available. Please call fetch() first.");var r=1e3*e.satoshi,n=t.lnurlpData,o=n.commentAllowed;if(!d({amount:r,min:n.min,max:n.max}))throw new Error("Invalid amount");if(e.comment&&o&&o>0&&e.comment.length>o)throw new Error("The comment length must be "+o+" characters or fewer");var i={amount:r.toString()};return e.comment&&(i.comment=e.comment),e.payerdata&&(i.payerdata=JSON.stringify(e.payerdata)),Promise.resolve(t.generateInvoice(i))}catch(e){return Promise.reject(e)}},t.boost=function(e,t){void 0===t&&(t=0);try{var r=this;if(!r.keysendData)throw new Error("No keysendData available. Please call fetch() first.");var n=r.keysendData,o=n.destination,i=n.customKey,a=n.customValue,s=r.getWebLN();if(!s)throw new Error("WebLN not available");return Promise.resolve(h({destination:o,customKey:i,customValue:a,amount:t,boost:e},{webln:s}))}catch(e){return Promise.reject(e)}},t.zapInvoice=function(e,t){var r=e.satoshi,n=e.comment,o=e.relays,i=e.e;void 0===t&&(t={});try{var a=this;if(!a.lnurlpData)throw new Error("No lnurlpData available. Please call fetch() first.");if(!a.nostrPubkey)throw new Error("Nostr Pubkey is missing");var s=a.nostrPubkey,u=1e3*r,l=a.lnurlpData,c=l.allowsNostr;if(!d({amount:u,min:l.min,max:l.max}))throw new Error("Invalid amount");if(!c)throw new Error("Your provider does not support zaps");return Promise.resolve(w({satoshi:u,comment:n,p:s,e:i,relays:o},t)).then(function(e){var t={amount:u.toString(),nostr:JSON.stringify(e)};return Promise.resolve(a.generateInvoice(t))})}catch(i){return Promise.reject(i)}},t.zap=function(e,t){void 0===t&&(t={});try{var r=this.zapInvoice(e,t),n=this.getWebLN();if(!n)throw new Error("WebLN not available");return Promise.resolve(n.enable()).then(function(){var e=n.sendPayment;return Promise.resolve(r).then(function(t){return e.call(n,t.paymentRequest)})})}catch(e){return Promise.reject(e)}},t.parseResponse=function(e,t,r){if(e&&(this.lnurlpData=function(e){if("payRequest"!==e.tag)throw new Error("Invalid pay service params");var t=(e.callback+"").trim();if(!p(t))throw new Error("Callback must be a valid url");var r,n,a=Math.ceil(Number(e.minSendable||0)),s=Math.floor(Number(e.maxSendable));if(!a||!s||a>s)throw new Error("Invalid pay service params");try{r=JSON.parse(e.metadata+""),n=i.default(e.metadata+"").toString(o.default)}catch(e){r=[],n=i.default("[]").toString(o.default)}for(var u="",l="",c="",h=0;h<r.length;h++){var m=r[h],f=m[0],v=m[1];switch(f){case"text/plain":l=v;break;case"text/identifier":c=v;break;case"image/png;base64":case"image/jpeg;base64":u="data:"+f+","+v}}var d,y=e.payerData;try{d=new URL(t).hostname}catch(e){}return{callback:t,fixed:a===s,min:a,max:s,domain:d,metadata:r,metadataHash:n,identifier:c,description:l,image:u,payerData:y,commentAllowed:Number(e.commentAllowed)||0,rawData:e,allowsNostr:e.allowsNostr||!1}}(e)),t&&(this.keysendData=function(e){if("keysend"!==e.tag)throw new Error("Invalid keysend params");if("OK"!==e.status)throw new Error("Keysend status not OK");if(!("customKey"in e.customData[0])||"696969"!=e.customData[0].customKey)throw new Error("Unable to find customKey");if(!("customValue"in e.customData[0])||!e.customData[0].customValue)throw new Error("Unable to find customValue");if(!e.pubkey)throw new Error("Pubkey does not exist");return{destination:e.pubkey,customKey:e.customData[0].customKey,customValue:e.customData[0].customValue}}(t)),r){var n=k(r,this.username);this.nostrData=n[0],this.nostrPubkey=n[1],this.nostrRelays=n[2]}},e}(),E=function(e){try{var t="https://getalby.com/api/rates/"+e.toLowerCase()+".json";return Promise.resolve(fetch(t)).then(function(e){return Promise.resolve(e.json()).then(function(e){return e.rate_float/1e8})})}catch(e){return Promise.reject(e)}},N=function(e){var t=e.satoshi;return Promise.resolve(E(e.currency)).then(function(e){return Number(t)*e})},S={__proto__:null,getFiatBtcRate:E,getFiatValue:N,getSatoshiValue:function(e){var t=e.amount;return Promise.resolve(E(e.currency)).then(function(e){return Math.floor(Number(t)/e)})},getFormattedFiatValue:function(e){var t=e.currency,r=e.locale;return r||(r="en"),Promise.resolve(N({satoshi:e.satoshi,currency:t})).then(function(e){return e.toLocaleString(r,{style:"currency",currency:t})})}};exports.Invoice=y,exports.LightningAddress=j,exports.boostagrams=m,exports.fetchWithL402=l,exports.fiat=S,exports.l402=c,exports.nostr=x,exports.sendBoostagram=h;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
},{"crypto-js/enc-hex.js":6,"crypto-js/sha256.js":7,"light-bolt11-decoder":8}],2:[function(require,module,exports){
|
|
6
|
-
// assign alby-tools exports to global window object (for index.browser.js)
|
|
7
|
-
// @ts-ignore this file is created at build time
|
|
8
|
-
window["lightningTools"] = require("./index.cjs");
|
|
9
|
-
|
|
10
|
-
},{"./index.cjs":1}],3:[function(require,module,exports){
|
|
11
|
-
"use strict";
|
|
12
|
-
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.bytes = exports.stringToBytes = exports.str = exports.bytesToString = exports.hex = exports.utf8 = exports.bech32m = exports.bech32 = exports.base58check = exports.base58xmr = exports.base58xrp = exports.base58flickr = exports.base58 = exports.base64url = exports.base64 = exports.base32crockford = exports.base32hex = exports.base32 = exports.base16 = exports.utils = exports.assertNumber = void 0;
|
|
15
|
-
function assertNumber(n) {
|
|
16
|
-
if (!Number.isSafeInteger(n))
|
|
17
|
-
throw new Error(`Wrong integer: ${n}`);
|
|
18
|
-
}
|
|
19
|
-
exports.assertNumber = assertNumber;
|
|
20
|
-
function chain(...args) {
|
|
21
|
-
const wrap = (a, b) => (c) => a(b(c));
|
|
22
|
-
const encode = Array.from(args)
|
|
23
|
-
.reverse()
|
|
24
|
-
.reduce((acc, i) => (acc ? wrap(acc, i.encode) : i.encode), undefined);
|
|
25
|
-
const decode = args.reduce((acc, i) => (acc ? wrap(acc, i.decode) : i.decode), undefined);
|
|
26
|
-
return { encode, decode };
|
|
27
|
-
}
|
|
28
|
-
function alphabet(alphabet) {
|
|
29
|
-
return {
|
|
30
|
-
encode: (digits) => {
|
|
31
|
-
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
|
|
32
|
-
throw new Error('alphabet.encode input should be an array of numbers');
|
|
33
|
-
return digits.map((i) => {
|
|
34
|
-
assertNumber(i);
|
|
35
|
-
if (i < 0 || i >= alphabet.length)
|
|
36
|
-
throw new Error(`Digit index outside alphabet: ${i} (alphabet: ${alphabet.length})`);
|
|
37
|
-
return alphabet[i];
|
|
38
|
-
});
|
|
39
|
-
},
|
|
40
|
-
decode: (input) => {
|
|
41
|
-
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
|
|
42
|
-
throw new Error('alphabet.decode input should be array of strings');
|
|
43
|
-
return input.map((letter) => {
|
|
44
|
-
if (typeof letter !== 'string')
|
|
45
|
-
throw new Error(`alphabet.decode: not string element=${letter}`);
|
|
46
|
-
const index = alphabet.indexOf(letter);
|
|
47
|
-
if (index === -1)
|
|
48
|
-
throw new Error(`Unknown letter: "${letter}". Allowed: ${alphabet}`);
|
|
49
|
-
return index;
|
|
50
|
-
});
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
function join(separator = '') {
|
|
55
|
-
if (typeof separator !== 'string')
|
|
56
|
-
throw new Error('join separator should be string');
|
|
57
|
-
return {
|
|
58
|
-
encode: (from) => {
|
|
59
|
-
if (!Array.isArray(from) || (from.length && typeof from[0] !== 'string'))
|
|
60
|
-
throw new Error('join.encode input should be array of strings');
|
|
61
|
-
for (let i of from)
|
|
62
|
-
if (typeof i !== 'string')
|
|
63
|
-
throw new Error(`join.encode: non-string input=${i}`);
|
|
64
|
-
return from.join(separator);
|
|
65
|
-
},
|
|
66
|
-
decode: (to) => {
|
|
67
|
-
if (typeof to !== 'string')
|
|
68
|
-
throw new Error('join.decode input should be string');
|
|
69
|
-
return to.split(separator);
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
function padding(bits, chr = '=') {
|
|
74
|
-
assertNumber(bits);
|
|
75
|
-
if (typeof chr !== 'string')
|
|
76
|
-
throw new Error('padding chr should be string');
|
|
77
|
-
return {
|
|
78
|
-
encode(data) {
|
|
79
|
-
if (!Array.isArray(data) || (data.length && typeof data[0] !== 'string'))
|
|
80
|
-
throw new Error('padding.encode input should be array of strings');
|
|
81
|
-
for (let i of data)
|
|
82
|
-
if (typeof i !== 'string')
|
|
83
|
-
throw new Error(`padding.encode: non-string input=${i}`);
|
|
84
|
-
while ((data.length * bits) % 8)
|
|
85
|
-
data.push(chr);
|
|
86
|
-
return data;
|
|
87
|
-
},
|
|
88
|
-
decode(input) {
|
|
89
|
-
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
|
|
90
|
-
throw new Error('padding.encode input should be array of strings');
|
|
91
|
-
for (let i of input)
|
|
92
|
-
if (typeof i !== 'string')
|
|
93
|
-
throw new Error(`padding.decode: non-string input=${i}`);
|
|
94
|
-
let end = input.length;
|
|
95
|
-
if ((end * bits) % 8)
|
|
96
|
-
throw new Error('Invalid padding: string should have whole number of bytes');
|
|
97
|
-
for (; end > 0 && input[end - 1] === chr; end--) {
|
|
98
|
-
if (!(((end - 1) * bits) % 8))
|
|
99
|
-
throw new Error('Invalid padding: string has too much padding');
|
|
100
|
-
}
|
|
101
|
-
return input.slice(0, end);
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
function normalize(fn) {
|
|
106
|
-
if (typeof fn !== 'function')
|
|
107
|
-
throw new Error('normalize fn should be function');
|
|
108
|
-
return { encode: (from) => from, decode: (to) => fn(to) };
|
|
109
|
-
}
|
|
110
|
-
function convertRadix(data, from, to) {
|
|
111
|
-
if (from < 2)
|
|
112
|
-
throw new Error(`convertRadix: wrong from=${from}, base cannot be less than 2`);
|
|
113
|
-
if (to < 2)
|
|
114
|
-
throw new Error(`convertRadix: wrong to=${to}, base cannot be less than 2`);
|
|
115
|
-
if (!Array.isArray(data))
|
|
116
|
-
throw new Error('convertRadix: data should be array');
|
|
117
|
-
if (!data.length)
|
|
118
|
-
return [];
|
|
119
|
-
let pos = 0;
|
|
120
|
-
const res = [];
|
|
121
|
-
const digits = Array.from(data);
|
|
122
|
-
digits.forEach((d) => {
|
|
123
|
-
assertNumber(d);
|
|
124
|
-
if (d < 0 || d >= from)
|
|
125
|
-
throw new Error(`Wrong integer: ${d}`);
|
|
126
|
-
});
|
|
127
|
-
while (true) {
|
|
128
|
-
let carry = 0;
|
|
129
|
-
let done = true;
|
|
130
|
-
for (let i = pos; i < digits.length; i++) {
|
|
131
|
-
const digit = digits[i];
|
|
132
|
-
const digitBase = from * carry + digit;
|
|
133
|
-
if (!Number.isSafeInteger(digitBase) ||
|
|
134
|
-
(from * carry) / from !== carry ||
|
|
135
|
-
digitBase - digit !== from * carry) {
|
|
136
|
-
throw new Error('convertRadix: carry overflow');
|
|
137
|
-
}
|
|
138
|
-
carry = digitBase % to;
|
|
139
|
-
digits[i] = Math.floor(digitBase / to);
|
|
140
|
-
if (!Number.isSafeInteger(digits[i]) || digits[i] * to + carry !== digitBase)
|
|
141
|
-
throw new Error('convertRadix: carry overflow');
|
|
142
|
-
if (!done)
|
|
143
|
-
continue;
|
|
144
|
-
else if (!digits[i])
|
|
145
|
-
pos = i;
|
|
146
|
-
else
|
|
147
|
-
done = false;
|
|
148
|
-
}
|
|
149
|
-
res.push(carry);
|
|
150
|
-
if (done)
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
|
|
154
|
-
res.push(0);
|
|
155
|
-
return res.reverse();
|
|
156
|
-
}
|
|
157
|
-
const gcd = (a, b) => (!b ? a : gcd(b, a % b));
|
|
158
|
-
const radix2carry = (from, to) => from + (to - gcd(from, to));
|
|
159
|
-
function convertRadix2(data, from, to, padding) {
|
|
160
|
-
if (!Array.isArray(data))
|
|
161
|
-
throw new Error('convertRadix2: data should be array');
|
|
162
|
-
if (from <= 0 || from > 32)
|
|
163
|
-
throw new Error(`convertRadix2: wrong from=${from}`);
|
|
164
|
-
if (to <= 0 || to > 32)
|
|
165
|
-
throw new Error(`convertRadix2: wrong to=${to}`);
|
|
166
|
-
if (radix2carry(from, to) > 32) {
|
|
167
|
-
throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);
|
|
168
|
-
}
|
|
169
|
-
let carry = 0;
|
|
170
|
-
let pos = 0;
|
|
171
|
-
const mask = 2 ** to - 1;
|
|
172
|
-
const res = [];
|
|
173
|
-
for (const n of data) {
|
|
174
|
-
assertNumber(n);
|
|
175
|
-
if (n >= 2 ** from)
|
|
176
|
-
throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
|
|
177
|
-
carry = (carry << from) | n;
|
|
178
|
-
if (pos + from > 32)
|
|
179
|
-
throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
|
|
180
|
-
pos += from;
|
|
181
|
-
for (; pos >= to; pos -= to)
|
|
182
|
-
res.push(((carry >> (pos - to)) & mask) >>> 0);
|
|
183
|
-
carry &= 2 ** pos - 1;
|
|
184
|
-
}
|
|
185
|
-
carry = (carry << (to - pos)) & mask;
|
|
186
|
-
if (!padding && pos >= from)
|
|
187
|
-
throw new Error('Excess padding');
|
|
188
|
-
if (!padding && carry)
|
|
189
|
-
throw new Error(`Non-zero padding: ${carry}`);
|
|
190
|
-
if (padding && pos > 0)
|
|
191
|
-
res.push(carry >>> 0);
|
|
192
|
-
return res;
|
|
193
|
-
}
|
|
194
|
-
function radix(num) {
|
|
195
|
-
assertNumber(num);
|
|
196
|
-
return {
|
|
197
|
-
encode: (bytes) => {
|
|
198
|
-
if (!(bytes instanceof Uint8Array))
|
|
199
|
-
throw new Error('radix.encode input should be Uint8Array');
|
|
200
|
-
return convertRadix(Array.from(bytes), 2 ** 8, num);
|
|
201
|
-
},
|
|
202
|
-
decode: (digits) => {
|
|
203
|
-
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
|
|
204
|
-
throw new Error('radix.decode input should be array of strings');
|
|
205
|
-
return Uint8Array.from(convertRadix(digits, num, 2 ** 8));
|
|
206
|
-
},
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
function radix2(bits, revPadding = false) {
|
|
210
|
-
assertNumber(bits);
|
|
211
|
-
if (bits <= 0 || bits > 32)
|
|
212
|
-
throw new Error('radix2: bits should be in (0..32]');
|
|
213
|
-
if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)
|
|
214
|
-
throw new Error('radix2: carry overflow');
|
|
215
|
-
return {
|
|
216
|
-
encode: (bytes) => {
|
|
217
|
-
if (!(bytes instanceof Uint8Array))
|
|
218
|
-
throw new Error('radix2.encode input should be Uint8Array');
|
|
219
|
-
return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
|
|
220
|
-
},
|
|
221
|
-
decode: (digits) => {
|
|
222
|
-
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
|
|
223
|
-
throw new Error('radix2.decode input should be array of strings');
|
|
224
|
-
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
|
|
225
|
-
},
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
function unsafeWrapper(fn) {
|
|
229
|
-
if (typeof fn !== 'function')
|
|
230
|
-
throw new Error('unsafeWrapper fn should be function');
|
|
231
|
-
return function (...args) {
|
|
232
|
-
try {
|
|
233
|
-
return fn.apply(null, args);
|
|
234
|
-
}
|
|
235
|
-
catch (e) { }
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
function checksum(len, fn) {
|
|
239
|
-
assertNumber(len);
|
|
240
|
-
if (typeof fn !== 'function')
|
|
241
|
-
throw new Error('checksum fn should be function');
|
|
242
|
-
return {
|
|
243
|
-
encode(data) {
|
|
244
|
-
if (!(data instanceof Uint8Array))
|
|
245
|
-
throw new Error('checksum.encode: input should be Uint8Array');
|
|
246
|
-
const checksum = fn(data).slice(0, len);
|
|
247
|
-
const res = new Uint8Array(data.length + len);
|
|
248
|
-
res.set(data);
|
|
249
|
-
res.set(checksum, data.length);
|
|
250
|
-
return res;
|
|
251
|
-
},
|
|
252
|
-
decode(data) {
|
|
253
|
-
if (!(data instanceof Uint8Array))
|
|
254
|
-
throw new Error('checksum.decode: input should be Uint8Array');
|
|
255
|
-
const payload = data.slice(0, -len);
|
|
256
|
-
const newChecksum = fn(payload).slice(0, len);
|
|
257
|
-
const oldChecksum = data.slice(-len);
|
|
258
|
-
for (let i = 0; i < len; i++)
|
|
259
|
-
if (newChecksum[i] !== oldChecksum[i])
|
|
260
|
-
throw new Error('Invalid checksum');
|
|
261
|
-
return payload;
|
|
262
|
-
},
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
exports.utils = { alphabet, chain, checksum, radix, radix2, join, padding };
|
|
266
|
-
exports.base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));
|
|
267
|
-
exports.base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));
|
|
268
|
-
exports.base32hex = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));
|
|
269
|
-
exports.base32crockford = chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));
|
|
270
|
-
exports.base64 = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));
|
|
271
|
-
exports.base64url = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));
|
|
272
|
-
const genBase58 = (abc) => chain(radix(58), alphabet(abc), join(''));
|
|
273
|
-
exports.base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
|
|
274
|
-
exports.base58flickr = genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');
|
|
275
|
-
exports.base58xrp = genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');
|
|
276
|
-
const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];
|
|
277
|
-
exports.base58xmr = {
|
|
278
|
-
encode(data) {
|
|
279
|
-
let res = '';
|
|
280
|
-
for (let i = 0; i < data.length; i += 8) {
|
|
281
|
-
const block = data.subarray(i, i + 8);
|
|
282
|
-
res += exports.base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');
|
|
283
|
-
}
|
|
284
|
-
return res;
|
|
285
|
-
},
|
|
286
|
-
decode(str) {
|
|
287
|
-
let res = [];
|
|
288
|
-
for (let i = 0; i < str.length; i += 11) {
|
|
289
|
-
const slice = str.slice(i, i + 11);
|
|
290
|
-
const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);
|
|
291
|
-
const block = exports.base58.decode(slice);
|
|
292
|
-
for (let j = 0; j < block.length - blockLen; j++) {
|
|
293
|
-
if (block[j] !== 0)
|
|
294
|
-
throw new Error('base58xmr: wrong padding');
|
|
295
|
-
}
|
|
296
|
-
res = res.concat(Array.from(block.slice(block.length - blockLen)));
|
|
297
|
-
}
|
|
298
|
-
return Uint8Array.from(res);
|
|
299
|
-
},
|
|
300
|
-
};
|
|
301
|
-
const base58check = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), exports.base58);
|
|
302
|
-
exports.base58check = base58check;
|
|
303
|
-
const BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));
|
|
304
|
-
const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
|
|
305
|
-
function bech32Polymod(pre) {
|
|
306
|
-
const b = pre >> 25;
|
|
307
|
-
let chk = (pre & 0x1ffffff) << 5;
|
|
308
|
-
for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
|
|
309
|
-
if (((b >> i) & 1) === 1)
|
|
310
|
-
chk ^= POLYMOD_GENERATORS[i];
|
|
311
|
-
}
|
|
312
|
-
return chk;
|
|
313
|
-
}
|
|
314
|
-
function bechChecksum(prefix, words, encodingConst = 1) {
|
|
315
|
-
const len = prefix.length;
|
|
316
|
-
let chk = 1;
|
|
317
|
-
for (let i = 0; i < len; i++) {
|
|
318
|
-
const c = prefix.charCodeAt(i);
|
|
319
|
-
if (c < 33 || c > 126)
|
|
320
|
-
throw new Error(`Invalid prefix (${prefix})`);
|
|
321
|
-
chk = bech32Polymod(chk) ^ (c >> 5);
|
|
322
|
-
}
|
|
323
|
-
chk = bech32Polymod(chk);
|
|
324
|
-
for (let i = 0; i < len; i++)
|
|
325
|
-
chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);
|
|
326
|
-
for (let v of words)
|
|
327
|
-
chk = bech32Polymod(chk) ^ v;
|
|
328
|
-
for (let i = 0; i < 6; i++)
|
|
329
|
-
chk = bech32Polymod(chk);
|
|
330
|
-
chk ^= encodingConst;
|
|
331
|
-
return BECH_ALPHABET.encode(convertRadix2([chk % 2 ** 30], 30, 5, false));
|
|
332
|
-
}
|
|
333
|
-
function genBech32(encoding) {
|
|
334
|
-
const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;
|
|
335
|
-
const _words = radix2(5);
|
|
336
|
-
const fromWords = _words.decode;
|
|
337
|
-
const toWords = _words.encode;
|
|
338
|
-
const fromWordsUnsafe = unsafeWrapper(fromWords);
|
|
339
|
-
function encode(prefix, words, limit = 90) {
|
|
340
|
-
if (typeof prefix !== 'string')
|
|
341
|
-
throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`);
|
|
342
|
-
if (!Array.isArray(words) || (words.length && typeof words[0] !== 'number'))
|
|
343
|
-
throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`);
|
|
344
|
-
const actualLength = prefix.length + 7 + words.length;
|
|
345
|
-
if (limit !== false && actualLength > limit)
|
|
346
|
-
throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
|
|
347
|
-
prefix = prefix.toLowerCase();
|
|
348
|
-
return `${prefix}1${BECH_ALPHABET.encode(words)}${bechChecksum(prefix, words, ENCODING_CONST)}`;
|
|
349
|
-
}
|
|
350
|
-
function decode(str, limit = 90) {
|
|
351
|
-
if (typeof str !== 'string')
|
|
352
|
-
throw new Error(`bech32.decode input should be string, not ${typeof str}`);
|
|
353
|
-
if (str.length < 8 || (limit !== false && str.length > limit))
|
|
354
|
-
throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`);
|
|
355
|
-
const lowered = str.toLowerCase();
|
|
356
|
-
if (str !== lowered && str !== str.toUpperCase())
|
|
357
|
-
throw new Error(`String must be lowercase or uppercase`);
|
|
358
|
-
str = lowered;
|
|
359
|
-
const sepIndex = str.lastIndexOf('1');
|
|
360
|
-
if (sepIndex === 0 || sepIndex === -1)
|
|
361
|
-
throw new Error(`Letter "1" must be present between prefix and data only`);
|
|
362
|
-
const prefix = str.slice(0, sepIndex);
|
|
363
|
-
const _words = str.slice(sepIndex + 1);
|
|
364
|
-
if (_words.length < 6)
|
|
365
|
-
throw new Error('Data must be at least 6 characters long');
|
|
366
|
-
const words = BECH_ALPHABET.decode(_words).slice(0, -6);
|
|
367
|
-
const sum = bechChecksum(prefix, words, ENCODING_CONST);
|
|
368
|
-
if (!_words.endsWith(sum))
|
|
369
|
-
throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
|
|
370
|
-
return { prefix, words };
|
|
371
|
-
}
|
|
372
|
-
const decodeUnsafe = unsafeWrapper(decode);
|
|
373
|
-
function decodeToBytes(str) {
|
|
374
|
-
const { prefix, words } = decode(str, false);
|
|
375
|
-
return { prefix, words, bytes: fromWords(words) };
|
|
376
|
-
}
|
|
377
|
-
return { encode, decode, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords };
|
|
378
|
-
}
|
|
379
|
-
exports.bech32 = genBech32('bech32');
|
|
380
|
-
exports.bech32m = genBech32('bech32m');
|
|
381
|
-
exports.utf8 = {
|
|
382
|
-
encode: (data) => new TextDecoder().decode(data),
|
|
383
|
-
decode: (str) => new TextEncoder().encode(str),
|
|
384
|
-
};
|
|
385
|
-
exports.hex = chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {
|
|
386
|
-
if (typeof s !== 'string' || s.length % 2)
|
|
387
|
-
throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);
|
|
388
|
-
return s.toLowerCase();
|
|
389
|
-
}));
|
|
390
|
-
const CODERS = {
|
|
391
|
-
utf8: exports.utf8, hex: exports.hex, base16: exports.base16, base32: exports.base32, base64: exports.base64, base64url: exports.base64url, base58: exports.base58, base58xmr: exports.base58xmr
|
|
392
|
-
};
|
|
393
|
-
const coderTypeError = `Invalid encoding type. Available types: ${Object.keys(CODERS).join(', ')}`;
|
|
394
|
-
const bytesToString = (type, bytes) => {
|
|
395
|
-
if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))
|
|
396
|
-
throw new TypeError(coderTypeError);
|
|
397
|
-
if (!(bytes instanceof Uint8Array))
|
|
398
|
-
throw new TypeError('bytesToString() expects Uint8Array');
|
|
399
|
-
return CODERS[type].encode(bytes);
|
|
400
|
-
};
|
|
401
|
-
exports.bytesToString = bytesToString;
|
|
402
|
-
exports.str = exports.bytesToString;
|
|
403
|
-
const stringToBytes = (type, str) => {
|
|
404
|
-
if (!CODERS.hasOwnProperty(type))
|
|
405
|
-
throw new TypeError(coderTypeError);
|
|
406
|
-
if (typeof str !== 'string')
|
|
407
|
-
throw new TypeError('stringToBytes() expects string');
|
|
408
|
-
return CODERS[type].decode(str);
|
|
409
|
-
};
|
|
410
|
-
exports.stringToBytes = stringToBytes;
|
|
411
|
-
exports.bytes = exports.stringToBytes;
|
|
412
|
-
|
|
413
|
-
},{}],4:[function(require,module,exports){
|
|
414
|
-
|
|
415
|
-
},{}],5:[function(require,module,exports){
|
|
416
|
-
(function (global){(function (){
|
|
417
|
-
;(function (root, factory) {
|
|
418
|
-
if (typeof exports === "object") {
|
|
419
|
-
// CommonJS
|
|
420
|
-
module.exports = exports = factory();
|
|
421
|
-
}
|
|
422
|
-
else if (typeof define === "function" && define.amd) {
|
|
423
|
-
// AMD
|
|
424
|
-
define([], factory);
|
|
425
|
-
}
|
|
426
|
-
else {
|
|
427
|
-
// Global (browser)
|
|
428
|
-
root.CryptoJS = factory();
|
|
429
|
-
}
|
|
430
|
-
}(this, function () {
|
|
431
|
-
|
|
432
|
-
/*globals window, global, require*/
|
|
433
|
-
|
|
434
|
-
/**
|
|
435
|
-
* CryptoJS core components.
|
|
436
|
-
*/
|
|
437
|
-
var CryptoJS = CryptoJS || (function (Math, undefined) {
|
|
438
|
-
|
|
439
|
-
var crypto;
|
|
440
|
-
|
|
441
|
-
// Native crypto from window (Browser)
|
|
442
|
-
if (typeof window !== 'undefined' && window.crypto) {
|
|
443
|
-
crypto = window.crypto;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
// Native crypto in web worker (Browser)
|
|
447
|
-
if (typeof self !== 'undefined' && self.crypto) {
|
|
448
|
-
crypto = self.crypto;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// Native crypto from worker
|
|
452
|
-
if (typeof globalThis !== 'undefined' && globalThis.crypto) {
|
|
453
|
-
crypto = globalThis.crypto;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
// Native (experimental IE 11) crypto from window (Browser)
|
|
457
|
-
if (!crypto && typeof window !== 'undefined' && window.msCrypto) {
|
|
458
|
-
crypto = window.msCrypto;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
// Native crypto from global (NodeJS)
|
|
462
|
-
if (!crypto && typeof global !== 'undefined' && global.crypto) {
|
|
463
|
-
crypto = global.crypto;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
// Native crypto import via require (NodeJS)
|
|
467
|
-
if (!crypto && typeof require === 'function') {
|
|
468
|
-
try {
|
|
469
|
-
crypto = require('crypto');
|
|
470
|
-
} catch (err) {}
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
/*
|
|
474
|
-
* Cryptographically secure pseudorandom number generator
|
|
475
|
-
*
|
|
476
|
-
* As Math.random() is cryptographically not safe to use
|
|
477
|
-
*/
|
|
478
|
-
var cryptoSecureRandomInt = function () {
|
|
479
|
-
if (crypto) {
|
|
480
|
-
// Use getRandomValues method (Browser)
|
|
481
|
-
if (typeof crypto.getRandomValues === 'function') {
|
|
482
|
-
try {
|
|
483
|
-
return crypto.getRandomValues(new Uint32Array(1))[0];
|
|
484
|
-
} catch (err) {}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// Use randomBytes method (NodeJS)
|
|
488
|
-
if (typeof crypto.randomBytes === 'function') {
|
|
489
|
-
try {
|
|
490
|
-
return crypto.randomBytes(4).readInt32LE();
|
|
491
|
-
} catch (err) {}
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
throw new Error('Native crypto module could not be used to get secure random number.');
|
|
496
|
-
};
|
|
497
|
-
|
|
498
|
-
/*
|
|
499
|
-
* Local polyfill of Object.create
|
|
500
|
-
|
|
501
|
-
*/
|
|
502
|
-
var create = Object.create || (function () {
|
|
503
|
-
function F() {}
|
|
504
|
-
|
|
505
|
-
return function (obj) {
|
|
506
|
-
var subtype;
|
|
507
|
-
|
|
508
|
-
F.prototype = obj;
|
|
509
|
-
|
|
510
|
-
subtype = new F();
|
|
511
|
-
|
|
512
|
-
F.prototype = null;
|
|
513
|
-
|
|
514
|
-
return subtype;
|
|
515
|
-
};
|
|
516
|
-
}());
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* CryptoJS namespace.
|
|
520
|
-
*/
|
|
521
|
-
var C = {};
|
|
522
|
-
|
|
523
|
-
/**
|
|
524
|
-
* Library namespace.
|
|
525
|
-
*/
|
|
526
|
-
var C_lib = C.lib = {};
|
|
527
|
-
|
|
528
|
-
/**
|
|
529
|
-
* Base object for prototypal inheritance.
|
|
530
|
-
*/
|
|
531
|
-
var Base = C_lib.Base = (function () {
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
return {
|
|
535
|
-
/**
|
|
536
|
-
* Creates a new object that inherits from this object.
|
|
537
|
-
*
|
|
538
|
-
* @param {Object} overrides Properties to copy into the new object.
|
|
539
|
-
*
|
|
540
|
-
* @return {Object} The new object.
|
|
541
|
-
*
|
|
542
|
-
* @static
|
|
543
|
-
*
|
|
544
|
-
* @example
|
|
545
|
-
*
|
|
546
|
-
* var MyType = CryptoJS.lib.Base.extend({
|
|
547
|
-
* field: 'value',
|
|
548
|
-
*
|
|
549
|
-
* method: function () {
|
|
550
|
-
* }
|
|
551
|
-
* });
|
|
552
|
-
*/
|
|
553
|
-
extend: function (overrides) {
|
|
554
|
-
// Spawn
|
|
555
|
-
var subtype = create(this);
|
|
556
|
-
|
|
557
|
-
// Augment
|
|
558
|
-
if (overrides) {
|
|
559
|
-
subtype.mixIn(overrides);
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
// Create default initializer
|
|
563
|
-
if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {
|
|
564
|
-
subtype.init = function () {
|
|
565
|
-
subtype.$super.init.apply(this, arguments);
|
|
566
|
-
};
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// Initializer's prototype is the subtype object
|
|
570
|
-
subtype.init.prototype = subtype;
|
|
571
|
-
|
|
572
|
-
// Reference supertype
|
|
573
|
-
subtype.$super = this;
|
|
574
|
-
|
|
575
|
-
return subtype;
|
|
576
|
-
},
|
|
577
|
-
|
|
578
|
-
/**
|
|
579
|
-
* Extends this object and runs the init method.
|
|
580
|
-
* Arguments to create() will be passed to init().
|
|
581
|
-
*
|
|
582
|
-
* @return {Object} The new object.
|
|
583
|
-
*
|
|
584
|
-
* @static
|
|
585
|
-
*
|
|
586
|
-
* @example
|
|
587
|
-
*
|
|
588
|
-
* var instance = MyType.create();
|
|
589
|
-
*/
|
|
590
|
-
create: function () {
|
|
591
|
-
var instance = this.extend();
|
|
592
|
-
instance.init.apply(instance, arguments);
|
|
593
|
-
|
|
594
|
-
return instance;
|
|
595
|
-
},
|
|
596
|
-
|
|
597
|
-
/**
|
|
598
|
-
* Initializes a newly created object.
|
|
599
|
-
* Override this method to add some logic when your objects are created.
|
|
600
|
-
*
|
|
601
|
-
* @example
|
|
602
|
-
*
|
|
603
|
-
* var MyType = CryptoJS.lib.Base.extend({
|
|
604
|
-
* init: function () {
|
|
605
|
-
* // ...
|
|
606
|
-
* }
|
|
607
|
-
* });
|
|
608
|
-
*/
|
|
609
|
-
init: function () {
|
|
610
|
-
},
|
|
611
|
-
|
|
612
|
-
/**
|
|
613
|
-
* Copies properties into this object.
|
|
614
|
-
*
|
|
615
|
-
* @param {Object} properties The properties to mix in.
|
|
616
|
-
*
|
|
617
|
-
* @example
|
|
618
|
-
*
|
|
619
|
-
* MyType.mixIn({
|
|
620
|
-
* field: 'value'
|
|
621
|
-
* });
|
|
622
|
-
*/
|
|
623
|
-
mixIn: function (properties) {
|
|
624
|
-
for (var propertyName in properties) {
|
|
625
|
-
if (properties.hasOwnProperty(propertyName)) {
|
|
626
|
-
this[propertyName] = properties[propertyName];
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
// IE won't copy toString using the loop above
|
|
631
|
-
if (properties.hasOwnProperty('toString')) {
|
|
632
|
-
this.toString = properties.toString;
|
|
633
|
-
}
|
|
634
|
-
},
|
|
635
|
-
|
|
636
|
-
/**
|
|
637
|
-
* Creates a copy of this object.
|
|
638
|
-
*
|
|
639
|
-
* @return {Object} The clone.
|
|
640
|
-
*
|
|
641
|
-
* @example
|
|
642
|
-
*
|
|
643
|
-
* var clone = instance.clone();
|
|
644
|
-
*/
|
|
645
|
-
clone: function () {
|
|
646
|
-
return this.init.prototype.extend(this);
|
|
647
|
-
}
|
|
648
|
-
};
|
|
649
|
-
}());
|
|
650
|
-
|
|
651
|
-
/**
|
|
652
|
-
* An array of 32-bit words.
|
|
653
|
-
*
|
|
654
|
-
* @property {Array} words The array of 32-bit words.
|
|
655
|
-
* @property {number} sigBytes The number of significant bytes in this word array.
|
|
656
|
-
*/
|
|
657
|
-
var WordArray = C_lib.WordArray = Base.extend({
|
|
658
|
-
/**
|
|
659
|
-
* Initializes a newly created word array.
|
|
660
|
-
*
|
|
661
|
-
* @param {Array} words (Optional) An array of 32-bit words.
|
|
662
|
-
* @param {number} sigBytes (Optional) The number of significant bytes in the words.
|
|
663
|
-
*
|
|
664
|
-
* @example
|
|
665
|
-
*
|
|
666
|
-
* var wordArray = CryptoJS.lib.WordArray.create();
|
|
667
|
-
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
|
|
668
|
-
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
|
|
669
|
-
*/
|
|
670
|
-
init: function (words, sigBytes) {
|
|
671
|
-
words = this.words = words || [];
|
|
672
|
-
|
|
673
|
-
if (sigBytes != undefined) {
|
|
674
|
-
this.sigBytes = sigBytes;
|
|
675
|
-
} else {
|
|
676
|
-
this.sigBytes = words.length * 4;
|
|
677
|
-
}
|
|
678
|
-
},
|
|
679
|
-
|
|
680
|
-
/**
|
|
681
|
-
* Converts this word array to a string.
|
|
682
|
-
*
|
|
683
|
-
* @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
|
|
684
|
-
*
|
|
685
|
-
* @return {string} The stringified word array.
|
|
686
|
-
*
|
|
687
|
-
* @example
|
|
688
|
-
*
|
|
689
|
-
* var string = wordArray + '';
|
|
690
|
-
* var string = wordArray.toString();
|
|
691
|
-
* var string = wordArray.toString(CryptoJS.enc.Utf8);
|
|
692
|
-
*/
|
|
693
|
-
toString: function (encoder) {
|
|
694
|
-
return (encoder || Hex).stringify(this);
|
|
695
|
-
},
|
|
696
|
-
|
|
697
|
-
/**
|
|
698
|
-
* Concatenates a word array to this word array.
|
|
699
|
-
*
|
|
700
|
-
* @param {WordArray} wordArray The word array to append.
|
|
701
|
-
*
|
|
702
|
-
* @return {WordArray} This word array.
|
|
703
|
-
*
|
|
704
|
-
* @example
|
|
705
|
-
*
|
|
706
|
-
* wordArray1.concat(wordArray2);
|
|
707
|
-
*/
|
|
708
|
-
concat: function (wordArray) {
|
|
709
|
-
// Shortcuts
|
|
710
|
-
var thisWords = this.words;
|
|
711
|
-
var thatWords = wordArray.words;
|
|
712
|
-
var thisSigBytes = this.sigBytes;
|
|
713
|
-
var thatSigBytes = wordArray.sigBytes;
|
|
714
|
-
|
|
715
|
-
// Clamp excess bits
|
|
716
|
-
this.clamp();
|
|
717
|
-
|
|
718
|
-
// Concat
|
|
719
|
-
if (thisSigBytes % 4) {
|
|
720
|
-
// Copy one byte at a time
|
|
721
|
-
for (var i = 0; i < thatSigBytes; i++) {
|
|
722
|
-
var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
|
|
723
|
-
thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
|
|
724
|
-
}
|
|
725
|
-
} else {
|
|
726
|
-
// Copy one word at a time
|
|
727
|
-
for (var j = 0; j < thatSigBytes; j += 4) {
|
|
728
|
-
thisWords[(thisSigBytes + j) >>> 2] = thatWords[j >>> 2];
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
this.sigBytes += thatSigBytes;
|
|
732
|
-
|
|
733
|
-
// Chainable
|
|
734
|
-
return this;
|
|
735
|
-
},
|
|
736
|
-
|
|
737
|
-
/**
|
|
738
|
-
* Removes insignificant bits.
|
|
739
|
-
*
|
|
740
|
-
* @example
|
|
741
|
-
*
|
|
742
|
-
* wordArray.clamp();
|
|
743
|
-
*/
|
|
744
|
-
clamp: function () {
|
|
745
|
-
// Shortcuts
|
|
746
|
-
var words = this.words;
|
|
747
|
-
var sigBytes = this.sigBytes;
|
|
748
|
-
|
|
749
|
-
// Clamp
|
|
750
|
-
words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
|
|
751
|
-
words.length = Math.ceil(sigBytes / 4);
|
|
752
|
-
},
|
|
753
|
-
|
|
754
|
-
/**
|
|
755
|
-
* Creates a copy of this word array.
|
|
756
|
-
*
|
|
757
|
-
* @return {WordArray} The clone.
|
|
758
|
-
*
|
|
759
|
-
* @example
|
|
760
|
-
*
|
|
761
|
-
* var clone = wordArray.clone();
|
|
762
|
-
*/
|
|
763
|
-
clone: function () {
|
|
764
|
-
var clone = Base.clone.call(this);
|
|
765
|
-
clone.words = this.words.slice(0);
|
|
766
|
-
|
|
767
|
-
return clone;
|
|
768
|
-
},
|
|
769
|
-
|
|
770
|
-
/**
|
|
771
|
-
* Creates a word array filled with random bytes.
|
|
772
|
-
*
|
|
773
|
-
* @param {number} nBytes The number of random bytes to generate.
|
|
774
|
-
*
|
|
775
|
-
* @return {WordArray} The random word array.
|
|
776
|
-
*
|
|
777
|
-
* @static
|
|
778
|
-
*
|
|
779
|
-
* @example
|
|
780
|
-
*
|
|
781
|
-
* var wordArray = CryptoJS.lib.WordArray.random(16);
|
|
782
|
-
*/
|
|
783
|
-
random: function (nBytes) {
|
|
784
|
-
var words = [];
|
|
785
|
-
|
|
786
|
-
for (var i = 0; i < nBytes; i += 4) {
|
|
787
|
-
words.push(cryptoSecureRandomInt());
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
return new WordArray.init(words, nBytes);
|
|
791
|
-
}
|
|
792
|
-
});
|
|
793
|
-
|
|
794
|
-
/**
|
|
795
|
-
* Encoder namespace.
|
|
796
|
-
*/
|
|
797
|
-
var C_enc = C.enc = {};
|
|
798
|
-
|
|
799
|
-
/**
|
|
800
|
-
* Hex encoding strategy.
|
|
801
|
-
*/
|
|
802
|
-
var Hex = C_enc.Hex = {
|
|
803
|
-
/**
|
|
804
|
-
* Converts a word array to a hex string.
|
|
805
|
-
*
|
|
806
|
-
* @param {WordArray} wordArray The word array.
|
|
807
|
-
*
|
|
808
|
-
* @return {string} The hex string.
|
|
809
|
-
*
|
|
810
|
-
* @static
|
|
811
|
-
*
|
|
812
|
-
* @example
|
|
813
|
-
*
|
|
814
|
-
* var hexString = CryptoJS.enc.Hex.stringify(wordArray);
|
|
815
|
-
*/
|
|
816
|
-
stringify: function (wordArray) {
|
|
817
|
-
// Shortcuts
|
|
818
|
-
var words = wordArray.words;
|
|
819
|
-
var sigBytes = wordArray.sigBytes;
|
|
820
|
-
|
|
821
|
-
// Convert
|
|
822
|
-
var hexChars = [];
|
|
823
|
-
for (var i = 0; i < sigBytes; i++) {
|
|
824
|
-
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
|
|
825
|
-
hexChars.push((bite >>> 4).toString(16));
|
|
826
|
-
hexChars.push((bite & 0x0f).toString(16));
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
return hexChars.join('');
|
|
830
|
-
},
|
|
831
|
-
|
|
832
|
-
/**
|
|
833
|
-
* Converts a hex string to a word array.
|
|
834
|
-
*
|
|
835
|
-
* @param {string} hexStr The hex string.
|
|
836
|
-
*
|
|
837
|
-
* @return {WordArray} The word array.
|
|
838
|
-
*
|
|
839
|
-
* @static
|
|
840
|
-
*
|
|
841
|
-
* @example
|
|
842
|
-
*
|
|
843
|
-
* var wordArray = CryptoJS.enc.Hex.parse(hexString);
|
|
844
|
-
*/
|
|
845
|
-
parse: function (hexStr) {
|
|
846
|
-
// Shortcut
|
|
847
|
-
var hexStrLength = hexStr.length;
|
|
848
|
-
|
|
849
|
-
// Convert
|
|
850
|
-
var words = [];
|
|
851
|
-
for (var i = 0; i < hexStrLength; i += 2) {
|
|
852
|
-
words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
return new WordArray.init(words, hexStrLength / 2);
|
|
856
|
-
}
|
|
857
|
-
};
|
|
858
|
-
|
|
859
|
-
/**
|
|
860
|
-
* Latin1 encoding strategy.
|
|
861
|
-
*/
|
|
862
|
-
var Latin1 = C_enc.Latin1 = {
|
|
863
|
-
/**
|
|
864
|
-
* Converts a word array to a Latin1 string.
|
|
865
|
-
*
|
|
866
|
-
* @param {WordArray} wordArray The word array.
|
|
867
|
-
*
|
|
868
|
-
* @return {string} The Latin1 string.
|
|
869
|
-
*
|
|
870
|
-
* @static
|
|
871
|
-
*
|
|
872
|
-
* @example
|
|
873
|
-
*
|
|
874
|
-
* var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
|
|
875
|
-
*/
|
|
876
|
-
stringify: function (wordArray) {
|
|
877
|
-
// Shortcuts
|
|
878
|
-
var words = wordArray.words;
|
|
879
|
-
var sigBytes = wordArray.sigBytes;
|
|
880
|
-
|
|
881
|
-
// Convert
|
|
882
|
-
var latin1Chars = [];
|
|
883
|
-
for (var i = 0; i < sigBytes; i++) {
|
|
884
|
-
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
|
|
885
|
-
latin1Chars.push(String.fromCharCode(bite));
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
return latin1Chars.join('');
|
|
889
|
-
},
|
|
890
|
-
|
|
891
|
-
/**
|
|
892
|
-
* Converts a Latin1 string to a word array.
|
|
893
|
-
*
|
|
894
|
-
* @param {string} latin1Str The Latin1 string.
|
|
895
|
-
*
|
|
896
|
-
* @return {WordArray} The word array.
|
|
897
|
-
*
|
|
898
|
-
* @static
|
|
899
|
-
*
|
|
900
|
-
* @example
|
|
901
|
-
*
|
|
902
|
-
* var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
|
|
903
|
-
*/
|
|
904
|
-
parse: function (latin1Str) {
|
|
905
|
-
// Shortcut
|
|
906
|
-
var latin1StrLength = latin1Str.length;
|
|
907
|
-
|
|
908
|
-
// Convert
|
|
909
|
-
var words = [];
|
|
910
|
-
for (var i = 0; i < latin1StrLength; i++) {
|
|
911
|
-
words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
return new WordArray.init(words, latin1StrLength);
|
|
915
|
-
}
|
|
916
|
-
};
|
|
917
|
-
|
|
918
|
-
/**
|
|
919
|
-
* UTF-8 encoding strategy.
|
|
920
|
-
*/
|
|
921
|
-
var Utf8 = C_enc.Utf8 = {
|
|
922
|
-
/**
|
|
923
|
-
* Converts a word array to a UTF-8 string.
|
|
924
|
-
*
|
|
925
|
-
* @param {WordArray} wordArray The word array.
|
|
926
|
-
*
|
|
927
|
-
* @return {string} The UTF-8 string.
|
|
928
|
-
*
|
|
929
|
-
* @static
|
|
930
|
-
*
|
|
931
|
-
* @example
|
|
932
|
-
*
|
|
933
|
-
* var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
|
|
934
|
-
*/
|
|
935
|
-
stringify: function (wordArray) {
|
|
936
|
-
try {
|
|
937
|
-
return decodeURIComponent(escape(Latin1.stringify(wordArray)));
|
|
938
|
-
} catch (e) {
|
|
939
|
-
throw new Error('Malformed UTF-8 data');
|
|
940
|
-
}
|
|
941
|
-
},
|
|
942
|
-
|
|
943
|
-
/**
|
|
944
|
-
* Converts a UTF-8 string to a word array.
|
|
945
|
-
*
|
|
946
|
-
* @param {string} utf8Str The UTF-8 string.
|
|
947
|
-
*
|
|
948
|
-
* @return {WordArray} The word array.
|
|
949
|
-
*
|
|
950
|
-
* @static
|
|
951
|
-
*
|
|
952
|
-
* @example
|
|
953
|
-
*
|
|
954
|
-
* var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
|
|
955
|
-
*/
|
|
956
|
-
parse: function (utf8Str) {
|
|
957
|
-
return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
|
|
958
|
-
}
|
|
959
|
-
};
|
|
960
|
-
|
|
961
|
-
/**
|
|
962
|
-
* Abstract buffered block algorithm template.
|
|
963
|
-
*
|
|
964
|
-
* The property blockSize must be implemented in a concrete subtype.
|
|
965
|
-
*
|
|
966
|
-
* @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
|
|
967
|
-
*/
|
|
968
|
-
var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
|
|
969
|
-
/**
|
|
970
|
-
* Resets this block algorithm's data buffer to its initial state.
|
|
971
|
-
*
|
|
972
|
-
* @example
|
|
973
|
-
*
|
|
974
|
-
* bufferedBlockAlgorithm.reset();
|
|
975
|
-
*/
|
|
976
|
-
reset: function () {
|
|
977
|
-
// Initial values
|
|
978
|
-
this._data = new WordArray.init();
|
|
979
|
-
this._nDataBytes = 0;
|
|
980
|
-
},
|
|
981
|
-
|
|
982
|
-
/**
|
|
983
|
-
* Adds new data to this block algorithm's buffer.
|
|
984
|
-
*
|
|
985
|
-
* @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
|
|
986
|
-
*
|
|
987
|
-
* @example
|
|
988
|
-
*
|
|
989
|
-
* bufferedBlockAlgorithm._append('data');
|
|
990
|
-
* bufferedBlockAlgorithm._append(wordArray);
|
|
991
|
-
*/
|
|
992
|
-
_append: function (data) {
|
|
993
|
-
// Convert string to WordArray, else assume WordArray already
|
|
994
|
-
if (typeof data == 'string') {
|
|
995
|
-
data = Utf8.parse(data);
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
// Append
|
|
999
|
-
this._data.concat(data);
|
|
1000
|
-
this._nDataBytes += data.sigBytes;
|
|
1001
|
-
},
|
|
1002
|
-
|
|
1003
|
-
/**
|
|
1004
|
-
* Processes available data blocks.
|
|
1005
|
-
*
|
|
1006
|
-
* This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
|
|
1007
|
-
*
|
|
1008
|
-
* @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
|
|
1009
|
-
*
|
|
1010
|
-
* @return {WordArray} The processed data.
|
|
1011
|
-
*
|
|
1012
|
-
* @example
|
|
1013
|
-
*
|
|
1014
|
-
* var processedData = bufferedBlockAlgorithm._process();
|
|
1015
|
-
* var processedData = bufferedBlockAlgorithm._process(!!'flush');
|
|
1016
|
-
*/
|
|
1017
|
-
_process: function (doFlush) {
|
|
1018
|
-
var processedWords;
|
|
1019
|
-
|
|
1020
|
-
// Shortcuts
|
|
1021
|
-
var data = this._data;
|
|
1022
|
-
var dataWords = data.words;
|
|
1023
|
-
var dataSigBytes = data.sigBytes;
|
|
1024
|
-
var blockSize = this.blockSize;
|
|
1025
|
-
var blockSizeBytes = blockSize * 4;
|
|
1026
|
-
|
|
1027
|
-
// Count blocks ready
|
|
1028
|
-
var nBlocksReady = dataSigBytes / blockSizeBytes;
|
|
1029
|
-
if (doFlush) {
|
|
1030
|
-
// Round up to include partial blocks
|
|
1031
|
-
nBlocksReady = Math.ceil(nBlocksReady);
|
|
1032
|
-
} else {
|
|
1033
|
-
// Round down to include only full blocks,
|
|
1034
|
-
// less the number of blocks that must remain in the buffer
|
|
1035
|
-
nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
// Count words ready
|
|
1039
|
-
var nWordsReady = nBlocksReady * blockSize;
|
|
1040
|
-
|
|
1041
|
-
// Count bytes ready
|
|
1042
|
-
var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
|
|
1043
|
-
|
|
1044
|
-
// Process blocks
|
|
1045
|
-
if (nWordsReady) {
|
|
1046
|
-
for (var offset = 0; offset < nWordsReady; offset += blockSize) {
|
|
1047
|
-
// Perform concrete-algorithm logic
|
|
1048
|
-
this._doProcessBlock(dataWords, offset);
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
// Remove processed words
|
|
1052
|
-
processedWords = dataWords.splice(0, nWordsReady);
|
|
1053
|
-
data.sigBytes -= nBytesReady;
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
|
-
// Return processed words
|
|
1057
|
-
return new WordArray.init(processedWords, nBytesReady);
|
|
1058
|
-
},
|
|
1059
|
-
|
|
1060
|
-
/**
|
|
1061
|
-
* Creates a copy of this object.
|
|
1062
|
-
*
|
|
1063
|
-
* @return {Object} The clone.
|
|
1064
|
-
*
|
|
1065
|
-
* @example
|
|
1066
|
-
*
|
|
1067
|
-
* var clone = bufferedBlockAlgorithm.clone();
|
|
1068
|
-
*/
|
|
1069
|
-
clone: function () {
|
|
1070
|
-
var clone = Base.clone.call(this);
|
|
1071
|
-
clone._data = this._data.clone();
|
|
1072
|
-
|
|
1073
|
-
return clone;
|
|
1074
|
-
},
|
|
1075
|
-
|
|
1076
|
-
_minBufferSize: 0
|
|
1077
|
-
});
|
|
1078
|
-
|
|
1079
|
-
/**
|
|
1080
|
-
* Abstract hasher template.
|
|
1081
|
-
*
|
|
1082
|
-
* @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
|
|
1083
|
-
*/
|
|
1084
|
-
var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
|
|
1085
|
-
/**
|
|
1086
|
-
* Configuration options.
|
|
1087
|
-
*/
|
|
1088
|
-
cfg: Base.extend(),
|
|
1089
|
-
|
|
1090
|
-
/**
|
|
1091
|
-
* Initializes a newly created hasher.
|
|
1092
|
-
*
|
|
1093
|
-
* @param {Object} cfg (Optional) The configuration options to use for this hash computation.
|
|
1094
|
-
*
|
|
1095
|
-
* @example
|
|
1096
|
-
*
|
|
1097
|
-
* var hasher = CryptoJS.algo.SHA256.create();
|
|
1098
|
-
*/
|
|
1099
|
-
init: function (cfg) {
|
|
1100
|
-
// Apply config defaults
|
|
1101
|
-
this.cfg = this.cfg.extend(cfg);
|
|
1102
|
-
|
|
1103
|
-
// Set initial values
|
|
1104
|
-
this.reset();
|
|
1105
|
-
},
|
|
1106
|
-
|
|
1107
|
-
/**
|
|
1108
|
-
* Resets this hasher to its initial state.
|
|
1109
|
-
*
|
|
1110
|
-
* @example
|
|
1111
|
-
*
|
|
1112
|
-
* hasher.reset();
|
|
1113
|
-
*/
|
|
1114
|
-
reset: function () {
|
|
1115
|
-
// Reset data buffer
|
|
1116
|
-
BufferedBlockAlgorithm.reset.call(this);
|
|
1117
|
-
|
|
1118
|
-
// Perform concrete-hasher logic
|
|
1119
|
-
this._doReset();
|
|
1120
|
-
},
|
|
1121
|
-
|
|
1122
|
-
/**
|
|
1123
|
-
* Updates this hasher with a message.
|
|
1124
|
-
*
|
|
1125
|
-
* @param {WordArray|string} messageUpdate The message to append.
|
|
1126
|
-
*
|
|
1127
|
-
* @return {Hasher} This hasher.
|
|
1128
|
-
*
|
|
1129
|
-
* @example
|
|
1130
|
-
*
|
|
1131
|
-
* hasher.update('message');
|
|
1132
|
-
* hasher.update(wordArray);
|
|
1133
|
-
*/
|
|
1134
|
-
update: function (messageUpdate) {
|
|
1135
|
-
// Append
|
|
1136
|
-
this._append(messageUpdate);
|
|
1137
|
-
|
|
1138
|
-
// Update the hash
|
|
1139
|
-
this._process();
|
|
1140
|
-
|
|
1141
|
-
// Chainable
|
|
1142
|
-
return this;
|
|
1143
|
-
},
|
|
1144
|
-
|
|
1145
|
-
/**
|
|
1146
|
-
* Finalizes the hash computation.
|
|
1147
|
-
* Note that the finalize operation is effectively a destructive, read-once operation.
|
|
1148
|
-
*
|
|
1149
|
-
* @param {WordArray|string} messageUpdate (Optional) A final message update.
|
|
1150
|
-
*
|
|
1151
|
-
* @return {WordArray} The hash.
|
|
1152
|
-
*
|
|
1153
|
-
* @example
|
|
1154
|
-
*
|
|
1155
|
-
* var hash = hasher.finalize();
|
|
1156
|
-
* var hash = hasher.finalize('message');
|
|
1157
|
-
* var hash = hasher.finalize(wordArray);
|
|
1158
|
-
*/
|
|
1159
|
-
finalize: function (messageUpdate) {
|
|
1160
|
-
// Final message update
|
|
1161
|
-
if (messageUpdate) {
|
|
1162
|
-
this._append(messageUpdate);
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
// Perform concrete-hasher logic
|
|
1166
|
-
var hash = this._doFinalize();
|
|
1167
|
-
|
|
1168
|
-
return hash;
|
|
1169
|
-
},
|
|
1170
|
-
|
|
1171
|
-
blockSize: 512/32,
|
|
1172
|
-
|
|
1173
|
-
/**
|
|
1174
|
-
* Creates a shortcut function to a hasher's object interface.
|
|
1175
|
-
*
|
|
1176
|
-
* @param {Hasher} hasher The hasher to create a helper for.
|
|
1177
|
-
*
|
|
1178
|
-
* @return {Function} The shortcut function.
|
|
1179
|
-
*
|
|
1180
|
-
* @static
|
|
1181
|
-
*
|
|
1182
|
-
* @example
|
|
1183
|
-
*
|
|
1184
|
-
* var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
|
|
1185
|
-
*/
|
|
1186
|
-
_createHelper: function (hasher) {
|
|
1187
|
-
return function (message, cfg) {
|
|
1188
|
-
return new hasher.init(cfg).finalize(message);
|
|
1189
|
-
};
|
|
1190
|
-
},
|
|
1191
|
-
|
|
1192
|
-
/**
|
|
1193
|
-
* Creates a shortcut function to the HMAC's object interface.
|
|
1194
|
-
*
|
|
1195
|
-
* @param {Hasher} hasher The hasher to use in this HMAC helper.
|
|
1196
|
-
*
|
|
1197
|
-
* @return {Function} The shortcut function.
|
|
1198
|
-
*
|
|
1199
|
-
* @static
|
|
1200
|
-
*
|
|
1201
|
-
* @example
|
|
1202
|
-
*
|
|
1203
|
-
* var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
|
|
1204
|
-
*/
|
|
1205
|
-
_createHmacHelper: function (hasher) {
|
|
1206
|
-
return function (message, key) {
|
|
1207
|
-
return new C_algo.HMAC.init(hasher, key).finalize(message);
|
|
1208
|
-
};
|
|
1209
|
-
}
|
|
1210
|
-
});
|
|
1211
|
-
|
|
1212
|
-
/**
|
|
1213
|
-
* Algorithm namespace.
|
|
1214
|
-
*/
|
|
1215
|
-
var C_algo = C.algo = {};
|
|
1216
|
-
|
|
1217
|
-
return C;
|
|
1218
|
-
}(Math));
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
return CryptoJS;
|
|
1222
|
-
|
|
1223
|
-
}));
|
|
1224
|
-
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
1225
|
-
},{"crypto":4}],6:[function(require,module,exports){
|
|
1226
|
-
;(function (root, factory) {
|
|
1227
|
-
if (typeof exports === "object") {
|
|
1228
|
-
// CommonJS
|
|
1229
|
-
module.exports = exports = factory(require("./core"));
|
|
1230
|
-
}
|
|
1231
|
-
else if (typeof define === "function" && define.amd) {
|
|
1232
|
-
// AMD
|
|
1233
|
-
define(["./core"], factory);
|
|
1234
|
-
}
|
|
1235
|
-
else {
|
|
1236
|
-
// Global (browser)
|
|
1237
|
-
factory(root.CryptoJS);
|
|
1238
|
-
}
|
|
1239
|
-
}(this, function (CryptoJS) {
|
|
1240
|
-
|
|
1241
|
-
return CryptoJS.enc.Hex;
|
|
1242
|
-
|
|
1243
|
-
}));
|
|
1244
|
-
},{"./core":5}],7:[function(require,module,exports){
|
|
1245
|
-
;(function (root, factory) {
|
|
1246
|
-
if (typeof exports === "object") {
|
|
1247
|
-
// CommonJS
|
|
1248
|
-
module.exports = exports = factory(require("./core"));
|
|
1249
|
-
}
|
|
1250
|
-
else if (typeof define === "function" && define.amd) {
|
|
1251
|
-
// AMD
|
|
1252
|
-
define(["./core"], factory);
|
|
1253
|
-
}
|
|
1254
|
-
else {
|
|
1255
|
-
// Global (browser)
|
|
1256
|
-
factory(root.CryptoJS);
|
|
1257
|
-
}
|
|
1258
|
-
}(this, function (CryptoJS) {
|
|
1259
|
-
|
|
1260
|
-
(function (Math) {
|
|
1261
|
-
// Shortcuts
|
|
1262
|
-
var C = CryptoJS;
|
|
1263
|
-
var C_lib = C.lib;
|
|
1264
|
-
var WordArray = C_lib.WordArray;
|
|
1265
|
-
var Hasher = C_lib.Hasher;
|
|
1266
|
-
var C_algo = C.algo;
|
|
1267
|
-
|
|
1268
|
-
// Initialization and round constants tables
|
|
1269
|
-
var H = [];
|
|
1270
|
-
var K = [];
|
|
1271
|
-
|
|
1272
|
-
// Compute constants
|
|
1273
|
-
(function () {
|
|
1274
|
-
function isPrime(n) {
|
|
1275
|
-
var sqrtN = Math.sqrt(n);
|
|
1276
|
-
for (var factor = 2; factor <= sqrtN; factor++) {
|
|
1277
|
-
if (!(n % factor)) {
|
|
1278
|
-
return false;
|
|
1279
|
-
}
|
|
1280
|
-
}
|
|
1281
|
-
|
|
1282
|
-
return true;
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
function getFractionalBits(n) {
|
|
1286
|
-
return ((n - (n | 0)) * 0x100000000) | 0;
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
var n = 2;
|
|
1290
|
-
var nPrime = 0;
|
|
1291
|
-
while (nPrime < 64) {
|
|
1292
|
-
if (isPrime(n)) {
|
|
1293
|
-
if (nPrime < 8) {
|
|
1294
|
-
H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));
|
|
1295
|
-
}
|
|
1296
|
-
K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));
|
|
1297
|
-
|
|
1298
|
-
nPrime++;
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
n++;
|
|
1302
|
-
}
|
|
1303
|
-
}());
|
|
1304
|
-
|
|
1305
|
-
// Reusable object
|
|
1306
|
-
var W = [];
|
|
1307
|
-
|
|
1308
|
-
/**
|
|
1309
|
-
* SHA-256 hash algorithm.
|
|
1310
|
-
*/
|
|
1311
|
-
var SHA256 = C_algo.SHA256 = Hasher.extend({
|
|
1312
|
-
_doReset: function () {
|
|
1313
|
-
this._hash = new WordArray.init(H.slice(0));
|
|
1314
|
-
},
|
|
1315
|
-
|
|
1316
|
-
_doProcessBlock: function (M, offset) {
|
|
1317
|
-
// Shortcut
|
|
1318
|
-
var H = this._hash.words;
|
|
1319
|
-
|
|
1320
|
-
// Working variables
|
|
1321
|
-
var a = H[0];
|
|
1322
|
-
var b = H[1];
|
|
1323
|
-
var c = H[2];
|
|
1324
|
-
var d = H[3];
|
|
1325
|
-
var e = H[4];
|
|
1326
|
-
var f = H[5];
|
|
1327
|
-
var g = H[6];
|
|
1328
|
-
var h = H[7];
|
|
1329
|
-
|
|
1330
|
-
// Computation
|
|
1331
|
-
for (var i = 0; i < 64; i++) {
|
|
1332
|
-
if (i < 16) {
|
|
1333
|
-
W[i] = M[offset + i] | 0;
|
|
1334
|
-
} else {
|
|
1335
|
-
var gamma0x = W[i - 15];
|
|
1336
|
-
var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
|
|
1337
|
-
((gamma0x << 14) | (gamma0x >>> 18)) ^
|
|
1338
|
-
(gamma0x >>> 3);
|
|
1339
|
-
|
|
1340
|
-
var gamma1x = W[i - 2];
|
|
1341
|
-
var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
|
|
1342
|
-
((gamma1x << 13) | (gamma1x >>> 19)) ^
|
|
1343
|
-
(gamma1x >>> 10);
|
|
1344
|
-
|
|
1345
|
-
W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];
|
|
1346
|
-
}
|
|
1347
|
-
|
|
1348
|
-
var ch = (e & f) ^ (~e & g);
|
|
1349
|
-
var maj = (a & b) ^ (a & c) ^ (b & c);
|
|
1350
|
-
|
|
1351
|
-
var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));
|
|
1352
|
-
var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25));
|
|
1353
|
-
|
|
1354
|
-
var t1 = h + sigma1 + ch + K[i] + W[i];
|
|
1355
|
-
var t2 = sigma0 + maj;
|
|
1356
|
-
|
|
1357
|
-
h = g;
|
|
1358
|
-
g = f;
|
|
1359
|
-
f = e;
|
|
1360
|
-
e = (d + t1) | 0;
|
|
1361
|
-
d = c;
|
|
1362
|
-
c = b;
|
|
1363
|
-
b = a;
|
|
1364
|
-
a = (t1 + t2) | 0;
|
|
1365
|
-
}
|
|
1366
|
-
|
|
1367
|
-
// Intermediate hash value
|
|
1368
|
-
H[0] = (H[0] + a) | 0;
|
|
1369
|
-
H[1] = (H[1] + b) | 0;
|
|
1370
|
-
H[2] = (H[2] + c) | 0;
|
|
1371
|
-
H[3] = (H[3] + d) | 0;
|
|
1372
|
-
H[4] = (H[4] + e) | 0;
|
|
1373
|
-
H[5] = (H[5] + f) | 0;
|
|
1374
|
-
H[6] = (H[6] + g) | 0;
|
|
1375
|
-
H[7] = (H[7] + h) | 0;
|
|
1376
|
-
},
|
|
1377
|
-
|
|
1378
|
-
_doFinalize: function () {
|
|
1379
|
-
// Shortcuts
|
|
1380
|
-
var data = this._data;
|
|
1381
|
-
var dataWords = data.words;
|
|
1382
|
-
|
|
1383
|
-
var nBitsTotal = this._nDataBytes * 8;
|
|
1384
|
-
var nBitsLeft = data.sigBytes * 8;
|
|
1385
|
-
|
|
1386
|
-
// Add padding
|
|
1387
|
-
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
|
|
1388
|
-
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
|
|
1389
|
-
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
|
|
1390
|
-
data.sigBytes = dataWords.length * 4;
|
|
1391
|
-
|
|
1392
|
-
// Hash final blocks
|
|
1393
|
-
this._process();
|
|
1394
|
-
|
|
1395
|
-
// Return final computed hash
|
|
1396
|
-
return this._hash;
|
|
1397
|
-
},
|
|
1398
|
-
|
|
1399
|
-
clone: function () {
|
|
1400
|
-
var clone = Hasher.clone.call(this);
|
|
1401
|
-
clone._hash = this._hash.clone();
|
|
1402
|
-
|
|
1403
|
-
return clone;
|
|
1404
|
-
}
|
|
1405
|
-
});
|
|
1406
|
-
|
|
1407
|
-
/**
|
|
1408
|
-
* Shortcut function to the hasher's object interface.
|
|
1409
|
-
*
|
|
1410
|
-
* @param {WordArray|string} message The message to hash.
|
|
1411
|
-
*
|
|
1412
|
-
* @return {WordArray} The hash.
|
|
1413
|
-
*
|
|
1414
|
-
* @static
|
|
1415
|
-
*
|
|
1416
|
-
* @example
|
|
1417
|
-
*
|
|
1418
|
-
* var hash = CryptoJS.SHA256('message');
|
|
1419
|
-
* var hash = CryptoJS.SHA256(wordArray);
|
|
1420
|
-
*/
|
|
1421
|
-
C.SHA256 = Hasher._createHelper(SHA256);
|
|
1422
|
-
|
|
1423
|
-
/**
|
|
1424
|
-
* Shortcut function to the HMAC's object interface.
|
|
1425
|
-
*
|
|
1426
|
-
* @param {WordArray|string} message The message to hash.
|
|
1427
|
-
* @param {WordArray|string} key The secret key.
|
|
1428
|
-
*
|
|
1429
|
-
* @return {WordArray} The HMAC.
|
|
1430
|
-
*
|
|
1431
|
-
* @static
|
|
1432
|
-
*
|
|
1433
|
-
* @example
|
|
1434
|
-
*
|
|
1435
|
-
* var hmac = CryptoJS.HmacSHA256(message, key);
|
|
1436
|
-
*/
|
|
1437
|
-
C.HmacSHA256 = Hasher._createHmacHelper(SHA256);
|
|
1438
|
-
}(Math));
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
return CryptoJS.SHA256;
|
|
1442
|
-
|
|
1443
|
-
}));
|
|
1444
|
-
},{"./core":5}],8:[function(require,module,exports){
|
|
1445
|
-
const {bech32, hex, utf8} = require('@scure/base')
|
|
1446
|
-
|
|
1447
|
-
// defaults for encode; default timestamp is current time at call
|
|
1448
|
-
const DEFAULTNETWORK = {
|
|
1449
|
-
// default network is bitcoin
|
|
1450
|
-
bech32: 'bc',
|
|
1451
|
-
pubKeyHash: 0x00,
|
|
1452
|
-
scriptHash: 0x05,
|
|
1453
|
-
validWitnessVersions: [0]
|
|
1454
|
-
}
|
|
1455
|
-
const TESTNETWORK = {
|
|
1456
|
-
bech32: 'tb',
|
|
1457
|
-
pubKeyHash: 0x6f,
|
|
1458
|
-
scriptHash: 0xc4,
|
|
1459
|
-
validWitnessVersions: [0]
|
|
1460
|
-
}
|
|
1461
|
-
const REGTESTNETWORK = {
|
|
1462
|
-
bech32: 'bcrt',
|
|
1463
|
-
pubKeyHash: 0x6f,
|
|
1464
|
-
scriptHash: 0xc4,
|
|
1465
|
-
validWitnessVersions: [0]
|
|
1466
|
-
}
|
|
1467
|
-
const SIMNETWORK = {
|
|
1468
|
-
bech32: 'sb',
|
|
1469
|
-
pubKeyHash: 0x3f,
|
|
1470
|
-
scriptHash: 0x7b,
|
|
1471
|
-
validWitnessVersions: [0]
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
const FEATUREBIT_ORDER = [
|
|
1475
|
-
'option_data_loss_protect',
|
|
1476
|
-
'initial_routing_sync',
|
|
1477
|
-
'option_upfront_shutdown_script',
|
|
1478
|
-
'gossip_queries',
|
|
1479
|
-
'var_onion_optin',
|
|
1480
|
-
'gossip_queries_ex',
|
|
1481
|
-
'option_static_remotekey',
|
|
1482
|
-
'payment_secret',
|
|
1483
|
-
'basic_mpp',
|
|
1484
|
-
'option_support_large_channel'
|
|
1485
|
-
]
|
|
1486
|
-
|
|
1487
|
-
const DIVISORS = {
|
|
1488
|
-
m: BigInt(1e3),
|
|
1489
|
-
u: BigInt(1e6),
|
|
1490
|
-
n: BigInt(1e9),
|
|
1491
|
-
p: BigInt(1e12)
|
|
1492
|
-
}
|
|
1493
|
-
|
|
1494
|
-
const MAX_MILLISATS = BigInt('2100000000000000000')
|
|
1495
|
-
|
|
1496
|
-
const MILLISATS_PER_BTC = BigInt(1e11)
|
|
1497
|
-
|
|
1498
|
-
const TAGCODES = {
|
|
1499
|
-
payment_hash: 1,
|
|
1500
|
-
payment_secret: 16,
|
|
1501
|
-
description: 13,
|
|
1502
|
-
payee: 19,
|
|
1503
|
-
description_hash: 23, // commit to longer descriptions (used by lnurl-pay)
|
|
1504
|
-
expiry: 6, // default: 3600 (1 hour)
|
|
1505
|
-
min_final_cltv_expiry: 24, // default: 9
|
|
1506
|
-
fallback_address: 9,
|
|
1507
|
-
route_hint: 3, // for extra routing info (private etc.)
|
|
1508
|
-
feature_bits: 5,
|
|
1509
|
-
metadata: 27
|
|
1510
|
-
}
|
|
1511
|
-
|
|
1512
|
-
// reverse the keys and values of TAGCODES and insert into TAGNAMES
|
|
1513
|
-
const TAGNAMES = {}
|
|
1514
|
-
for (let i = 0, keys = Object.keys(TAGCODES); i < keys.length; i++) {
|
|
1515
|
-
const currentName = keys[i]
|
|
1516
|
-
const currentCode = TAGCODES[keys[i]].toString()
|
|
1517
|
-
TAGNAMES[currentCode] = currentName
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
|
-
const TAGPARSERS = {
|
|
1521
|
-
1: words => hex.encode(bech32.fromWordsUnsafe(words)), // 256 bits
|
|
1522
|
-
16: words => hex.encode(bech32.fromWordsUnsafe(words)), // 256 bits
|
|
1523
|
-
13: words => utf8.encode(bech32.fromWordsUnsafe(words)), // string variable length
|
|
1524
|
-
19: words => hex.encode(bech32.fromWordsUnsafe(words)), // 264 bits
|
|
1525
|
-
23: words => hex.encode(bech32.fromWordsUnsafe(words)), // 256 bits
|
|
1526
|
-
27: words => hex.encode(bech32.fromWordsUnsafe(words)), // variable
|
|
1527
|
-
6: wordsToIntBE, // default: 3600 (1 hour)
|
|
1528
|
-
24: wordsToIntBE, // default: 9
|
|
1529
|
-
3: routingInfoParser, // for extra routing info (private etc.)
|
|
1530
|
-
5: featureBitsParser // keep feature bits as array of 5 bit words
|
|
1531
|
-
}
|
|
1532
|
-
|
|
1533
|
-
function getUnknownParser(tagCode) {
|
|
1534
|
-
return words => ({
|
|
1535
|
-
tagCode: parseInt(tagCode),
|
|
1536
|
-
words: bech32.encode('unknown', words, Number.MAX_SAFE_INTEGER)
|
|
1537
|
-
})
|
|
1538
|
-
}
|
|
1539
|
-
|
|
1540
|
-
function wordsToIntBE(words) {
|
|
1541
|
-
return words.reverse().reduce((total, item, index) => {
|
|
1542
|
-
return total + item * Math.pow(32, index)
|
|
1543
|
-
}, 0)
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
|
-
// first convert from words to buffer, trimming padding where necessary
|
|
1547
|
-
// parse in 51 byte chunks. See encoder for details.
|
|
1548
|
-
function routingInfoParser(words) {
|
|
1549
|
-
const routes = []
|
|
1550
|
-
let pubkey,
|
|
1551
|
-
shortChannelId,
|
|
1552
|
-
feeBaseMSats,
|
|
1553
|
-
feeProportionalMillionths,
|
|
1554
|
-
cltvExpiryDelta
|
|
1555
|
-
let routesBuffer = bech32.fromWordsUnsafe(words)
|
|
1556
|
-
while (routesBuffer.length > 0) {
|
|
1557
|
-
pubkey = hex.encode(routesBuffer.slice(0, 33)) // 33 bytes
|
|
1558
|
-
shortChannelId = hex.encode(routesBuffer.slice(33, 41)) // 8 bytes
|
|
1559
|
-
feeBaseMSats = parseInt(hex.encode(routesBuffer.slice(41, 45)), 16) // 4 bytes
|
|
1560
|
-
feeProportionalMillionths = parseInt(
|
|
1561
|
-
hex.encode(routesBuffer.slice(45, 49)),
|
|
1562
|
-
16
|
|
1563
|
-
) // 4 bytes
|
|
1564
|
-
cltvExpiryDelta = parseInt(hex.encode(routesBuffer.slice(49, 51)), 16) // 2 bytes
|
|
1565
|
-
|
|
1566
|
-
routesBuffer = routesBuffer.slice(51)
|
|
1567
|
-
|
|
1568
|
-
routes.push({
|
|
1569
|
-
pubkey,
|
|
1570
|
-
short_channel_id: shortChannelId,
|
|
1571
|
-
fee_base_msat: feeBaseMSats,
|
|
1572
|
-
fee_proportional_millionths: feeProportionalMillionths,
|
|
1573
|
-
cltv_expiry_delta: cltvExpiryDelta
|
|
1574
|
-
})
|
|
1575
|
-
}
|
|
1576
|
-
return routes
|
|
1577
|
-
}
|
|
1578
|
-
|
|
1579
|
-
function featureBitsParser(words) {
|
|
1580
|
-
const bools = words
|
|
1581
|
-
.slice()
|
|
1582
|
-
.reverse()
|
|
1583
|
-
.map(word => [
|
|
1584
|
-
!!(word & 0b1),
|
|
1585
|
-
!!(word & 0b10),
|
|
1586
|
-
!!(word & 0b100),
|
|
1587
|
-
!!(word & 0b1000),
|
|
1588
|
-
!!(word & 0b10000)
|
|
1589
|
-
])
|
|
1590
|
-
.reduce((finalArr, itemArr) => finalArr.concat(itemArr), [])
|
|
1591
|
-
while (bools.length < FEATUREBIT_ORDER.length * 2) {
|
|
1592
|
-
bools.push(false)
|
|
1593
|
-
}
|
|
1594
|
-
|
|
1595
|
-
const featureBits = {}
|
|
1596
|
-
|
|
1597
|
-
FEATUREBIT_ORDER.forEach((featureName, index) => {
|
|
1598
|
-
let status
|
|
1599
|
-
if (bools[index * 2]) {
|
|
1600
|
-
status = 'required'
|
|
1601
|
-
} else if (bools[index * 2 + 1]) {
|
|
1602
|
-
status = 'supported'
|
|
1603
|
-
} else {
|
|
1604
|
-
status = 'unsupported'
|
|
1605
|
-
}
|
|
1606
|
-
featureBits[featureName] = status
|
|
1607
|
-
})
|
|
1608
|
-
|
|
1609
|
-
const extraBits = bools.slice(FEATUREBIT_ORDER.length * 2)
|
|
1610
|
-
featureBits.extra_bits = {
|
|
1611
|
-
start_bit: FEATUREBIT_ORDER.length * 2,
|
|
1612
|
-
bits: extraBits,
|
|
1613
|
-
has_required: extraBits.reduce(
|
|
1614
|
-
(result, bit, index) =>
|
|
1615
|
-
index % 2 !== 0 ? result || false : result || bit,
|
|
1616
|
-
false
|
|
1617
|
-
)
|
|
1618
|
-
}
|
|
1619
|
-
|
|
1620
|
-
return featureBits
|
|
1621
|
-
}
|
|
1622
|
-
|
|
1623
|
-
function hrpToMillisat(hrpString, outputString) {
|
|
1624
|
-
let divisor, value
|
|
1625
|
-
if (hrpString.slice(-1).match(/^[munp]$/)) {
|
|
1626
|
-
divisor = hrpString.slice(-1)
|
|
1627
|
-
value = hrpString.slice(0, -1)
|
|
1628
|
-
} else if (hrpString.slice(-1).match(/^[^munp0-9]$/)) {
|
|
1629
|
-
throw new Error('Not a valid multiplier for the amount')
|
|
1630
|
-
} else {
|
|
1631
|
-
value = hrpString
|
|
1632
|
-
}
|
|
1633
|
-
|
|
1634
|
-
if (!value.match(/^\d+$/))
|
|
1635
|
-
throw new Error('Not a valid human readable amount')
|
|
1636
|
-
|
|
1637
|
-
const valueBN = BigInt(value)
|
|
1638
|
-
|
|
1639
|
-
const millisatoshisBN = divisor
|
|
1640
|
-
? (valueBN * MILLISATS_PER_BTC) / DIVISORS[divisor]
|
|
1641
|
-
: valueBN * MILLISATS_PER_BTC
|
|
1642
|
-
|
|
1643
|
-
if (
|
|
1644
|
-
(divisor === 'p' && !(valueBN % BigInt(10) === BigInt(0))) ||
|
|
1645
|
-
millisatoshisBN > MAX_MILLISATS
|
|
1646
|
-
) {
|
|
1647
|
-
throw new Error('Amount is outside of valid range')
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
return outputString ? millisatoshisBN.toString() : millisatoshisBN
|
|
1651
|
-
}
|
|
1652
|
-
|
|
1653
|
-
// decode will only have extra comments that aren't covered in encode comments.
|
|
1654
|
-
// also if anything is hard to read I'll comment.
|
|
1655
|
-
function decode(paymentRequest, network) {
|
|
1656
|
-
if (typeof paymentRequest !== 'string')
|
|
1657
|
-
throw new Error('Lightning Payment Request must be string')
|
|
1658
|
-
if (paymentRequest.slice(0, 2).toLowerCase() !== 'ln')
|
|
1659
|
-
throw new Error('Not a proper lightning payment request')
|
|
1660
|
-
|
|
1661
|
-
const sections = []
|
|
1662
|
-
const decoded = bech32.decode(paymentRequest, Number.MAX_SAFE_INTEGER)
|
|
1663
|
-
paymentRequest = paymentRequest.toLowerCase()
|
|
1664
|
-
const prefix = decoded.prefix
|
|
1665
|
-
let words = decoded.words
|
|
1666
|
-
let letters = paymentRequest.slice(prefix.length + 1)
|
|
1667
|
-
let sigWords = words.slice(-104)
|
|
1668
|
-
words = words.slice(0, -104)
|
|
1669
|
-
|
|
1670
|
-
// Without reverse lookups, can't say that the multipier at the end must
|
|
1671
|
-
// have a number before it, so instead we parse, and if the second group
|
|
1672
|
-
// doesn't have anything, there's a good chance the last letter of the
|
|
1673
|
-
// coin type got captured by the third group, so just re-regex without
|
|
1674
|
-
// the number.
|
|
1675
|
-
let prefixMatches = prefix.match(/^ln(\S+?)(\d*)([a-zA-Z]?)$/)
|
|
1676
|
-
if (prefixMatches && !prefixMatches[2])
|
|
1677
|
-
prefixMatches = prefix.match(/^ln(\S+)$/)
|
|
1678
|
-
if (!prefixMatches) {
|
|
1679
|
-
throw new Error('Not a proper lightning payment request')
|
|
1680
|
-
}
|
|
1681
|
-
|
|
1682
|
-
// "ln" section
|
|
1683
|
-
sections.push({
|
|
1684
|
-
name: 'lightning_network',
|
|
1685
|
-
letters: 'ln'
|
|
1686
|
-
})
|
|
1687
|
-
|
|
1688
|
-
// "bc" section
|
|
1689
|
-
const bech32Prefix = prefixMatches[1]
|
|
1690
|
-
let coinNetwork
|
|
1691
|
-
if (!network) {
|
|
1692
|
-
switch (bech32Prefix) {
|
|
1693
|
-
case DEFAULTNETWORK.bech32:
|
|
1694
|
-
coinNetwork = DEFAULTNETWORK
|
|
1695
|
-
break
|
|
1696
|
-
case TESTNETWORK.bech32:
|
|
1697
|
-
coinNetwork = TESTNETWORK
|
|
1698
|
-
break
|
|
1699
|
-
case REGTESTNETWORK.bech32:
|
|
1700
|
-
coinNetwork = REGTESTNETWORK
|
|
1701
|
-
break
|
|
1702
|
-
case SIMNETWORK.bech32:
|
|
1703
|
-
coinNetwork = SIMNETWORK
|
|
1704
|
-
break
|
|
1705
|
-
}
|
|
1706
|
-
} else {
|
|
1707
|
-
if (
|
|
1708
|
-
network.bech32 === undefined ||
|
|
1709
|
-
network.pubKeyHash === undefined ||
|
|
1710
|
-
network.scriptHash === undefined ||
|
|
1711
|
-
!Array.isArray(network.validWitnessVersions)
|
|
1712
|
-
)
|
|
1713
|
-
throw new Error('Invalid network')
|
|
1714
|
-
coinNetwork = network
|
|
1715
|
-
}
|
|
1716
|
-
if (!coinNetwork || coinNetwork.bech32 !== bech32Prefix) {
|
|
1717
|
-
throw new Error('Unknown coin bech32 prefix')
|
|
1718
|
-
}
|
|
1719
|
-
sections.push({
|
|
1720
|
-
name: 'coin_network',
|
|
1721
|
-
letters: bech32Prefix,
|
|
1722
|
-
value: coinNetwork
|
|
1723
|
-
})
|
|
1724
|
-
|
|
1725
|
-
// amount section
|
|
1726
|
-
const value = prefixMatches[2]
|
|
1727
|
-
let millisatoshis
|
|
1728
|
-
if (value) {
|
|
1729
|
-
const divisor = prefixMatches[3]
|
|
1730
|
-
millisatoshis = hrpToMillisat(value + divisor, true)
|
|
1731
|
-
sections.push({
|
|
1732
|
-
name: 'amount',
|
|
1733
|
-
letters: prefixMatches[2] + prefixMatches[3],
|
|
1734
|
-
value: millisatoshis
|
|
1735
|
-
})
|
|
1736
|
-
} else {
|
|
1737
|
-
millisatoshis = null
|
|
1738
|
-
}
|
|
1739
|
-
|
|
1740
|
-
// "1" separator
|
|
1741
|
-
sections.push({
|
|
1742
|
-
name: 'separator',
|
|
1743
|
-
letters: '1'
|
|
1744
|
-
})
|
|
1745
|
-
|
|
1746
|
-
// timestamp
|
|
1747
|
-
const timestamp = wordsToIntBE(words.slice(0, 7))
|
|
1748
|
-
words = words.slice(7) // trim off the left 7 words
|
|
1749
|
-
sections.push({
|
|
1750
|
-
name: 'timestamp',
|
|
1751
|
-
letters: letters.slice(0, 7),
|
|
1752
|
-
value: timestamp
|
|
1753
|
-
})
|
|
1754
|
-
letters = letters.slice(7)
|
|
1755
|
-
|
|
1756
|
-
let tagName, parser, tagLength, tagWords
|
|
1757
|
-
// we have no tag count to go on, so just keep hacking off words
|
|
1758
|
-
// until we have none.
|
|
1759
|
-
while (words.length > 0) {
|
|
1760
|
-
const tagCode = words[0].toString()
|
|
1761
|
-
tagName = TAGNAMES[tagCode] || 'unknown_tag'
|
|
1762
|
-
parser = TAGPARSERS[tagCode] || getUnknownParser(tagCode)
|
|
1763
|
-
words = words.slice(1)
|
|
1764
|
-
|
|
1765
|
-
tagLength = wordsToIntBE(words.slice(0, 2))
|
|
1766
|
-
words = words.slice(2)
|
|
1767
|
-
|
|
1768
|
-
tagWords = words.slice(0, tagLength)
|
|
1769
|
-
words = words.slice(tagLength)
|
|
1770
|
-
|
|
1771
|
-
sections.push({
|
|
1772
|
-
name: tagName,
|
|
1773
|
-
tag: letters[0],
|
|
1774
|
-
letters: letters.slice(0, 1 + 2 + tagLength),
|
|
1775
|
-
value: parser(tagWords) // see: parsers for more comments
|
|
1776
|
-
})
|
|
1777
|
-
letters = letters.slice(1 + 2 + tagLength)
|
|
1778
|
-
}
|
|
1779
|
-
|
|
1780
|
-
// signature
|
|
1781
|
-
sections.push({
|
|
1782
|
-
name: 'signature',
|
|
1783
|
-
letters: letters.slice(0, 104),
|
|
1784
|
-
value: hex.encode(bech32.fromWordsUnsafe(sigWords))
|
|
1785
|
-
})
|
|
1786
|
-
letters = letters.slice(104)
|
|
1787
|
-
|
|
1788
|
-
// checksum
|
|
1789
|
-
sections.push({
|
|
1790
|
-
name: 'checksum',
|
|
1791
|
-
letters: letters
|
|
1792
|
-
})
|
|
1793
|
-
|
|
1794
|
-
let result = {
|
|
1795
|
-
paymentRequest,
|
|
1796
|
-
sections,
|
|
1797
|
-
|
|
1798
|
-
get expiry() {
|
|
1799
|
-
let exp = sections.find(s => s.name === 'expiry')
|
|
1800
|
-
if (exp) return getValue('timestamp') + exp.value
|
|
1801
|
-
},
|
|
1802
|
-
|
|
1803
|
-
get route_hints() {
|
|
1804
|
-
return sections.filter(s => s.name === 'route_hint').map(s => s.value)
|
|
1805
|
-
}
|
|
1806
|
-
}
|
|
1807
|
-
|
|
1808
|
-
for (let name in TAGCODES) {
|
|
1809
|
-
if (name === 'route_hint') {
|
|
1810
|
-
// route hints can be multiple, so this won't work for them
|
|
1811
|
-
continue
|
|
1812
|
-
}
|
|
1813
|
-
|
|
1814
|
-
Object.defineProperty(result, name, {
|
|
1815
|
-
get() {
|
|
1816
|
-
return getValue(name)
|
|
1817
|
-
}
|
|
1818
|
-
})
|
|
1819
|
-
}
|
|
1820
|
-
|
|
1821
|
-
return result
|
|
1822
|
-
|
|
1823
|
-
function getValue(name) {
|
|
1824
|
-
let section = sections.find(s => s.name === name)
|
|
1825
|
-
return section ? section.value : undefined
|
|
1826
|
-
}
|
|
1827
|
-
}
|
|
1828
|
-
|
|
1829
|
-
module.exports = {
|
|
1830
|
-
decode,
|
|
1831
|
-
hrpToMillisat
|
|
1832
|
-
}
|
|
1833
|
-
|
|
1834
|
-
},{"@scure/base":3}]},{},[2]);
|