{"_id":"bolt04","_rev":"13-d6f418d29abb4c5c38178589fdc86559","name":"bolt04","dist-tags":{"latest":"1.3.0"},"versions":{"1.0.0":{"name":"bolt04","version":"1.0.0","keywords":["blinded-path","bolt","lightning","lightning-network","lnd","onion","onion-message","route-blinding","sphinx"],"author":{"url":"https://twitter.com/alexbosworth","name":"Alex Bosworth"},"license":"MIT","_id":"bolt04@1.0.0","maintainers":[{"name":"alexbosworth","email":"alex.bosworth+npm@gmail.com"}],"homepage":"https://github.com/alexbosworth/bolt04#readme","bugs":{"url":"https://github.com/alexbosworth/bolt04/issues"},"dist":{"shasum":"8eecfc454b3b87e6e20dd28c7c9db93be6baf4d9","tarball":"https://registry.npmjs.org/bolt04/-/bolt04-1.0.0.tgz","fileCount":70,"integrity":"sha512-DX26eZZKuvdL8Mk0AFMwoHrHdj/zmwG+hIt47UBTy4N4VR2zBe1F1RTItrKisU4qEysp94hh0ULxFc3FBhspEg==","signatures":[{"sig":"MEUCIQDISoWIaDVO21RsDyKovo7UuO5qIzjFU7JfrS8TVVx/vQIgS6wAy45Qu9xBQ7u+5DLzYaVg21jY04L3VVckCQrVt/M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":235569},"main":"index.js","engines":{"node":">=22"},"gitHead":"04230ba016a42d0db00c533d3f97beaf9d0e6a0a","scripts":{"test":"node --experimental-test-coverage --test"},"_npmUser":{"name":"alexbosworth","email":"alex.bosworth+npm@gmail.com"},"repository":{"url":"git+https://github.com/alexbosworth/bolt04.git","type":"git"},"_npmVersion":"11.19.0","description":"Utilities for working with bolt04 data formats","directories":{},"_nodeVersion":"24.18.0","dependencies":{"bolt01":"4.0.0","bolt07":"2.0.0","tiny-secp256k1":"2.2.4"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/bolt04_1.0.0_1789135015729_0.622888047906321","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"bolt04","version":"1.1.0","keywords":["blinded-path","bolt","lightning","lightning-network","lnd","onion","onion-message","route-blinding","sphinx"],"author":{"url":"https://twitter.com/alexbosworth","name":"Alex Bosworth"},"license":"MIT","_id":"bolt04@1.1.0","maintainers":[{"name":"alexbosworth","email":"alex.bosworth+npm@gmail.com"}],"homepage":"https://github.com/alexbosworth/bolt04#readme","bugs":{"url":"https://github.com/alexbosworth/bolt04/issues"},"dist":{"shasum":"232a7c7b705334aa5424fa4551a2405ee8c855c1","tarball":"https://registry.npmjs.org/bolt04/-/bolt04-1.1.0.tgz","fileCount":78,"integrity":"sha512-64fRgAFc5ztqT3DAiSlZS9Fu+NHCKfyLKn7WO+MFMrTNDdGHnMkOmCd6U6wfu7u/+xVl8mzhhyXfI5fkgdXdkA==","signatures":[{"sig":"MEUCIQD7HUcUE1jwznre2+Jfg7YC7ob0bZKDGijcJzKkzu/IogIgHnuS8QcKYgiU8R7QisZbUnhdr6yuVwcBrTSc0OYUeWM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIGBerwYNo7aCD9NpQ+ovVtvRouHQ3g+trCd5esk4EYdlAiAD+7Amq/IcPhnJ8qLosXZG4qhiXNyoyau4EWhV0GmFhQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":284495},"main":"index.js","engines":{"node":">=22"},"gitHead":"824af817ac9173d1f796e5a75df3c04f9728efb5","scripts":{"test":"node --experimental-test-coverage --test"},"_npmUser":{"name":"alexbosworth","email":"alex.bosworth+npm@gmail.com"},"repository":{"url":"git+https://github.com/alexbosworth/bolt04.git","type":"git"},"_npmVersion":"11.19.0","description":"Utilities for working with bolt04 data formats","directories":{},"_nodeVersion":"24.18.0","dependencies":{"bolt01":"4.0.0","bolt07":"2.0.0","tiny-secp256k1":"2.2.4"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/bolt04_1.1.0_1789743690500_0.8161046142156421","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"bolt04","version":"1.2.0","keywords":["blinded-path","bolt","lightning","lightning-network","lnd","onion","onion-message","route-blinding","sphinx"],"author":{"url":"https://twitter.com/alexbosworth","name":"Alex Bosworth"},"license":"MIT","_id":"bolt04@1.2.0","maintainers":[{"name":"alexbosworth","email":"alex.bosworth+npm@gmail.com"}],"homepage":"https://github.com/alexbosworth/bolt04#readme","bugs":{"url":"https://github.com/alexbosworth/bolt04/issues"},"dist":{"shasum":"1587c75b029c1942f87964b042799350cb977aaf","tarball":"https://registry.npmjs.org/bolt04/-/bolt04-1.2.0.tgz","fileCount":78,"integrity":"sha512-0synN8dpe0D7e5OjVI+M/L+tJaVQ/TBxWIsJejLdYmWCnB6cpmVqyKdtjKzK+VI4YK6gLP+v76kd6NsQlaXXKQ==","signatures":[{"sig":"MEUCIFBtai5Kr6mD7spqpUdxtsiYQlixkBcOT7w/fYzC/KPgAiEA2bj75Bqu2GLq12AQ+FA0vjhM/fd3Z7dgsv77uaD9scA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIEmKYcDb9WQA/lacVIH3tXJBqaLE4dkaVEQvOWFKIHvkAiAJTBFyArgomkUfZmfc1lo1B/APyq+CGeL9Hf1hA+D6QQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":289768},"main":"index.js","engines":{"node":">=22"},"gitHead":"0f0d50497a4bbc3279aff9ae93091211bb90633e","scripts":{"test":"node --experimental-test-coverage --test"},"_npmUser":{"name":"alexbosworth","email":"alex.bosworth+npm@gmail.com"},"repository":{"url":"git+https://github.com/alexbosworth/bolt04.git","type":"git"},"_npmVersion":"11.19.0","description":"Utilities for working with bolt04 data formats","directories":{},"_nodeVersion":"24.18.0","dependencies":{"bolt01":"4.0.0","bolt07":"2.0.0","tiny-secp256k1":"2.2.4"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/bolt04_1.2.0_1789837024344_0.0706246718434771","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"_id":"bolt04@1.3.0","bugs":{"url":"https://github.com/alexbosworth/bolt04/issues"},"dist":{"shasum":"de17e2fe79bc0030c258d05005d0554bb61dcb66","tarball":"https://registry.npmjs.org/bolt04/-/bolt04-1.3.0.tgz","fileCount":43,"integrity":"sha512-pwcpzoXcYx+N3ulH0OstL1MN21z5HstYvvMKFt7qb80d0PJ9BuppeFxtHHej8s3t+dJutsIoMfY/Sz4c227Nng==","signatures":[{"sig":"MEYCIQDSNT5Lkn+RKyXCSckC62jNcCj170nSr8k7+guskCAn6AIhAN6szgbbMRQ39rf5dCPP+VH99+ZkSfGEuVP3grUhcuu5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICvs/X0kfJCB1wfaC8W8W8e7EG0gGod6SEB2H3i8LNXFAiBXBLfzet9cko5wQVIDpVW81JU4QR2FDsXwl95WrBtduQ=="}],"unpackedSize":102929},"main":"index.js","name":"bolt04","author":{"url":"https://twitter.com/alexbosworth","name":"Alex Bosworth"},"engines":{"node":">=22"},"gitHead":"6a412a2439f98a0814bd1b2cf863ee18b1bc42aa","license":"MIT","scripts":{"test":"node --experimental-test-coverage --test"},"version":"1.3.0","_npmUser":{"name":"alexbosworth","email":"alex.bosworth+npm@gmail.com"},"homepage":"https://github.com/alexbosworth/bolt04#readme","keywords":["blinded-path","bolt","lightning","lightning-network","lnd","onion","onion-message","route-blinding","sphinx"],"repository":{"url":"git+https://github.com/alexbosworth/bolt04.git","type":"git"},"_npmVersion":"11.19.0","description":"Utilities for working with bolt04 data formats","directories":{},"maintainers":[{"name":"alexbosworth","email":"alex.bosworth+npm@gmail.com"}],"_nodeVersion":"24.18.0","dependencies":{"bolt01":"4.0.0","bolt07":"2.0.0","tiny-secp256k1":"2.2.4"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/bolt04_1.3.0_1790115919361_0.5293467600775612"}}},"time":{"created":"2026-09-11T13:56:55.658Z","modified":"2026-09-22T22:25:19.640Z","0.1.0":"2019-11-19T18:53:54.149Z","0.1.1":"2019-11-20T02:25:59.729Z","0.1.2":"2019-11-20T02:32:02.673Z","0.1.3":"2019-11-20T18:38:10.258Z","0.1.4":"2019-11-21T07:14:30.920Z","0.1.5":"2019-11-21T22:23:17.354Z","1.0.0":"2026-09-11T13:56:55.897Z","1.1.0":"2026-09-18T15:01:30.616Z","1.2.0":"2026-09-19T16:57:04.421Z","1.3.0":"2026-09-22T22:25:19.464Z"},"bugs":{"url":"https://github.com/alexbosworth/bolt04/issues"},"author":{"url":"https://twitter.com/alexbosworth","name":"Alex Bosworth"},"license":"MIT","homepage":"https://github.com/alexbosworth/bolt04#readme","keywords":["blinded-path","bolt","lightning","lightning-network","lnd","onion","onion-message","route-blinding","sphinx"],"repository":{"url":"git+https://github.com/alexbosworth/bolt04.git","type":"git"},"description":"Utilities for working with bolt04 data formats","maintainers":[{"name":"alexbosworth","email":"alex.bosworth+npm@gmail.com"}],"readme":"# BOLT04\n\nUtilities for working with Lightning Network [BOLT 04](https://github.com/lightning/bolts/blob/master/04-onion-routing.md)\n\n## Methods\n\n- [blindedPathFromHops](#blindedpathfromhops) - Blind a path of nodes to a\n    destination that ends with a path id\n- [blindedPathToNode](#blindedpathtonode) - Blind a path of nodes culminating\n    in a destination\n- [decryptBlindedPath](#decryptblindedpath) - Decrypt the data of a hop in a\n    blinded path\n- [onionForPath](#onionforpath) - Construct an onion message packet to send\n    into a published blinded path\n- [paymentPathFromChannels](#paymentpathfromchannels) - Blind a payment path\n    through channels to a destination with payment relay data\n\n### blindedPathFromHops\n\nCreate a blinded path from a series of hops to a destination\n\nThe final hop is the destination, which is given a path `id` for reference.\n\n    {\n      hops: [<Relaying Node Public Key Id Hex String>]\n      [id]: <Path Identifier Hex String>\n    }\n\n    @throws\n    <Error>\n\n    @returns\n    {\n      id: <Path Identifier Hex String>\n      key: <Path Key Hex String>\n      path: [{\n        encrypted_data: <Encrypted Data Hex String>\n        relay_key: <Blinded Node Public Key Hex String>\n      }]\n    }\n\nExample:\n\n```node\nconst {blindedPathFromHops} = require('bolt04');\n\n// Blind a path through a forwarding node to the destination with a path id\nconst {id, key, path} = blindedPathFromHops({\n  hops: [forwardingNodePublicKey, destinationNodePublicKey],\n});\n```\n\n### blindedPathToNode\n\nCreate a blinded path from a series of hops culminating in a destination\n\n    {\n      hops: [<Relaying Node Public Key Hex String>]\n    }\n\n    @throws\n    <Error>\n\n    @returns\n    {\n      key: <Path Key Hex String>\n      path: [{\n        encrypted_data: <Encrypted Data Hex String>\n        relay_key: <Blinded Node Public Key Hex String>\n      }]\n    }\n\nExample:\n\n```node\nconst {blindedPathToNode} = require('bolt04');\n\n// Blind a path through a forwarding node to a destination node id\nconst {key, path} = blindedPathToNode({\n  hops: [forwardingNodePublicKey, destinationNodePublicKey],\n});\n```\n\n### decryptBlindedPath\n\nDecrypt the data of a hop in a blinded path\n\n`secret` is a shared secret computed from the node identity and the path key\n\n`features` are a total whitelist of feature bits allowed on the path\n\n    {\n      encrypted: <Encrypted Data Hex String>\n      key: <Path Key Public Key Hex String>\n      secret: <Path Key Shared Secret Hex String>\n    }\n\n    @throws\n    <Error>\n\n    @returns\n    {\n      data: <Decrypted Data TLV Stream Hex String>\n      features: [<Allowed Feature Bit Number>]\n      [id]: <Path Identifier Hex String>\n      [next_channel_id]: <Next Hop Standard Format Channel Id String>\n      [next_node_id]: <Next Node Public Key Hex String>\n      next_path_key: <Next Hop Path Key Public Key Hex String>\n      records: [{\n        type: <Record Type Number String>\n        value: <Record Value Hex String>\n      }]\n    }\n\nExample:\n\n```node\nconst {decryptBlindedPath} = require('bolt04');\n\n// The node derives the shared secret with the path key using its private key\nconst {secret} = await ecdh({public_key: receivedPathKey});\n\n// A forwarding hop forwards to the next node id with the next path key\nconst {id, next_node_id, next_path_key} = decryptBlindedPath({\n  encrypted: encryptedRecipientData,\n  key: receivedPathKey,\n  secret,\n});\n```\n\n### onionForPath\n\nCreate an onion for a given path\n\n`inbound` are the blinded hops of the published blinded path\n\n`outbound` are nodes to reach the blinded path, ending with its introduction\n\n`records` are added to the payload of the final hop\n\n`reply` is a route back to the sender that ends with the sender's node id\n\nSend the `onion` to the first `outbound` node with the path's `key`\n\n    {\n      inbound: [{\n        encrypted_data: <Encrypted Data Hex String>\n        relay_key: <Blinded Relaying Public Key Into Destination Hex String>\n      }]\n      key: <Inbound Path Key Public Key Hex String>\n      outbound: [<Relaying Node Public Key Out of Source Hex String>]\n      [records]: [{\n        type: <Final Hop Additional Record Type Number String>\n        value: <Final Hop Additional Record Value Hex String>\n      }]\n      [reply]: [<Reply Path Relaying Node Public Key Back To Sender Hex String>]\n      [secret]: <Outbound Path Key Secret Private Key Hex String>\n    }\n\n    @throws\n    <Error>\n\n    @returns\n    {\n      [id]: <Reply Path Identifier Hex String>\n      key: <Path Key To Send With Onion Public Key Hex String>\n      onion: <Onion Packet Hex String>\n    }\n\nExample:\n\n```node\nconst {onionForPath} = require('bolt04');\n\n// Send through a relaying peer into a published blinded path with a message,\n// with a reply path back through the relaying peer to get an answer over\nconst {id, key, onion} = onionForPath({\n  inbound: publishedHops.map(hop => ({\n    encrypted_data: hop.encrypted_data,\n    relay_key: hop.blinded_public_key,\n  })),\n  key: publishedFirstPathKey,\n  outbound: [relayingPeerPublicKey, publishedFirstNodeId],\n  records: [{type: '65537', value: message}],\n  reply: [relayingPeerPublicKey, ownPublicKey],\n});\n```\n\n### paymentPathFromChannels\n\nCreate a blinded payment path from a series of channels to a destination\n\n    {\n      [blocks_until_expiry]: <Blocks Until Path Expires Number>\n      channels: [{\n        id: <Standard Format Channel Id String>\n        policies: [{\n          base_fee_mtokens: <Base Fee Millitokens String>\n          cltv_delta: <Locktime Delta Number>\n          fee_rate: <Fees Charged in Millitokens Per Million Number>\n          max_htlc_mtokens: <Maximum HTLC Millitokens Value String>\n          min_htlc_mtokens: <Minimum HTLC Millitokens Value String>\n          public_key: <Node Identity Public Key Hex String>\n        }]\n      }]\n      cltv_delta: <Final Hop CLTV Delta Number>\n      current_block_height: <Current Block Height Number>\n      destination: <Destination Node Public Key Hex String>\n      [receiver_base_fee_mtokens]: <Receiver Base Fee Millitokens String>\n      [receiver_fee_rate]: <Receiver Fee Rate Millitokens Per Million Number>\n      [hop_count]: <Total Padding Inclusive Blinded Hop Count Number>\n      [id]: <Path Identifier Hex String>\n      max_mtokens: <Maximum Millitokens Number Allowed Through Path String>\n    }\n\n    @throws\n    <Error>\n\n    @returns\n    {\n      base_fee_mtokens: <Accumulated Base Fee Millitokens String>\n      cltv_delta: <Accumulated CLTV Expiry Delta Number>\n      fee_rate: <Accumulated Fee Rate Millitokens Per Million Number>\n      hops: [{\n        encrypted_data: <Encrypted Recipient Data Hex String>\n        relay_key: <Blinded Node Public Key Hex String>\n      }]\n      id: <Path Identifier Hex String>\n      introduction_node: <Introduction Node Public Key Hex String>\n      key: <First Hop Path Key Public Key Hex String>\n      max_htlc_mtokens: <Maximum HTLC Millitokens String>\n      min_htlc_mtokens: <Minimum HTLC Millitokens String>\n    }\n\nExample:\n\n```node\nconst {paymentPathFromChannels} = require('bolt04');\n\n// Blind a path through a peer's channel to include in an invoice with its fees\nconst path = paymentPathFromChannels({\n  channels: [{id: peerChannelId, policies: [peerPolicy, ownPolicy]}],\n  cltv_delta: finalCltvDelta,\n  current_block_height: currentBlockHeight,\n  destination: ownPublicKey,\n  max_mtokens: invoiceMtokens,\n});\n```\n","readmeFilename":"README.md"}