Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: New method of dealing with networks #76

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions payreq.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,6 @@ export declare function satToHrp(satoshis: number | string): string;
export declare function millisatToHrp(millisatoshis: number | string): string;
export declare function hrpToSat(hrpString: string, outputString?: boolean): string | BN;
export declare function hrpToMillisat(hrpString: string, outputString?: boolean): string | BN;
export declare function setDefaultNetworks(newDefaults: Network[]): void;
export declare function appendNetwork(network: Network): void;
export declare function prependNetwork(network: Network): void;
67 changes: 46 additions & 21 deletions payreq.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ const SIMNETWORK = {
scriptHash: 0x7b,
validWitnessVersions: [0, 1]
}
let DEFAULT_NETWORKS = [
DEFAULTNETWORK, // First network has special meaning and is default
TESTNETWORK,
REGTESTNETWORK,
SIMNETWORK
]
const DEFAULTEXPIRETIME = 3600
const DEFAULTCLTVEXPIRY = 9
const DEFAULTDESCRIPTION = ''
Expand Down Expand Up @@ -570,8 +576,8 @@ function encode (inputData, addDefaults) {
// if no cointype is defined, set to testnet
let coinTypeObj
if (data.network === undefined && !canReconstruct) {
data.network = DEFAULTNETWORK
coinTypeObj = DEFAULTNETWORK
data.network = DEFAULT_NETWORKS[0]
coinTypeObj = DEFAULT_NETWORKS[0]
} else if (data.network === undefined && canReconstruct) {
throw new Error('Need network for proper payment request reconstruction')
} else {
Expand Down Expand Up @@ -897,27 +903,14 @@ function decode (paymentRequest, network) {
const bech32Prefix = prefixMatches[1]
let coinNetwork
if (!network) {
switch (bech32Prefix) {
case DEFAULTNETWORK.bech32:
coinNetwork = DEFAULTNETWORK
break
case TESTNETWORK.bech32:
coinNetwork = TESTNETWORK
break
case REGTESTNETWORK.bech32:
coinNetwork = REGTESTNETWORK
break
case SIMNETWORK.bech32:
coinNetwork = SIMNETWORK
for (const defaultNetwork of DEFAULT_NETWORKS) {
if (defaultNetwork.bech32 === bech32Prefix) {
coinNetwork = defaultNetwork
break
}
}
} else {
if (
network.bech32 === undefined ||
network.pubKeyHash === undefined ||
network.scriptHash === undefined ||
!Array.isArray(network.validWitnessVersions)
) throw new Error('Invalid network')
if (!isNetwork(network)) throw new Error('Invalid network')
coinNetwork = network
}
if (!coinNetwork || coinNetwork.bech32 !== bech32Prefix) {
Expand Down Expand Up @@ -1026,12 +1019,44 @@ function getTagsObject (tags) {
return result
}

function isNetwork (network) {
return typeof network.bech32 === 'string' &&
typeof network.pubKeyHash === 'number' &&
typeof network.scriptHash === 'number' &&
Array.isArray(network.validWitnessVersions) &&
network.validWitnessVersions.every(item => typeof item === 'number')
}

function setDefaultNetworks (newDefaults) {
if (!Array.isArray(newDefaults) || newDefaults.length === 0 || newDefaults.some(network => !isNetwork(network))) {
throw new Error('setDefaultNetworks argument contained invalid data')
}
DEFAULT_NETWORKS = newDefaults
}

function appendNetwork (network) {
if (!isNetwork(network)) {
throw new Error('appendNetwork argument contained invalid data')
}
DEFAULT_NETWORKS.push(network)
}

function prependNetwork (network) {
if (!isNetwork(network)) {
throw new Error('prependNetwork argument contained invalid data')
}
DEFAULT_NETWORKS.unshift(network)
}

module.exports = {
encode,
decode,
sign,
satToHrp,
millisatToHrp,
hrpToSat,
hrpToMillisat
hrpToMillisat,
setDefaultNetworks,
appendNetwork,
prependNetwork
}
40 changes: 40 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,3 +323,43 @@ tape('can encode and decode small timestamp', (t) => {
t.same(reEncoded.paymentRequest, signedData.paymentRequest)
t.end()
})

tape('can set default networks', (t) => {
t.throws(() => {
lnpayreq.setDefaultNetworks('not an array')
}, new RegExp('setDefaultNetworks argument contained invalid data'))
t.throws(() => {
lnpayreq.setDefaultNetworks([])
}, new RegExp('setDefaultNetworks argument contained invalid data'))
t.throws(() => {
lnpayreq.setDefaultNetworks([{}])
}, new RegExp('setDefaultNetworks argument contained invalid data'))
lnpayreq.setDefaultNetworks([{
bech32: 'bcrt',
pubKeyHash: 0x6f,
scriptHash: 0xc4,
validWitnessVersions: [0, 1]
}])

t.throws(() => {
lnpayreq.prependNetwork({})
}, new RegExp('prependNetwork argument contained invalid data'))
lnpayreq.prependNetwork({
bech32: 'bcrt',
pubKeyHash: 0x6f,
scriptHash: 0xc4,
validWitnessVersions: [0, 1]
})

t.throws(() => {
lnpayreq.appendNetwork({})
}, new RegExp('appendNetwork argument contained invalid data'))
lnpayreq.appendNetwork({
bech32: 'bcrt',
pubKeyHash: 0x6f,
scriptHash: 0xc4,
validWitnessVersions: [0, 1]
})

t.end()
})
Loading